~ubuntu-branches/ubuntu/quantal/python-django/quantal-security

« back to all changes in this revision

Viewing changes to django/contrib/auth/models.py

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2010-05-21 07:52:55 UTC
  • mfrom: (1.3.6 upstream)
  • mto: This revision was merged to the branch mainline in revision 28.
  • Revision ID: james.westby@ubuntu.com-20100521075255-ii78v1dyfmyu3uzx
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
from django.utils.hashcompat import md5_constructor, sha_constructor
11
11
from django.utils.translation import ugettext_lazy as _
12
12
 
 
13
 
13
14
UNUSABLE_PASSWORD = '!' # This will never be a valid hash
14
15
 
15
 
try:
16
 
    set
17
 
except NameError:
18
 
    from sets import Set as set   # Python 2.3 fallback
19
 
 
20
16
def get_hexdigest(algorithm, salt, raw_password):
21
17
    """
22
18
    Returns a string of the hexdigest of the given plaintext password and salt
47
43
class SiteProfileNotAvailable(Exception):
48
44
    pass
49
45
 
 
46
class PermissionManager(models.Manager):
 
47
    def get_by_natural_key(self, codename, app_label, model):
 
48
        return self.get(
 
49
            codename=codename,
 
50
            content_type=ContentType.objects.get_by_natural_key(app_label, model)
 
51
        )
 
52
 
50
53
class Permission(models.Model):
51
54
    """The permissions system provides a way to assign permissions to specific users and groups of users.
52
55
 
63
66
    name = models.CharField(_('name'), max_length=50)
64
67
    content_type = models.ForeignKey(ContentType)
65
68
    codename = models.CharField(_('codename'), max_length=100)
 
69
    objects = PermissionManager()
66
70
 
67
71
    class Meta:
68
72
        verbose_name = _('permission')
69
73
        verbose_name_plural = _('permissions')
70
74
        unique_together = (('content_type', 'codename'),)
71
 
        ordering = ('content_type__app_label', 'codename')
 
75
        ordering = ('content_type__app_label', 'content_type__model', 'codename')
72
76
 
73
77
    def __unicode__(self):
74
78
        return u"%s | %s | %s" % (
76
80
            unicode(self.content_type),
77
81
            unicode(self.name))
78
82
 
 
83
    def natural_key(self):
 
84
        return (self.codename,) + self.content_type.natural_key()
 
85
    natural_key.dependencies = ['contenttypes.contenttype']
 
86
 
79
87
class Group(models.Model):
80
88
    """Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups.
81
89
 
95
103
 
96
104
class UserManager(models.Manager):
97
105
    def create_user(self, username, email, password=None):
98
 
        "Creates and saves a User with the given username, e-mail and password."
 
106
        """
 
107
        Creates and saves a User with the given username, e-mail and password.
 
108
        """
 
109
 
99
110
        now = datetime.datetime.now()
100
 
        user = self.model(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now)
 
111
        
 
112
        # Normalize the address by lowercasing the domain part of the email
 
113
        # address.
 
114
        try:
 
115
            email_name, domain_part = email.strip().split('@', 1)
 
116
        except ValueError:
 
117
            pass
 
118
        else:
 
119
            email = '@'.join([email_name, domain_part.lower()])
 
120
 
 
121
        user = self.model(username=username, email=email, is_staff=False,
 
122
                         is_active=True, is_superuser=False, last_login=now,
 
123
                         date_joined=now)
 
124
 
101
125
        if password:
102
126
            user.set_password(password)
103
127
        else:
104
128
            user.set_unusable_password()
105
 
        user.save()
 
129
        user.save(using=self._db)
106
130
        return user
107
131
 
108
132
    def create_superuser(self, username, email, password):
110
134
        u.is_staff = True
111
135
        u.is_active = True
112
136
        u.is_superuser = True
113
 
        u.save()
 
137
        u.save(using=self._db)
114
138
        return u
115
139
 
116
140
    def make_random_password(self, length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'):
120
144
        from random import choice
121
145
        return ''.join([choice(allowed_chars) for i in range(length)])
122
146
 
 
147
 
 
148
# A few helper functions for common logic between User and AnonymousUser.
 
149
def _user_get_all_permissions(user, obj):
 
150
    permissions = set()
 
151
    anon = user.is_anonymous()
 
152
    for backend in auth.get_backends():
 
153
        if not anon or backend.supports_anonymous_user:
 
154
            if hasattr(backend, "get_all_permissions"):
 
155
                if obj is not None:
 
156
                    if backend.supports_object_permissions:
 
157
                        permissions.update(
 
158
                            backend.get_all_permissions(user, obj)
 
159
                        )
 
160
                else:
 
161
                    permissions.update(backend.get_all_permissions(user))
 
162
    return permissions
 
163
 
 
164
 
 
165
def _user_has_perm(user, perm, obj):
 
166
    anon = user.is_anonymous()
 
167
    for backend in auth.get_backends():
 
168
        if not anon or backend.supports_anonymous_user:
 
169
            if hasattr(backend, "has_perm"):
 
170
                if obj is not None:
 
171
                    if (backend.supports_object_permissions and
 
172
                        backend.has_perm(user, perm, obj)):
 
173
                            return True
 
174
                else:
 
175
                    if backend.has_perm(user, perm):
 
176
                        return True
 
177
    return False
 
178
 
 
179
 
 
180
def _user_has_module_perms(user, app_label):
 
181
    anon = user.is_anonymous()
 
182
    for backend in auth.get_backends():
 
183
        if not anon or backend.supports_anonymous_user:
 
184
            if hasattr(backend, "has_module_perms"):
 
185
                if backend.has_module_perms(user, app_label):
 
186
                    return True
 
187
    return False
 
188
 
 
189
 
123
190
class User(models.Model):
124
 
    """Users within the Django authentication system are represented by this model.
 
