Django

Code

root/django/trunk/django/contrib/auth/backends.py

Revision 10063, 5.2 kB (checked in by gwilson, 4 months ago)

Fixed #689 -- Added a middleware and authentication backend to contrib.auth for supporting external authentication solutions. Thanks to all who contributed to this patch, including Ian Holsman, garthk, Koen Biermans, Marc Fargas, ekarulf, and Ramiro Morales.

  • Property svn:eol-style set to native
Line 
1 try:
2     set
3 except NameError:
4     from sets import Set as set # Python 2.3 fallback
5
6 from django.db import connection
7 from django.contrib.auth.models import User
8
9
10 class ModelBackend(object):
11     """
12     Authenticates against django.contrib.auth.models.User.
13     """
14     # TODO: Model, login attribute name and password attribute name should be
15     # configurable.
16     def authenticate(self, username=None, password=None):
17         try:
18             user = User.objects.get(username=username)
19             if user.check_password(password):
20                 return user
21         except User.DoesNotExist:
22             return None
23
24     def get_group_permissions(self, user_obj):
25         """
26         Returns a set of permission strings that this user has through his/her
27         groups.
28         """
29         if not hasattr(user_obj, '_group_perm_cache'):
30             cursor = connection.cursor()
31             # The SQL below works out to the following, after DB quoting:
32             # cursor.execute("""
33             #     SELECT ct."app_label", p."codename"
34             #     FROM "auth_permission" p, "auth_group_permissions" gp, "auth_user_groups" ug, "django_content_type" ct
35             #     WHERE p."id" = gp."permission_id"
36             #         AND gp."group_id" = ug."group_id"
37             #         AND ct."id" = p."content_type_id"
38             #         AND ug."user_id" = %s, [self.id])
39             qn = connection.ops.quote_name
40             sql = """
41                 SELECT ct.%s, p.%s
42                 FROM %s p, %s gp, %s ug, %s ct
43                 WHERE p.%s = gp.%s
44                     AND gp.%s = ug.%s
45                     AND ct.%s = p.%s
46                     AND ug.%s = %%s""" % (
47                 qn('app_label'), qn('codename'),
48                 qn('auth_permission'), qn('auth_group_permissions'),
49                 qn('auth_user_groups'), qn('django_content_type'),
50                 qn('id'), qn('permission_id'),
51                 qn('group_id'), qn('group_id'),
52                 qn('id'), qn('content_type_id'),
53                 qn('user_id'),)
54             cursor.execute(sql, [user_obj.id])
55             user_obj._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
56         return user_obj._group_perm_cache
57
58     def get_all_permissions(self, user_obj):
59         if not hasattr(user_obj, '_perm_cache'):
60             user_obj._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in user_obj.user_permissions.select_related()])
61             user_obj._perm_cache.update(self.get_group_permissions(user_obj))
62         return user_obj._perm_cache
63
64     def has_perm(self, user_obj, perm):
65         return perm in self.get_all_permissions(user_obj)
66
67     def has_module_perms(self, user_obj, app_label):
68         """
69         Returns True if user_obj has any permissions in the given app_label.
70         """
71         for perm in self.get_all_permissions(user_obj):
72             if perm[:perm.index('.')] == app_label:
73                 return True
74         return False
75
76     def get_user(self, user_id):
77         try:
78             return User.objects.get(pk=user_id)
79         except User.DoesNotExist:
80             return None
81
82
83 class RemoteUserBackend(ModelBackend):
84     """
85     This backend is to be used in conjunction with the ``RemoteUserMiddleware``
86     found in the middleware module of this package, and is used when the server
87     is handling authentication outside of Django.
88
89     By default, the ``authenticate`` method creates ``User`` objects for
90     usernames that don't already exist in the database.  Subclasses can disable
91     this behavior by setting the ``create_unknown_user`` attribute to
92     ``False``.
93     """
94
95     # Create a User object if not already in the database?
96     create_unknown_user = True
97
98     def authenticate(self, remote_user):
99         """
100         The username passed as ``remote_user`` is considered trusted.  This
101         method simply returns the ``User`` object with the given username,
102         creating a new ``User`` object if ``create_unknown_user`` is ``True``.
103
104         Returns None if ``create_unknown_user`` is ``False`` and a ``User``
105         object with the given username is not found in the database.
106         """
107         if not remote_user:
108             return
109         user = None
110         username = self.clean_username(remote_user)
111
112         # Note that this could be accomplished in one try-except clause, but
113         # instead we use get_or_create when creating unknown users since it has
114         # built-in safeguards for multiple threads.
115         if self.create_unknown_user:
116             user, created = User.objects.get_or_create(username=username)
117             if created:
118                 user = self.configure_user(user)
119         else:
120             try:
121                 user = User.objects.get(username=username)
122             except User.DoesNotExist:
123                 pass
124         return user
125
126     def clean_username(self, username):
127         """
128         Performs any cleaning on the "username" prior to using it to get or
129         create the user object.  Returns the cleaned username.
130
131         By default, returns the username unchanged.
132         """
133         return username
134
135     def configure_user(self, user):
136         """
137         Configures a user after creation and returns the updated user.
138
139         By default, returns the user unmodified.
140         """
141         return user
Note: See TracBrowser for help on using the browser.