|
1 from django.db import connection |
|
2 from django.contrib.auth.models import User, Permission |
|
3 |
|
4 |
|
5 class ModelBackend(object): |
|
6 """ |
|
7 Authenticates against django.contrib.auth.models.User. |
|
8 """ |
|
9 supports_object_permissions = False |
|
10 supports_anonymous_user = True |
|
11 |
|
12 # TODO: Model, login attribute name and password attribute name should be |
|
13 # configurable. |
|
14 def authenticate(self, username=None, password=None): |
|
15 try: |
|
16 user = User.objects.get(username=username) |
|
17 if user.check_password(password): |
|
18 return user |
|
19 except User.DoesNotExist: |
|
20 return None |
|
21 |
|
22 def get_group_permissions(self, user_obj): |
|
23 """ |
|
24 Returns a set of permission strings that this user has through his/her |
|
25 groups. |
|
26 """ |
|
27 if not hasattr(user_obj, '_group_perm_cache'): |
|
28 perms = Permission.objects.filter(group__user=user_obj |
|
29 ).values_list('content_type__app_label', 'codename' |
|
30 ).order_by() |
|
31 user_obj._group_perm_cache = set(["%s.%s" % (ct, name) for ct, name in perms]) |
|
32 return user_obj._group_perm_cache |
|
33 |
|
34 def get_all_permissions(self, user_obj): |
|
35 if user_obj.is_anonymous(): |
|
36 return set() |
|
37 if not hasattr(user_obj, '_perm_cache'): |
|
38 user_obj._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in user_obj.user_permissions.select_related()]) |
|
39 user_obj._perm_cache.update(self.get_group_permissions(user_obj)) |
|
40 return user_obj._perm_cache |
|
41 |
|
42 def has_perm(self, user_obj, perm): |
|
43 return perm in self.get_all_permissions(user_obj) |
|
44 |
|
45 def has_module_perms(self, user_obj, app_label): |
|
46 """ |
|
47 Returns True if user_obj has any permissions in the given app_label. |
|
48 """ |
|
49 for perm in self.get_all_permissions(user_obj): |
|
50 if perm[:perm.index('.')] == app_label: |
|
51 return True |
|
52 return False |
|
53 |
|
54 def get_user(self, user_id): |
|
55 try: |
|
56 return User.objects.get(pk=user_id) |
|
57 except User.DoesNotExist: |
|
58 return None |
|
59 |
|
60 |
|
61 class RemoteUserBackend(ModelBackend): |
|
62 """ |
|
63 This backend is to be used in conjunction with the ``RemoteUserMiddleware`` |
|
64 found in the middleware module of this package, and is used when the server |
|
65 is handling authentication outside of Django. |
|
66 |
|
67 By default, the ``authenticate`` method creates ``User`` objects for |
|
68 usernames that don't already exist in the database. Subclasses can disable |
|
69 this behavior by setting the ``create_unknown_user`` attribute to |
|
70 ``False``. |
|
71 """ |
|
72 |
|
73 # Create a User object if not already in the database? |
|
74 create_unknown_user = True |
|
75 |
|
76 def authenticate(self, remote_user): |
|
77 """ |
|
78 The username passed as ``remote_user`` is considered trusted. This |
|
79 method simply returns the ``User`` object with the given username, |
|
80 creating a new ``User`` object if ``create_unknown_user`` is ``True``. |
|
81 |
|
82 Returns None if ``create_unknown_user`` is ``False`` and a ``User`` |
|
83 object with the given username is not found in the database. |
|
84 """ |
|
85 if not remote_user: |
|
86 return |
|
87 user = None |
|
88 username = self.clean_username(remote_user) |
|
89 |
|
90 # Note that this could be accomplished in one try-except clause, but |
|
91 # instead we use get_or_create when creating unknown users since it has |
|
92 # built-in safeguards for multiple threads. |
|
93 if self.create_unknown_user: |
|
94 user, created = User.objects.get_or_create(username=username) |
|
95 if created: |
|
96 user = self.configure_user(user) |
|
97 else: |
|
98 try: |
|
99 user = User.objects.get(username=username) |
|
100 except User.DoesNotExist: |
|
101 pass |
|
102 return user |
|
103 |
|
104 def clean_username(self, username): |
|
105 """ |
|
106 Performs any cleaning on the "username" prior to using it to get or |
|
107 create the user object. Returns the cleaned username. |
|
108 |
|
109 By default, returns the username unchanged. |
|
110 """ |
|
111 return username |
|
112 |
|
113 def configure_user(self, user): |
|
114 """ |
|
115 Configures a user after creation and returns the updated user. |
|
116 |
|
117 By default, returns the user unmodified. |
|
118 """ |
|
119 return user |