web/lib/django/contrib/auth/__init__.py
changeset 38 77b6da96e6f1
equal deleted inserted replaced
37:8d941af65caf 38:77b6da96e6f1
       
     1 import datetime
       
     2 from warnings import warn
       
     3 from django.core.exceptions import ImproperlyConfigured
       
     4 from django.utils.importlib import import_module
       
     5 
       
     6 SESSION_KEY = '_auth_user_id'
       
     7 BACKEND_SESSION_KEY = '_auth_user_backend'
       
     8 REDIRECT_FIELD_NAME = 'next'
       
     9 
       
    10 def load_backend(path):
       
    11     i = path.rfind('.')
       
    12     module, attr = path[:i], path[i+1:]
       
    13     try:
       
    14         mod = import_module(module)
       
    15     except ImportError, e:
       
    16         raise ImproperlyConfigured('Error importing authentication backend %s: "%s"' % (module, e))
       
    17     except ValueError, e:
       
    18         raise ImproperlyConfigured('Error importing authentication backends. Is AUTHENTICATION_BACKENDS a correctly defined list or tuple?')
       
    19     try:
       
    20         cls = getattr(mod, attr)
       
    21     except AttributeError:
       
    22         raise ImproperlyConfigured('Module "%s" does not define a "%s" authentication backend' % (module, attr))
       
    23     try:
       
    24         getattr(cls, 'supports_object_permissions')
       
    25     except AttributeError:
       
    26         warn("Authentication backends without a `supports_object_permissions` attribute are deprecated. Please define it in %s." % cls,
       
    27              PendingDeprecationWarning)
       
    28         cls.supports_object_permissions = False
       
    29     try:
       
    30         getattr(cls, 'supports_anonymous_user')
       
    31     except AttributeError:
       
    32         warn("Authentication backends without a `supports_anonymous_user` attribute are deprecated. Please define it in %s." % cls,
       
    33              PendingDeprecationWarning)
       
    34         cls.supports_anonymous_user = False
       
    35     return cls()
       
    36 
       
    37 def get_backends():
       
    38     from django.conf import settings
       
    39     backends = []
       
    40     for backend_path in settings.AUTHENTICATION_BACKENDS:
       
    41         backends.append(load_backend(backend_path))
       
    42     return backends
       
    43 
       
    44 def authenticate(**credentials):
       
    45     """
       
    46     If the given credentials are valid, return a User object.
       
    47     """
       
    48     for backend in get_backends():
       
    49         try:
       
    50             user = backend.authenticate(**credentials)
       
    51         except TypeError:
       
    52             # This backend doesn't accept these credentials as arguments. Try the next one.
       
    53             continue
       
    54         if user is None:
       
    55             continue
       
    56         # Annotate the user object with the path of the backend.
       
    57         user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
       
    58         return user
       
    59 
       
    60 def login(request, user):
       
    61     """
       
    62     Persist a user id and a backend in the request. This way a user doesn't
       
    63     have to reauthenticate on every request.
       
    64     """
       
    65     if user is None:
       
    66         user = request.user
       
    67     # TODO: It would be nice to support different login methods, like signed cookies.
       
    68     user.last_login = datetime.datetime.now()
       
    69     user.save()
       
    70 
       
    71     if SESSION_KEY in request.session:
       
    72         if request.session[SESSION_KEY] != user.id:
       
    73             # To avoid reusing another user's session, create a new, empty
       
    74             # session if the existing session corresponds to a different
       
    75             # authenticated user.
       
    76             request.session.flush()
       
    77     else:
       
    78         request.session.cycle_key()
       
    79     request.session[SESSION_KEY] = user.id
       
    80     request.session[BACKEND_SESSION_KEY] = user.backend
       
    81     if hasattr(request, 'user'):
       
    82         request.user = user
       
    83 
       
    84 def logout(request):
       
    85     """
       
    86     Removes the authenticated user's ID from the request and flushes their
       
    87     session data.
       
    88     """
       
    89     request.session.flush()
       
    90     if hasattr(request, 'user'):
       
    91         from django.contrib.auth.models import AnonymousUser
       
    92         request.user = AnonymousUser()
       
    93 
       
    94 def get_user(request):
       
    95     from django.contrib.auth.models import AnonymousUser
       
    96     try:
       
    97         user_id = request.session[SESSION_KEY]
       
    98         backend_path = request.session[BACKEND_SESSION_KEY]
       
    99         backend = load_backend(backend_path)
       
   100         user = backend.get_user(user_id) or AnonymousUser()
       
   101     except KeyError:
       
   102         user = AnonymousUser()
       
   103     return user