This repository has been archived by the owner on Apr 6, 2022. It is now read-only.
/
models.py
239 lines (205 loc) · 6.28 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib import messages
import datetime
import uuid
from hicap.billing.models import MembershipPayment
from hicap.membership.email import send_password_reset
from hicap.utils import AttrDict
from django.utils.translation import ugettext_lazy as _
from django.db.models.signals import post_save
import yaml
import os
with open(os.path.join(settings.BASE_PATH, "membership", "profile.yaml")) as fh:
profile_schema = yaml.load(fh)['profile']
class Maker(models.Model):
username = models.CharField(_('username'), max_length=255, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"))
first_name = models.CharField(_('first name'), max_length=255, blank=True)
last_name = models.CharField(_('last name'), max_length=255, blank=True)
email = models.EmailField(_('e-mail address'), blank=True)
password = models.CharField(_('password'), max_length=255, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))
last_login = models.DateTimeField(_('last login'), default=datetime.datetime.now)
date_joined = models.DateTimeField(_('date joined'), default=datetime.datetime.now)
publish_membership = models.BooleanField(_('Publish Membership'), default=False)
get_full_name = User.__dict__['get_full_name']
set_password = User.__dict__['set_password']
check_password = User.__dict__['check_password']
email_user = User.__dict__['email_user']
is_authenticated = User.__dict__['is_authenticated']
#_shadowed_user : Memoized value of associated admin user (if it exists)
#_password_set : Temporary store for assigned password
def __unicode__(self):
return self.username
def save(self, *args, **kwargs):
self._password_set = None
if self.password == "":
password = User.objects.make_random_password()
self.set_password(password)
self._password_set = password
else:
try:
faux_maker = Maker.objects.get(pk=self.pk)
prev_password = faux_maker.password
except Maker.DoesNotExist:
prev_password = ""
if prev_password != self.password:
self._password_set = self.password
self.set_password(self.password)
super(Maker, self).save(*args, **kwargs)
def is_current(self, date = None):
if date is None:
date = datetime.datetime.now()
objs = self.membershippayment_set.filter(cycle_start__lte=date, norm_cycle_end__gte=date)
if len(objs):
return True
return False
def last_cycle_end(self):
try:
obj = self.membershippayment_set.latest('norm_cycle_end')
return obj.norm_cycle_end
except MembershipPayment.DoesNotExist:
return None
@property
def is_active(self):
if self.associated_user:
return self.associated_user.is_active
return False
@property
def is_staff(self):
if self.associated_user:
return self.associated_user.is_staff
return False
@property
def is_public(self):
return self.publish_membership
def has_perm(self, perm, obj=None):
if self.associated_user:
return self.associated_user.has_perm(perm, obj)
return False
def has_module_perms(self, package_name):
if self.associated_user:
return self.associated_user.has_module_perms(package_name)
return False
@property
def associated_user(self):
if not hasattr(self, "_shadowed_user"):
try:
user = User.objects.get(username=self.username)
self._shadowed_user = user
except User.DoesNotExist:
self._shadowed_user = None
return self._shadowed_user
@staticmethod
def active_members(date):
objs = MembershipPayment.objects.filter(cycle_start__lte=date, norm_cycle_end__gte=date)
return len(objs)
@property
def forJSON(self):
return {
'id': self.pk,
'name': self.get_full_name(),
'email': self.email,
}
def send_password_reset(self):
rn = ResetNonce.create_for_maker(self)
send_password_reset(rn)
@property
def profile_data(self):
return ProfileDataManager(self, self.profileinfo_set.all())
class ResetNonce(models.Model):
maker = models.ForeignKey(Maker)
nonce = models.CharField(max_length=255)
created = models.DateTimeField(_('created'), default=datetime.datetime.now)
@staticmethod
def create_for_maker(maker):
rn = ResetNonce(maker=maker)
rn.nonce = str(uuid.uuid4())
rn.save()
return rn
class ProfileInfo(models.Model):
maker = models.ForeignKey(Maker)
key = models.CharField(max_length=255)
value = models.TextField()
def __unicode__(self):
return "{name}: {key} -> {value}".format(
name = self.maker.username,
key = self.key,
value = self.value
)
class ProfileDataManager(object):
def __init__(self, maker, data):
self.maker = maker
self._queryset = data
self._data = dict((i.key, i.value) for i in data)
self.has_changed = False
@property
def data(self):
return self._data
def update(self, name, value):
if name not in self.data and value not in ('', None):
self.data[name] = value
pi = ProfileInfo(
maker = self.maker,
key = name,
value = value
)
pi.save()
elif name in self.data and self.data[name] != value:
pi = ProfileInfo.objects.get(maker=self.maker, key=name)
if value != '':
pi.value = value
pi.save()
else:
pi.delete()
else:
pass
@property
def info(self):
ret = {}
for field in profile_schema['info']:
if field['id'] not in self.data:
continue
ret[field['id']] = {
'id': field['id'],
'label': field['label'],
'value': self.data[field['id']]
}
return ret
@property
def tags(self):
ret = {}
for field in profile_schema['tags']:
if field['id'] not in self.data:
continue
ret[field['id']] = {
'id': field['id'],
'label': field['label'],
'values': self.data[field['id']].split(',')
}
return ret
@property
def links(self):
ret = {}
for field in profile_schema['links']:
if field['id'] not in self.data:
continue
ret[field['id']] = {
'id': field['id'],
'label': field['label'],
'prefix': field['prefix'],
'value': self.data[field['id']]
}
return ret
def on_post_save(instance, **kwargs):
if instance._password_set is not None:
user = instance.associated_user
if user is not None:
user.set_password(instance._password_set)
user.save()
post_save.connect(
on_post_save,
dispatch_uid = "maker_post_save",
sender = Maker,
weak = False,
)