1 |
1 |
import random
|
2 |
2 |
import time
|
3 |
3 |
import logging
|
4 |
4 |
import urllib
|
5 |
5 |
import six
|
6 |
6 |
import urlparse
|
7 |
7 |
from functools import wraps
|
|
8 |
import inspect
|
|
9 |
import pickle
|
8 |
10 |
|
9 |
11 |
from importlib import import_module
|
10 |
12 |
|
11 |
13 |
from django.conf import settings
|
12 |
14 |
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
|
13 |
|
from django.core.exceptions import ImproperlyConfigured
|
|
15 |
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
|
|
16 |
from django.contrib.auth import _clean_credentials
|
|
17 |
from django.contrib.auth.signals import user_login_failed
|
14 |
18 |
from django.core import urlresolvers
|
15 |
19 |
from django.http.request import QueryDict
|
16 |
20 |
from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login
|
17 |
21 |
from django import forms
|
18 |
22 |
from django.forms.util import ErrorList
|
19 |
23 |
from django.utils import html, http
|
20 |
24 |
from django.utils.translation import ugettext as _
|
21 |
25 |
|
... | ... | |
300 |
304 |
'''Find an authentication event occurring during this session and matching
|
301 |
305 |
this nonce.'''
|
302 |
306 |
authentication_events = request.session.pop(constants.AUTHENTICATION_EVENTS_SESSION_KEY, [])
|
303 |
307 |
for event in authentication_events:
|
304 |
308 |
if event.get('nonce') == nonce:
|
305 |
309 |
return event
|
306 |
310 |
return None
|
307 |
311 |
|
308 |
|
def login(request, user, how, **kwargs):
|
309 |
|
'''Login a user model, record the authentication event and redirect to next
|
310 |
|
URL or settings.LOGIN_REDIRECT_URL.'''
|
311 |
|
auth_login(request, user)
|
312 |
|
record_authentication_event(request, how)
|
313 |
|
return continue_to_next_url(request, **kwargs)
|
314 |
|
|
315 |
312 |
def login_require(request, next_url=None, login_url='auth_login', **kwargs):
|
316 |
313 |
'''Require a login and come back to current URL'''
|
317 |
314 |
next_url = next_url or request.get_full_path()
|
318 |
315 |
params = kwargs.setdefault('params', {})
|
319 |
316 |
params[REDIRECT_FIELD_NAME] = next_url
|
320 |
317 |
return redirect(request, login_url, **kwargs)
|
321 |
318 |
|
322 |
319 |
def redirect_to_logout(request, next_url=None, logout_url='auth_logout', **kwargs):
|
... | ... | |
434 |
431 |
|
435 |
432 |
def csrf_token_check(request, form):
|
436 |
433 |
'''Check a request for CSRF cookie validation, and add an error to the form
|
437 |
434 |
if check fails.
|
438 |
435 |
'''
|
439 |
436 |
if form.is_valid() and not getattr(request, 'csrf_processing_done', False):
|
440 |
437 |
msg = _('The form was out of date, please try again.')
|
441 |
438 |
form._errors[forms.forms.NON_FIELD_ERRORS] = ErrorList([msg])
|
|
439 |
|
|
440 |
def _get_backends(return_tuples=False):
|
|
441 |
backends = []
|
|
442 |
for backend_path in settings.AUTHENTICATION_BACKENDS:
|
|
443 |
backend = load_backend(backend_path)
|
|
444 |
backends.append((backend, backend_path) if return_tuples else backend)
|
|
445 |
if not backends:
|
|
446 |
raise ImproperlyConfigured(
|
|
447 |
'No authentication backends have been defined. Does '
|
|
448 |
'AUTHENTICATION_BACKENDS contain anything?'
|
|
449 |
)
|
|
450 |
return backends
|
|
451 |
|
|
452 |
def authenticate(**credentials):
|
|
453 |
"""
|
|
454 |
If the given credentials are valid, return a User object.
|
|
455 |
"""
|
|
456 |
for backend, backend_path in _get_backends(return_tuples=True):
|
|
457 |
try:
|
|
458 |
inspect.getcallargs(backend.authenticate, **credentials)
|
|
459 |
except TypeError:
|
|
460 |
# This backend doesn't accept these credentials as arguments. Try the next one.
|
|
461 |
continue
|
|
462 |
|
|
463 |
try:
|
|
464 |
user = backend.authenticate(**credentials)
|
|
465 |
except PermissionDenied:
|
|
466 |
# This backend says to stop in our tracks - this user should not be allowed in at all.
|
|
467 |
return None
|
|
468 |
if user is None:
|
|
469 |
continue
|
|
470 |
# Allow backends to return multiple matches
|
|
471 |
if isinstance(user, (list, tuple)):
|
|
472 |
users = user
|
|
473 |
for user in users:
|
|
474 |
# Annotate the user object with the path of the backend.
|
|
475 |
user.backend = backend_path
|
|
476 |
return users
|
|
477 |
else:
|
|
478 |
# Annotate the user object with the path of the backend.
|
|
479 |
user.backend = backend_path
|
|
480 |
return user
|
|
481 |
|
|
482 |
# The credentials supplied are invalid to all backends, fire signal
|
|
483 |
user_login_failed.send(sender=__name__,
|
|
484 |
credentials=_clean_credentials(credentials))
|
|
485 |
|
|
486 |
MULTIPLE_USER_SESSION_KEY = 'multiple_users'
|
|
487 |
|
|
488 |
def login(request, user, how, multiple_login_url='a2-multiple-login', **kwargs):
|
|
489 |
'''Login a user or if user is a list of users, redirect so that user can
|
|
490 |
pick one.
|
|
491 |
'''
|
|
492 |
if isinstance(user, (list, tuple)):
|
|
493 |
request.session[MULTIPLE_USER_SESSION_KEY] = pickle.dumps(user)
|
|
494 |
return redirect_to_login(request, login_url=multiple_login_url)
|
|
495 |
else:
|
|
496 |
auth_login(request, user)
|
|
497 |
record_authentication_event(request, how)
|
|
498 |
return continue_to_next_url(request, **kwargs)
|
|
499 |
|
|
500 |
|
442 |
|
-
|