191
    """
 
192
    Users within the Django authentication system are represented by this model.
125
193
 
126
194
    Username and password are required. Other fields are optional.
127
195
    """
128
 
    username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."))
 
196
    username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"))
129
197
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
130
198
    last_name = models.CharField(_('last name'), max_length=30, blank=True)
131
199
    email = models.EmailField(_('e-mail address'), blank=True)
151
219
        return "/users/%s/" % urllib.quote(smart_str(self.username))
152
220
 
153
221
    def is_anonymous(self):
154
 
        "Always returns False. This is a way of comparing User objects to anonymous users."
 
222
        """
 
223
        Always returns False. This is a way of comparing User objects to
 
224
        anonymous users.
 
225
        """
155
226
        return False
156
227
 
157
228
    def is_authenticated(self):
158
 
        """Always return True. This is a way to tell if the user has been authenticated in templates.
 
229
        """
 
230
        Always return True. This is a way to tell if the user has been
 
231
        authenticated in templates.
159
232
        """
160
233
        return True
161
234
 
194
267
    def has_usable_password(self):
195
268
        return self.password != UNUSABLE_PASSWORD
196
269
 
197
 
    def get_group_permissions(self):
 
270
    def get_group_permissions(self, obj=None):
198
271
        """
199
272
        Returns a list of permission strings that this user has through
200
273
        his/her groups. This method queries all available auth backends.
 
274
        If an object is passed in, only permissions matching this object
 
275
        are returned.
201
276
        """
202
277
        permissions = set()
203
278
        for backend in auth.get_backends():
204
279
            if hasattr(backend, "get_group_permissions"):
205
 
                permissions.update(backend.get_group_permissions(self))
206
 
        return permissions
207
 
 
208
 
    def get_all_permissions(self):
209
 
        permissions = set()
210
 
        for backend in auth.get_backends():
211
 
            if hasattr(backend, "get_all_permissions"):
212
 
                permissions.update(backend.get_all_permissions(self))
213
 
        return permissions
214
 
 
215
 
    def has_perm(self, perm):
 
280
                if obj is not None:
 
281
                    if backend.supports_object_permissions:
 
282
                        permissions.update(
 
283
                            backend.get_group_permissions(self, obj)
 
284
                        )
 
285
                else:
 
286
                    permissions.update(backend.get_group_permissions(self))
 
287
        return permissions
 
288
 
 
289
    def get_all_permissions(self, obj=None):
 
290
        return _user_get_all_permissions(self, obj)
 
291
 
 
292
    def has_perm(self, perm, obj=None):
216
293
        """
217
294
        Returns True if the user has the specified permission. This method
218
295
        queries all available auth backends, but returns immediately if any
219
296
        backend returns True. Thus, a user who has permission from a single
220
 
        auth backend is assumed to have permission in general.
 
297
        auth backend is assumed to have permission in general. If an object
 
298
        is provided, permissions for this specific object are checked.
