Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #5016 - Views mutate user object when using force_request #5066

Closed
wants to merge 1 commit into from

Conversation

alaminopu
Copy link
Contributor

PR will fix issue - #5016

@@ -22,7 +23,7 @@


def force_authenticate(request, user=None, token=None):
request._force_auth_user = user
request._force_auth_user = copy.deepcopy(user)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little concerned about the use of deepcopy here. It's pretty much magic, and there's no guarantee that it might not fail in some cases (user can be a custom model, or have been modified by middleware, and might have almost anything stored in state on it)

I'm not sure what the best action is here. Perhaps we should catch exceptions and fall back to simply assigning user, tho that seems problematic too.

Perhaps I'm being overly cautious about the possibility of deepcopy failing here?

Copy link
Member

@rpkilby rpkilby May 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've ran into some weird issues recently with deepcopy in regards to the request object. Although it'd be unusual, it's not inconceivable that the request would be somehow accessible from the user via an authenticator or middleware, which deepcopy would pick up. I'm also hesitant about deepcopy here.

Although, if this is happening before any middleware or authenticator machinery, then it's probably fine?

@tomchristie
Copy link
Member

One comment for open discussion.

@tomchristie
Copy link
Member

On balance I'd say let's accept this, but defer it to the 3.7 release, rather than introduce it in a minor release.

@carltongibson
Copy link
Collaborator

carltongibson commented Sep 25, 2017

@tomchristie We can have this — with #4102 tests are there — but just wondering if a note in the docs saying "You may need to call refresh_from_db on your user if the in-memory state will not be correct" is not a better option?

This was from the issue:

        # At this point in the test code one would expect that user1
        # wouldn't have any 'gender' property, since we never saved the
        # user model in the 'put' method. However, the implementation of 
        # force_authenticate uses the user object that's passed in directly
        # instead of doing `user = copy.deepcopy(user).`

        request2 = self.factory.get('/user')
        force_authenticate(request2, user=user1)
        resp2 = self.view(request2)

But here we know user1 isn't correct. So user1.refresh_from_db() needs to be called before reusing the user.

(What do you think?)

@tomchristie
Copy link
Member

@carltongibson I think i'd prefer that, yup - good call. deepcopy is a really fuzzy bit of behaviour to introduce here.

@carltongibson
Copy link
Collaborator

OK. I'll make it so.

carltongibson added a commit to carltongibson/django-rest-framework that referenced this pull request Sep 25, 2017
…in case you’re reusing the same in-memory user whilst updating it in the DB.

Closes encode#5016, closes encode#5066, closes encode#4102
carltongibson added a commit that referenced this pull request Sep 25, 2017
…in case you’re reusing the same in-memory user whilst updating it in the DB.

Closes #5016, closes #5066, closes #4102
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants