Skip to content

django-oauth-toolkit compatibility #426

@nickdjones

Description

@nickdjones

I feel like I'm being stupid here as these are both Jazzband projects but I can't get my head around how to get django-axes working with django-oauth-toolkit.

If I try and authenticate without changing anything, it will complain that

File "/home/user/.virtualenvs/project/lib/python3.6/site-packages/oauth2_provider/oauth2_validators.py", line 520, in validate_user
    u = authenticate(username=username, password=password)
  File "/home/user/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/auth/__init__.py", line 70, in authenticate
    user = _authenticate_with_backend(backend, backend_path, request, credentials)
  File "/home/user/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/auth/__init__.py", line 116, in _authenticate_with_backend
    return backend.authenticate(*args, **credentials)
  File "/home/user/.virtualenvs/project/lib/python3.6/site-packages/axes/backends.py", line 37, in authenticate
    raise AxesModelBackend.RequestParameterRequired()
axes.backends.AxesModelBackend.RequestParameterRequired: AxesModelBackend requires calls to authenticate to pass `request` as an argument.

The cause of this can be seen quite clearly in the stacktrace - because of this call in oauth2_validators: https://github.com/jazzband/django-oauth-toolkit/blob/master/oauth2_provider/oauth2_validators.py#L615

However if I then customise DOT and set a custom validator including request in authenticate() as follows:

OAUTH2_PROVIDER = {
    'OAUTH2_VALIDATOR_CLASS': 'custom.app.MyOAuth2Validator',
    'SCOPES': {'read': 'Read scope', 'write': 'Write scope'},
}
class MyOAuth2Validator(OAuth2Validator):
    def validate_user(self, username, password, client, request, *args, **kwargs):
        """
        Check username and password correspond to a valid and active User
        """
        u = authenticate(request=request, username=username, password=password)
        if u is not None and u.is_active:
            request.user = u
            return True
        return False

it then throws the error:

File "/home/user/.virtualenvs/project/lib/python3.6/site-packages/axes/attempts.py", line 178, in is_already_locked
    ip = get_client_ip(request)
  File "/home/user/.virtualenvs/project/lib/python3.6/site-packages/axes/utils.py", line 69, in get_client_ip
    request_header_order=settings.AXES_META_PRECEDENCE_ORDER,
  File "/home/user/.virtualenvs/project/lib/python3.6/site-packages/ipware/ip2.py", line 25, in get_client_ip
    value = util.get_request_meta(request, key)
  File "/home/user/.virtualenvs/project/lib/python3.6/site-packages/ipware/utils.py", line 66, in get_request_meta
    value = request.META.get(key, request.META.get(key.replace('_', '-'), '')).strip()
  File "/home/user/.virtualenvs/project/lib/python3.6/site-packages/oauthlib/common.py", line 435, in __getattr__
    raise AttributeError(name)
AttributeError: META

This again makes sense, because the Request inside the validator is from oauthlib.common and not from Django and therefore doesn't have any META data.

How on earth are these supposed to work together??

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions