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

AttributeError: 'ObjectPermissionBackend' object has no attribute 'get_user' #46

Closed
blueyed opened this issue Nov 16, 2016 · 8 comments
Closed

Comments

@blueyed
Copy link

blueyed commented Nov 16, 2016

I am trying to use Django's Client.force_login during tests, which appears to trigger an AttributeError when using ObjectPermissionBackend in settings.AUTHENTICATION_BACKENDS:

[25]   …/app/tests/test_middleware.py(23)test_ddt_middleware_normal()
-> response = client.get('/api/', HTTP_ACCEPT='text/html')
[26]   …/Vcs/django/django/test/client.py(531)get()
-> **extra)
[27]   …/Vcs/django/django/test/client.py(333)get()
-> return self.generic('GET', path, secure=secure, **r)
[28]   …/Vcs/django/django/test/client.py(409)generic()
-> return self.request(**r)
[29]   …/Vcs/django/django/test/client.py(478)request()
-> response = self.handler(environ)
[30]   …/Vcs/django/django/utils/six.py(686)reraise()
-> raise value
[31]   …/Vcs/django/django/core/handlers/exception.py(39)inner()
-> response = get_response(request)
[32]   …/app/middleware.py(37)__call__()
-> if not (request.user and
[33]   …/Vcs/django/django/utils/functional.py(234)inner()
-> self._setup()
[34]   …/Vcs/django/django/utils/functional.py(380)_setup()
-> self._wrapped = self._setupfunc()
[35]   …/Vcs/django/django/contrib/auth/middleware.py(24)<lambda>()
-> request.user = SimpleLazyObject(lambda: get_user(request))
[36]   …/Vcs/django/django/contrib/auth/middleware.py(12)get_user()
-> request._cached_user = auth.get_user(request)
[37] > …/Vcs/django/django/contrib/auth/__init__.py(187)get_user()
-> user = backend.get_user(user_id)

The pytest test looks like this:

def test_foobar(db, client, some_user, some_group):
    some_user.groups.add(some_group)
    some_user.save()
    client.force_login(some_user)

Setting a password and using login works:

def test_foobar(db, client, some_user, some_group):
    some_user.groups.add(some_group)
    some_user.set_password('password')
    some_user.save()
    assert client.login(username=some_user.username,
                        password='password')

According to the documentation the get_user method is required:
https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#writing-an-authentication-backend.

@blueyed
Copy link
Author

blueyed commented Nov 16, 2016

I think you are meant to pass in an explicit backend, if the first one does not work. Closing.

Django code reference: https://github.com/django/django/blob/59bbacf88db1b533ae05ea38e01b5e1ec9f59622/django/test/client.py#L628-L632

@blueyed blueyed closed this as completed Nov 16, 2016
@orf
Copy link
Contributor

orf commented Nov 23, 2016

I think this should be added to the documentation, this is quite confusing.

@blueyed
Copy link
Author

blueyed commented Nov 24, 2016

@orf
Please consider creating a PR then.

@dfunckt
Copy link
Owner

dfunckt commented Nov 28, 2016

Reopening to have the issue as a reminder to investigate whether adding get_user to the backend breaks other stuff, as that would be the proper "fix" here.

@dfunckt dfunckt reopened this Nov 28, 2016
@orf
Copy link
Contributor

orf commented Nov 28, 2016

I don't think that's a good idea, I think it's a Django problem. Instead of blindly getting the first auth backend it should be a little smart and skip ones without a get_user.

@dfunckt
Copy link
Owner

dfunckt commented Nov 28, 2016

Hmm, yeah, I went through Django's code and it seems it's not a good idea -- you'd force_login a user but you'd later get AnonymousUser back instead, if the backend's get_user method returned None (as rules' one would).

Agreed, the proper way forward is documenting it here and raising an issue with Django.

@orf
Copy link
Contributor

orf commented Nov 28, 2016

I've made a ticket on the Django bug tracker: https://code.djangoproject.com/ticket/27542#ticket

PR #47 adds a note to the readme about this.

@blueyed
Copy link
Author

blueyed commented Dec 2, 2016

Awesome, it got fixed in Django: django/django@47744a0.
Let's close it here then.

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

No branches or pull requests

3 participants