221
299
        """
222
300
        # Inactive users have no permissions.
223
301
        if not self.is_active:
228
306
            return True
229
307
 
230
308
        # Otherwise we need to check the backends.
231
 
        for backend in auth.get_backends():
232
 
            if hasattr(backend, "has_perm"):
233
 
                if backend.has_perm(self, perm):
234
 
                    return True
235
 
        return False
 
309
        return _user_has_perm(self, perm, obj)
236
310
 
237
 
    def has_perms(self, perm_list):
238
 
        """Returns True if the user has each of the specified permissions."""
 
311
    def has_perms(self, perm_list, obj=None):
 
312
        """
 
313
        Returns True if the user has each of the specified permissions.
 
314
        If object is passed, it checks if the user has all required perms
 
315
        for this object.
 
316
        """
239
317
        for perm in perm_list:
240
 
            if not self.has_perm(perm):
 
318
            if not self.has_perm(perm, obj):
241
319
                return False
242
320
        return True
243
321
 
252
330
        if self.is_superuser:
253
331
            return True
254
332
 
255
 
        for backend in auth.get_backends():
256
 
            if hasattr(backend, "has_module_perms"):
257
 
                if backend.has_module_perms(self, app_label):
258
 
                    return True
259
 
        return False
 
333
        return _user_has_module_perms(self, app_label)
260
334
 
261
335
    def get_and_delete_messages(self):
262
336
        messages = []
278
352
        if not hasattr(self, '_profile_cache'):
279
353
            from django.conf import settings
280
354
            if not getattr(settings, 'AUTH_PROFILE_MODULE', False):
281
 
                raise SiteProfileNotAvailable
 
355
                raise SiteProfileNotAvailable('You need to set AUTH_PROFILE_MO'
 
356
                                              'DULE in your project settings')
282
357
            try:
283
358
                app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.')
 
359
            except ValueError:
 
360
                raise SiteProfileNotAvailable('app_label and model_name should'
 
361
                        ' be separated by a dot in the AUTH_PROFILE_MODULE set'
 
362
                        'ting')
 
363
 
 
364
            try:
284
365
                model = models.get_model(app_label, model_name)
285
 
                self._profile_cache = model._default_manager.get(user__id__exact=self.id)
 
366
                if model is None:
 
367
                    raise SiteProfileNotAvailable('Unable to load the profile '
 
368
                        'model, check AUTH_PROFILE_MODULE in your project sett'
 
369
                        'ings')
 
370
                self._profile_cache = model._default_manager.using(self._state.db).get(user__id__exact=self.id)
286
371
                self._profile_cache.user = self
287
372
            except (ImportError, ImproperlyConfigured):
288
373
                raise SiteProfileNotAvailable
289
374
        return self._profile_cache
290
375
 
 
376
    def _get_message_set(self):
 
377
        import warnings
 
378
        warnings.warn('The user messaging API is deprecated. Please update'
 
379
                      ' your code to use the new messages framework.',
 
380
                      category=PendingDeprecationWarning)
 
381
        return self._message_set
 
382
    message_set = property(_get_message_set)
 
383
 
291
384
class Message(models.Model):
292
385
    """
293
386
    The message system is a lightweight way to queue messages for given
297
390
    actions. For example, "The poll Foo was created successfully." is a
298
391
    message.
299
392
    """
300
 
    user = models.ForeignKey(User)
 
393
    user = models.ForeignKey(User, related_name='_message_set')
301
394
    message = models.TextField(_('message'))
302
395
 
303
396
    def __unicode__(self):
350
443
        return self._user_permissions
351
444
    user_permissions = property(_get_user_permissions)
352
445
 
353
 
    def has_perm(self, perm):
354
 
        return False
355
 
 
356
 
    def has_perms(self, perm_list):
357
 
        return False
 
446
    def get_group_permissions(self, obj=None):
 
447
        return set()
 
448
 
 
449
    def get_all_permissions(self, obj=None):
 
450
        return _user_get_all_permissions(self, obj=obj)
 
451
 
 
452
    def has_perm(self, perm, obj=None):
 
453
        return _user_has_perm(self, perm, obj=obj)
 
454
 
 
455
    def has_perms(self, perm_list, obj=None):
 
456
        for perm in perm_list:
 
457
            if not self.has_perm(perm, obj):
 
458
                return False
 
459
        return True
358
460
 
359
461
    def has_module_perms(self, module):
360
 
        return False
 
462
        return _user_has_module_perms(self, module)
361
463
 
362
464
    def get_and_delete_messages(self):
363
465
        return []