Revision 5ce3ce4f snf-astakos-app/astakos/im/models.py
b/snf-astakos-app/astakos/im/models.py | ||
---|---|---|
51 | 51 |
from django.db.models import Q |
52 | 52 |
|
53 | 53 |
from astakos.im.settings import (DEFAULT_USER_LEVEL, INVITATIONS_PER_LEVEL, |
54 |
AUTH_TOKEN_DURATION, BILLING_FIELDS, EMAILCHANGE_ACTIVATION_DAYS, LOGGING_LEVEL |
|
55 |
) |
|
54 |
AUTH_TOKEN_DURATION, BILLING_FIELDS, EMAILCHANGE_ACTIVATION_DAYS, LOGGING_LEVEL
|
|
55 |
)
|
|
56 | 56 |
from astakos.im.endpoints.quotaholder import register_users, send_quota |
57 | 57 |
from astakos.im.endpoints.aquarium.producer import report_user_event |
58 | 58 |
|
... | ... | |
60 | 60 |
|
61 | 61 |
logger = logging.getLogger(__name__) |
62 | 62 |
|
63 |
|
|
63 | 64 |
class Service(models.Model): |
64 | 65 |
name = models.CharField('Name', max_length=255, unique=True, db_index=True) |
65 | 66 |
url = models.FilePathField() |
... | ... | |
67 | 68 |
auth_token = models.CharField('Authentication Token', max_length=32, |
68 | 69 |
null=True, blank=True) |
69 | 70 |
auth_token_created = models.DateTimeField('Token creation date', null=True) |
70 |
auth_token_expires = models.DateTimeField('Token expiration date', null=True) |
|
71 |
|
|
71 |
auth_token_expires = models.DateTimeField( |
|
72 |
'Token expiration date', null=True) |
|
73 |
|
|
72 | 74 |
def save(self, **kwargs): |
73 | 75 |
if not self.id: |
74 | 76 |
self.renew_token() |
75 | 77 |
self.full_clean() |
76 | 78 |
super(Service, self).save(**kwargs) |
77 |
|
|
79 |
|
|
78 | 80 |
def renew_token(self): |
79 | 81 |
md5 = hashlib.md5() |
80 | 82 |
md5.update(self.name.encode('ascii', 'ignore')) |
... | ... | |
84 | 86 |
self.auth_token = b64encode(md5.digest()) |
85 | 87 |
self.auth_token_created = datetime.now() |
86 | 88 |
self.auth_token_expires = self.auth_token_created + \ |
87 |
timedelta(hours=AUTH_TOKEN_DURATION)
|
|
88 |
|
|
89 |
timedelta(hours=AUTH_TOKEN_DURATION) |
|
90 |
|
|
89 | 91 |
def __str__(self): |
90 | 92 |
return self.name |
91 | 93 |
|
94 |
|
|
92 | 95 |
class ResourceMetadata(models.Model): |
93 | 96 |
key = models.CharField('Name', max_length=255, unique=True, db_index=True) |
94 | 97 |
value = models.CharField('Value', max_length=255) |
95 | 98 |
|
99 |
|
|
96 | 100 |
class Resource(models.Model): |
97 | 101 |
name = models.CharField('Name', max_length=255, unique=True, db_index=True) |
98 | 102 |
meta = models.ManyToManyField(ResourceMetadata) |
99 | 103 |
service = models.ForeignKey(Service) |
100 |
|
|
104 |
|
|
101 | 105 |
def __str__(self): |
102 | 106 |
return '%s : %s' % (self.service, self.name) |
103 | 107 |
|
108 |
|
|
104 | 109 |
class GroupKind(models.Model): |
105 | 110 |
name = models.CharField('Name', max_length=255, unique=True, db_index=True) |
106 |
|
|
111 |
|
|
107 | 112 |
def __str__(self): |
108 | 113 |
return self.name |
109 | 114 |
|
115 |
|
|
110 | 116 |
class AstakosGroup(Group): |
111 | 117 |
kind = models.ForeignKey(GroupKind) |
112 |
homepage = models.CharField('Homepage', max_length=255, null=True, blank=True) |
|
118 |
homepage = models.CharField( |
|
119 |
'Homepage', max_length=255, null=True, blank=True) |
|
113 | 120 |
desc = models.TextField('Description', null=True) |
114 | 121 |
policy = models.ManyToManyField(Resource, null=True, blank=True, |
115 |
through='AstakosGroupQuota' |
|
116 |
) |
|
122 |
through='AstakosGroupQuota'
|
|
123 |
)
|
|
117 | 124 |
creation_date = models.DateTimeField('Creation date', |
118 |
default=datetime.now() |
|
119 |
) |
|
125 |
default=datetime.now()
|
|
126 |
)
|
|
120 | 127 |
issue_date = models.DateTimeField('Issue date', null=True) |
121 | 128 |
expiration_date = models.DateTimeField('Expiration date', null=True) |
122 | 129 |
moderation_enabled = models.BooleanField('Moderated membership?', |
123 |
default=True |
|
124 |
) |
|
130 |
default=True
|
|
131 |
)
|
|
125 | 132 |
approval_date = models.DateTimeField('Activation date', null=True, |
126 |
blank=True |
|
127 |
) |
|
133 |
blank=True
|
|
134 |
)
|
|
128 | 135 |
estimated_participants = models.PositiveIntegerField('Estimated #members', |
129 |
null=True |
|
130 |
) |
|
131 |
|
|
136 |
null=True
|
|
137 |
)
|
|
138 |
|
|
132 | 139 |
@property |
133 | 140 |
def is_disabled(self): |
134 | 141 |
if not self.approval_date: |
135 | 142 |
return True |
136 | 143 |
return False |
137 |
|
|
144 |
|
|
138 | 145 |
@property |
139 | 146 |
def is_enabled(self): |
140 | 147 |
if self.is_disabled: |
... | ... | |
149 | 156 |
if now >= self.expiration_date: |
150 | 157 |
return False |
151 | 158 |
return True |
152 |
|
|
159 |
|
|
153 | 160 |
def enable(self): |
154 | 161 |
if self.is_enabled: |
155 | 162 |
return |
156 | 163 |
self.approval_date = datetime.now() |
157 | 164 |
self.save() |
158 | 165 |
quota_disturbed.send(sender=self, users=self.approved_members) |
159 |
propagate_groupmembers_quota.apply_async(args=[self], eta=self.issue_date) |
|
160 |
propagate_groupmembers_quota.apply_async(args=[self], eta=self.expiration_date) |
|
161 |
|
|
166 |
propagate_groupmembers_quota.apply_async( |
|
167 |
args=[self], eta=self.issue_date) |
|
168 |
propagate_groupmembers_quota.apply_async( |
|
169 |
args=[self], eta=self.expiration_date) |
|
170 |
|
|
162 | 171 |
def disable(self): |
163 | 172 |
if self.is_disabled: |
164 | 173 |
return |
165 | 174 |
self.approval_date = None |
166 | 175 |
self.save() |
167 | 176 |
quota_disturbed.send(sender=self, users=self.approved_members) |
168 |
|
|
177 |
|
|
169 | 178 |
def approve_member(self, person): |
170 | 179 |
m, created = self.membership_set.get_or_create(person=person) |
171 | 180 |
# update date_joined in any case |
172 |
m.date_joined=datetime.now()
|
|
181 |
m.date_joined = datetime.now()
|
|
173 | 182 |
m.save() |
174 |
|
|
183 |
|
|
175 | 184 |
def disapprove_member(self, person): |
176 | 185 |
self.membership_set.remove(person=person) |
177 |
|
|
186 |
|
|
178 | 187 |
@property |
179 | 188 |
def members(self): |
180 | 189 |
return [m.person for m in self.membership_set.all()] |
181 |
|
|
190 |
|
|
182 | 191 |
@property |
183 | 192 |
def approved_members(self): |
184 | 193 |
return [m.person for m in self.membership_set.all() if m.is_approved] |
185 |
|
|
194 |
|
|
186 | 195 |
@property |
187 | 196 |
def quota(self): |
188 | 197 |
d = defaultdict(int) |
189 | 198 |
for q in self.astakosgroupquota_set.all(): |
190 | 199 |
d[q.resource] += q.limit |
191 | 200 |
return d |
192 |
|
|
201 |
|
|
193 | 202 |
@property |
194 | 203 |
def owners(self): |
195 | 204 |
return self.owner.all() |
196 |
|
|
205 |
|
|
197 | 206 |
@owners.setter |
198 | 207 |
def owners(self, l): |
199 | 208 |
self.owner = l |
200 | 209 |
map(self.approve_member, l) |
201 | 210 |
|
211 |
|
|
202 | 212 |
class AstakosUser(User): |
203 | 213 |
""" |
204 | 214 |
Extends ``django.contrib.auth.models.User`` by defining additional fields. |
... | ... | |
212 | 222 |
#for invitations |
213 | 223 |
user_level = DEFAULT_USER_LEVEL |
214 | 224 |
level = models.IntegerField('Inviter level', default=user_level) |
215 |
invitations = models.IntegerField('Invitations left', default=INVITATIONS_PER_LEVEL.get(user_level, 0)) |
|
225 |
invitations = models.IntegerField( |
|
226 |
'Invitations left', default=INVITATIONS_PER_LEVEL.get(user_level, 0)) |
|
216 | 227 |
|
217 | 228 |
auth_token = models.CharField('Authentication Token', max_length=32, |
218 | 229 |
null=True, blank=True) |
219 | 230 |
auth_token_created = models.DateTimeField('Token creation date', null=True) |
220 |
auth_token_expires = models.DateTimeField('Token expiration date', null=True) |
|
231 |
auth_token_expires = models.DateTimeField( |
|
232 |
'Token expiration date', null=True) |
|
221 | 233 |
|
222 | 234 |
updated = models.DateTimeField('Update date') |
223 | 235 |
is_verified = models.BooleanField('Is verified?', default=False) |
224 | 236 |
|
225 | 237 |
# ex. screen_name for twitter, eppn for shibboleth |
226 |
third_party_identifier = models.CharField('Third-party identifier', max_length=255, null=True, blank=True) |
|
238 |
third_party_identifier = models.CharField( |
|
239 |
'Third-party identifier', max_length=255, null=True, blank=True) |
|
227 | 240 |
|
228 | 241 |
email_verified = models.BooleanField('Email verified?', default=False) |
229 | 242 |
|
230 | 243 |
has_credits = models.BooleanField('Has credits?', default=False) |
231 |
has_signed_terms = models.BooleanField('Agree with the terms?', default=False) |
|
232 |
date_signed_terms = models.DateTimeField('Signed terms date', null=True, blank=True) |
|
233 |
|
|
234 |
activation_sent = models.DateTimeField('Activation sent data', null=True, blank=True) |
|
235 |
|
|
236 |
policy = models.ManyToManyField(Resource, null=True, through='AstakosUserQuota') |
|
237 |
|
|
238 |
astakos_groups = models.ManyToManyField(AstakosGroup, verbose_name=_('agroups'), blank=True, |
|
244 |
has_signed_terms = models.BooleanField( |
|
245 |
'Agree with the terms?', default=False) |
|
246 |
date_signed_terms = models.DateTimeField( |
|
247 |
'Signed terms date', null=True, blank=True) |
|
248 |
|
|
249 |
activation_sent = models.DateTimeField( |
|
250 |
'Activation sent data', null=True, blank=True) |
|
251 |
|
|
252 |
policy = models.ManyToManyField( |
|
253 |
Resource, null=True, through='AstakosUserQuota') |
|
254 |
|
|
255 |
astakos_groups = models.ManyToManyField( |
|
256 |
AstakosGroup, verbose_name=_('agroups'), blank=True, |
|
239 | 257 |
help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."), |
240 | 258 |
through='Membership') |
241 |
|
|
259 |
|
|
242 | 260 |
__has_signed_terms = False |
243 |
|
|
244 |
owner = models.ManyToManyField(AstakosGroup, related_name='owner', null=True) |
|
245 |
|
|
261 |
|
|
262 |
owner = models.ManyToManyField( |
|
263 |
AstakosGroup, related_name='owner', null=True) |
|
264 |
|
|
246 | 265 |
class Meta: |
247 | 266 |
unique_together = ("provider", "third_party_identifier") |
248 |
|
|
267 |
|
|
249 | 268 |
def __init__(self, *args, **kwargs): |
250 | 269 |
super(AstakosUser, self).__init__(*args, **kwargs) |
251 | 270 |
self.__has_signed_terms = self.has_signed_terms |
252 | 271 |
if not self.id: |
253 | 272 |
self.is_active = False |
254 |
|
|
273 |
|
|
255 | 274 |
@property |
256 | 275 |
def realname(self): |
257 |
return '%s %s' %(self.first_name, self.last_name) |
|
276 |
return '%s %s' % (self.first_name, self.last_name)
|
|
258 | 277 |
|
259 | 278 |
@realname.setter |
260 | 279 |
def realname(self, value): |
... | ... | |
271 | 290 |
return Invitation.objects.get(username=self.email) |
272 | 291 |
except Invitation.DoesNotExist: |
273 | 292 |
return None |
274 |
|
|
293 |
|
|
275 | 294 |
@property |
276 | 295 |
def quota(self): |
277 | 296 |
d = defaultdict(int) |
278 |
for q in self.astakosuserquota_set.all():
|
|
297 |
for q in self.astakosuserquota_set.all(): |
|
279 | 298 |
d[q.resource.name] += q.limit |
280 | 299 |
for m in self.membership_set.all(): |
281 | 300 |
if not m.is_approved: |
... | ... | |
287 | 306 |
d[r] += limit |
288 | 307 |
# TODO set default for remaining |
289 | 308 |
return d |
290 |
|
|
309 |
|
|
291 | 310 |
def save(self, update_timestamps=True, **kwargs): |
292 | 311 |
if update_timestamps: |
293 | 312 |
if not self.id: |
294 | 313 |
self.date_joined = datetime.now() |
295 | 314 |
self.updated = datetime.now() |
296 |
|
|
315 |
|
|
297 | 316 |
# update date_signed_terms if necessary |
298 | 317 |
if self.__has_signed_terms != self.has_signed_terms: |
299 | 318 |
self.date_signed_terms = datetime.now() |
300 |
|
|
319 |
|
|
301 | 320 |
if not self.id: |
302 | 321 |
# set username |
303 | 322 |
while not self.username: |
304 |
username = uuid.uuid4().hex[:30]
|
|
323 |
username = uuid.uuid4().hex[:30] |
|
305 | 324 |
try: |
306 |
AstakosUser.objects.get(username = username)
|
|
325 |
AstakosUser.objects.get(username=username)
|
|
307 | 326 |
except AstakosUser.DoesNotExist: |
308 | 327 |
self.username = username |
309 | 328 |
if not self.provider: |
... | ... | |
312 | 331 |
if self.is_active and self.activation_sent: |
313 | 332 |
# reset the activation sent |
314 | 333 |
self.activation_sent = None |
315 |
|
|
334 |
|
|
316 | 335 |
super(AstakosUser, self).save(**kwargs) |
317 |
|
|
336 |
|
|
318 | 337 |
def renew_token(self): |
319 | 338 |
md5 = hashlib.md5() |
320 | 339 |
md5.update(self.username) |
... | ... | |
324 | 343 |
self.auth_token = b64encode(md5.digest()) |
325 | 344 |
self.auth_token_created = datetime.now() |
326 | 345 |
self.auth_token_expires = self.auth_token_created + \ |
327 |
timedelta(hours=AUTH_TOKEN_DURATION)
|
|
346 |
timedelta(hours=AUTH_TOKEN_DURATION) |
|
328 | 347 |
msg = 'Token renewed for %s' % self.email |
329 | 348 |
logger.log(LOGGING_LEVEL, msg) |
330 | 349 |
|
331 | 350 |
def __unicode__(self): |
332 | 351 |
return '%s (%s)' % (self.realname, self.email) |
333 |
|
|
352 |
|
|
334 | 353 |
def conflicting_email(self): |
335 |
q = AstakosUser.objects.exclude(username = self.username)
|
|
336 |
q = q.filter(email = self.email)
|
|
354 |
q = AstakosUser.objects.exclude(username=self.username)
|
|
355 |
q = q.filter(email=self.email)
|
|
337 | 356 |
if q.count() != 0: |
338 | 357 |
return True |
339 | 358 |
return False |
340 |
|
|
359 |
|
|
341 | 360 |
def validate_unique_email_isactive(self): |
342 | 361 |
""" |
343 | 362 |
Implements a unique_together constraint for email and is_active fields. |
344 | 363 |
""" |
345 |
q = AstakosUser.objects.exclude(username = self.username)
|
|
346 |
q = q.filter(email = self.email)
|
|
347 |
q = q.filter(is_active = self.is_active)
|
|
364 |
q = AstakosUser.objects.exclude(username=self.username)
|
|
365 |
q = q.filter(email=self.email)
|
|
366 |
q = q.filter(is_active=self.is_active)
|
|
348 | 367 |
if q.count() != 0: |
349 |
raise ValidationError({'__all__':[_('Another account with the same email & is_active combination found.')]}) |
|
350 |
|
|
368 |
raise ValidationError({'__all__': [_('Another account with the same email & is_active combination found.')]})
|
|
369 |
|
|
351 | 370 |
@property |
352 | 371 |
def signed_terms(self): |
353 | 372 |
term = get_latest_terms() |
... | ... | |
364 | 383 |
return False |
365 | 384 |
return True |
366 | 385 |
|
386 |
|
|
367 | 387 |
class Membership(models.Model): |
368 | 388 |
person = models.ForeignKey(AstakosUser) |
369 | 389 |
group = models.ForeignKey(AstakosGroup) |
370 | 390 |
date_requested = models.DateField(default=datetime.now(), blank=True) |
371 | 391 |
date_joined = models.DateField(null=True, db_index=True, blank=True) |
372 |
|
|
392 |
|
|
373 | 393 |
class Meta: |
374 | 394 |
unique_together = ("person", "group") |
375 |
|
|
395 |
|
|
376 | 396 |
def save(self, *args, **kwargs): |
377 | 397 |
if not self.id: |
378 | 398 |
if not self.group.moderation_enabled: |
379 | 399 |
self.date_joined = datetime.now() |
380 | 400 |
super(Membership, self).save(*args, **kwargs) |
381 |
|
|
401 |
|
|
382 | 402 |
@property |
383 | 403 |
def is_approved(self): |
384 | 404 |
if self.date_joined: |
385 | 405 |
return True |
386 | 406 |
return False |
387 |
|
|
407 |
|
|
388 | 408 |
def approve(self): |
389 | 409 |
self.date_joined = datetime.now() |
390 | 410 |
self.save() |
391 | 411 |
quota_disturbed.send(sender=self, users=(self.person,)) |
392 |
|
|
412 |
|
|
393 | 413 |
def disapprove(self): |
394 | 414 |
self.delete() |
395 | 415 |
quota_disturbed.send(sender=self, users=(self.person,)) |
396 | 416 |
|
417 |
|
|
397 | 418 |
class AstakosGroupQuota(models.Model): |
398 | 419 |
limit = models.PositiveIntegerField('Limit') |
399 | 420 |
resource = models.ForeignKey(Resource) |
400 | 421 |
group = models.ForeignKey(AstakosGroup, blank=True) |
401 |
|
|
422 |
|
|
402 | 423 |
class Meta: |
403 | 424 |
unique_together = ("resource", "group") |
404 | 425 |
|
426 |
|
|
405 | 427 |
class AstakosUserQuota(models.Model): |
406 | 428 |
limit = models.PositiveIntegerField('Limit') |
407 | 429 |
resource = models.ForeignKey(Resource) |
408 | 430 |
user = models.ForeignKey(AstakosUser) |
409 |
|
|
431 |
|
|
410 | 432 |
class Meta: |
411 | 433 |
unique_together = ("resource", "user") |
412 | 434 |
|
435 |
|
|
413 | 436 |
class ApprovalTerms(models.Model): |
414 | 437 |
""" |
415 | 438 |
Model for approval terms |
416 | 439 |
""" |
417 | 440 |
|
418 |
date = models.DateTimeField('Issue date', db_index=True, default=datetime.now()) |
|
441 |
date = models.DateTimeField( |
|
442 |
'Issue date', db_index=True, default=datetime.now()) |
|
419 | 443 |
location = models.CharField('Terms location', max_length=255) |
420 | 444 |
|
445 |
|
|
421 | 446 |
class Invitation(models.Model): |
422 | 447 |
""" |
423 | 448 |
Model for registring invitations |
... | ... | |
430 | 455 |
is_consumed = models.BooleanField('Consumed?', default=False) |
431 | 456 |
created = models.DateTimeField('Creation date', auto_now_add=True) |
432 | 457 |
consumed = models.DateTimeField('Consumption date', null=True, blank=True) |
433 |
|
|
458 |
|
|
434 | 459 |
def __init__(self, *args, **kwargs): |
435 | 460 |
super(Invitation, self).__init__(*args, **kwargs) |
436 | 461 |
if not self.id: |
437 | 462 |
self.code = _generate_invitation_code() |
438 |
|
|
463 |
|
|
439 | 464 |
def consume(self): |
440 | 465 |
self.is_consumed = True |
441 | 466 |
self.consumed = datetime.now() |
... | ... | |
444 | 469 |
def __unicode__(self): |
445 | 470 |
return '%s -> %s [%d]' % (self.inviter, self.username, self.code) |
446 | 471 |
|
472 |
|
|
447 | 473 |
class EmailChangeManager(models.Manager): |
448 | 474 |
@transaction.commit_on_success |
449 | 475 |
def change_email(self, activation_key): |
... | ... | |
464 | 490 |
Throws ValueError if there is already |
465 | 491 |
""" |
466 | 492 |
try: |
467 |
email_change = self.model.objects.get(activation_key=activation_key) |
|
493 |
email_change = self.model.objects.get( |
|
494 |
activation_key=activation_key) |
|
468 | 495 |
if email_change.activation_key_expired(): |
469 | 496 |
email_change.delete() |
470 | 497 |
raise EmailChange.DoesNotExist |
... | ... | |
484 | 511 |
except EmailChange.DoesNotExist: |
485 | 512 |
raise ValueError(_('Invalid activation key')) |
486 | 513 |
|
514 |
|
|
487 | 515 |
class EmailChange(models.Model): |
488 | 516 |
new_email_address = models.EmailField(_(u'new e-mail address'), help_text=_(u'Your old email address will be used until you verify your new one.')) |
489 |
user = models.ForeignKey(AstakosUser, unique=True, related_name='emailchange_user') |
|
517 |
user = models.ForeignKey( |
|
518 |
AstakosUser, unique=True, related_name='emailchange_user') |
|
490 | 519 |
requested_at = models.DateTimeField(default=datetime.now()) |
491 |
activation_key = models.CharField(max_length=40, unique=True, db_index=True) |
|
520 |
activation_key = models.CharField( |
|
521 |
max_length=40, unique=True, db_index=True) |
|
492 | 522 |
|
493 | 523 |
objects = EmailChangeManager() |
494 | 524 |
|
... | ... | |
496 | 526 |
expiration_date = timedelta(days=EMAILCHANGE_ACTIVATION_DAYS) |
497 | 527 |
return self.requested_at + expiration_date < datetime.now() |
498 | 528 |
|
529 |
|
|
499 | 530 |
class AdditionalMail(models.Model): |
500 | 531 |
""" |
501 | 532 |
Model for registring invitations |
... | ... | |
503 | 534 |
owner = models.ForeignKey(AstakosUser) |
504 | 535 |
email = models.EmailField() |
505 | 536 |
|
537 |
|
|
506 | 538 |
def _generate_invitation_code(): |
507 | 539 |
while True: |
508 |
code = randint(1, 2L**63 - 1)
|
|
540 |
code = randint(1, 2L ** 63 - 1)
|
|
509 | 541 |
try: |
510 | 542 |
Invitation.objects.get(code=code) |
511 | 543 |
# An invitation with this code already exists, try again |
512 | 544 |
except Invitation.DoesNotExist: |
513 | 545 |
return code |
514 | 546 |
|
547 |
|
|
515 | 548 |
def get_latest_terms(): |
516 | 549 |
try: |
517 | 550 |
term = ApprovalTerms.objects.order_by('-id')[0] |
... | ... | |
520 | 553 |
pass |
521 | 554 |
return None |
522 | 555 |
|
556 |
|
|
523 | 557 |
def create_astakos_user(u): |
524 | 558 |
try: |
525 | 559 |
AstakosUser.objects.get(user_ptr=u.pk) |
... | ... | |
532 | 566 |
logger.exception(e) |
533 | 567 |
pass |
534 | 568 |
|
569 |
|
|
535 | 570 |
def fix_superusers(sender, **kwargs): |
536 | 571 |
# Associate superusers with AstakosUser |
537 | 572 |
admins = User.objects.filter(is_superuser=True) |
538 | 573 |
for u in admins: |
539 | 574 |
create_astakos_user(u) |
540 | 575 |
|
576 |
|
|
541 | 577 |
def user_post_save(sender, instance, created, **kwargs): |
542 | 578 |
if not created: |
543 | 579 |
return |
544 | 580 |
create_astakos_user(instance) |
545 | 581 |
|
582 |
|
|
546 | 583 |
def set_default_group(user): |
547 | 584 |
try: |
548 |
default = AstakosGroup.objects.get(name = 'default') |
|
549 |
Membership(group=default, person=user, date_joined=datetime.now()).save() |
|
585 |
default = AstakosGroup.objects.get(name='default') |
|
586 |
Membership( |
|
587 |
group=default, person=user, date_joined=datetime.now()).save() |
|
550 | 588 |
except AstakosGroup.DoesNotExist, e: |
551 | 589 |
logger.exception(e) |
552 | 590 |
|
591 |
|
|
553 | 592 |
def astakosuser_pre_save(sender, instance, **kwargs): |
554 | 593 |
instance.aquarium_report = False |
555 | 594 |
instance.new = False |
556 | 595 |
try: |
557 |
db_instance = AstakosUser.objects.get(id = instance.id)
|
|
596 |
db_instance = AstakosUser.objects.get(id=instance.id)
|
|
558 | 597 |
except AstakosUser.DoesNotExist: |
559 | 598 |
# create event |
560 | 599 |
instance.aquarium_report = True |
... | ... | |
562 | 601 |
else: |
563 | 602 |
get = AstakosUser.__getattribute__ |
564 | 603 |
l = filter(lambda f: get(db_instance, f) != get(instance, f), |
565 |
BILLING_FIELDS |
|
566 |
) |
|
604 |
BILLING_FIELDS
|
|
605 |
)
|
|
567 | 606 |
instance.aquarium_report = True if l else False |
568 | 607 |
|
608 |
|
|
569 | 609 |
def astakosuser_post_save(sender, instance, created, **kwargs): |
570 | 610 |
if instance.aquarium_report: |
571 | 611 |
report_user_event(instance, create=instance.new) |
... | ... | |
575 | 615 |
# TODO handle socket.error & IOError |
576 | 616 |
register_users((instance,)) |
577 | 617 |
|
618 |
|
|
578 | 619 |
def send_quota_disturbed(sender, instance, **kwargs): |
579 | 620 |
users = [] |
580 | 621 |
extend = users.extend |
... | ... | |
593 | 634 |
return |
594 | 635 |
quota_disturbed.send(sender=sender, users=users) |
595 | 636 |
|
637 |
|
|
596 | 638 |
def on_quota_disturbed(sender, users, **kwargs): |
597 | 639 |
print '>>>', locals() |
598 | 640 |
if not users: |
... | ... | |
612 | 654 |
post_save.connect(send_quota_disturbed, sender=AstakosUserQuota) |
613 | 655 |
post_delete.connect(send_quota_disturbed, sender=AstakosUserQuota) |
614 | 656 |
post_save.connect(send_quota_disturbed, sender=AstakosGroupQuota) |
615 |
post_delete.connect(send_quota_disturbed, sender=AstakosGroupQuota) |
|
657 |
post_delete.connect(send_quota_disturbed, sender=AstakosGroupQuota) |
Also available in: Unified diff