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