1
from django.core import meta, validators
2
from django.models import core
3
from django.utils.translation import gettext_lazy as _
5
class Permission(meta.Model):
6
name = meta.CharField(_('name'), maxlength=50)
7
package = meta.ForeignKey(core.Package, db_column='package')
8
codename = meta.CharField(_('codename'), maxlength=100)
10
verbose_name = _('Permission')
11
verbose_name_plural = _('Permissions')
12
unique_together = (('package', 'codename'),)
13
ordering = ('package', 'codename')
16
return "%s | %s" % (self.package_id, self.name)
18
class Group(meta.Model):
19
name = meta.CharField(_('name'), maxlength=80, unique=True)
20
permissions = meta.ManyToManyField(Permission, blank=True, filter_interface=meta.HORIZONTAL)
22
verbose_name = _('Group')
23
verbose_name_plural = _('Groups')
26
search_fields = ('name',),
32
class User(meta.Model):
33
username = meta.CharField(_('username'), maxlength=30, unique=True, validator_list=[validators.isAlphaNumeric])
34
first_name = meta.CharField(_('first name'), maxlength=30, blank=True)
35
last_name = meta.CharField(_('last name'), maxlength=30, blank=True)
36
email = meta.EmailField(_('e-mail address'), blank=True)
37
password = meta.CharField(_('password'), maxlength=128, help_text=_("Use '[algo]$[salt]$[hexdigest]'"))
38
is_staff = meta.BooleanField(_('staff status'), help_text=_("Designates whether the user can log into this admin site."))
39
is_active = meta.BooleanField(_('active'), default=True)
40
is_superuser = meta.BooleanField(_('superuser status'))
41
last_login = meta.DateTimeField(_('last login'), default=meta.LazyDate())
42
date_joined = meta.DateTimeField(_('date joined'), default=meta.LazyDate())
43
groups = meta.ManyToManyField(Group, blank=True,
44
help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."))
45
user_permissions = meta.ManyToManyField(Permission, blank=True, filter_interface=meta.HORIZONTAL)
47
verbose_name = _('User')
48
verbose_name_plural = _('Users')
50
'SESSION_KEY': '_auth_user_id',
52
ordering = ('username',)
53
exceptions = ('SiteProfileNotAvailable',)
56
(None, {'fields': ('username', 'password')}),
57
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
58
(_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}),
59
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
60
(_('Groups'), {'fields': ('groups',)}),
62
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff'),
63
list_filter = ('is_staff', 'is_superuser'),
64
search_fields = ('username', 'first_name', 'last_name', 'email'),
70
def get_absolute_url(self):
71
return "/users/%s/" % self.username
73
def is_anonymous(self):
76
def get_full_name(self):
77
full_name = '%s %s' % (self.first_name, self.last_name)
78
return full_name.strip()
80
def set_password(self, raw_password):
83
salt = sha.new(str(random.random())).hexdigest()[:5]
84
hsh = sha.new(salt+raw_password).hexdigest()
85
self.password = '%s$%s$%s' % (algo, salt, hsh)
87
def check_password(self, raw_password):
89
Returns a boolean of whether the raw_password was correct. Handles
90
encryption formats behind the scenes.
92
# Backwards-compatibility check. Older passwords won't include the
94
if '$' not in self.password:
96
is_correct = (self.password == md5.new(raw_password).hexdigest())
98
# Convert the password to the new, more secure format.
99
self.set_password(raw_password)
102
algo, salt, hsh = self.password.split('$')
105
return hsh == md5.new(salt+raw_password).hexdigest()
108
return hsh == sha.new(salt+raw_password).hexdigest()
109
raise ValueError, "Got unknown password algorithm type in password."
111
def get_group_permissions(self):
112
"Returns a list of permission strings that this user has through his/her groups."
113
if not hasattr(self, '_group_perm_cache'):
116
# The SQL below works out to the following, after DB quoting:
118
# SELECT p.package, p.codename
119
# FROM auth_permissions p, auth_groups_permissions gp, auth_users_groups ug
120
# WHERE p.id = gp.permission_id
121
# AND gp.group_id = ug.group_id
122
# AND ug.user_id = %s""", [self.id])
125
FROM %s p, %s gp, %s ug
128
AND ug.%s = %%s""" % (
129
db.quote_name('package'), db.quote_name('codename'),
130
db.quote_name('auth_permissions'), db.quote_name('auth_groups_permissions'),
131
db.quote_name('auth_users_groups'), db.quote_name('id'),
132
db.quote_name('permission_id'), db.quote_name('group_id'),
133
db.quote_name('group_id'), db.quote_name('user_id'))
134
cursor.execute(sql, [self.id])
135
self._group_perm_cache = sets.Set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
136
return self._group_perm_cache
138
def get_all_permissions(self):
139
if not hasattr(self, '_perm_cache'):
141
self._perm_cache = sets.Set(["%s.%s" % (p.package_id, p.codename) for p in self.get_permission_list()])
142
self._perm_cache.update(self.get_group_permissions())
143
return self._perm_cache
145
def has_perm(self, perm):
146
"Returns True if the user has the specified permission."
147
if not self.is_active:
149
if self.is_superuser:
151
return perm in self.get_all_permissions()
153
def has_perms(self, perm_list):
154
"Returns True if the user has each of the specified permissions."
155
for perm in perm_list:
156
if not self.has_perm(perm):
160
def has_module_perms(self, package_name):
161
"Returns True if the user has any permissions in the given package."
162
if self.is_superuser:
164
return bool(len([p for p in self.get_all_permissions() if p[:p.index('.')] == package_name]))
166
def get_and_delete_messages(self):
168
for m in self.get_message_list():
169
messages.append(m.message)
173
def email_user(self, subject, message, from_email=None):
174
"Sends an e-mail to this User."
175
from django.core.mail import send_mail
176
send_mail(subject, message, from_email, [self.email])
178
def get_profile(self):
180
Returns site-specific profile for this user. Raises
181
SiteProfileNotAvailable if this site does not allow profiles.
183
if not hasattr(self, '_profile_cache'):
184
from django.conf.settings import AUTH_PROFILE_MODULE
185
if not AUTH_PROFILE_MODULE:
186
raise SiteProfileNotAvailable
188
app, mod = AUTH_PROFILE_MODULE.split('.')
189
module = __import__('ellington.%s.apps.%s' % (app, mod), [], [], [''])
190
self._profile_cache = module.get_object(user_id=self.id)
193
module = __import__('django.models.%s' % AUTH_PROFILE_MODULE, [], [], [''])
194
self._profile_cache = module.get_object(user__id__exact=self.id)
196
raise SiteProfileNotAvailable
197
return self._profile_cache
199
def _module_create_user(username, email, password):
200
"Creates and saves a User with the given username, e-mail and password."
201
now = datetime.datetime.now()
202
user = User(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now)
203
user.set_password(password)
207
def _module_make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'):
208
"Generates a random password with the given length and given allowed_chars"
209
# Note that default value of allowed_chars does not have "I" or letters
210
# that look like it -- just to avoid confusion.
211
from random import choice
212
return ''.join([choice(allowed_chars) for i in range(length)])
214
class Message(meta.Model):
215
user = meta.ForeignKey(User)
216
message = meta.TextField(_('Message'))