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

added call to authentication callback, rewrote creds extraction #68

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 55 additions & 25 deletions jsonrpc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ def decorator(func):
X['arg_names'] = authentication_arguments + X['arg_names']
X['name'] = _inject_args(X['name'], ('String', 'String'))
from django.contrib.auth import authenticate as _authenticate
from django.contrib.auth.models import User
# allow replacement of User Model - is User actually used?
# this breaks Django 1.4 compatibilty, so commenting out as
# it seems the model is not used anywhere directly anyway
# import django.contrib.auth
# User = django.contrib.auth.get_user_model()
else:
authenticate = authenticated
@six.wraps(func)
Expand All @@ -198,32 +202,58 @@ def _func(request, *args, **kwargs):
if ((user is not None
and six.callable(is_authenticated) and not is_authenticated())
or user is None):
user = None
try:
creds = args[:len(authentication_arguments)]
if len(creds) == 0:
raise IndexError
# Django's authenticate() method takes arguments as dict
user = _authenticate(username=creds[0], password=creds[1], *creds[2:])
if user is not None:
args = args[len(authentication_arguments):]
except IndexError:
auth_kwargs = {}
try:
for auth_kwarg in authentication_arguments:
auth_kwargs[auth_kwarg] = kwargs[auth_kwarg]
except KeyError:

creds = {}
# first look for creds in kwargs
for auth_kwarg in authentication_arguments:
if auth_kwarg in kwargs:
creds[auth_kwarg] = kwargs.pop(auth_kwarg)

if not len(creds)==len(authentication_arguments):
# not able to find (all) auth args in kwargs, trying args
creds = {}
# try to blindly use the first elements in args as kwargs...
try:
index = 0
for auth_kwarg in authentication_arguments:
creds[auth_kwarg] = args[index]
index+=1
args=args[index:]
except IndexError:
creds={}

if not len(creds)==len(authentication_arguments):
# still no success with finding the credentials
raise InvalidParamsError(
'Authenticated methods require at least '
'[%s] or {%s} arguments', authentication_arguments)

user = _authenticate(**auth_kwargs)
if user is not None:
for auth_kwarg in authentication_arguments:
kwargs.pop(auth_kwarg)
if user is None:
raise InvalidCredentialsError
request.user = user
'[%s] or {%s} arguments',
(authentication_arguments, authentication_arguments)
)

# if callback is provided, calling callback with creds
if callable(authenticated):

try:
user = authenticated(**creds)
except Exception:
user = None
# callback threw exception

if user is not None:
request.user = user
return func(request, *args, **kwargs)
else:
raise InvalidCredentialsError

# finally trying djangos auth, e.g. callback was not provided

# Django's authenticate() method takes arguments as dict,
# default configuration of authentication_arguments matches.
user = _authenticate(**creds)
if user is None:
raise InvalidCredentialsError

request.user = user
return func(request, *args, **kwargs)
else:
_func = func
Expand Down