root / snf-astakos-app / astakos / im / models.py @ 85d444db
History | View | Annotate | Download (72.1 kB)
1 | aba1e498 | Antony Chazapis | # Copyright 2011-2012 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | 6c736ed7 | Kostas Papadimitriou | #
|
3 | 64cd4730 | Antony Chazapis | # Redistribution and use in source and binary forms, with or
|
4 | 64cd4730 | Antony Chazapis | # without modification, are permitted provided that the following
|
5 | 64cd4730 | Antony Chazapis | # conditions are met:
|
6 | 6c736ed7 | Kostas Papadimitriou | #
|
7 | 64cd4730 | Antony Chazapis | # 1. Redistributions of source code must retain the above
|
8 | 64cd4730 | Antony Chazapis | # copyright notice, this list of conditions and the following
|
9 | 64cd4730 | Antony Chazapis | # disclaimer.
|
10 | 6c736ed7 | Kostas Papadimitriou | #
|
11 | 64cd4730 | Antony Chazapis | # 2. Redistributions in binary form must reproduce the above
|
12 | 64cd4730 | Antony Chazapis | # copyright notice, this list of conditions and the following
|
13 | 64cd4730 | Antony Chazapis | # disclaimer in the documentation and/or other materials
|
14 | 64cd4730 | Antony Chazapis | # provided with the distribution.
|
15 | 6c736ed7 | Kostas Papadimitriou | #
|
16 | 64cd4730 | Antony Chazapis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | 64cd4730 | Antony Chazapis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | 64cd4730 | Antony Chazapis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | 64cd4730 | Antony Chazapis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | 64cd4730 | Antony Chazapis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | 64cd4730 | Antony Chazapis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | 64cd4730 | Antony Chazapis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | 64cd4730 | Antony Chazapis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | 64cd4730 | Antony Chazapis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | 64cd4730 | Antony Chazapis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | 64cd4730 | Antony Chazapis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | 64cd4730 | Antony Chazapis | # POSSIBILITY OF SUCH DAMAGE.
|
28 | 6c736ed7 | Kostas Papadimitriou | #
|
29 | 64cd4730 | Antony Chazapis | # The views and conclusions contained in the software and
|
30 | 64cd4730 | Antony Chazapis | # documentation are those of the authors and should not be
|
31 | 64cd4730 | Antony Chazapis | # interpreted as representing official policies, either expressed
|
32 | 64cd4730 | Antony Chazapis | # or implied, of GRNET S.A.
|
33 | 64cd4730 | Antony Chazapis | |
34 | 64cd4730 | Antony Chazapis | import hashlib |
35 | 15efc749 | Sofia Papagiannaki | import uuid |
36 | 18ffbee1 | Sofia Papagiannaki | import logging |
37 | 3a72a5d4 | Kostas Papadimitriou | import json |
38 | 64cd4730 | Antony Chazapis | |
39 | d6fdc91e | Georgios D. Tsoukalas | from time import asctime, sleep |
40 | 64cd4730 | Antony Chazapis | from datetime import datetime, timedelta |
41 | 64cd4730 | Antony Chazapis | from base64 import b64encode |
42 | ef20ea07 | Sofia Papagiannaki | from urlparse import urlparse |
43 | d2633501 | Kostas Papadimitriou | from urllib import quote |
44 | 8f5a3a06 | Sofia Papagiannaki | from random import randint |
45 | 65360c65 | Georgios D. Tsoukalas | from collections import defaultdict, namedtuple |
46 | 64cd4730 | Antony Chazapis | |
47 | d6fdc91e | Georgios D. Tsoukalas | from django.db import models, IntegrityError, transaction, connection |
48 | 9a06d96f | Olga Brani | from django.contrib.auth.models import User, UserManager, Group, Permission |
49 | 0a569195 | Sofia Papagiannaki | from django.utils.translation import ugettext as _ |
50 | 49790d9d | Sofia Papagiannaki | from django.db import transaction |
51 | 0a569195 | Sofia Papagiannaki | from django.core.exceptions import ValidationError |
52 | c0b26605 | Sofia Papagiannaki | from django.db.models.signals import ( |
53 | 73fbaec4 | Sofia Papagiannaki | pre_save, post_save, post_syncdb, post_delete) |
54 | 9a06d96f | Olga Brani | from django.contrib.contenttypes.models import ContentType |
55 | 9a06d96f | Olga Brani | |
56 | fc1e2f02 | Sofia Papagiannaki | from django.dispatch import Signal |
57 | e6759494 | Sofia Papagiannaki | from django.db.models import Q |
58 | d2633501 | Kostas Papadimitriou | from django.core.urlresolvers import reverse |
59 | d2633501 | Kostas Papadimitriou | from django.utils.http import int_to_base36 |
60 | d2633501 | Kostas Papadimitriou | from django.contrib.auth.tokens import default_token_generator |
61 | 8f8c43b2 | Sofia Papagiannaki | from django.conf import settings |
62 | bf0c6de5 | Sofia Papagiannaki | from django.utils.importlib import import_module |
63 | c4b1a172 | Kostas Papadimitriou | from django.utils.safestring import mark_safe |
64 | d2633501 | Kostas Papadimitriou | from django.core.validators import email_re |
65 | 73fbaec4 | Sofia Papagiannaki | from django.core.exceptions import PermissionDenied, ObjectDoesNotExist |
66 | 64cd4730 | Antony Chazapis | |
67 | e1a80257 | Sofia Papagiannaki | from astakos.im.settings import ( |
68 | e1a80257 | Sofia Papagiannaki | DEFAULT_USER_LEVEL, INVITATIONS_PER_LEVEL, |
69 | e1a80257 | Sofia Papagiannaki | AUTH_TOKEN_DURATION, BILLING_FIELDS, |
70 | 71a38edf | Sofia Papagiannaki | EMAILCHANGE_ACTIVATION_DAYS, LOGGING_LEVEL, |
71 | 47b77c8b | Sofia Papagiannaki | SITENAME, SERVICES, MODERATION_ENABLED) |
72 | c4b1a172 | Kostas Papadimitriou | from astakos.im import settings as astakos_settings |
73 | c0b26605 | Sofia Papagiannaki | from astakos.im.endpoints.qh import ( |
74 | ee45eb81 | Giorgos Korfiatis | register_users, send_quota, register_resources, qh_add_quota, QuotaLimits, |
75 | ee45eb81 | Giorgos Korfiatis | qh_query_serials, qh_ack_serials) |
76 | d2633501 | Kostas Papadimitriou | from astakos.im import auth_providers |
77 | 73fbaec4 | Sofia Papagiannaki | #from astakos.im.endpoints.aquarium.producer import report_user_event
|
78 | f8f86e83 | root | #from astakos.im.tasks import propagate_groupmembers_quota
|
79 | 9c01d9d1 | Sofia Papagiannaki | |
80 | ae497612 | Olga Brani | import astakos.im.messages as astakos_messages |
81 | ee45eb81 | Giorgos Korfiatis | from .managers import ForUpdateManager |
82 | 64cd4730 | Antony Chazapis | |
83 | 18ffbee1 | Sofia Papagiannaki | logger = logging.getLogger(__name__) |
84 | 18ffbee1 | Sofia Papagiannaki | |
85 | 9a06d96f | Olga Brani | DEFAULT_CONTENT_TYPE = None
|
86 | e65c21df | Georgios D. Tsoukalas | _content_type = None
|
87 | e65c21df | Georgios D. Tsoukalas | |
88 | e65c21df | Georgios D. Tsoukalas | def get_content_type(): |
89 | e65c21df | Georgios D. Tsoukalas | global _content_type
|
90 | e65c21df | Georgios D. Tsoukalas | if _content_type is not None: |
91 | e65c21df | Georgios D. Tsoukalas | return _content_type
|
92 | e65c21df | Georgios D. Tsoukalas | |
93 | e65c21df | Georgios D. Tsoukalas | try:
|
94 | e65c21df | Georgios D. Tsoukalas | content_type = ContentType.objects.get(app_label='im', model='astakosuser') |
95 | e65c21df | Georgios D. Tsoukalas | except:
|
96 | e65c21df | Georgios D. Tsoukalas | content_type = DEFAULT_CONTENT_TYPE |
97 | e65c21df | Georgios D. Tsoukalas | _content_type = content_type |
98 | e65c21df | Georgios D. Tsoukalas | return content_type
|
99 | 9a06d96f | Olga Brani | |
100 | 9a06d96f | Olga Brani | RESOURCE_SEPARATOR = '.'
|
101 | 9a06d96f | Olga Brani | |
102 | 9ee0c6a2 | Sofia Papagiannaki | inf = float('inf') |
103 | 5ce3ce4f | Sofia Papagiannaki | |
104 | 8e45d6fd | Sofia Papagiannaki | class Service(models.Model): |
105 | e1a80257 | Sofia Papagiannaki | name = models.CharField(_('Name'), max_length=255, unique=True, db_index=True) |
106 | 8e45d6fd | Sofia Papagiannaki | url = models.FilePathField() |
107 | 8e45d6fd | Sofia Papagiannaki | icon = models.FilePathField(blank=True)
|
108 | e1a80257 | Sofia Papagiannaki | auth_token = models.CharField(_('Authentication Token'), max_length=32, |
109 | 8e45d6fd | Sofia Papagiannaki | null=True, blank=True) |
110 | e1a80257 | Sofia Papagiannaki | auth_token_created = models.DateTimeField(_('Token creation date'), null=True) |
111 | 5ce3ce4f | Sofia Papagiannaki | auth_token_expires = models.DateTimeField( |
112 | e1a80257 | Sofia Papagiannaki | _('Token expiration date'), null=True) |
113 | 5ce3ce4f | Sofia Papagiannaki | |
114 | 8e45d6fd | Sofia Papagiannaki | def renew_token(self): |
115 | 8e45d6fd | Sofia Papagiannaki | md5 = hashlib.md5() |
116 | 8e45d6fd | Sofia Papagiannaki | md5.update(self.name.encode('ascii', 'ignore')) |
117 | 8e45d6fd | Sofia Papagiannaki | md5.update(self.url.encode('ascii', 'ignore')) |
118 | 8e45d6fd | Sofia Papagiannaki | md5.update(asctime()) |
119 | 8e45d6fd | Sofia Papagiannaki | |
120 | 8e45d6fd | Sofia Papagiannaki | self.auth_token = b64encode(md5.digest())
|
121 | 8e45d6fd | Sofia Papagiannaki | self.auth_token_created = datetime.now()
|
122 | 8e45d6fd | Sofia Papagiannaki | self.auth_token_expires = self.auth_token_created + \ |
123 | 5ce3ce4f | Sofia Papagiannaki | timedelta(hours=AUTH_TOKEN_DURATION) |
124 | 5ce3ce4f | Sofia Papagiannaki | |
125 | 8e45d6fd | Sofia Papagiannaki | def __str__(self): |
126 | 8e45d6fd | Sofia Papagiannaki | return self.name |
127 | 8e45d6fd | Sofia Papagiannaki | |
128 | 9a06d96f | Olga Brani | @property
|
129 | 9a06d96f | Olga Brani | def resources(self): |
130 | 9a06d96f | Olga Brani | return self.resource_set.all() |
131 | 9a06d96f | Olga Brani | |
132 | 9a06d96f | Olga Brani | @resources.setter
|
133 | 9a06d96f | Olga Brani | def resources(self, resources): |
134 | 9a06d96f | Olga Brani | for s in resources: |
135 | 9a06d96f | Olga Brani | self.resource_set.create(**s)
|
136 | 2e90e3ec | Kostas Papadimitriou | |
137 | 9a06d96f | Olga Brani | def add_resource(self, service, resource, uplimit, update=True): |
138 | 9a06d96f | Olga Brani | """Raises ObjectDoesNotExist, IntegrityError"""
|
139 | 9a06d96f | Olga Brani | resource = Resource.objects.get(service__name=service, name=resource) |
140 | 9a06d96f | Olga Brani | if update:
|
141 | 9a06d96f | Olga Brani | AstakosUserQuota.objects.update_or_create(user=self,
|
142 | 9a06d96f | Olga Brani | resource=resource, |
143 | 9a06d96f | Olga Brani | defaults={'uplimit': uplimit})
|
144 | 9a06d96f | Olga Brani | else:
|
145 | 9a06d96f | Olga Brani | q = self.astakosuserquota_set
|
146 | 9a06d96f | Olga Brani | q.create(resource=resource, uplimit=uplimit) |
147 | 9a06d96f | Olga Brani | |
148 | 5ce3ce4f | Sofia Papagiannaki | |
149 | 8e45d6fd | Sofia Papagiannaki | class ResourceMetadata(models.Model): |
150 | e1a80257 | Sofia Papagiannaki | key = models.CharField(_('Name'), max_length=255, unique=True, db_index=True) |
151 | e1a80257 | Sofia Papagiannaki | value = models.CharField(_('Value'), max_length=255) |
152 | 8e45d6fd | Sofia Papagiannaki | |
153 | 5ce3ce4f | Sofia Papagiannaki | |
154 | 8e45d6fd | Sofia Papagiannaki | class Resource(models.Model): |
155 | 43e09b6c | Sofia Papagiannaki | name = models.CharField(_('Name'), max_length=255) |
156 | 8e45d6fd | Sofia Papagiannaki | meta = models.ManyToManyField(ResourceMetadata) |
157 | 8e45d6fd | Sofia Papagiannaki | service = models.ForeignKey(Service) |
158 | e1a80257 | Sofia Papagiannaki | desc = models.TextField(_('Description'), null=True) |
159 | e1a80257 | Sofia Papagiannaki | unit = models.CharField(_('Name'), null=True, max_length=255) |
160 | e1a80257 | Sofia Papagiannaki | group = models.CharField(_('Group'), null=True, max_length=255) |
161 | 425e2e95 | Sofia Papagiannaki | |
162 | 43e09b6c | Sofia Papagiannaki | class Meta: |
163 | 43e09b6c | Sofia Papagiannaki | unique_together = ("name", "service") |
164 | 5ce3ce4f | Sofia Papagiannaki | |
165 | 8e45d6fd | Sofia Papagiannaki | def __str__(self): |
166 | 9a06d96f | Olga Brani | return '%s%s%s' % (self.service, RESOURCE_SEPARATOR, self.name) |
167 | 8e45d6fd | Sofia Papagiannaki | |
168 | 5ce3ce4f | Sofia Papagiannaki | |
169 | 8e45d6fd | Sofia Papagiannaki | class GroupKind(models.Model): |
170 | e1a80257 | Sofia Papagiannaki | name = models.CharField(_('Name'), max_length=255, unique=True, db_index=True) |
171 | 5ce3ce4f | Sofia Papagiannaki | |
172 | 8e45d6fd | Sofia Papagiannaki | def __str__(self): |
173 | 8e45d6fd | Sofia Papagiannaki | return self.name |
174 | 8e45d6fd | Sofia Papagiannaki | |
175 | 5ce3ce4f | Sofia Papagiannaki | |
176 | 8e45d6fd | Sofia Papagiannaki | class AstakosGroup(Group): |
177 | 8e45d6fd | Sofia Papagiannaki | kind = models.ForeignKey(GroupKind) |
178 | 2b1a5f5d | Olga Brani | homepage = models.URLField( |
179 | e1a80257 | Sofia Papagiannaki | _('Homepage Url'), max_length=255, null=True, blank=True) |
180 | e1a80257 | Sofia Papagiannaki | desc = models.TextField(_('Description'), null=True) |
181 | 9a06d96f | Olga Brani | policy = models.ManyToManyField( |
182 | 9a06d96f | Olga Brani | Resource, |
183 | 9a06d96f | Olga Brani | null=True,
|
184 | 9a06d96f | Olga Brani | blank=True,
|
185 | 9a06d96f | Olga Brani | through='AstakosGroupQuota'
|
186 | 9a06d96f | Olga Brani | ) |
187 | 9a06d96f | Olga Brani | creation_date = models.DateTimeField( |
188 | e1a80257 | Sofia Papagiannaki | _('Creation date'),
|
189 | 9a06d96f | Olga Brani | default=datetime.now() |
190 | 9a06d96f | Olga Brani | ) |
191 | 8327782d | Sofia Papagiannaki | issue_date = models.DateTimeField( |
192 | 8327782d | Sofia Papagiannaki | _('Start date'),
|
193 | 8327782d | Sofia Papagiannaki | null=True
|
194 | 8327782d | Sofia Papagiannaki | ) |
195 | 9a06d96f | Olga Brani | expiration_date = models.DateTimeField( |
196 | e1a80257 | Sofia Papagiannaki | _('Expiration date'),
|
197 | e1a80257 | Sofia Papagiannaki | null=True
|
198 | 9a06d96f | Olga Brani | ) |
199 | 9a06d96f | Olga Brani | moderation_enabled = models.BooleanField( |
200 | e1a80257 | Sofia Papagiannaki | _('Moderated membership?'),
|
201 | 9a06d96f | Olga Brani | default=True
|
202 | 9a06d96f | Olga Brani | ) |
203 | 9a06d96f | Olga Brani | approval_date = models.DateTimeField( |
204 | e1a80257 | Sofia Papagiannaki | _('Activation date'),
|
205 | 9a06d96f | Olga Brani | null=True,
|
206 | 9a06d96f | Olga Brani | blank=True
|
207 | 9a06d96f | Olga Brani | ) |
208 | 9a06d96f | Olga Brani | estimated_participants = models.PositiveIntegerField( |
209 | e1a80257 | Sofia Papagiannaki | _('Estimated #members'),
|
210 | 9a06d96f | Olga Brani | null=True,
|
211 | 9a06d96f | Olga Brani | blank=True,
|
212 | 9a06d96f | Olga Brani | ) |
213 | 9a06d96f | Olga Brani | max_participants = models.PositiveIntegerField( |
214 | e1a80257 | Sofia Papagiannaki | _('Maximum numder of participants'),
|
215 | 9a06d96f | Olga Brani | null=True,
|
216 | 9a06d96f | Olga Brani | blank=True
|
217 | 9a06d96f | Olga Brani | ) |
218 | 2e90e3ec | Kostas Papadimitriou | |
219 | 8e45d6fd | Sofia Papagiannaki | @property
|
220 | 8e45d6fd | Sofia Papagiannaki | def is_disabled(self): |
221 | ffb1e7a8 | Sofia Papagiannaki | if not self.approval_date: |
222 | ffb1e7a8 | Sofia Papagiannaki | return True |
223 | ffb1e7a8 | Sofia Papagiannaki | return False |
224 | 5ce3ce4f | Sofia Papagiannaki | |
225 | 8e45d6fd | Sofia Papagiannaki | @property
|
226 | ffb1e7a8 | Sofia Papagiannaki | def is_enabled(self): |
227 | 8e45d6fd | Sofia Papagiannaki | if self.is_disabled: |
228 | 8e45d6fd | Sofia Papagiannaki | return False |
229 | 8e45d6fd | Sofia Papagiannaki | if not self.issue_date: |
230 | 8e45d6fd | Sofia Papagiannaki | return False |
231 | 8e45d6fd | Sofia Papagiannaki | if not self.expiration_date: |
232 | 8e45d6fd | Sofia Papagiannaki | return True |
233 | 8e45d6fd | Sofia Papagiannaki | now = datetime.now() |
234 | 8e45d6fd | Sofia Papagiannaki | if self.issue_date > now: |
235 | 8e45d6fd | Sofia Papagiannaki | return False |
236 | 8e45d6fd | Sofia Papagiannaki | if now >= self.expiration_date: |
237 | 8e45d6fd | Sofia Papagiannaki | return False |
238 | 8e45d6fd | Sofia Papagiannaki | return True |
239 | 5ce3ce4f | Sofia Papagiannaki | |
240 | ffb1e7a8 | Sofia Papagiannaki | def enable(self): |
241 | fc1e2f02 | Sofia Papagiannaki | if self.is_enabled: |
242 | fc1e2f02 | Sofia Papagiannaki | return
|
243 | 8e45d6fd | Sofia Papagiannaki | self.approval_date = datetime.now()
|
244 | 8e45d6fd | Sofia Papagiannaki | self.save()
|
245 | 20d50182 | Sofia Papagiannaki | quota_disturbed.send(sender=self, users=self.approved_members) |
246 | f8f86e83 | root | #propagate_groupmembers_quota.apply_async(
|
247 | f8f86e83 | root | # args=[self], eta=self.issue_date)
|
248 | f8f86e83 | root | #propagate_groupmembers_quota.apply_async(
|
249 | f8f86e83 | root | # args=[self], eta=self.expiration_date)
|
250 | 5ce3ce4f | Sofia Papagiannaki | |
251 | ffb1e7a8 | Sofia Papagiannaki | def disable(self): |
252 | fc1e2f02 | Sofia Papagiannaki | if self.is_disabled: |
253 | fc1e2f02 | Sofia Papagiannaki | return
|
254 | 8e45d6fd | Sofia Papagiannaki | self.approval_date = None |
255 | 8e45d6fd | Sofia Papagiannaki | self.save()
|
256 | fc1e2f02 | Sofia Papagiannaki | quota_disturbed.send(sender=self, users=self.approved_members) |
257 | 5ce3ce4f | Sofia Papagiannaki | |
258 | 01ac12d5 | Sofia Papagiannaki | def approve_member(self, person): |
259 | 0f4fa26d | Sofia Papagiannaki | m, created = self.membership_set.get_or_create(person=person)
|
260 | e1a80257 | Sofia Papagiannaki | m.approve() |
261 | 5ce3ce4f | Sofia Papagiannaki | |
262 | 01ac12d5 | Sofia Papagiannaki | @property
|
263 | 01ac12d5 | Sofia Papagiannaki | def members(self): |
264 | 032ade79 | Sofia Papagiannaki | q = self.membership_set.select_related().all()
|
265 | 032ade79 | Sofia Papagiannaki | return [m.person for m in q] |
266 | 2e90e3ec | Kostas Papadimitriou | |
267 | 01ac12d5 | Sofia Papagiannaki | @property
|
268 | 01ac12d5 | Sofia Papagiannaki | def approved_members(self): |
269 | 032ade79 | Sofia Papagiannaki | q = self.membership_set.select_related().all()
|
270 | 032ade79 | Sofia Papagiannaki | return [m.person for m in q if m.is_approved] |
271 | 5ce3ce4f | Sofia Papagiannaki | |
272 | 01ac12d5 | Sofia Papagiannaki | @property
|
273 | ffb1e7a8 | Sofia Papagiannaki | def quota(self): |
274 | 0f4fa26d | Sofia Papagiannaki | d = defaultdict(int)
|
275 | dfdc64d2 | Sofia Papagiannaki | for q in self.astakosgroupquota_set.select_related().all(): |
276 | 9ee0c6a2 | Sofia Papagiannaki | d[q.resource] += q.uplimit or inf
|
277 | ffb1e7a8 | Sofia Papagiannaki | return d
|
278 | 2e90e3ec | Kostas Papadimitriou | |
279 | 9a06d96f | Olga Brani | def add_policy(self, service, resource, uplimit, update=True): |
280 | 9a06d96f | Olga Brani | """Raises ObjectDoesNotExist, IntegrityError"""
|
281 | 9a06d96f | Olga Brani | resource = Resource.objects.get(service__name=service, name=resource) |
282 | 9a06d96f | Olga Brani | if update:
|
283 | 9a06d96f | Olga Brani | AstakosGroupQuota.objects.update_or_create( |
284 | 9a06d96f | Olga Brani | group=self,
|
285 | 9a06d96f | Olga Brani | resource=resource, |
286 | 9a06d96f | Olga Brani | defaults={'uplimit': uplimit}
|
287 | 9a06d96f | Olga Brani | ) |
288 | 9a06d96f | Olga Brani | else:
|
289 | 9a06d96f | Olga Brani | q = self.astakosgroupquota_set
|
290 | 9a06d96f | Olga Brani | q.create(resource=resource, uplimit=uplimit) |
291 | 2e90e3ec | Kostas Papadimitriou | |
292 | 9a06d96f | Olga Brani | @property
|
293 | 9a06d96f | Olga Brani | def policies(self): |
294 | 9a06d96f | Olga Brani | return self.astakosgroupquota_set.select_related().all() |
295 | 9a06d96f | Olga Brani | |
296 | 9a06d96f | Olga Brani | @policies.setter
|
297 | 9a06d96f | Olga Brani | def policies(self, policies): |
298 | 9a06d96f | Olga Brani | for p in policies: |
299 | 9a06d96f | Olga Brani | service = p.get('service', None) |
300 | 9a06d96f | Olga Brani | resource = p.get('resource', None) |
301 | 9a06d96f | Olga Brani | uplimit = p.get('uplimit', 0) |
302 | 9a06d96f | Olga Brani | update = p.get('update', True) |
303 | 9a06d96f | Olga Brani | self.add_policy(service, resource, uplimit, update)
|
304 | 2e90e3ec | Kostas Papadimitriou | |
305 | 01ac12d5 | Sofia Papagiannaki | @property
|
306 | 0f4fa26d | Sofia Papagiannaki | def owners(self): |
307 | 0f4fa26d | Sofia Papagiannaki | return self.owner.all() |
308 | 5ce3ce4f | Sofia Papagiannaki | |
309 | 032ade79 | Sofia Papagiannaki | @property
|
310 | 032ade79 | Sofia Papagiannaki | def owner_details(self): |
311 | 032ade79 | Sofia Papagiannaki | return self.owner.select_related().all() |
312 | 032ade79 | Sofia Papagiannaki | |
313 | 0f4fa26d | Sofia Papagiannaki | @owners.setter
|
314 | 0f4fa26d | Sofia Papagiannaki | def owners(self, l): |
315 | 0f4fa26d | Sofia Papagiannaki | self.owner = l
|
316 | 0f4fa26d | Sofia Papagiannaki | map(self.approve_member, l) |
317 | 8e45d6fd | Sofia Papagiannaki | |
318 | b4789608 | Sofia Papagiannaki | _default_quota = {} |
319 | b4789608 | Sofia Papagiannaki | def get_default_quota(): |
320 | b4789608 | Sofia Papagiannaki | global _default_quota
|
321 | b4789608 | Sofia Papagiannaki | if _default_quota:
|
322 | b4789608 | Sofia Papagiannaki | return _default_quota
|
323 | b4789608 | Sofia Papagiannaki | for s, data in SERVICES.iteritems(): |
324 | b4789608 | Sofia Papagiannaki | map(
|
325 | b4789608 | Sofia Papagiannaki | lambda d:_default_quota.update(
|
326 | b4789608 | Sofia Papagiannaki | {'%s%s%s' % (s, RESOURCE_SEPARATOR, d.get('name')):d.get('uplimit', 0)} |
327 | b4789608 | Sofia Papagiannaki | ), |
328 | b4789608 | Sofia Papagiannaki | data.get('resources', {})
|
329 | b4789608 | Sofia Papagiannaki | ) |
330 | b4789608 | Sofia Papagiannaki | return _default_quota
|
331 | d2633501 | Kostas Papadimitriou | |
332 | 6b9a334b | Sofia Papagiannaki | class AstakosUserManager(UserManager): |
333 | d2633501 | Kostas Papadimitriou | |
334 | d2633501 | Kostas Papadimitriou | def get_auth_provider_user(self, provider, **kwargs): |
335 | d2633501 | Kostas Papadimitriou | """
|
336 | d2633501 | Kostas Papadimitriou | Retrieve AstakosUser instance associated with the specified third party
|
337 | d2633501 | Kostas Papadimitriou | id.
|
338 | d2633501 | Kostas Papadimitriou | """
|
339 | d2633501 | Kostas Papadimitriou | kwargs = dict(map(lambda x: ('auth_providers__%s' % x[0], x[1]), |
340 | d2633501 | Kostas Papadimitriou | kwargs.iteritems())) |
341 | d2633501 | Kostas Papadimitriou | return self.get(auth_providers__module=provider, **kwargs) |
342 | d2633501 | Kostas Papadimitriou | |
343 | c630fee6 | Kostas Papadimitriou | def get_by_email(self, email): |
344 | c630fee6 | Kostas Papadimitriou | return self.get(email=email) |
345 | c630fee6 | Kostas Papadimitriou | |
346 | e5966bd9 | Kostas Papadimitriou | def get_by_identifier(self, email_or_username, **kwargs): |
347 | e5966bd9 | Kostas Papadimitriou | try:
|
348 | e5966bd9 | Kostas Papadimitriou | return self.get(email__iexact=email_or_username, **kwargs) |
349 | e5966bd9 | Kostas Papadimitriou | except AstakosUser.DoesNotExist:
|
350 | e5966bd9 | Kostas Papadimitriou | return self.get(username__iexact=email_or_username, **kwargs) |
351 | e5966bd9 | Kostas Papadimitriou | |
352 | e5966bd9 | Kostas Papadimitriou | def user_exists(self, email_or_username, **kwargs): |
353 | e5966bd9 | Kostas Papadimitriou | qemail = Q(email__iexact=email_or_username) |
354 | e5966bd9 | Kostas Papadimitriou | qusername = Q(username__iexact=email_or_username) |
355 | e5966bd9 | Kostas Papadimitriou | return self.filter(qemail | qusername).exists() |
356 | e5966bd9 | Kostas Papadimitriou | |
357 | e5966bd9 | Kostas Papadimitriou | |
358 | 0905ccd2 | Sofia Papagiannaki | class AstakosUser(User): |
359 | 890b0eaf | Sofia Papagiannaki | """
|
360 | 890b0eaf | Sofia Papagiannaki | Extends ``django.contrib.auth.models.User`` by defining additional fields.
|
361 | 890b0eaf | Sofia Papagiannaki | """
|
362 | e1a80257 | Sofia Papagiannaki | affiliation = models.CharField(_('Affiliation'), max_length=255, blank=True, |
363 | d2633501 | Kostas Papadimitriou | null=True)
|
364 | d2633501 | Kostas Papadimitriou | |
365 | d2633501 | Kostas Papadimitriou | # DEPRECATED FIELDS: provider, third_party_identifier moved in
|
366 | d2633501 | Kostas Papadimitriou | # AstakosUserProvider model.
|
367 | e1a80257 | Sofia Papagiannaki | provider = models.CharField(_('Provider'), max_length=255, blank=True, |
368 | d2633501 | Kostas Papadimitriou | null=True)
|
369 | d2633501 | Kostas Papadimitriou | # ex. screen_name for twitter, eppn for shibboleth
|
370 | e1a80257 | Sofia Papagiannaki | third_party_identifier = models.CharField(_('Third-party identifier'),
|
371 | d2633501 | Kostas Papadimitriou | max_length=255, null=True, |
372 | d2633501 | Kostas Papadimitriou | blank=True)
|
373 | d2633501 | Kostas Papadimitriou | |
374 | 6c736ed7 | Kostas Papadimitriou | |
375 | 64cd4730 | Antony Chazapis | #for invitations
|
376 | 92defad4 | Sofia Papagiannaki | user_level = DEFAULT_USER_LEVEL |
377 | e1a80257 | Sofia Papagiannaki | level = models.IntegerField(_('Inviter level'), default=user_level)
|
378 | 5ce3ce4f | Sofia Papagiannaki | invitations = models.IntegerField( |
379 | e1a80257 | Sofia Papagiannaki | _('Invitations left'), default=INVITATIONS_PER_LEVEL.get(user_level, 0)) |
380 | 6c736ed7 | Kostas Papadimitriou | |
381 | e1a80257 | Sofia Papagiannaki | auth_token = models.CharField(_('Authentication Token'), max_length=32, |
382 | 0905ccd2 | Sofia Papagiannaki | null=True, blank=True) |
383 | e1a80257 | Sofia Papagiannaki | auth_token_created = models.DateTimeField(_('Token creation date'), null=True) |
384 | 5ce3ce4f | Sofia Papagiannaki | auth_token_expires = models.DateTimeField( |
385 | e1a80257 | Sofia Papagiannaki | _('Token expiration date'), null=True) |
386 | 6c736ed7 | Kostas Papadimitriou | |
387 | e1a80257 | Sofia Papagiannaki | updated = models.DateTimeField(_('Update date'))
|
388 | e1a80257 | Sofia Papagiannaki | is_verified = models.BooleanField(_('Is verified?'), default=False) |
389 | 6c736ed7 | Kostas Papadimitriou | |
390 | e1a80257 | Sofia Papagiannaki | email_verified = models.BooleanField(_('Email verified?'), default=False) |
391 | 6c736ed7 | Kostas Papadimitriou | |
392 | e1a80257 | Sofia Papagiannaki | has_credits = models.BooleanField(_('Has credits?'), default=False) |
393 | 5ce3ce4f | Sofia Papagiannaki | has_signed_terms = models.BooleanField( |
394 | e1a80257 | Sofia Papagiannaki | _('I agree with the terms'), default=False) |
395 | 5ce3ce4f | Sofia Papagiannaki | date_signed_terms = models.DateTimeField( |
396 | e1a80257 | Sofia Papagiannaki | _('Signed terms date'), null=True, blank=True) |
397 | 5ce3ce4f | Sofia Papagiannaki | |
398 | 5ce3ce4f | Sofia Papagiannaki | activation_sent = models.DateTimeField( |
399 | e1a80257 | Sofia Papagiannaki | _('Activation sent data'), null=True, blank=True) |
400 | 5ce3ce4f | Sofia Papagiannaki | |
401 | 5ce3ce4f | Sofia Papagiannaki | policy = models.ManyToManyField( |
402 | 5ce3ce4f | Sofia Papagiannaki | Resource, null=True, through='AstakosUserQuota') |
403 | 5ce3ce4f | Sofia Papagiannaki | |
404 | 836a0fb0 | Kostas Papadimitriou | uuid = models.CharField(max_length=255, null=True, blank=False, unique=True) |
405 | 836a0fb0 | Kostas Papadimitriou | |
406 | 5ce3ce4f | Sofia Papagiannaki | astakos_groups = models.ManyToManyField( |
407 | 5ce3ce4f | Sofia Papagiannaki | AstakosGroup, verbose_name=_('agroups'), blank=True, |
408 | ae497612 | Olga Brani | help_text=_(astakos_messages.ASTAKOSUSER_GROUPS_HELP), |
409 | 8e45d6fd | Sofia Papagiannaki | through='Membership')
|
410 | 5ce3ce4f | Sofia Papagiannaki | |
411 | 18ffbee1 | Sofia Papagiannaki | __has_signed_terms = False
|
412 | e1a80257 | Sofia Papagiannaki | disturbed_quota = models.BooleanField(_('Needs quotaholder syncing'),
|
413 | 9a06d96f | Olga Brani | default=False, db_index=True) |
414 | d2633501 | Kostas Papadimitriou | |
415 | d2633501 | Kostas Papadimitriou | objects = AstakosUserManager() |
416 | fbaa4f3c | Kostas Papadimitriou | |
417 | 836a0fb0 | Kostas Papadimitriou | |
418 | 5ce3ce4f | Sofia Papagiannaki | owner = models.ManyToManyField( |
419 | 5ce3ce4f | Sofia Papagiannaki | AstakosGroup, related_name='owner', null=True) |
420 | 5ce3ce4f | Sofia Papagiannaki | |
421 | 18ffbee1 | Sofia Papagiannaki | def __init__(self, *args, **kwargs): |
422 | 18ffbee1 | Sofia Papagiannaki | super(AstakosUser, self).__init__(*args, **kwargs) |
423 | 18ffbee1 | Sofia Papagiannaki | self.__has_signed_terms = self.has_signed_terms |
424 | a3637508 | Sofia Papagiannaki | if not self.id: |
425 | 18ffbee1 | Sofia Papagiannaki | self.is_active = False |
426 | 5ce3ce4f | Sofia Papagiannaki | |
427 | 0905ccd2 | Sofia Papagiannaki | @property
|
428 | 0905ccd2 | Sofia Papagiannaki | def realname(self): |
429 | 5ce3ce4f | Sofia Papagiannaki | return '%s %s' % (self.first_name, self.last_name) |
430 | 6c736ed7 | Kostas Papadimitriou | |
431 | 0905ccd2 | Sofia Papagiannaki | @realname.setter
|
432 | 0905ccd2 | Sofia Papagiannaki | def realname(self, value): |
433 | 0905ccd2 | Sofia Papagiannaki | parts = value.split(' ')
|
434 | 0905ccd2 | Sofia Papagiannaki | if len(parts) == 2: |
435 | 0905ccd2 | Sofia Papagiannaki | self.first_name = parts[0] |
436 | 0905ccd2 | Sofia Papagiannaki | self.last_name = parts[1] |
437 | 0905ccd2 | Sofia Papagiannaki | else:
|
438 | 0905ccd2 | Sofia Papagiannaki | self.last_name = parts[0] |
439 | 6c736ed7 | Kostas Papadimitriou | |
440 | 9a06d96f | Olga Brani | def add_permission(self, pname): |
441 | 9a06d96f | Olga Brani | if self.has_perm(pname): |
442 | 9a06d96f | Olga Brani | return
|
443 | e65c21df | Georgios D. Tsoukalas | p, created = Permission.objects.get_or_create( |
444 | e65c21df | Georgios D. Tsoukalas | codename=pname, |
445 | e65c21df | Georgios D. Tsoukalas | name=pname.capitalize(), |
446 | e65c21df | Georgios D. Tsoukalas | content_type=get_content_type()) |
447 | 9a06d96f | Olga Brani | self.user_permissions.add(p)
|
448 | 9a06d96f | Olga Brani | |
449 | 9a06d96f | Olga Brani | def remove_permission(self, pname): |
450 | 9a06d96f | Olga Brani | if self.has_perm(pname): |
451 | 9a06d96f | Olga Brani | return
|
452 | 9a06d96f | Olga Brani | p = Permission.objects.get(codename=pname, |
453 | e65c21df | Georgios D. Tsoukalas | content_type=get_content_type()) |
454 | 9a06d96f | Olga Brani | self.user_permissions.remove(p)
|
455 | 9a06d96f | Olga Brani | |
456 | 64cd4730 | Antony Chazapis | @property
|
457 | 64cd4730 | Antony Chazapis | def invitation(self): |
458 | 64cd4730 | Antony Chazapis | try:
|
459 | 9fb8e808 | Sofia Papagiannaki | return Invitation.objects.get(username=self.email) |
460 | 64cd4730 | Antony Chazapis | except Invitation.DoesNotExist:
|
461 | 64cd4730 | Antony Chazapis | return None |
462 | 6c736ed7 | Kostas Papadimitriou | |
463 | ffb1e7a8 | Sofia Papagiannaki | @property
|
464 | ffb1e7a8 | Sofia Papagiannaki | def quota(self): |
465 | 9a06d96f | Olga Brani | """Returns a dict with the sum of quota limits per resource"""
|
466 | ffb1e7a8 | Sofia Papagiannaki | d = defaultdict(int)
|
467 | b4789608 | Sofia Papagiannaki | default_quota = get_default_quota() |
468 | b4789608 | Sofia Papagiannaki | d.update(default_quota) |
469 | 9a06d96f | Olga Brani | for q in self.policies: |
470 | 9ee0c6a2 | Sofia Papagiannaki | d[q.resource] += q.uplimit or inf
|
471 | ccab6eb5 | Sofia Papagiannaki | for m in self.projectmembership_set.select_related().all(): |
472 | ccab6eb5 | Sofia Papagiannaki | if not m.acceptance_date: |
473 | fc1e2f02 | Sofia Papagiannaki | continue
|
474 | ccab6eb5 | Sofia Papagiannaki | p = m.project |
475 | ccab6eb5 | Sofia Papagiannaki | if not p.is_active: |
476 | ffb1e7a8 | Sofia Papagiannaki | continue
|
477 | ee45eb81 | Giorgos Korfiatis | grants = p.application.projectresourcegrant_set.all() |
478 | ccab6eb5 | Sofia Papagiannaki | for g in grants: |
479 | 73fbaec4 | Sofia Papagiannaki | d[str(g.resource)] += g.member_capacity or inf |
480 | ffb1e7a8 | Sofia Papagiannaki | # TODO set default for remaining
|
481 | ffb1e7a8 | Sofia Papagiannaki | return d
|
482 | 5ce3ce4f | Sofia Papagiannaki | |
483 | 9a06d96f | Olga Brani | @property
|
484 | 9a06d96f | Olga Brani | def policies(self): |
485 | 9a06d96f | Olga Brani | return self.astakosuserquota_set.select_related().all() |
486 | 9a06d96f | Olga Brani | |
487 | 9a06d96f | Olga Brani | @policies.setter
|
488 | 9a06d96f | Olga Brani | def policies(self, policies): |
489 | 9a06d96f | Olga Brani | for p in policies: |
490 | 9a06d96f | Olga Brani | service = policies.get('service', None) |
491 | 9a06d96f | Olga Brani | resource = policies.get('resource', None) |
492 | 9a06d96f | Olga Brani | uplimit = policies.get('uplimit', 0) |
493 | 9a06d96f | Olga Brani | update = policies.get('update', True) |
494 | 9a06d96f | Olga Brani | self.add_policy(service, resource, uplimit, update)
|
495 | 9a06d96f | Olga Brani | |
496 | 9a06d96f | Olga Brani | def add_policy(self, service, resource, uplimit, update=True): |
497 | 9a06d96f | Olga Brani | """Raises ObjectDoesNotExist, IntegrityError"""
|
498 | 9a06d96f | Olga Brani | resource = Resource.objects.get(service__name=service, name=resource) |
499 | 9a06d96f | Olga Brani | if update:
|
500 | 9a06d96f | Olga Brani | AstakosUserQuota.objects.update_or_create(user=self,
|
501 | 9a06d96f | Olga Brani | resource=resource, |
502 | 9a06d96f | Olga Brani | defaults={'uplimit': uplimit})
|
503 | 9a06d96f | Olga Brani | else:
|
504 | 9a06d96f | Olga Brani | q = self.astakosuserquota_set
|
505 | 9a06d96f | Olga Brani | q.create(resource=resource, uplimit=uplimit) |
506 | 9a06d96f | Olga Brani | |
507 | 9a06d96f | Olga Brani | def remove_policy(self, service, resource): |
508 | 9a06d96f | Olga Brani | """Raises ObjectDoesNotExist, IntegrityError"""
|
509 | 9a06d96f | Olga Brani | resource = Resource.objects.get(service__name=service, name=resource) |
510 | 9a06d96f | Olga Brani | q = self.policies.get(resource=resource).delete()
|
511 | 9a06d96f | Olga Brani | |
512 | 836a0fb0 | Kostas Papadimitriou | def update_uuid(self): |
513 | 836a0fb0 | Kostas Papadimitriou | while not self.uuid: |
514 | 836a0fb0 | Kostas Papadimitriou | uuid_val = str(uuid.uuid4())
|
515 | 836a0fb0 | Kostas Papadimitriou | try:
|
516 | 836a0fb0 | Kostas Papadimitriou | AstakosUser.objects.get(uuid=uuid_val) |
517 | 836a0fb0 | Kostas Papadimitriou | except AstakosUser.DoesNotExist, e:
|
518 | 836a0fb0 | Kostas Papadimitriou | self.uuid = uuid_val
|
519 | 836a0fb0 | Kostas Papadimitriou | return self.uuid |
520 | 836a0fb0 | Kostas Papadimitriou | |
521 | 9a06d96f | Olga Brani | @property
|
522 | 9a06d96f | Olga Brani | def extended_groups(self): |
523 | 9a06d96f | Olga Brani | return self.membership_set.select_related().all() |
524 | 9a06d96f | Olga Brani | |
525 | 9a06d96f | Olga Brani | @extended_groups.setter
|
526 | 9a06d96f | Olga Brani | def extended_groups(self, groups): |
527 | 9a06d96f | Olga Brani | #TODO exceptions
|
528 | 40a0cd8b | Sofia Papagiannaki | for name in (groups or ()): |
529 | 9a06d96f | Olga Brani | group = AstakosGroup.objects.get(name=name) |
530 | 9a06d96f | Olga Brani | self.membership_set.create(group=group)
|
531 | 9a06d96f | Olga Brani | |
532 | 64cd4730 | Antony Chazapis | def save(self, update_timestamps=True, **kwargs): |
533 | 64cd4730 | Antony Chazapis | if update_timestamps:
|
534 | 64cd4730 | Antony Chazapis | if not self.id: |
535 | 0905ccd2 | Sofia Papagiannaki | self.date_joined = datetime.now()
|
536 | 64cd4730 | Antony Chazapis | self.updated = datetime.now()
|
537 | 5ce3ce4f | Sofia Papagiannaki | |
538 | 18ffbee1 | Sofia Papagiannaki | # update date_signed_terms if necessary
|
539 | 18ffbee1 | Sofia Papagiannaki | if self.__has_signed_terms != self.has_signed_terms: |
540 | 18ffbee1 | Sofia Papagiannaki | self.date_signed_terms = datetime.now()
|
541 | 5ce3ce4f | Sofia Papagiannaki | |
542 | 836a0fb0 | Kostas Papadimitriou | self.update_uuid()
|
543 | 836a0fb0 | Kostas Papadimitriou | |
544 | 836a0fb0 | Kostas Papadimitriou | if self.username != self.email.lower(): |
545 | 9c01d9d1 | Sofia Papagiannaki | # set username
|
546 | e5966bd9 | Kostas Papadimitriou | self.username = self.email.lower() |
547 | fbaa4f3c | Kostas Papadimitriou | |
548 | 591d0505 | Sofia Papagiannaki | self.validate_unique_email_isactive()
|
549 | 5ce3ce4f | Sofia Papagiannaki | |
550 | 0905ccd2 | Sofia Papagiannaki | super(AstakosUser, self).save(**kwargs) |
551 | 2e90e3ec | Kostas Papadimitriou | |
552 | bf0c6de5 | Sofia Papagiannaki | def renew_token(self, flush_sessions=False, current_key=None): |
553 | 64cd4730 | Antony Chazapis | md5 = hashlib.md5() |
554 | 8f8c43b2 | Sofia Papagiannaki | md5.update(settings.SECRET_KEY) |
555 | 0905ccd2 | Sofia Papagiannaki | md5.update(self.username)
|
556 | 64cd4730 | Antony Chazapis | md5.update(self.realname.encode('ascii', 'ignore')) |
557 | 64cd4730 | Antony Chazapis | md5.update(asctime()) |
558 | 2e90e3ec | Kostas Papadimitriou | |
559 | 64cd4730 | Antony Chazapis | self.auth_token = b64encode(md5.digest())
|
560 | 64cd4730 | Antony Chazapis | self.auth_token_created = datetime.now()
|
561 | 64cd4730 | Antony Chazapis | self.auth_token_expires = self.auth_token_created + \ |
562 | 92defad4 | Sofia Papagiannaki | timedelta(hours=AUTH_TOKEN_DURATION) |
563 | bf0c6de5 | Sofia Papagiannaki | if flush_sessions:
|
564 | bf0c6de5 | Sofia Papagiannaki | self.flush_sessions(current_key)
|
565 | 111f3da6 | Sofia Papagiannaki | msg = 'Token renewed for %s' % self.email |
566 | aab4d540 | Sofia Papagiannaki | logger.log(LOGGING_LEVEL, msg) |
567 | 6c736ed7 | Kostas Papadimitriou | |
568 | bf0c6de5 | Sofia Papagiannaki | def flush_sessions(self, current_key=None): |
569 | bf0c6de5 | Sofia Papagiannaki | q = self.sessions
|
570 | bf0c6de5 | Sofia Papagiannaki | if current_key:
|
571 | bf0c6de5 | Sofia Papagiannaki | q = q.exclude(session_key=current_key) |
572 | 2e90e3ec | Kostas Papadimitriou | |
573 | bf0c6de5 | Sofia Papagiannaki | keys = q.values_list('session_key', flat=True) |
574 | bf0c6de5 | Sofia Papagiannaki | if keys:
|
575 | bf0c6de5 | Sofia Papagiannaki | msg = 'Flushing sessions: %s' % ','.join(keys) |
576 | c0b26605 | Sofia Papagiannaki | logger.log(LOGGING_LEVEL, msg, []) |
577 | bf0c6de5 | Sofia Papagiannaki | engine = import_module(settings.SESSION_ENGINE) |
578 | bf0c6de5 | Sofia Papagiannaki | for k in keys: |
579 | bf0c6de5 | Sofia Papagiannaki | s = engine.SessionStore(k) |
580 | bf0c6de5 | Sofia Papagiannaki | s.flush() |
581 | bf0c6de5 | Sofia Papagiannaki | |
582 | 64cd4730 | Antony Chazapis | def __unicode__(self): |
583 | 3abf6c78 | Sofia Papagiannaki | return '%s (%s)' % (self.realname, self.email) |
584 | 5ce3ce4f | Sofia Papagiannaki | |
585 | 0a569195 | Sofia Papagiannaki | def conflicting_email(self): |
586 | 5ce3ce4f | Sofia Papagiannaki | q = AstakosUser.objects.exclude(username=self.username)
|
587 | 789a5951 | Sofia Papagiannaki | q = q.filter(email__iexact=self.email)
|
588 | 0a569195 | Sofia Papagiannaki | if q.count() != 0: |
589 | 0a569195 | Sofia Papagiannaki | return True |
590 | 0a569195 | Sofia Papagiannaki | return False |
591 | 5ce3ce4f | Sofia Papagiannaki | |
592 | 591d0505 | Sofia Papagiannaki | def validate_unique_email_isactive(self): |
593 | 0a569195 | Sofia Papagiannaki | """
|
594 | 0a569195 | Sofia Papagiannaki | Implements a unique_together constraint for email and is_active fields.
|
595 | 0a569195 | Sofia Papagiannaki | """
|
596 | e6759494 | Sofia Papagiannaki | q = AstakosUser.objects.all() |
597 | 0a569195 | Sofia Papagiannaki | q = q.filter(email = self.email)
|
598 | e6759494 | Sofia Papagiannaki | if self.id: |
599 | e6759494 | Sofia Papagiannaki | q = q.filter(~Q(id = self.id))
|
600 | 0a569195 | Sofia Papagiannaki | if q.count() != 0: |
601 | 73fbaec4 | Sofia Papagiannaki | m = 'Another account with the same email = %(email)s & \
|
602 | 425e2e95 | Sofia Papagiannaki | is_active = %(is_active)s found.' % self.__dict__ |
603 | 73fbaec4 | Sofia Papagiannaki | raise ValidationError(m)
|
604 | 5ce3ce4f | Sofia Papagiannaki | |
605 | 34a76cdb | Kostas Papadimitriou | def email_change_is_pending(self): |
606 | 34a76cdb | Kostas Papadimitriou | return self.emailchanges.count() > 0 |
607 | 34a76cdb | Kostas Papadimitriou | |
608 | 0712a55c | Kostas Papadimitriou | def email_change_is_pending(self): |
609 | 0712a55c | Kostas Papadimitriou | return self.emailchanges.count() > 0 |
610 | 0712a55c | Kostas Papadimitriou | |
611 | fcf90160 | Sofia Papagiannaki | @property
|
612 | 09e7393c | Sofia Papagiannaki | def signed_terms(self): |
613 | 09e7393c | Sofia Papagiannaki | term = get_latest_terms() |
614 | 09e7393c | Sofia Papagiannaki | if not term: |
615 | 09e7393c | Sofia Papagiannaki | return True |
616 | 09e7393c | Sofia Papagiannaki | if not self.has_signed_terms: |
617 | 09e7393c | Sofia Papagiannaki | return False |
618 | 09e7393c | Sofia Papagiannaki | if not self.date_signed_terms: |
619 | 09e7393c | Sofia Papagiannaki | return False |
620 | 09e7393c | Sofia Papagiannaki | if self.date_signed_terms < term.date: |
621 | 09e7393c | Sofia Papagiannaki | self.has_signed_terms = False |
622 | f0f92965 | Sofia Papagiannaki | self.date_signed_terms = None |
623 | 09e7393c | Sofia Papagiannaki | self.save()
|
624 | 09e7393c | Sofia Papagiannaki | return False |
625 | 09e7393c | Sofia Papagiannaki | return True |
626 | 09e7393c | Sofia Papagiannaki | |
627 | d2633501 | Kostas Papadimitriou | def set_invitations_level(self): |
628 | d2633501 | Kostas Papadimitriou | """
|
629 | d2633501 | Kostas Papadimitriou | Update user invitation level
|
630 | d2633501 | Kostas Papadimitriou | """
|
631 | d2633501 | Kostas Papadimitriou | level = self.invitation.inviter.level + 1 |
632 | d2633501 | Kostas Papadimitriou | self.level = level
|
633 | d2633501 | Kostas Papadimitriou | self.invitations = INVITATIONS_PER_LEVEL.get(level, 0) |
634 | d2633501 | Kostas Papadimitriou | |
635 | d2633501 | Kostas Papadimitriou | def can_login_with_auth_provider(self, provider): |
636 | d2633501 | Kostas Papadimitriou | if not self.has_auth_provider(provider): |
637 | d2633501 | Kostas Papadimitriou | return False |
638 | d2633501 | Kostas Papadimitriou | else:
|
639 | d2633501 | Kostas Papadimitriou | return auth_providers.get_provider(provider).is_available_for_login()
|
640 | d2633501 | Kostas Papadimitriou | |
641 | f432088a | Kostas Papadimitriou | def can_add_auth_provider(self, provider, **kwargs): |
642 | d2633501 | Kostas Papadimitriou | provider_settings = auth_providers.get_provider(provider) |
643 | 222d8e52 | Kostas Papadimitriou | |
644 | 222d8e52 | Kostas Papadimitriou | if not provider_settings.is_available_for_add(): |
645 | d2633501 | Kostas Papadimitriou | return False |
646 | f432088a | Kostas Papadimitriou | |
647 | d2633501 | Kostas Papadimitriou | if self.has_auth_provider(provider) and \ |
648 | d2633501 | Kostas Papadimitriou | provider_settings.one_per_user: |
649 | d2633501 | Kostas Papadimitriou | return False |
650 | f432088a | Kostas Papadimitriou | |
651 | c630fee6 | Kostas Papadimitriou | if 'provider_info' in kwargs: |
652 | c630fee6 | Kostas Papadimitriou | kwargs.pop('provider_info')
|
653 | c630fee6 | Kostas Papadimitriou | |
654 | f432088a | Kostas Papadimitriou | if 'identifier' in kwargs: |
655 | f432088a | Kostas Papadimitriou | try:
|
656 | f432088a | Kostas Papadimitriou | # provider with specified params already exist
|
657 | f432088a | Kostas Papadimitriou | existing_user = AstakosUser.objects.get_auth_provider_user(provider, |
658 | f432088a | Kostas Papadimitriou | **kwargs) |
659 | f432088a | Kostas Papadimitriou | except AstakosUser.DoesNotExist:
|
660 | f432088a | Kostas Papadimitriou | return True |
661 | f432088a | Kostas Papadimitriou | else:
|
662 | f432088a | Kostas Papadimitriou | return False |
663 | f432088a | Kostas Papadimitriou | |
664 | d2633501 | Kostas Papadimitriou | return True |
665 | d2633501 | Kostas Papadimitriou | |
666 | 63836eda | Kostas Papadimitriou | def can_remove_auth_provider(self, module): |
667 | 63836eda | Kostas Papadimitriou | provider = auth_providers.get_provider(module) |
668 | 63836eda | Kostas Papadimitriou | existing = self.get_active_auth_providers()
|
669 | 63836eda | Kostas Papadimitriou | existing_for_provider = self.get_active_auth_providers(module=module)
|
670 | 63836eda | Kostas Papadimitriou | |
671 | 63836eda | Kostas Papadimitriou | if len(existing) <= 1: |
672 | 63836eda | Kostas Papadimitriou | return False |
673 | 63836eda | Kostas Papadimitriou | |
674 | 63836eda | Kostas Papadimitriou | if len(existing_for_provider) == 1 and provider.is_required(): |
675 | d2633501 | Kostas Papadimitriou | return False |
676 | 63836eda | Kostas Papadimitriou | |
677 | d2633501 | Kostas Papadimitriou | return True |
678 | d2633501 | Kostas Papadimitriou | |
679 | d2633501 | Kostas Papadimitriou | def can_change_password(self): |
680 | d2633501 | Kostas Papadimitriou | return self.has_auth_provider('local', auth_backend='astakos') |
681 | d2633501 | Kostas Papadimitriou | |
682 | 63836eda | Kostas Papadimitriou | def has_required_auth_providers(self): |
683 | 63836eda | Kostas Papadimitriou | required = auth_providers.REQUIRED_PROVIDERS |
684 | 63836eda | Kostas Papadimitriou | for provider in required: |
685 | 63836eda | Kostas Papadimitriou | if not self.has_auth_provider(provider): |
686 | 63836eda | Kostas Papadimitriou | return False |
687 | 63836eda | Kostas Papadimitriou | return True |
688 | 63836eda | Kostas Papadimitriou | |
689 | d2633501 | Kostas Papadimitriou | def has_auth_provider(self, provider, **kwargs): |
690 | d2633501 | Kostas Papadimitriou | return bool(self.auth_providers.filter(module=provider, |
691 | d2633501 | Kostas Papadimitriou | **kwargs).count()) |
692 | d2633501 | Kostas Papadimitriou | |
693 | d2633501 | Kostas Papadimitriou | def add_auth_provider(self, provider, **kwargs): |
694 | 3a72a5d4 | Kostas Papadimitriou | info_data = ''
|
695 | 3a72a5d4 | Kostas Papadimitriou | if 'provider_info' in kwargs: |
696 | c630fee6 | Kostas Papadimitriou | info_data = kwargs.pop('provider_info')
|
697 | c630fee6 | Kostas Papadimitriou | if isinstance(info_data, dict): |
698 | c630fee6 | Kostas Papadimitriou | info_data = json.dumps(info_data) |
699 | 3a72a5d4 | Kostas Papadimitriou | |
700 | f432088a | Kostas Papadimitriou | if self.can_add_auth_provider(provider, **kwargs): |
701 | 3a72a5d4 | Kostas Papadimitriou | self.auth_providers.create(module=provider, active=True, |
702 | 3a72a5d4 | Kostas Papadimitriou | info_data=info_data, |
703 | 3a72a5d4 | Kostas Papadimitriou | **kwargs) |
704 | f432088a | Kostas Papadimitriou | else:
|
705 | f432088a | Kostas Papadimitriou | raise Exception('Cannot add provider') |
706 | d2633501 | Kostas Papadimitriou | |
707 | d2633501 | Kostas Papadimitriou | def add_pending_auth_provider(self, pending): |
708 | d2633501 | Kostas Papadimitriou | """
|
709 | d2633501 | Kostas Papadimitriou | Convert PendingThirdPartyUser object to AstakosUserAuthProvider entry for
|
710 | d2633501 | Kostas Papadimitriou | the current user.
|
711 | d2633501 | Kostas Papadimitriou | """
|
712 | d2633501 | Kostas Papadimitriou | if not isinstance(pending, PendingThirdPartyUser): |
713 | d2633501 | Kostas Papadimitriou | pending = PendingThirdPartyUser.objects.get(token=pending) |
714 | d2633501 | Kostas Papadimitriou | |
715 | d2633501 | Kostas Papadimitriou | provider = self.add_auth_provider(pending.provider,
|
716 | c630fee6 | Kostas Papadimitriou | identifier=pending.third_party_identifier, |
717 | c630fee6 | Kostas Papadimitriou | affiliation=pending.affiliation, |
718 | c630fee6 | Kostas Papadimitriou | provider_info=pending.info) |
719 | d2633501 | Kostas Papadimitriou | |
720 | fbaa4f3c | Kostas Papadimitriou | if email_re.match(pending.email or '') and pending.email != self.email: |
721 | d2633501 | Kostas Papadimitriou | self.additionalmail_set.get_or_create(email=pending.email)
|
722 | d2633501 | Kostas Papadimitriou | |
723 | d2633501 | Kostas Papadimitriou | pending.delete() |
724 | d2633501 | Kostas Papadimitriou | return provider
|
725 | d2633501 | Kostas Papadimitriou | |
726 | d2633501 | Kostas Papadimitriou | def remove_auth_provider(self, provider, **kwargs): |
727 | d2633501 | Kostas Papadimitriou | self.auth_providers.get(module=provider, **kwargs).delete()
|
728 | d2633501 | Kostas Papadimitriou | |
729 | d2633501 | Kostas Papadimitriou | # user urls
|
730 | d2633501 | Kostas Papadimitriou | def get_resend_activation_url(self): |
731 | c630fee6 | Kostas Papadimitriou | return reverse('send_activation', kwargs={'user_id': self.pk}) |
732 | c630fee6 | Kostas Papadimitriou | |
733 | c630fee6 | Kostas Papadimitriou | def get_provider_remove_url(self, module, **kwargs): |
734 | c630fee6 | Kostas Papadimitriou | return reverse('remove_auth_provider', kwargs={ |
735 | c630fee6 | Kostas Papadimitriou | 'pk': self.auth_providers.get(module=module, **kwargs).pk}) |
736 | d2633501 | Kostas Papadimitriou | |
737 | d2633501 | Kostas Papadimitriou | def get_activation_url(self, nxt=False): |
738 | d2633501 | Kostas Papadimitriou | url = "%s?auth=%s" % (reverse('astakos.im.views.activate'), |
739 | d2633501 | Kostas Papadimitriou | quote(self.auth_token))
|
740 | d2633501 | Kostas Papadimitriou | if nxt:
|
741 | d2633501 | Kostas Papadimitriou | url += "&next=%s" % quote(nxt)
|
742 | d2633501 | Kostas Papadimitriou | return url
|
743 | d2633501 | Kostas Papadimitriou | |
744 | d2633501 | Kostas Papadimitriou | def get_password_reset_url(self, token_generator=default_token_generator): |
745 | d2633501 | Kostas Papadimitriou | return reverse('django.contrib.auth.views.password_reset_confirm', |
746 | d2633501 | Kostas Papadimitriou | kwargs={'uidb36':int_to_base36(self.id), |
747 | d2633501 | Kostas Papadimitriou | 'token':token_generator.make_token(self)}) |
748 | d2633501 | Kostas Papadimitriou | |
749 | d2633501 | Kostas Papadimitriou | def get_auth_providers(self): |
750 | d2633501 | Kostas Papadimitriou | return self.auth_providers.all() |
751 | d2633501 | Kostas Papadimitriou | |
752 | d2633501 | Kostas Papadimitriou | def get_available_auth_providers(self): |
753 | d2633501 | Kostas Papadimitriou | """
|
754 | d2633501 | Kostas Papadimitriou | Returns a list of providers available for user to connect to.
|
755 | d2633501 | Kostas Papadimitriou | """
|
756 | d2633501 | Kostas Papadimitriou | providers = [] |
757 | d2633501 | Kostas Papadimitriou | for module, provider_settings in auth_providers.PROVIDERS.iteritems(): |
758 | f432088a | Kostas Papadimitriou | if self.can_add_auth_provider(module): |
759 | d2633501 | Kostas Papadimitriou | providers.append(provider_settings(self))
|
760 | d2633501 | Kostas Papadimitriou | |
761 | d2633501 | Kostas Papadimitriou | return providers
|
762 | d2633501 | Kostas Papadimitriou | |
763 | 63836eda | Kostas Papadimitriou | def get_active_auth_providers(self, **filters): |
764 | d2633501 | Kostas Papadimitriou | providers = [] |
765 | 63836eda | Kostas Papadimitriou | for provider in self.auth_providers.active(**filters): |
766 | d2633501 | Kostas Papadimitriou | if auth_providers.get_provider(provider.module).is_available_for_login():
|
767 | d2633501 | Kostas Papadimitriou | providers.append(provider) |
768 | d2633501 | Kostas Papadimitriou | return providers
|
769 | d2633501 | Kostas Papadimitriou | |
770 | b778b6fa | Kostas Papadimitriou | @property
|
771 | b778b6fa | Kostas Papadimitriou | def auth_providers_display(self): |
772 | b778b6fa | Kostas Papadimitriou | return ",".join(map(lambda x:unicode(x), self.auth_providers.active())) |
773 | b778b6fa | Kostas Papadimitriou | |
774 | c4b1a172 | Kostas Papadimitriou | def get_inactive_message(self): |
775 | c4b1a172 | Kostas Papadimitriou | msg_extra = ''
|
776 | c4b1a172 | Kostas Papadimitriou | message = ''
|
777 | c4b1a172 | Kostas Papadimitriou | if self.activation_sent: |
778 | c4b1a172 | Kostas Papadimitriou | if self.email_verified: |
779 | c4b1a172 | Kostas Papadimitriou | message = _(astakos_messages.ACCOUNT_INACTIVE) |
780 | c4b1a172 | Kostas Papadimitriou | else:
|
781 | c4b1a172 | Kostas Papadimitriou | message = _(astakos_messages.ACCOUNT_PENDING_ACTIVATION) |
782 | fc655b6f | Kostas Papadimitriou | if astakos_settings.MODERATION_ENABLED:
|
783 | c4b1a172 | Kostas Papadimitriou | msg_extra = _(astakos_messages.ACCOUNT_PENDING_ACTIVATION_HELP) |
784 | c4b1a172 | Kostas Papadimitriou | else:
|
785 | c4b1a172 | Kostas Papadimitriou | url = self.get_resend_activation_url()
|
786 | c4b1a172 | Kostas Papadimitriou | msg_extra = mark_safe(_(astakos_messages.ACCOUNT_PENDING_ACTIVATION_HELP) + \ |
787 | a15a19b2 | Kostas Papadimitriou | u' ' + \
|
788 | c4b1a172 | Kostas Papadimitriou | _('<a href="%s">%s?</a>') % (url,
|
789 | c4b1a172 | Kostas Papadimitriou | _(astakos_messages.ACCOUNT_RESEND_ACTIVATION_PROMPT))) |
790 | c4b1a172 | Kostas Papadimitriou | else:
|
791 | fc655b6f | Kostas Papadimitriou | if astakos_settings.MODERATION_ENABLED:
|
792 | c4b1a172 | Kostas Papadimitriou | message = _(astakos_messages.ACCOUNT_PENDING_MODERATION) |
793 | c4b1a172 | Kostas Papadimitriou | else:
|
794 | c4b1a172 | Kostas Papadimitriou | message = astakos_messages.ACCOUNT_PENDING_ACTIVATION |
795 | c4b1a172 | Kostas Papadimitriou | url = self.get_resend_activation_url()
|
796 | c4b1a172 | Kostas Papadimitriou | msg_extra = mark_safe(_('<a href="%s">%s?</a>') % (url,
|
797 | c4b1a172 | Kostas Papadimitriou | _(astakos_messages.ACCOUNT_RESEND_ACTIVATION_PROMPT))) |
798 | c4b1a172 | Kostas Papadimitriou | |
799 | a15a19b2 | Kostas Papadimitriou | return mark_safe(message + u' '+ msg_extra) |
800 | c4b1a172 | Kostas Papadimitriou | |
801 | d2633501 | Kostas Papadimitriou | |
802 | d2633501 | Kostas Papadimitriou | class AstakosUserAuthProviderManager(models.Manager): |
803 | d2633501 | Kostas Papadimitriou | |
804 | 63836eda | Kostas Papadimitriou | def active(self, **filters): |
805 | 63836eda | Kostas Papadimitriou | return self.filter(active=True, **filters) |
806 | d2633501 | Kostas Papadimitriou | |
807 | d2633501 | Kostas Papadimitriou | |
808 | d2633501 | Kostas Papadimitriou | class AstakosUserAuthProvider(models.Model): |
809 | d2633501 | Kostas Papadimitriou | """
|
810 | d2633501 | Kostas Papadimitriou | Available user authentication methods.
|
811 | d2633501 | Kostas Papadimitriou | """
|
812 | e1a80257 | Sofia Papagiannaki | affiliation = models.CharField(_('Affiliation'), max_length=255, blank=True, |
813 | d2633501 | Kostas Papadimitriou | null=True, default=None) |
814 | d2633501 | Kostas Papadimitriou | user = models.ForeignKey(AstakosUser, related_name='auth_providers')
|
815 | e1a80257 | Sofia Papagiannaki | module = models.CharField(_('Provider'), max_length=255, blank=False, |
816 | d2633501 | Kostas Papadimitriou | default='local')
|
817 | e1a80257 | Sofia Papagiannaki | identifier = models.CharField(_('Third-party identifier'),
|
818 | d2633501 | Kostas Papadimitriou | max_length=255, null=True, |
819 | d2633501 | Kostas Papadimitriou | blank=True)
|
820 | d2633501 | Kostas Papadimitriou | active = models.BooleanField(default=True)
|
821 | e1a80257 | Sofia Papagiannaki | auth_backend = models.CharField(_('Backend'), max_length=255, blank=False, |
822 | d2633501 | Kostas Papadimitriou | default='astakos')
|
823 | 3a72a5d4 | Kostas Papadimitriou | info_data = models.TextField(default="", null=True, blank=True) |
824 | c630fee6 | Kostas Papadimitriou | created = models.DateTimeField('Creation date', auto_now_add=True) |
825 | d2633501 | Kostas Papadimitriou | |
826 | d2633501 | Kostas Papadimitriou | objects = AstakosUserAuthProviderManager() |
827 | d2633501 | Kostas Papadimitriou | |
828 | d2633501 | Kostas Papadimitriou | class Meta: |
829 | d2633501 | Kostas Papadimitriou | unique_together = (('identifier', 'module', 'user'), ) |
830 | c630fee6 | Kostas Papadimitriou | ordering = ('module', 'created') |
831 | d2633501 | Kostas Papadimitriou | |
832 | 3a72a5d4 | Kostas Papadimitriou | def __init__(self, *args, **kwargs): |
833 | 3a72a5d4 | Kostas Papadimitriou | super(AstakosUserAuthProvider, self).__init__(*args, **kwargs) |
834 | 3a72a5d4 | Kostas Papadimitriou | try:
|
835 | 3a72a5d4 | Kostas Papadimitriou | self.info = json.loads(self.info_data) |
836 | c630fee6 | Kostas Papadimitriou | if not self.info: |
837 | c630fee6 | Kostas Papadimitriou | self.info = {}
|
838 | c630fee6 | Kostas Papadimitriou | except Exception, e: |
839 | 3a72a5d4 | Kostas Papadimitriou | self.info = {}
|
840 | c630fee6 | Kostas Papadimitriou | |
841 | 3a72a5d4 | Kostas Papadimitriou | for key,value in self.info.iteritems(): |
842 | 3a72a5d4 | Kostas Papadimitriou | setattr(self, 'info_%s' % key, value) |
843 | 3a72a5d4 | Kostas Papadimitriou | |
844 | d2633501 | Kostas Papadimitriou | |
845 | d2633501 | Kostas Papadimitriou | @property
|
846 | d2633501 | Kostas Papadimitriou | def settings(self): |
847 | d2633501 | Kostas Papadimitriou | return auth_providers.get_provider(self.module) |
848 | d2633501 | Kostas Papadimitriou | |
849 | d2633501 | Kostas Papadimitriou | @property
|
850 | d2633501 | Kostas Papadimitriou | def details_display(self): |
851 | c630fee6 | Kostas Papadimitriou | try:
|
852 | c630fee6 | Kostas Papadimitriou | return self.settings.get_details_tpl_display % self.__dict__ |
853 | c630fee6 | Kostas Papadimitriou | except:
|
854 | c630fee6 | Kostas Papadimitriou | return '' |
855 | 3a72a5d4 | Kostas Papadimitriou | |
856 | 3a72a5d4 | Kostas Papadimitriou | @property
|
857 | 3a72a5d4 | Kostas Papadimitriou | def title_display(self): |
858 | 3a72a5d4 | Kostas Papadimitriou | title_tpl = self.settings.get_title_display
|
859 | 3a72a5d4 | Kostas Papadimitriou | try:
|
860 | 3a72a5d4 | Kostas Papadimitriou | if self.settings.get_user_title_display: |
861 | 3a72a5d4 | Kostas Papadimitriou | title_tpl = self.settings.get_user_title_display
|
862 | 3a72a5d4 | Kostas Papadimitriou | except Exception, e: |
863 | 3a72a5d4 | Kostas Papadimitriou | pass
|
864 | c630fee6 | Kostas Papadimitriou | try:
|
865 | c630fee6 | Kostas Papadimitriou | return title_tpl % self.__dict__ |
866 | c630fee6 | Kostas Papadimitriou | except:
|
867 | c630fee6 | Kostas Papadimitriou | return self.settings.get_title_display % self.__dict__ |
868 | d2633501 | Kostas Papadimitriou | |
869 | d2633501 | Kostas Papadimitriou | def can_remove(self): |
870 | d2633501 | Kostas Papadimitriou | return self.user.can_remove_auth_provider(self.module) |
871 | d2633501 | Kostas Papadimitriou | |
872 | d2633501 | Kostas Papadimitriou | def delete(self, *args, **kwargs): |
873 | d2633501 | Kostas Papadimitriou | ret = super(AstakosUserAuthProvider, self).delete(*args, **kwargs) |
874 | 5156e663 | Kostas Papadimitriou | if self.module == 'local': |
875 | 5156e663 | Kostas Papadimitriou | self.user.set_unusable_password()
|
876 | 5156e663 | Kostas Papadimitriou | self.user.save()
|
877 | d2633501 | Kostas Papadimitriou | return ret
|
878 | d2633501 | Kostas Papadimitriou | |
879 | f432088a | Kostas Papadimitriou | def __repr__(self): |
880 | f432088a | Kostas Papadimitriou | return '<AstakosUserAuthProvider %s:%s>' % (self.module, self.identifier) |
881 | f432088a | Kostas Papadimitriou | |
882 | b778b6fa | Kostas Papadimitriou | def __unicode__(self): |
883 | b778b6fa | Kostas Papadimitriou | if self.identifier: |
884 | b778b6fa | Kostas Papadimitriou | return "%s:%s" % (self.module, self.identifier) |
885 | b778b6fa | Kostas Papadimitriou | if self.auth_backend: |
886 | b778b6fa | Kostas Papadimitriou | return "%s:%s" % (self.module, self.auth_backend) |
887 | b778b6fa | Kostas Papadimitriou | return self.module |
888 | b778b6fa | Kostas Papadimitriou | |
889 | 3a72a5d4 | Kostas Papadimitriou | def save(self, *args, **kwargs): |
890 | 3a72a5d4 | Kostas Papadimitriou | self.info_data = json.dumps(self.info) |
891 | 3a72a5d4 | Kostas Papadimitriou | return super(AstakosUserAuthProvider, self).save(*args, **kwargs) |
892 | b778b6fa | Kostas Papadimitriou | |
893 | d2633501 | Kostas Papadimitriou | |
894 | 8e45d6fd | Sofia Papagiannaki | class Membership(models.Model): |
895 | 8e45d6fd | Sofia Papagiannaki | person = models.ForeignKey(AstakosUser) |
896 | 8e45d6fd | Sofia Papagiannaki | group = models.ForeignKey(AstakosGroup) |
897 | 01ac12d5 | Sofia Papagiannaki | date_requested = models.DateField(default=datetime.now(), blank=True)
|
898 | 01ac12d5 | Sofia Papagiannaki | date_joined = models.DateField(null=True, db_index=True, blank=True) |
899 | 5ce3ce4f | Sofia Papagiannaki | |
900 | 8e45d6fd | Sofia Papagiannaki | class Meta: |
901 | 8e45d6fd | Sofia Papagiannaki | unique_together = ("person", "group") |
902 | 5ce3ce4f | Sofia Papagiannaki | |
903 | ffb1e7a8 | Sofia Papagiannaki | def save(self, *args, **kwargs): |
904 | 28252c7f | Sofia Papagiannaki | if not self.id: |
905 | 28252c7f | Sofia Papagiannaki | if not self.group.moderation_enabled: |
906 | 28252c7f | Sofia Papagiannaki | self.date_joined = datetime.now()
|
907 | ffb1e7a8 | Sofia Papagiannaki | super(Membership, self).save(*args, **kwargs) |
908 | 5ce3ce4f | Sofia Papagiannaki | |
909 | 8e45d6fd | Sofia Papagiannaki | @property
|
910 | 8e45d6fd | Sofia Papagiannaki | def is_approved(self): |
911 | 8e45d6fd | Sofia Papagiannaki | if self.date_joined: |
912 | 8e45d6fd | Sofia Papagiannaki | return True |
913 | 8e45d6fd | Sofia Papagiannaki | return False |
914 | 5ce3ce4f | Sofia Papagiannaki | |
915 | 01ac12d5 | Sofia Papagiannaki | def approve(self): |
916 | c0b26605 | Sofia Papagiannaki | if self.is_approved: |
917 | c0b26605 | Sofia Papagiannaki | return
|
918 | ae497612 | Olga Brani | if self.group.max_participants: |
919 | a4075f5a | root | assert len(self.group.approved_members) + 1 <= self.group.max_participants, \ |
920 | c0b26605 | Sofia Papagiannaki | 'Maximum participant number has been reached.'
|
921 | 01ac12d5 | Sofia Papagiannaki | self.date_joined = datetime.now()
|
922 | 01ac12d5 | Sofia Papagiannaki | self.save()
|
923 | fc1e2f02 | Sofia Papagiannaki | quota_disturbed.send(sender=self, users=(self.person,)) |
924 | 5ce3ce4f | Sofia Papagiannaki | |
925 | 01ac12d5 | Sofia Papagiannaki | def disapprove(self): |
926 | e1a80257 | Sofia Papagiannaki | approved = self.is_approved()
|
927 | 01ac12d5 | Sofia Papagiannaki | self.delete()
|
928 | e1a80257 | Sofia Papagiannaki | if approved:
|
929 | e1a80257 | Sofia Papagiannaki | quota_disturbed.send(sender=self, users=(self.person,)) |
930 | 8e45d6fd | Sofia Papagiannaki | |
931 | e1a80257 | Sofia Papagiannaki | class ExtendedManager(models.Manager): |
932 | 9a06d96f | Olga Brani | def _update_or_create(self, **kwargs): |
933 | 9a06d96f | Olga Brani | assert kwargs, \
|
934 | 9a06d96f | Olga Brani | 'update_or_create() must be passed at least one keyword argument'
|
935 | 9a06d96f | Olga Brani | obj, created = self.get_or_create(**kwargs)
|
936 | 9a06d96f | Olga Brani | defaults = kwargs.pop('defaults', {})
|
937 | 9a06d96f | Olga Brani | if created:
|
938 | 9a06d96f | Olga Brani | return obj, True, False |
939 | 9a06d96f | Olga Brani | else:
|
940 | 9a06d96f | Olga Brani | try:
|
941 | 9a06d96f | Olga Brani | params = dict(
|
942 | 9a06d96f | Olga Brani | [(k, v) for k, v in kwargs.items() if '__' not in k]) |
943 | 9a06d96f | Olga Brani | params.update(defaults) |
944 | 9a06d96f | Olga Brani | for attr, val in params.items(): |
945 | 9a06d96f | Olga Brani | if hasattr(obj, attr): |
946 | 9a06d96f | Olga Brani | setattr(obj, attr, val)
|
947 | 9a06d96f | Olga Brani | sid = transaction.savepoint() |
948 | 9a06d96f | Olga Brani | obj.save(force_update=True)
|
949 | 9a06d96f | Olga Brani | transaction.savepoint_commit(sid) |
950 | 9a06d96f | Olga Brani | return obj, False, True |
951 | 9a06d96f | Olga Brani | except IntegrityError, e:
|
952 | 9a06d96f | Olga Brani | transaction.savepoint_rollback(sid) |
953 | 9a06d96f | Olga Brani | try:
|
954 | 9a06d96f | Olga Brani | return self.get(**kwargs), False, False |
955 | 9a06d96f | Olga Brani | except self.model.DoesNotExist: |
956 | 9a06d96f | Olga Brani | raise e
|
957 | 9a06d96f | Olga Brani | |
958 | 9a06d96f | Olga Brani | update_or_create = _update_or_create |
959 | 5ce3ce4f | Sofia Papagiannaki | |
960 | 8e45d6fd | Sofia Papagiannaki | class AstakosGroupQuota(models.Model): |
961 | e1a80257 | Sofia Papagiannaki | objects = ExtendedManager() |
962 | e1a80257 | Sofia Papagiannaki | limit = models.PositiveIntegerField(_('Limit'), null=True) # obsolete field |
963 | e1a80257 | Sofia Papagiannaki | uplimit = models.BigIntegerField(_('Up limit'), null=True) |
964 | 8e45d6fd | Sofia Papagiannaki | resource = models.ForeignKey(Resource) |
965 | 8e45d6fd | Sofia Papagiannaki | group = models.ForeignKey(AstakosGroup, blank=True)
|
966 | 5ce3ce4f | Sofia Papagiannaki | |
967 | 8e45d6fd | Sofia Papagiannaki | class Meta: |
968 | 8e45d6fd | Sofia Papagiannaki | unique_together = ("resource", "group") |
969 | 8e45d6fd | Sofia Papagiannaki | |
970 | 8e45d6fd | Sofia Papagiannaki | class AstakosUserQuota(models.Model): |
971 | e1a80257 | Sofia Papagiannaki | objects = ExtendedManager() |
972 | e1a80257 | Sofia Papagiannaki | limit = models.PositiveIntegerField(_('Limit'), null=True) # obsolete field |
973 | e1a80257 | Sofia Papagiannaki | uplimit = models.BigIntegerField(_('Up limit'), null=True) |
974 | 8e45d6fd | Sofia Papagiannaki | resource = models.ForeignKey(Resource) |
975 | 8e45d6fd | Sofia Papagiannaki | user = models.ForeignKey(AstakosUser) |
976 | 5ce3ce4f | Sofia Papagiannaki | |
977 | 8e45d6fd | Sofia Papagiannaki | class Meta: |
978 | 8e45d6fd | Sofia Papagiannaki | unique_together = ("resource", "user") |
979 | 09e7393c | Sofia Papagiannaki | |
980 | 5ce3ce4f | Sofia Papagiannaki | |
981 | 270dd48d | Sofia Papagiannaki | class ApprovalTerms(models.Model): |
982 | 270dd48d | Sofia Papagiannaki | """
|
983 | 270dd48d | Sofia Papagiannaki | Model for approval terms
|
984 | 270dd48d | Sofia Papagiannaki | """
|
985 | 6c736ed7 | Kostas Papadimitriou | |
986 | 5ce3ce4f | Sofia Papagiannaki | date = models.DateTimeField( |
987 | e1a80257 | Sofia Papagiannaki | _('Issue date'), db_index=True, default=datetime.now()) |
988 | e1a80257 | Sofia Papagiannaki | location = models.CharField(_('Terms location'), max_length=255) |
989 | 270dd48d | Sofia Papagiannaki | |
990 | 5ce3ce4f | Sofia Papagiannaki | |
991 | 64cd4730 | Antony Chazapis | class Invitation(models.Model): |
992 | 890b0eaf | Sofia Papagiannaki | """
|
993 | 890b0eaf | Sofia Papagiannaki | Model for registring invitations
|
994 | 890b0eaf | Sofia Papagiannaki | """
|
995 | 0905ccd2 | Sofia Papagiannaki | inviter = models.ForeignKey(AstakosUser, related_name='invitations_sent',
|
996 | 64cd4730 | Antony Chazapis | null=True)
|
997 | e1a80257 | Sofia Papagiannaki | realname = models.CharField(_('Real name'), max_length=255) |
998 | e1a80257 | Sofia Papagiannaki | username = models.CharField(_('Unique ID'), max_length=255, unique=True) |
999 | e1a80257 | Sofia Papagiannaki | code = models.BigIntegerField(_('Invitation code'), db_index=True) |
1000 | e1a80257 | Sofia Papagiannaki | is_consumed = models.BooleanField(_('Consumed?'), default=False) |
1001 | e1a80257 | Sofia Papagiannaki | created = models.DateTimeField(_('Creation date'), auto_now_add=True) |
1002 | e1a80257 | Sofia Papagiannaki | consumed = models.DateTimeField(_('Consumption date'), null=True, blank=True) |
1003 | 5ce3ce4f | Sofia Papagiannaki | |
1004 | 18ffbee1 | Sofia Papagiannaki | def __init__(self, *args, **kwargs): |
1005 | 18ffbee1 | Sofia Papagiannaki | super(Invitation, self).__init__(*args, **kwargs) |
1006 | 8f5a3a06 | Sofia Papagiannaki | if not self.id: |
1007 | 8f5a3a06 | Sofia Papagiannaki | self.code = _generate_invitation_code()
|
1008 | 5ce3ce4f | Sofia Papagiannaki | |
1009 | 64cd4730 | Antony Chazapis | def consume(self): |
1010 | 64cd4730 | Antony Chazapis | self.is_consumed = True |
1011 | 64cd4730 | Antony Chazapis | self.consumed = datetime.now()
|
1012 | 64cd4730 | Antony Chazapis | self.save()
|
1013 | 6c736ed7 | Kostas Papadimitriou | |
1014 | 64cd4730 | Antony Chazapis | def __unicode__(self): |
1015 | 0905ccd2 | Sofia Papagiannaki | return '%s -> %s [%d]' % (self.inviter, self.username, self.code) |
1016 | 9c01d9d1 | Sofia Papagiannaki | |
1017 | 49790d9d | Sofia Papagiannaki | |
1018 | 49790d9d | Sofia Papagiannaki | class EmailChangeManager(models.Manager): |
1019 | 34a76cdb | Kostas Papadimitriou | |
1020 | 49790d9d | Sofia Papagiannaki | @transaction.commit_on_success
|
1021 | 49790d9d | Sofia Papagiannaki | def change_email(self, activation_key): |
1022 | 49790d9d | Sofia Papagiannaki | """
|
1023 | 49790d9d | Sofia Papagiannaki | Validate an activation key and change the corresponding
|
1024 | 49790d9d | Sofia Papagiannaki | ``User`` if valid.
|
1025 | 49790d9d | Sofia Papagiannaki |
|
1026 | 49790d9d | Sofia Papagiannaki | If the key is valid and has not expired, return the ``User``
|
1027 | 49790d9d | Sofia Papagiannaki | after activating.
|
1028 | 49790d9d | Sofia Papagiannaki |
|
1029 | 49790d9d | Sofia Papagiannaki | If the key is not valid or has expired, return ``None``.
|
1030 | 49790d9d | Sofia Papagiannaki |
|
1031 | 49790d9d | Sofia Papagiannaki | If the key is valid but the ``User`` is already active,
|
1032 | 49790d9d | Sofia Papagiannaki | return ``None``.
|
1033 | 49790d9d | Sofia Papagiannaki |
|
1034 | 49790d9d | Sofia Papagiannaki | After successful email change the activation record is deleted.
|
1035 | 49790d9d | Sofia Papagiannaki |
|
1036 | 49790d9d | Sofia Papagiannaki | Throws ValueError if there is already
|
1037 | 49790d9d | Sofia Papagiannaki | """
|
1038 | 49790d9d | Sofia Papagiannaki | try:
|
1039 | 5ce3ce4f | Sofia Papagiannaki | email_change = self.model.objects.get(
|
1040 | 5ce3ce4f | Sofia Papagiannaki | activation_key=activation_key) |
1041 | 49790d9d | Sofia Papagiannaki | if email_change.activation_key_expired():
|
1042 | 49790d9d | Sofia Papagiannaki | email_change.delete() |
1043 | 49790d9d | Sofia Papagiannaki | raise EmailChange.DoesNotExist
|
1044 | 49790d9d | Sofia Papagiannaki | # is there an active user with this address?
|
1045 | 49790d9d | Sofia Papagiannaki | try:
|
1046 | 789a5951 | Sofia Papagiannaki | AstakosUser.objects.get(email__iexact=email_change.new_email_address) |
1047 | 49790d9d | Sofia Papagiannaki | except AstakosUser.DoesNotExist:
|
1048 | 49790d9d | Sofia Papagiannaki | pass
|
1049 | 49790d9d | Sofia Papagiannaki | else:
|
1050 | 73fbaec4 | Sofia Papagiannaki | raise ValueError(_('The new email address is reserved.')) |
1051 | 49790d9d | Sofia Papagiannaki | # update user
|
1052 | 49790d9d | Sofia Papagiannaki | user = AstakosUser.objects.get(pk=email_change.user_id) |
1053 | 34a76cdb | Kostas Papadimitriou | old_email = user.email |
1054 | 49790d9d | Sofia Papagiannaki | user.email = email_change.new_email_address |
1055 | 49790d9d | Sofia Papagiannaki | user.save() |
1056 | 49790d9d | Sofia Papagiannaki | email_change.delete() |
1057 | 34a76cdb | Kostas Papadimitriou | msg = "User %d changed email from %s to %s" % (user.pk, old_email,
|
1058 | 34a76cdb | Kostas Papadimitriou | user.email) |
1059 | 34a76cdb | Kostas Papadimitriou | logger.log(LOGGING_LEVEL, msg) |
1060 | 49790d9d | Sofia Papagiannaki | return user
|
1061 | 49790d9d | Sofia Papagiannaki | except EmailChange.DoesNotExist:
|
1062 | 73fbaec4 | Sofia Papagiannaki | raise ValueError(_('Invalid activation key.')) |
1063 | 49790d9d | Sofia Papagiannaki | |
1064 | 49790d9d | Sofia Papagiannaki | |
1065 | 49790d9d | Sofia Papagiannaki | class EmailChange(models.Model): |
1066 | 73fbaec4 | Sofia Papagiannaki | new_email_address = models.EmailField( |
1067 | 73fbaec4 | Sofia Papagiannaki | _(u'new e-mail address'),
|
1068 | 73fbaec4 | Sofia Papagiannaki | help_text=_('Your old email address will be used until you verify your new one.'))
|
1069 | 5ce3ce4f | Sofia Papagiannaki | user = models.ForeignKey( |
1070 | 34a76cdb | Kostas Papadimitriou | AstakosUser, unique=True, related_name='emailchanges') |
1071 | 49790d9d | Sofia Papagiannaki | requested_at = models.DateTimeField(default=datetime.now()) |
1072 | 5ce3ce4f | Sofia Papagiannaki | activation_key = models.CharField( |
1073 | 5ce3ce4f | Sofia Papagiannaki | max_length=40, unique=True, db_index=True) |
1074 | 49790d9d | Sofia Papagiannaki | |
1075 | 49790d9d | Sofia Papagiannaki | objects = EmailChangeManager() |
1076 | 49790d9d | Sofia Papagiannaki | |
1077 | 34a76cdb | Kostas Papadimitriou | def get_url(self): |
1078 | 34a76cdb | Kostas Papadimitriou | return reverse('email_change_confirm', |
1079 | 34a76cdb | Kostas Papadimitriou | kwargs={'activation_key': self.activation_key}) |
1080 | 34a76cdb | Kostas Papadimitriou | |
1081 | 49790d9d | Sofia Papagiannaki | def activation_key_expired(self): |
1082 | 49790d9d | Sofia Papagiannaki | expiration_date = timedelta(days=EMAILCHANGE_ACTIVATION_DAYS) |
1083 | ff9290ec | Sofia Papagiannaki | return self.requested_at + expiration_date < datetime.now() |
1084 | ff9290ec | Sofia Papagiannaki | |
1085 | 6b03a847 | Sofia Papagiannaki | |
1086 | ca828a10 | Sofia Papagiannaki | class AdditionalMail(models.Model): |
1087 | ca828a10 | Sofia Papagiannaki | """
|
1088 | ca828a10 | Sofia Papagiannaki | Model for registring invitations
|
1089 | ca828a10 | Sofia Papagiannaki | """
|
1090 | ca828a10 | Sofia Papagiannaki | owner = models.ForeignKey(AstakosUser) |
1091 | 1eec103a | Sofia Papagiannaki | email = models.EmailField() |
1092 | ca828a10 | Sofia Papagiannaki | |
1093 | 5ce3ce4f | Sofia Papagiannaki | |
1094 | fc1e2f02 | Sofia Papagiannaki | def _generate_invitation_code(): |
1095 | fc1e2f02 | Sofia Papagiannaki | while True: |
1096 | 5ce3ce4f | Sofia Papagiannaki | code = randint(1, 2L ** 63 - 1) |
1097 | fc1e2f02 | Sofia Papagiannaki | try:
|
1098 | fc1e2f02 | Sofia Papagiannaki | Invitation.objects.get(code=code) |
1099 | fc1e2f02 | Sofia Papagiannaki | # An invitation with this code already exists, try again
|
1100 | fc1e2f02 | Sofia Papagiannaki | except Invitation.DoesNotExist:
|
1101 | fc1e2f02 | Sofia Papagiannaki | return code
|
1102 | fc1e2f02 | Sofia Papagiannaki | |
1103 | 5ce3ce4f | Sofia Papagiannaki | |
1104 | fc1e2f02 | Sofia Papagiannaki | def get_latest_terms(): |
1105 | fc1e2f02 | Sofia Papagiannaki | try:
|
1106 | fc1e2f02 | Sofia Papagiannaki | term = ApprovalTerms.objects.order_by('-id')[0] |
1107 | fc1e2f02 | Sofia Papagiannaki | return term
|
1108 | fc1e2f02 | Sofia Papagiannaki | except IndexError: |
1109 | fc1e2f02 | Sofia Papagiannaki | pass
|
1110 | fc1e2f02 | Sofia Papagiannaki | return None |
1111 | fc1e2f02 | Sofia Papagiannaki | |
1112 | ef20ea07 | Sofia Papagiannaki | class PendingThirdPartyUser(models.Model): |
1113 | ef20ea07 | Sofia Papagiannaki | """
|
1114 | ef20ea07 | Sofia Papagiannaki | Model for registring successful third party user authentications
|
1115 | ef20ea07 | Sofia Papagiannaki | """
|
1116 | e1a80257 | Sofia Papagiannaki | third_party_identifier = models.CharField(_('Third-party identifier'), max_length=255, null=True, blank=True) |
1117 | e1a80257 | Sofia Papagiannaki | provider = models.CharField(_('Provider'), max_length=255, blank=True) |
1118 | 678b2236 | Sofia Papagiannaki | email = models.EmailField(_('e-mail address'), blank=True, null=True) |
1119 | ef20ea07 | Sofia Papagiannaki | first_name = models.CharField(_('first name'), max_length=30, blank=True) |
1120 | ef20ea07 | Sofia Papagiannaki | last_name = models.CharField(_('last name'), max_length=30, blank=True) |
1121 | ef20ea07 | Sofia Papagiannaki | affiliation = models.CharField('Affiliation', max_length=255, blank=True) |
1122 | ef20ea07 | Sofia Papagiannaki | username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters")) |
1123 | e1a80257 | Sofia Papagiannaki | token = models.CharField(_('Token'), max_length=255, null=True, blank=True) |
1124 | d2633501 | Kostas Papadimitriou | created = models.DateTimeField(auto_now_add=True, null=True, blank=True) |
1125 | c630fee6 | Kostas Papadimitriou | info = models.TextField(default="", null=True, blank=True) |
1126 | d2633501 | Kostas Papadimitriou | |
1127 | 678b2236 | Sofia Papagiannaki | class Meta: |
1128 | 678b2236 | Sofia Papagiannaki | unique_together = ("provider", "third_party_identifier") |
1129 | ef20ea07 | Sofia Papagiannaki | |
1130 | c630fee6 | Kostas Papadimitriou | def get_user_instance(self): |
1131 | c630fee6 | Kostas Papadimitriou | d = self.__dict__
|
1132 | c630fee6 | Kostas Papadimitriou | d.pop('_state', None) |
1133 | c630fee6 | Kostas Papadimitriou | d.pop('id', None) |
1134 | c630fee6 | Kostas Papadimitriou | d.pop('token', None) |
1135 | c630fee6 | Kostas Papadimitriou | d.pop('created', None) |
1136 | c630fee6 | Kostas Papadimitriou | d.pop('info', None) |
1137 | c630fee6 | Kostas Papadimitriou | user = AstakosUser(**d) |
1138 | c630fee6 | Kostas Papadimitriou | |
1139 | c630fee6 | Kostas Papadimitriou | return user
|
1140 | c630fee6 | Kostas Papadimitriou | |
1141 | ef20ea07 | Sofia Papagiannaki | @property
|
1142 | ef20ea07 | Sofia Papagiannaki | def realname(self): |
1143 | ef20ea07 | Sofia Papagiannaki | return '%s %s' %(self.first_name, self.last_name) |
1144 | ef20ea07 | Sofia Papagiannaki | |
1145 | ef20ea07 | Sofia Papagiannaki | @realname.setter
|
1146 | ef20ea07 | Sofia Papagiannaki | def realname(self, value): |
1147 | ef20ea07 | Sofia Papagiannaki | parts = value.split(' ')
|
1148 | ef20ea07 | Sofia Papagiannaki | if len(parts) == 2: |
1149 | ef20ea07 | Sofia Papagiannaki | self.first_name = parts[0] |
1150 | ef20ea07 | Sofia Papagiannaki | self.last_name = parts[1] |
1151 | ef20ea07 | Sofia Papagiannaki | else:
|
1152 | ef20ea07 | Sofia Papagiannaki | self.last_name = parts[0] |
1153 | 2e90e3ec | Kostas Papadimitriou | |
1154 | ef20ea07 | Sofia Papagiannaki | def save(self, **kwargs): |
1155 | ef20ea07 | Sofia Papagiannaki | if not self.id: |
1156 | ef20ea07 | Sofia Papagiannaki | # set username
|
1157 | ef20ea07 | Sofia Papagiannaki | while not self.username: |
1158 | ef20ea07 | Sofia Papagiannaki | username = uuid.uuid4().hex[:30]
|
1159 | ef20ea07 | Sofia Papagiannaki | try:
|
1160 | ef20ea07 | Sofia Papagiannaki | AstakosUser.objects.get(username = username) |
1161 | ef20ea07 | Sofia Papagiannaki | except AstakosUser.DoesNotExist, e:
|
1162 | ef20ea07 | Sofia Papagiannaki | self.username = username
|
1163 | ef20ea07 | Sofia Papagiannaki | super(PendingThirdPartyUser, self).save(**kwargs) |
1164 | ef20ea07 | Sofia Papagiannaki | |
1165 | d2633501 | Kostas Papadimitriou | def generate_token(self): |
1166 | d2633501 | Kostas Papadimitriou | self.password = self.third_party_identifier |
1167 | d2633501 | Kostas Papadimitriou | self.last_login = datetime.now()
|
1168 | d2633501 | Kostas Papadimitriou | self.token = default_token_generator.make_token(self) |
1169 | d2633501 | Kostas Papadimitriou | |
1170 | bf0c6de5 | Sofia Papagiannaki | class SessionCatalog(models.Model): |
1171 | bf0c6de5 | Sofia Papagiannaki | session_key = models.CharField(_('session key'), max_length=40) |
1172 | bf0c6de5 | Sofia Papagiannaki | user = models.ForeignKey(AstakosUser, related_name='sessions', null=True) |
1173 | bf0c6de5 | Sofia Papagiannaki | |
1174 | ccab6eb5 | Sofia Papagiannaki | class MemberJoinPolicy(models.Model): |
1175 | e1a80257 | Sofia Papagiannaki | policy = models.CharField(_('Policy'), max_length=255, unique=True, db_index=True) |
1176 | e1a80257 | Sofia Papagiannaki | description = models.CharField(_('Description'), max_length=80) |
1177 | e1a80257 | Sofia Papagiannaki | |
1178 | e1a80257 | Sofia Papagiannaki | def __str__(self): |
1179 | e1a80257 | Sofia Papagiannaki | return self.policy |
1180 | e1a80257 | Sofia Papagiannaki | |
1181 | ccab6eb5 | Sofia Papagiannaki | class MemberLeavePolicy(models.Model): |
1182 | b22de10a | Sofia Papagiannaki | policy = models.CharField(_('Policy'), max_length=255, unique=True, db_index=True) |
1183 | b22de10a | Sofia Papagiannaki | description = models.CharField(_('Description'), max_length=80) |
1184 | b22de10a | Sofia Papagiannaki | |
1185 | b22de10a | Sofia Papagiannaki | def __str__(self): |
1186 | b22de10a | Sofia Papagiannaki | return self.policy |
1187 | b22de10a | Sofia Papagiannaki | |
1188 | ccab6eb5 | Sofia Papagiannaki | _auto_accept_join = False
|
1189 | ccab6eb5 | Sofia Papagiannaki | def get_auto_accept_join(): |
1190 | bfe23b13 | Sofia Papagiannaki | global _auto_accept_join
|
1191 | bfe23b13 | Sofia Papagiannaki | if _auto_accept_join is not False: |
1192 | bfe23b13 | Sofia Papagiannaki | return _auto_accept_join
|
1193 | e65c21df | Georgios D. Tsoukalas | try:
|
1194 | ccab6eb5 | Sofia Papagiannaki | auto_accept = MemberJoinPolicy.objects.get(policy='auto_accept')
|
1195 | ccab6eb5 | Sofia Papagiannaki | except:
|
1196 | ccab6eb5 | Sofia Papagiannaki | auto_accept = None
|
1197 | bfe23b13 | Sofia Papagiannaki | _auto_accept_join = auto_accept |
1198 | ccab6eb5 | Sofia Papagiannaki | return auto_accept
|
1199 | ccab6eb5 | Sofia Papagiannaki | |
1200 | bfe23b13 | Sofia Papagiannaki | _closed_join = False
|
1201 | bfe23b13 | Sofia Papagiannaki | def get_closed_join(): |
1202 | bfe23b13 | Sofia Papagiannaki | global _closed_join
|
1203 | bfe23b13 | Sofia Papagiannaki | if _closed_join is not False: |
1204 | bfe23b13 | Sofia Papagiannaki | return _closed_join
|
1205 | bfe23b13 | Sofia Papagiannaki | try:
|
1206 | bfe23b13 | Sofia Papagiannaki | closed = MemberJoinPolicy.objects.get(policy='closed')
|
1207 | bfe23b13 | Sofia Papagiannaki | except:
|
1208 | bfe23b13 | Sofia Papagiannaki | closed = None
|
1209 | bfe23b13 | Sofia Papagiannaki | _closed_join = closed |
1210 | bfe23b13 | Sofia Papagiannaki | return closed
|
1211 | bfe23b13 | Sofia Papagiannaki | |
1212 | ccab6eb5 | Sofia Papagiannaki | _auto_accept_leave = False
|
1213 | ccab6eb5 | Sofia Papagiannaki | def get_auto_accept_leave(): |
1214 | bfe23b13 | Sofia Papagiannaki | global _auto_accept_leave
|
1215 | bfe23b13 | Sofia Papagiannaki | if _auto_accept_leave is not False: |
1216 | bfe23b13 | Sofia Papagiannaki | return _auto_accept_leave
|
1217 | ccab6eb5 | Sofia Papagiannaki | try:
|
1218 | ccab6eb5 | Sofia Papagiannaki | auto_accept = MemberLeavePolicy.objects.get(policy='auto_accept')
|
1219 | e65c21df | Georgios D. Tsoukalas | except:
|
1220 | e65c21df | Georgios D. Tsoukalas | auto_accept = None
|
1221 | bfe23b13 | Sofia Papagiannaki | _auto_accept_leave = auto_accept |
1222 | e65c21df | Georgios D. Tsoukalas | return auto_accept
|
1223 | e1a80257 | Sofia Papagiannaki | |
1224 | bfe23b13 | Sofia Papagiannaki | _closed_leave = False
|
1225 | bfe23b13 | Sofia Papagiannaki | def get_closed_leave(): |
1226 | bfe23b13 | Sofia Papagiannaki | global _closed_leave
|
1227 | bfe23b13 | Sofia Papagiannaki | if _closed_leave is not False: |
1228 | bfe23b13 | Sofia Papagiannaki | return _closed_leave
|
1229 | bfe23b13 | Sofia Papagiannaki | try:
|
1230 | bfe23b13 | Sofia Papagiannaki | closed = MemberLeavePolicy.objects.get(policy='closed')
|
1231 | bfe23b13 | Sofia Papagiannaki | except:
|
1232 | bfe23b13 | Sofia Papagiannaki | closed = None
|
1233 | bfe23b13 | Sofia Papagiannaki | _closed_leave = closed |
1234 | 09ab0996 | Sofia Papagiannaki | return closed
|
1235 | bfe23b13 | Sofia Papagiannaki | |
1236 | 65360c65 | Georgios D. Tsoukalas | |
1237 | 65360c65 | Georgios D. Tsoukalas | ### PROJECTS ###
|
1238 | 65360c65 | Georgios D. Tsoukalas | ################
|
1239 | 65360c65 | Georgios D. Tsoukalas | |
1240 | 65360c65 | Georgios D. Tsoukalas | |
1241 | e546df49 | Georgios D. Tsoukalas | def synced_model_metaclass(class_name, class_parents, class_attributes): |
1242 | 65360c65 | Georgios D. Tsoukalas | |
1243 | e546df49 | Georgios D. Tsoukalas | new_attributes = {} |
1244 | e546df49 | Georgios D. Tsoukalas | sync_attributes = {} |
1245 | 65360c65 | Georgios D. Tsoukalas | |
1246 | e546df49 | Georgios D. Tsoukalas | for name, value in class_attributes.iteritems(): |
1247 | e546df49 | Georgios D. Tsoukalas | sync, underscore, rest = name.partition('_')
|
1248 | e546df49 | Georgios D. Tsoukalas | if sync == 'sync' and underscore == '_': |
1249 | e546df49 | Georgios D. Tsoukalas | sync_attributes[rest] = value |
1250 | e546df49 | Georgios D. Tsoukalas | else:
|
1251 | e546df49 | Georgios D. Tsoukalas | new_attributes[name] = value |
1252 | 65360c65 | Georgios D. Tsoukalas | |
1253 | e546df49 | Georgios D. Tsoukalas | if 'prefix' not in sync_attributes: |
1254 | e546df49 | Georgios D. Tsoukalas | m = ("you did not specify a 'sync_prefix' attribute "
|
1255 | e546df49 | Georgios D. Tsoukalas | "in class '%s'" % (class_name,))
|
1256 | e546df49 | Georgios D. Tsoukalas | raise ValueError(m) |
1257 | 65360c65 | Georgios D. Tsoukalas | |
1258 | e546df49 | Georgios D. Tsoukalas | prefix = sync_attributes.pop('prefix')
|
1259 | e546df49 | Georgios D. Tsoukalas | class_name = sync_attributes.pop('classname', prefix + '_model') |
1260 | 65360c65 | Georgios D. Tsoukalas | |
1261 | e546df49 | Georgios D. Tsoukalas | for name, value in sync_attributes.iteritems(): |
1262 | e546df49 | Georgios D. Tsoukalas | newname = prefix + '_' + name
|
1263 | e546df49 | Georgios D. Tsoukalas | if newname in new_attributes: |
1264 | e546df49 | Georgios D. Tsoukalas | m = ("class '%s' was specified with prefix '%s' "
|
1265 | e546df49 | Georgios D. Tsoukalas | "but it already has an attribute named '%s'"
|
1266 | e546df49 | Georgios D. Tsoukalas | % (class_name, prefix, newname)) |
1267 | e546df49 | Georgios D. Tsoukalas | raise ValueError(m) |
1268 | 65360c65 | Georgios D. Tsoukalas | |
1269 | e546df49 | Georgios D. Tsoukalas | new_attributes[newname] = value |
1270 | e546df49 | Georgios D. Tsoukalas | |
1271 | e546df49 | Georgios D. Tsoukalas | newclass = type(class_name, class_parents, new_attributes)
|
1272 | e546df49 | Georgios D. Tsoukalas | return newclass
|
1273 | e546df49 | Georgios D. Tsoukalas | |
1274 | e546df49 | Georgios D. Tsoukalas | |
1275 | e546df49 | Georgios D. Tsoukalas | def make_synced(prefix='sync', name='SyncedState'): |
1276 | e546df49 | Georgios D. Tsoukalas | |
1277 | e546df49 | Georgios D. Tsoukalas | the_name = name |
1278 | e546df49 | Georgios D. Tsoukalas | the_prefix = prefix |
1279 | e546df49 | Georgios D. Tsoukalas | |
1280 | e546df49 | Georgios D. Tsoukalas | class SyncedState(models.Model): |
1281 | e546df49 | Georgios D. Tsoukalas | |
1282 | e546df49 | Georgios D. Tsoukalas | sync_classname = the_name |
1283 | e546df49 | Georgios D. Tsoukalas | sync_prefix = the_prefix |
1284 | e546df49 | Georgios D. Tsoukalas | __metaclass__ = synced_model_metaclass |
1285 | e546df49 | Georgios D. Tsoukalas | |
1286 | e546df49 | Georgios D. Tsoukalas | sync_new_state = models.BigIntegerField(null=True)
|
1287 | e546df49 | Georgios D. Tsoukalas | sync_synced_state = models.BigIntegerField(null=True)
|
1288 | e546df49 | Georgios D. Tsoukalas | STATUS_SYNCED = 0
|
1289 | e546df49 | Georgios D. Tsoukalas | STATUS_PENDING = 1
|
1290 | e546df49 | Georgios D. Tsoukalas | sync_status = models.IntegerField(db_index=True)
|
1291 | e546df49 | Georgios D. Tsoukalas | |
1292 | e546df49 | Georgios D. Tsoukalas | class Meta: |
1293 | e546df49 | Georgios D. Tsoukalas | abstract = True
|
1294 | e546df49 | Georgios D. Tsoukalas | |
1295 | e546df49 | Georgios D. Tsoukalas | class NotSynced(Exception): |
1296 | e546df49 | Georgios D. Tsoukalas | pass
|
1297 | e546df49 | Georgios D. Tsoukalas | |
1298 | e546df49 | Georgios D. Tsoukalas | def sync_init_state(self, state): |
1299 | e546df49 | Georgios D. Tsoukalas | self.sync_synced_state = state
|
1300 | e546df49 | Georgios D. Tsoukalas | self.sync_new_state = state
|
1301 | 65360c65 | Georgios D. Tsoukalas | self.sync_status = self.STATUS_SYNCED |
1302 | 65360c65 | Georgios D. Tsoukalas | |
1303 | e546df49 | Georgios D. Tsoukalas | def sync_get_status(self): |
1304 | e546df49 | Georgios D. Tsoukalas | return self.sync_status |
1305 | 65360c65 | Georgios D. Tsoukalas | |
1306 | e546df49 | Georgios D. Tsoukalas | def sync_set_status(self): |
1307 | e546df49 | Georgios D. Tsoukalas | if self.sync_new_state != self.sync_synced_state: |
1308 | e546df49 | Georgios D. Tsoukalas | self.sync_status = self.STATUS_PENDING |
1309 | e546df49 | Georgios D. Tsoukalas | else:
|
1310 | e546df49 | Georgios D. Tsoukalas | self.sync_status = self.STATUS_SYNCED |
1311 | 65360c65 | Georgios D. Tsoukalas | |
1312 | e546df49 | Georgios D. Tsoukalas | def sync_set_synced(self): |
1313 | e546df49 | Georgios D. Tsoukalas | self.sync_synced_state = self.sync_new_state |
1314 | e546df49 | Georgios D. Tsoukalas | self.sync_status = self.STATUS_SYNCED |
1315 | 65360c65 | Georgios D. Tsoukalas | |
1316 | e546df49 | Georgios D. Tsoukalas | def sync_get_synced_state(self): |
1317 | e546df49 | Georgios D. Tsoukalas | return self.sync_synced_state |
1318 | 65360c65 | Georgios D. Tsoukalas | |
1319 | e546df49 | Georgios D. Tsoukalas | def sync_set_new_state(self, new_state): |
1320 | e546df49 | Georgios D. Tsoukalas | self.sync_new_state = new_state
|
1321 | e546df49 | Georgios D. Tsoukalas | self.sync_set_status()
|
1322 | 65360c65 | Georgios D. Tsoukalas | |
1323 | e546df49 | Georgios D. Tsoukalas | def sync_get_new_state(self): |
1324 | e546df49 | Georgios D. Tsoukalas | return self.sync_new_state |
1325 | 65360c65 | Georgios D. Tsoukalas | |
1326 | e546df49 | Georgios D. Tsoukalas | def sync_set_synced_state(self, synced_state): |
1327 | e546df49 | Georgios D. Tsoukalas | self.sync_synced_state = synced_state
|
1328 | e546df49 | Georgios D. Tsoukalas | self.sync_set_status()
|
1329 | 65360c65 | Georgios D. Tsoukalas | |
1330 | e546df49 | Georgios D. Tsoukalas | def sync_get_pending_objects(self): |
1331 | e546df49 | Georgios D. Tsoukalas | kw = dict((the_prefix + '_status', self.STATUS_PENDING)) |
1332 | e546df49 | Georgios D. Tsoukalas | return self.objects.filter(**kw) |
1333 | 65360c65 | Georgios D. Tsoukalas | |
1334 | e546df49 | Georgios D. Tsoukalas | def sync_get_synced_objects(self): |
1335 | e546df49 | Georgios D. Tsoukalas | kw = dict((the_prefix + '_status', self.STATUS_SYNCED)) |
1336 | e546df49 | Georgios D. Tsoukalas | return self.objects.filter(**kw) |
1337 | 65360c65 | Georgios D. Tsoukalas | |
1338 | e546df49 | Georgios D. Tsoukalas | def sync_verify_get_synced_state(self): |
1339 | e546df49 | Georgios D. Tsoukalas | status = self.sync_get_status()
|
1340 | e546df49 | Georgios D. Tsoukalas | state = self.sync_get_synced_state()
|
1341 | e546df49 | Georgios D. Tsoukalas | verified = (status == self.STATUS_SYNCED)
|
1342 | e546df49 | Georgios D. Tsoukalas | return state, verified
|
1343 | e546df49 | Georgios D. Tsoukalas | |
1344 | e546df49 | Georgios D. Tsoukalas | def sync_is_synced(self): |
1345 | e546df49 | Georgios D. Tsoukalas | state, verified = self.sync_verify_get_synced_state()
|
1346 | e546df49 | Georgios D. Tsoukalas | return verified
|
1347 | e546df49 | Georgios D. Tsoukalas | |
1348 | e546df49 | Georgios D. Tsoukalas | return SyncedState
|
1349 | e546df49 | Georgios D. Tsoukalas | |
1350 | e546df49 | Georgios D. Tsoukalas | SyncedState = make_synced(prefix='sync', name='SyncedState') |
1351 | 425e2e95 | Sofia Papagiannaki | |
1352 | 425e2e95 | Sofia Papagiannaki | |
1353 | 8aed306c | Giorgos Korfiatis | class ProjectApplication(models.Model): |
1354 | 85d444db | Sofia Papagiannaki | PENDING, APPROVED, REPLACED, UNKNOWN = 'Pending', 'Approved', 'Replaced', 'Unknown' |
1355 | 425e2e95 | Sofia Papagiannaki | applicant = models.ForeignKey( |
1356 | 425e2e95 | Sofia Papagiannaki | AstakosUser, |
1357 | d6fdc91e | Georgios D. Tsoukalas | related_name='projects_applied',
|
1358 | d6fdc91e | Georgios D. Tsoukalas | db_index=True)
|
1359 | d6fdc91e | Georgios D. Tsoukalas | |
1360 | d6fdc91e | Georgios D. Tsoukalas | state = models.CharField(max_length=80,
|
1361 | a7aba804 | Sofia Papagiannaki | default=UNKNOWN) |
1362 | d6fdc91e | Georgios D. Tsoukalas | |
1363 | 425e2e95 | Sofia Papagiannaki | owner = models.ForeignKey( |
1364 | 425e2e95 | Sofia Papagiannaki | AstakosUser, |
1365 | d6fdc91e | Georgios D. Tsoukalas | related_name='projects_owned',
|
1366 | d6fdc91e | Georgios D. Tsoukalas | db_index=True)
|
1367 | d6fdc91e | Georgios D. Tsoukalas | |
1368 | 425e2e95 | Sofia Papagiannaki | precursor_application = models.OneToOneField('ProjectApplication',
|
1369 | 425e2e95 | Sofia Papagiannaki | null=True,
|
1370 | 425e2e95 | Sofia Papagiannaki | blank=True,
|
1371 | d6fdc91e | Georgios D. Tsoukalas | db_index=True)
|
1372 | 425e2e95 | Sofia Papagiannaki | |
1373 | 52784759 | Olga Brani | name = models.CharField(max_length=80, help_text=" The Project's name should be in a domain format. The domain shouldn't neccessarily exist in the real world but is helpful to imply a structure. e.g.: myproject.mylab.ntua.gr or myservice.myteam.myorganization ",) |
1374 | 425e2e95 | Sofia Papagiannaki | homepage = models.URLField(max_length=255, null=True, |
1375 | 52784759 | Olga Brani | blank=True,help_text="This should be a URL pointing at your project's site. e.g.: http://myproject.com ",) |
1376 | 52784759 | Olga Brani | description = models.TextField(null=True, blank=True,help_text= "Please provide a short but descriptive abstract of your Project, so that anyone searching can quickly understand what this Project is about. ") |
1377 | 52784759 | Olga Brani | start_date = models.DateTimeField(help_text= "Here you specify the date you want your Project to start granting its resources. Its members will get the resources coming from this Project on this exact date.")
|
1378 | 52784759 | Olga Brani | end_date = models.DateTimeField(help_text= "Here you specify the date you want your Project to cease. This means that after this date all members will no longer be able to allocate resources from this Project. ")
|
1379 | 425e2e95 | Sofia Papagiannaki | member_join_policy = models.ForeignKey(MemberJoinPolicy) |
1380 | 425e2e95 | Sofia Papagiannaki | member_leave_policy = models.ForeignKey(MemberLeavePolicy) |
1381 | 425e2e95 | Sofia Papagiannaki | limit_on_members_number = models.PositiveIntegerField(null=True,
|
1382 | 52784759 | Olga Brani | blank=True,help_text= "Here you specify the number of members this Project is going to have. This means that this number of people will be granted the resources you will specify in the next step. This can be '1' if you are the only one wanting to get resources. ") |
1383 | 425e2e95 | Sofia Papagiannaki | resource_grants = models.ManyToManyField( |
1384 | 425e2e95 | Sofia Papagiannaki | Resource, |
1385 | 425e2e95 | Sofia Papagiannaki | null=True,
|
1386 | 425e2e95 | Sofia Papagiannaki | blank=True,
|
1387 | d6fdc91e | Georgios D. Tsoukalas | through='ProjectResourceGrant')
|
1388 | 425e2e95 | Sofia Papagiannaki | comments = models.TextField(null=True, blank=True) |
1389 | 425e2e95 | Sofia Papagiannaki | issue_date = models.DateTimeField() |
1390 | 425e2e95 | Sofia Papagiannaki | |
1391 | a7aba804 | Sofia Papagiannaki | def add_resource_policy(self, service, resource, uplimit): |
1392 | e1a80257 | Sofia Papagiannaki | """Raises ObjectDoesNotExist, IntegrityError"""
|
1393 | a7aba804 | Sofia Papagiannaki | q = self.projectresourcegrant_set
|
1394 | e1a80257 | Sofia Papagiannaki | resource = Resource.objects.get(service__name=service, name=resource) |
1395 | a7aba804 | Sofia Papagiannaki | q.create(resource=resource, member_capacity=uplimit) |
1396 | e1a80257 | Sofia Papagiannaki | |
1397 | 669cfe19 | Olga Brani | |
1398 | 669cfe19 | Olga Brani | @property
|
1399 | 669cfe19 | Olga Brani | def grants(self): |
1400 | 669cfe19 | Olga Brani | return self.projectresourcegrant_set.values('member_capacity', 'resource__name', 'resource__service__name') |
1401 | 669cfe19 | Olga Brani | |
1402 | e1a80257 | Sofia Papagiannaki | @property
|
1403 | e1a80257 | Sofia Papagiannaki | def resource_policies(self): |
1404 | f3342849 | Sofia Papagiannaki | return self.projectresourcegrant_set.all() |
1405 | e1a80257 | Sofia Papagiannaki | |
1406 | e1a80257 | Sofia Papagiannaki | @resource_policies.setter
|
1407 | e1a80257 | Sofia Papagiannaki | def resource_policies(self, policies): |
1408 | e1a80257 | Sofia Papagiannaki | for p in policies: |
1409 | e1a80257 | Sofia Papagiannaki | service = p.get('service', None) |
1410 | e1a80257 | Sofia Papagiannaki | resource = p.get('resource', None) |
1411 | e1a80257 | Sofia Papagiannaki | uplimit = p.get('uplimit', 0) |
1412 | a7aba804 | Sofia Papagiannaki | self.add_resource_policy(service, resource, uplimit)
|
1413 | 425e2e95 | Sofia Papagiannaki | |
1414 | ccab6eb5 | Sofia Papagiannaki | @property
|
1415 | ccab6eb5 | Sofia Papagiannaki | def follower(self): |
1416 | ccab6eb5 | Sofia Papagiannaki | try:
|
1417 | ccab6eb5 | Sofia Papagiannaki | return ProjectApplication.objects.get(precursor_application=self) |
1418 | ccab6eb5 | Sofia Papagiannaki | except ProjectApplication.DoesNotExist:
|
1419 | ccab6eb5 | Sofia Papagiannaki | return
|
1420 | ccab6eb5 | Sofia Papagiannaki | |
1421 | 73fbaec4 | Sofia Papagiannaki | def submit(self, resource_policies, applicant, comments, |
1422 | 30a6c330 | Sofia Papagiannaki | precursor_application=None):
|
1423 | ece3b66e | Giorgos Korfiatis | |
1424 | 8327782d | Sofia Papagiannaki | if precursor_application:
|
1425 | 73fbaec4 | Sofia Papagiannaki | self.precursor_application = precursor_application
|
1426 | 73fbaec4 | Sofia Papagiannaki | self.owner = precursor_application.owner
|
1427 | bfe23b13 | Sofia Papagiannaki | else:
|
1428 | 73fbaec4 | Sofia Papagiannaki | self.owner = applicant
|
1429 | 73fbaec4 | Sofia Papagiannaki | |
1430 | 73fbaec4 | Sofia Papagiannaki | self.id = None |
1431 | 73fbaec4 | Sofia Papagiannaki | self.applicant = applicant
|
1432 | 73fbaec4 | Sofia Papagiannaki | self.comments = comments
|
1433 | 73fbaec4 | Sofia Papagiannaki | self.issue_date = datetime.now()
|
1434 | 85d444db | Sofia Papagiannaki | self.state = self.PENDING |
1435 | d6fdc91e | Georgios D. Tsoukalas | self.save()
|
1436 | a7aba804 | Sofia Papagiannaki | self.resource_policies = resource_policies
|
1437 | ece3b66e | Giorgos Korfiatis | |
1438 | 4f22664f | Georgios D. Tsoukalas | def _get_project(self): |
1439 | 4f22664f | Georgios D. Tsoukalas | precursor = self
|
1440 | 4f22664f | Georgios D. Tsoukalas | while precursor:
|
1441 | 4f22664f | Georgios D. Tsoukalas | try:
|
1442 | 4f22664f | Georgios D. Tsoukalas | project = precursor.project |
1443 | 4f22664f | Georgios D. Tsoukalas | return project
|
1444 | 4f22664f | Georgios D. Tsoukalas | except Project.DoesNotExist:
|
1445 | 4f22664f | Georgios D. Tsoukalas | pass
|
1446 | 4f22664f | Georgios D. Tsoukalas | precursor = precursor.precursor_application |
1447 | 4f22664f | Georgios D. Tsoukalas | |
1448 | 4f22664f | Georgios D. Tsoukalas | return None |
1449 | 4f22664f | Georgios D. Tsoukalas | |
1450 | ccab6eb5 | Sofia Papagiannaki | def approve(self, approval_user=None): |
1451 | ccab6eb5 | Sofia Papagiannaki | """
|
1452 | ccab6eb5 | Sofia Papagiannaki | If approval_user then during owner membership acceptance
|
1453 | ccab6eb5 | Sofia Papagiannaki | it is checked whether the request_user is eligible.
|
1454 | 262e04c6 | Giorgos Korfiatis |
|
1455 | 2553efae | Sofia Papagiannaki | Raises:
|
1456 | b8f05f8d | Sofia Papagiannaki | PermissionDenied
|
1457 | ccab6eb5 | Sofia Papagiannaki | """
|
1458 | 4f22664f | Georgios D. Tsoukalas | |
1459 | 4f22664f | Georgios D. Tsoukalas | if not transaction.is_managed(): |
1460 | 4f22664f | Georgios D. Tsoukalas | raise AssertionError("NOPE") |
1461 | 4f22664f | Georgios D. Tsoukalas | |
1462 | 73fbaec4 | Sofia Papagiannaki | new_project_name = self.name
|
1463 | 85d444db | Sofia Papagiannaki | if self.state != self.PENDING: |
1464 | 65360c65 | Georgios D. Tsoukalas | m = _("cannot approve: project '%s' in state '%s'") % (
|
1465 | 65360c65 | Georgios D. Tsoukalas | new_project_name, self.state)
|
1466 | 4f22664f | Georgios D. Tsoukalas | raise PermissionDenied(m) # invalid argument |
1467 | 262e04c6 | Giorgos Korfiatis | |
1468 | fdafae27 | Giorgos Korfiatis | now = datetime.now() |
1469 | 4f22664f | Georgios D. Tsoukalas | project = self._get_project()
|
1470 | 3cc9637a | Giorgos Korfiatis | |
1471 | 3cc9637a | Giorgos Korfiatis | try:
|
1472 | 3cc9637a | Giorgos Korfiatis | # needs SERIALIZABLE
|
1473 | 3cc9637a | Giorgos Korfiatis | conflicting_project = Project.objects.get(name=new_project_name) |
1474 | 3cc9637a | Giorgos Korfiatis | if (conflicting_project.is_alive and |
1475 | 37705b5f | Giorgos Korfiatis | conflicting_project != project): |
1476 | 3cc9637a | Giorgos Korfiatis | m = (_("cannot approve: project with name '%s' "
|
1477 | 3cc9637a | Giorgos Korfiatis | "already exists (serial: %s)") % (
|
1478 | 3cc9637a | Giorgos Korfiatis | new_project_name, conflicting_project.id)) |
1479 | 3cc9637a | Giorgos Korfiatis | raise PermissionDenied(m) # invalid argument |
1480 | 3cc9637a | Giorgos Korfiatis | except Project.DoesNotExist:
|
1481 | 3cc9637a | Giorgos Korfiatis | pass
|
1482 | 3cc9637a | Giorgos Korfiatis | |
1483 | 4f22664f | Georgios D. Tsoukalas | if project is None: |
1484 | 3cc9637a | Giorgos Korfiatis | project = Project(creation_date=now) |
1485 | fdafae27 | Giorgos Korfiatis | |
1486 | 3cc9637a | Giorgos Korfiatis | project.name = new_project_name |
1487 | ee45eb81 | Giorgos Korfiatis | project.application = self
|
1488 | 425e2e95 | Sofia Papagiannaki | |
1489 | ee45eb81 | Giorgos Korfiatis | # This will block while syncing,
|
1490 | ee45eb81 | Giorgos Korfiatis | # but unblock before setting the membership state.
|
1491 | ee45eb81 | Giorgos Korfiatis | # See ProjectMembership.set_sync()
|
1492 | ee45eb81 | Giorgos Korfiatis | project.set_membership_pending_sync() |
1493 | 425e2e95 | Sofia Papagiannaki | |
1494 | fdafae27 | Giorgos Korfiatis | project.last_approval_date = now |
1495 | 73fbaec4 | Sofia Papagiannaki | project.save() |
1496 | 4f22664f | Georgios D. Tsoukalas | #ProjectMembership.add_to_project(self)
|
1497 | 4f22664f | Georgios D. Tsoukalas | project.add_member(self.owner)
|
1498 | fdafae27 | Giorgos Korfiatis | |
1499 | 4f22664f | Georgios D. Tsoukalas | precursor = self.precursor_application
|
1500 | 4f22664f | Georgios D. Tsoukalas | while precursor:
|
1501 | 85d444db | Sofia Papagiannaki | precursor.state = self.REPLACED
|
1502 | 4f22664f | Georgios D. Tsoukalas | precursor.save() |
1503 | 4f22664f | Georgios D. Tsoukalas | precursor = precursor.precursor_application |
1504 | 262e04c6 | Giorgos Korfiatis | |
1505 | 85d444db | Sofia Papagiannaki | self.state = self.APPROVED |
1506 | bfe23b13 | Sofia Papagiannaki | self.save()
|
1507 | 262e04c6 | Giorgos Korfiatis | |
1508 | ccab6eb5 | Sofia Papagiannaki | |
1509 | 73fbaec4 | Sofia Papagiannaki | class ProjectResourceGrant(models.Model): |
1510 | e1a80257 | Sofia Papagiannaki | |
1511 | 425e2e95 | Sofia Papagiannaki | resource = models.ForeignKey(Resource) |
1512 | 425e2e95 | Sofia Papagiannaki | project_application = models.ForeignKey(ProjectApplication, |
1513 | 5200e864 | Sofia Papagiannaki | null=True)
|
1514 | 425e2e95 | Sofia Papagiannaki | project_capacity = models.BigIntegerField(null=True)
|
1515 | 425e2e95 | Sofia Papagiannaki | project_import_limit = models.BigIntegerField(null=True)
|
1516 | 425e2e95 | Sofia Papagiannaki | project_export_limit = models.BigIntegerField(null=True)
|
1517 | 425e2e95 | Sofia Papagiannaki | member_capacity = models.BigIntegerField(null=True)
|
1518 | 425e2e95 | Sofia Papagiannaki | member_import_limit = models.BigIntegerField(null=True)
|
1519 | 425e2e95 | Sofia Papagiannaki | member_export_limit = models.BigIntegerField(null=True)
|
1520 | 73fbaec4 | Sofia Papagiannaki | |
1521 | 73fbaec4 | Sofia Papagiannaki | objects = ExtendedManager() |
1522 | 73fbaec4 | Sofia Papagiannaki | |
1523 | 73fbaec4 | Sofia Papagiannaki | class Meta: |
1524 | 73fbaec4 | Sofia Papagiannaki | unique_together = ("resource", "project_application") |
1525 | 8327782d | Sofia Papagiannaki | |
1526 | e546df49 | Georgios D. Tsoukalas | |
1527 | d6fdc91e | Georgios D. Tsoukalas | class Project(models.Model): |
1528 | e546df49 | Georgios D. Tsoukalas | |
1529 | ee45eb81 | Giorgos Korfiatis | application = models.OneToOneField( |
1530 | 4f22664f | Georgios D. Tsoukalas | ProjectApplication, |
1531 | 782d9118 | Giorgos Korfiatis | related_name='project')
|
1532 | 4f22664f | Georgios D. Tsoukalas | last_approval_date = models.DateTimeField(null=True)
|
1533 | 4f22664f | Georgios D. Tsoukalas | |
1534 | 4f22664f | Georgios D. Tsoukalas | members = models.ManyToManyField( |
1535 | 4f22664f | Georgios D. Tsoukalas | AstakosUser, |
1536 | 4f22664f | Georgios D. Tsoukalas | through='ProjectMembership')
|
1537 | 4f22664f | Georgios D. Tsoukalas | |
1538 | 4f22664f | Georgios D. Tsoukalas | termination_start_date = models.DateTimeField(null=True)
|
1539 | 4f22664f | Georgios D. Tsoukalas | termination_date = models.DateTimeField(null=True)
|
1540 | 4f22664f | Georgios D. Tsoukalas | |
1541 | 4f22664f | Georgios D. Tsoukalas | creation_date = models.DateTimeField() |
1542 | 4f22664f | Georgios D. Tsoukalas | name = models.CharField( |
1543 | 4f22664f | Georgios D. Tsoukalas | max_length=80,
|
1544 | 4f22664f | Georgios D. Tsoukalas | db_index=True,
|
1545 | 4f22664f | Georgios D. Tsoukalas | unique=True)
|
1546 | 425e2e95 | Sofia Papagiannaki | |
1547 | e1a80257 | Sofia Papagiannaki | @property
|
1548 | 8aed306c | Giorgos Korfiatis | def violated_resource_grants(self): |
1549 | 8aed306c | Giorgos Korfiatis | return False |
1550 | 425e2e95 | Sofia Papagiannaki | |
1551 | b22de10a | Sofia Papagiannaki | @property
|
1552 | b22de10a | Sofia Papagiannaki | def violated_members_number_limit(self): |
1553 | ee45eb81 | Giorgos Korfiatis | application = self.application
|
1554 | 4e78511a | Giorgos Korfiatis | return len(self.approved_members) > application.limit_on_members_number |
1555 | 425e2e95 | Sofia Papagiannaki | |
1556 | e1a80257 | Sofia Papagiannaki | @property
|
1557 | 8aed306c | Giorgos Korfiatis | def is_terminated(self): |
1558 | 782d9118 | Giorgos Korfiatis | return bool(self.termination_date) |
1559 | 425e2e95 | Sofia Papagiannaki | |
1560 | 8aed306c | Giorgos Korfiatis | @property
|
1561 | 8aed306c | Giorgos Korfiatis | def is_still_approved(self): |
1562 | 8aed306c | Giorgos Korfiatis | return bool(self.last_approval_date) |
1563 | 8aed306c | Giorgos Korfiatis | |
1564 | 8aed306c | Giorgos Korfiatis | @property
|
1565 | e1a80257 | Sofia Papagiannaki | def is_active(self): |
1566 | 8aed306c | Giorgos Korfiatis | if (self.is_terminated or |
1567 | 8aed306c | Giorgos Korfiatis | not self.is_still_approved or |
1568 | 8aed306c | Giorgos Korfiatis | self.violated_resource_grants):
|
1569 | e1a80257 | Sofia Papagiannaki | return False |
1570 | b22de10a | Sofia Papagiannaki | # if self.violated_members_number_limit:
|
1571 | b22de10a | Sofia Papagiannaki | # return False
|
1572 | e1a80257 | Sofia Papagiannaki | return True |
1573 | fc655b6f | Kostas Papadimitriou | |
1574 | e1a80257 | Sofia Papagiannaki | @property
|
1575 | e1a80257 | Sofia Papagiannaki | def is_suspended(self): |
1576 | 8aed306c | Giorgos Korfiatis | if (self.is_terminated or |
1577 | 8aed306c | Giorgos Korfiatis | self.is_still_approved or |
1578 | 8aed306c | Giorgos Korfiatis | not self.violated_resource_grants): |
1579 | e1a80257 | Sofia Papagiannaki | return False |
1580 | b22de10a | Sofia Papagiannaki | # if not self.violated_members_number_limit:
|
1581 | b22de10a | Sofia Papagiannaki | # return False
|
1582 | e1a80257 | Sofia Papagiannaki | return True |
1583 | 425e2e95 | Sofia Papagiannaki | |
1584 | e1a80257 | Sofia Papagiannaki | @property
|
1585 | e1a80257 | Sofia Papagiannaki | def is_alive(self): |
1586 | e1a80257 | Sofia Papagiannaki | return self.is_active or self.is_suspended |
1587 | 425e2e95 | Sofia Papagiannaki | |
1588 | e1a80257 | Sofia Papagiannaki | @property
|
1589 | e1a80257 | Sofia Papagiannaki | def is_inconsistent(self): |
1590 | e1a80257 | Sofia Papagiannaki | now = datetime.now() |
1591 | e1a80257 | Sofia Papagiannaki | if self.creation_date > now: |
1592 | e1a80257 | Sofia Papagiannaki | return True |
1593 | e1a80257 | Sofia Papagiannaki | if self.last_approval_date > now: |
1594 | e1a80257 | Sofia Papagiannaki | return True |
1595 | e1a80257 | Sofia Papagiannaki | if self.terminaton_date > now: |
1596 | e1a80257 | Sofia Papagiannaki | return True |
1597 | e1a80257 | Sofia Papagiannaki | return False |
1598 | 65360c65 | Georgios D. Tsoukalas | |
1599 | 425e2e95 | Sofia Papagiannaki | @property
|
1600 | 425e2e95 | Sofia Papagiannaki | def approved_memberships(self): |
1601 | ee45eb81 | Giorgos Korfiatis | ACCEPTED = ProjectMembership.ACCEPTED |
1602 | ee45eb81 | Giorgos Korfiatis | PENDING = ProjectMembership.PENDING |
1603 | 425e2e95 | Sofia Papagiannaki | return self.projectmembership_set.filter( |
1604 | ee45eb81 | Giorgos Korfiatis | Q(state=ACCEPTED) | Q(state=PENDING)) |
1605 | 4f22664f | Georgios D. Tsoukalas | |
1606 | 425e2e95 | Sofia Papagiannaki | @property
|
1607 | 425e2e95 | Sofia Papagiannaki | def approved_members(self): |
1608 | 425e2e95 | Sofia Papagiannaki | return [m.person for m in self.approved_memberships] |
1609 | 4f22664f | Georgios D. Tsoukalas | |
1610 | ee45eb81 | Giorgos Korfiatis | def set_membership_pending_sync(self): |
1611 | ee45eb81 | Giorgos Korfiatis | ACCEPTED = ProjectMembership.ACCEPTED |
1612 | ee45eb81 | Giorgos Korfiatis | PENDING = ProjectMembership.PENDING |
1613 | ee45eb81 | Giorgos Korfiatis | sfu = self.projectmembership_set.select_for_update()
|
1614 | ee45eb81 | Giorgos Korfiatis | members = sfu.filter(Q(state=ACCEPTED) | Q(state=PENDING)) |
1615 | 4f22664f | Georgios D. Tsoukalas | |
1616 | 425e2e95 | Sofia Papagiannaki | for member in members: |
1617 | ee45eb81 | Giorgos Korfiatis | member.state = member.PENDING |
1618 | 425e2e95 | Sofia Papagiannaki | member.save() |
1619 | 4f22664f | Georgios D. Tsoukalas | |
1620 | 4f22664f | Georgios D. Tsoukalas | def add_member(self, user): |
1621 | bfe23b13 | Sofia Papagiannaki | """
|
1622 | bfe23b13 | Sofia Papagiannaki | Raises:
|
1623 | bfe23b13 | Sofia Papagiannaki | django.exceptions.PermissionDenied
|
1624 | bfe23b13 | Sofia Papagiannaki | astakos.im.models.AstakosUser.DoesNotExist
|
1625 | bfe23b13 | Sofia Papagiannaki | """
|
1626 | 2a965273 | Sofia Papagiannaki | if isinstance(user, int): |
1627 | 4f22664f | Georgios D. Tsoukalas | user = AstakosUser.objects.get(user=user) |
1628 | 4f22664f | Georgios D. Tsoukalas | |
1629 | ccab6eb5 | Sofia Papagiannaki | m, created = ProjectMembership.objects.get_or_create( |
1630 | ccab6eb5 | Sofia Papagiannaki | person=user, project=self
|
1631 | 2a965273 | Sofia Papagiannaki | ) |
1632 | 4f22664f | Georgios D. Tsoukalas | m.accept() |
1633 | ccab6eb5 | Sofia Papagiannaki | |
1634 | 4f22664f | Georgios D. Tsoukalas | def remove_member(self, user): |
1635 | bfe23b13 | Sofia Papagiannaki | """
|
1636 | bfe23b13 | Sofia Papagiannaki | Raises:
|
1637 | bfe23b13 | Sofia Papagiannaki | django.exceptions.PermissionDenied
|
1638 | bfe23b13 | Sofia Papagiannaki | astakos.im.models.AstakosUser.DoesNotExist
|
1639 | bfe23b13 | Sofia Papagiannaki | astakos.im.models.ProjectMembership.DoesNotExist
|
1640 | bfe23b13 | Sofia Papagiannaki | """
|
1641 | ccab6eb5 | Sofia Papagiannaki | if isinstance(user, int): |
1642 | 4f22664f | Georgios D. Tsoukalas | user = AstakosUser.objects.get(user=user) |
1643 | 4f22664f | Georgios D. Tsoukalas | |
1644 | bfe23b13 | Sofia Papagiannaki | m = ProjectMembership.objects.get(person=user, project=self)
|
1645 | bfe23b13 | Sofia Papagiannaki | m.remove() |
1646 | 4f22664f | Georgios D. Tsoukalas | |
1647 | b22de10a | Sofia Papagiannaki | def terminate(self): |
1648 | b22de10a | Sofia Papagiannaki | self.termination_start_date = datetime.now()
|
1649 | b22de10a | Sofia Papagiannaki | self.terminaton_date = None |
1650 | b22de10a | Sofia Papagiannaki | self.save()
|
1651 | 425e2e95 | Sofia Papagiannaki | |
1652 | b22de10a | Sofia Papagiannaki | rejected = self.sync()
|
1653 | b22de10a | Sofia Papagiannaki | if not rejected: |
1654 | b22de10a | Sofia Papagiannaki | self.termination_start_date = None |
1655 | 75fae793 | Sofia Papagiannaki | self.termination_date = datetime.now()
|
1656 | b22de10a | Sofia Papagiannaki | self.save()
|
1657 | 425e2e95 | Sofia Papagiannaki | |
1658 | 73fbaec4 | Sofia Papagiannaki | # try:
|
1659 | 73fbaec4 | Sofia Papagiannaki | # notification = build_notification(
|
1660 | 73fbaec4 | Sofia Papagiannaki | # settings.SERVER_EMAIL,
|
1661 | 974ee6a6 | Sofia Papagiannaki | # [self.application.owner.email],
|
1662 | 73fbaec4 | Sofia Papagiannaki | # _(PROJECT_TERMINATION_SUBJECT) % self.__dict__,
|
1663 | 73fbaec4 | Sofia Papagiannaki | # template='im/projects/project_termination_notification.txt',
|
1664 | 974ee6a6 | Sofia Papagiannaki | # dictionary={'object':self.application}
|
1665 | 73fbaec4 | Sofia Papagiannaki | # ).send()
|
1666 | 73fbaec4 | Sofia Papagiannaki | # except NotificationError, e:
|
1667 | f7fc5a34 | Giorgos Korfiatis | # logger.error(e.message)
|
1668 | b22de10a | Sofia Papagiannaki | |
1669 | b22de10a | Sofia Papagiannaki | def suspend(self): |
1670 | b22de10a | Sofia Papagiannaki | self.last_approval_date = None |
1671 | b22de10a | Sofia Papagiannaki | self.save()
|
1672 | c4d1b547 | Sofia Papagiannaki | self.sync()
|
1673 | b8f05f8d | Sofia Papagiannaki | |
1674 | 73fbaec4 | Sofia Papagiannaki | # try:
|
1675 | 73fbaec4 | Sofia Papagiannaki | # notification = build_notification(
|
1676 | 73fbaec4 | Sofia Papagiannaki | # settings.SERVER_EMAIL,
|
1677 | 974ee6a6 | Sofia Papagiannaki | # [self.application.owner.email],
|
1678 | 974ee6a6 | Sofia Papagiannaki | # _(PROJECT_SUSPENSION_SUBJECT) % self.__dict__,
|
1679 | 73fbaec4 | Sofia Papagiannaki | # template='im/projects/project_suspension_notification.txt',
|
1680 | 974ee6a6 | Sofia Papagiannaki | # dictionary={'object':self.application}
|
1681 | 73fbaec4 | Sofia Papagiannaki | # ).send()
|
1682 | 73fbaec4 | Sofia Papagiannaki | # except NotificationError, e:
|
1683 | f7fc5a34 | Giorgos Korfiatis | # logger.error(e.message)
|
1684 | b22de10a | Sofia Papagiannaki | |
1685 | 4f22664f | Georgios D. Tsoukalas | |
1686 | d6fdc91e | Georgios D. Tsoukalas | class ProjectMembership(models.Model): |
1687 | 4f22664f | Georgios D. Tsoukalas | |
1688 | 425e2e95 | Sofia Papagiannaki | person = models.ForeignKey(AstakosUser) |
1689 | 425e2e95 | Sofia Papagiannaki | request_date = models.DateField(default=datetime.now()) |
1690 | d6fdc91e | Georgios D. Tsoukalas | project = models.ForeignKey(Project) |
1691 | d6fdc91e | Georgios D. Tsoukalas | |
1692 | d6fdc91e | Georgios D. Tsoukalas | state = models.IntegerField(default=0)
|
1693 | 5200e864 | Sofia Papagiannaki | application = models.ForeignKey( |
1694 | 5200e864 | Sofia Papagiannaki | ProjectApplication, |
1695 | 5200e864 | Sofia Papagiannaki | null=True,
|
1696 | 5200e864 | Sofia Papagiannaki | related_name='memberships')
|
1697 | 5200e864 | Sofia Papagiannaki | pending_application = models.ForeignKey( |
1698 | 5200e864 | Sofia Papagiannaki | ProjectApplication, |
1699 | 5200e864 | Sofia Papagiannaki | null=True,
|
1700 | 5200e864 | Sofia Papagiannaki | related_name='pending_memebrships')
|
1701 | d6fdc91e | Georgios D. Tsoukalas | pending_serial = models.BigIntegerField(null=True, db_index=True) |
1702 | 425e2e95 | Sofia Papagiannaki | |
1703 | 425e2e95 | Sofia Papagiannaki | acceptance_date = models.DateField(null=True, db_index=True) |
1704 | 425e2e95 | Sofia Papagiannaki | leave_request_date = models.DateField(null=True)
|
1705 | 2a965273 | Sofia Papagiannaki | |
1706 | ee45eb81 | Giorgos Korfiatis | objects = ForUpdateManager() |
1707 | ee45eb81 | Giorgos Korfiatis | |
1708 | 65360c65 | Georgios D. Tsoukalas | REQUESTED = 0
|
1709 | d6fdc91e | Georgios D. Tsoukalas | PENDING = 1
|
1710 | d6fdc91e | Georgios D. Tsoukalas | ACCEPTED = 2
|
1711 | d6fdc91e | Georgios D. Tsoukalas | REMOVING = 3
|
1712 | d6fdc91e | Georgios D. Tsoukalas | REMOVED = 4
|
1713 | 65360c65 | Georgios D. Tsoukalas | |
1714 | 0cc22d47 | Sofia Papagiannaki | class Meta: |
1715 | 0cc22d47 | Sofia Papagiannaki | unique_together = ("person", "project") |
1716 | d6fdc91e | Georgios D. Tsoukalas | #index_together = [["project", "state"]]
|
1717 | bfe23b13 | Sofia Papagiannaki | |
1718 | 65360c65 | Georgios D. Tsoukalas | def __str__(self): |
1719 | 65360c65 | Georgios D. Tsoukalas | return _("<'%s' membership in project '%s'>") % ( |
1720 | 65360c65 | Georgios D. Tsoukalas | self.person.username, self.project.application) |
1721 | 65360c65 | Georgios D. Tsoukalas | |
1722 | 65360c65 | Georgios D. Tsoukalas | __repr__ = __str__ |
1723 | 65360c65 | Georgios D. Tsoukalas | |
1724 | 65360c65 | Georgios D. Tsoukalas | def __init__(self, *args, **kwargs): |
1725 | ee45eb81 | Giorgos Korfiatis | self.state = self.REQUESTED |
1726 | 65360c65 | Georgios D. Tsoukalas | super(ProjectMembership, self).__init__(*args, **kwargs) |
1727 | 65360c65 | Georgios D. Tsoukalas | |
1728 | 4f22664f | Georgios D. Tsoukalas | def _set_history_item(self, reason, date=None): |
1729 | 4f22664f | Georgios D. Tsoukalas | if isinstance(reason, basestring): |
1730 | 4f22664f | Georgios D. Tsoukalas | reason = ProjectMembershipHistory.reasons.get(reason, -1)
|
1731 | 4f22664f | Georgios D. Tsoukalas | |
1732 | 4f22664f | Georgios D. Tsoukalas | history_item = ProjectMembershipHistory( |
1733 | 4f22664f | Georgios D. Tsoukalas | serial=self.id,
|
1734 | 4f22664f | Georgios D. Tsoukalas | person=self.person,
|
1735 | 4f22664f | Georgios D. Tsoukalas | project=self.project,
|
1736 | 8f975b72 | Sofia Papagiannaki | date=date or datetime.now(),
|
1737 | 4f22664f | Georgios D. Tsoukalas | reason=reason) |
1738 | 4f22664f | Georgios D. Tsoukalas | history_item.save() |
1739 | 4f22664f | Georgios D. Tsoukalas | serial = history_item.id |
1740 | 4f22664f | Georgios D. Tsoukalas | |
1741 | 4f22664f | Georgios D. Tsoukalas | def accept(self): |
1742 | 5200e864 | Sofia Papagiannaki | state = self.state
|
1743 | 65360c65 | Georgios D. Tsoukalas | if state != self.REQUESTED: |
1744 | d6fdc91e | Georgios D. Tsoukalas | m = _("%s: attempt to accept in state [%s]") % (self, state) |
1745 | 65360c65 | Georgios D. Tsoukalas | raise AssertionError(m) |
1746 | 4f22664f | Georgios D. Tsoukalas | |
1747 | 65360c65 | Georgios D. Tsoukalas | now = datetime.now() |
1748 | 65360c65 | Georgios D. Tsoukalas | self.acceptance_date = now
|
1749 | 65360c65 | Georgios D. Tsoukalas | self._set_history_item(reason='ACCEPT', date=now) |
1750 | d6fdc91e | Georgios D. Tsoukalas | self.state = self.PENDING |
1751 | 65360c65 | Georgios D. Tsoukalas | self.save()
|
1752 | 4f22664f | Georgios D. Tsoukalas | |
1753 | 65360c65 | Georgios D. Tsoukalas | def remove(self): |
1754 | 974ee6a6 | Sofia Papagiannaki | state = self.state
|
1755 | 65360c65 | Georgios D. Tsoukalas | if state != self.ACCEPTED: |
1756 | 65360c65 | Georgios D. Tsoukalas | m = _("%s: attempt to remove in state '%s'") % (self, state) |
1757 | 65360c65 | Georgios D. Tsoukalas | raise AssertionError(m) |
1758 | 4f22664f | Georgios D. Tsoukalas | |
1759 | ee45eb81 | Giorgos Korfiatis | self._set_history_item(reason='REMOVE') |
1760 | d6fdc91e | Georgios D. Tsoukalas | self.state = self.REMOVING |
1761 | 0cc22d47 | Sofia Papagiannaki | self.save()
|
1762 | b8f05f8d | Sofia Papagiannaki | |
1763 | 65360c65 | Georgios D. Tsoukalas | def reject(self): |
1764 | 974ee6a6 | Sofia Papagiannaki | state = self.state
|
1765 | 65360c65 | Georgios D. Tsoukalas | if state != self.REQUESTED: |
1766 | 65360c65 | Georgios D. Tsoukalas | m = _("%s: attempt to remove in state '%s'") % (self, state) |
1767 | 65360c65 | Georgios D. Tsoukalas | raise AssertionError(m) |
1768 | 65360c65 | Georgios D. Tsoukalas | |
1769 | 65360c65 | Georgios D. Tsoukalas | # rejected requests don't need sync,
|
1770 | 65360c65 | Georgios D. Tsoukalas | # because they were never effected
|
1771 | 65360c65 | Georgios D. Tsoukalas | self._set_history_item(reason='REJECT') |
1772 | 0cc22d47 | Sofia Papagiannaki | self.delete()
|
1773 | b8f05f8d | Sofia Papagiannaki | |
1774 | d2b32360 | Giorgos Korfiatis | def get_diff_quotas(self, sub_list=None, add_list=None, remove=False): |
1775 | d2b32360 | Giorgos Korfiatis | if sub_list is None: |
1776 | d2b32360 | Giorgos Korfiatis | sub_list = [] |
1777 | d2b32360 | Giorgos Korfiatis | |
1778 | d2b32360 | Giorgos Korfiatis | if add_list is None: |
1779 | d2b32360 | Giorgos Korfiatis | add_list = [] |
1780 | d6fdc91e | Georgios D. Tsoukalas | |
1781 | d2b32360 | Giorgos Korfiatis | sub_append = sub_list.append |
1782 | d2b32360 | Giorgos Korfiatis | add_append = add_list.append |
1783 | d75c432e | Sofia Papagiannaki | holder = self.person.uuid
|
1784 | d6fdc91e | Georgios D. Tsoukalas | |
1785 | d6fdc91e | Georgios D. Tsoukalas | synced_application = self.application
|
1786 | d6fdc91e | Georgios D. Tsoukalas | if synced_application is not None: |
1787 | 5f2e4042 | Sofia Papagiannaki | cur_grants = synced_application.projectresourcegrant_set.all() |
1788 | d6fdc91e | Georgios D. Tsoukalas | for grant in cur_grants: |
1789 | d2b32360 | Giorgos Korfiatis | sub_append(QuotaLimits( |
1790 | d2b32360 | Giorgos Korfiatis | holder = holder, |
1791 | f3e93707 | Sofia Papagiannaki | resource = str(grant.resource),
|
1792 | d2b32360 | Giorgos Korfiatis | capacity = grant.member_capacity, |
1793 | d2b32360 | Giorgos Korfiatis | import_limit = grant.member_import_limit, |
1794 | d2b32360 | Giorgos Korfiatis | export_limit = grant.member_export_limit)) |
1795 | d6fdc91e | Georgios D. Tsoukalas | |
1796 | d6fdc91e | Georgios D. Tsoukalas | if not remove: |
1797 | ce80d7ae | Sofia Papagiannaki | new_grants = self.pending_application.projectresourcegrant_set.all()
|
1798 | d6fdc91e | Georgios D. Tsoukalas | for new_grant in new_grants: |
1799 | d2b32360 | Giorgos Korfiatis | add_append(QuotaLimits( |
1800 | d2b32360 | Giorgos Korfiatis | holder = holder, |
1801 | f3e93707 | Sofia Papagiannaki | resource = str(new_grant.resource),
|
1802 | 974ee6a6 | Sofia Papagiannaki | capacity = new_grant.member_capacity, |
1803 | 974ee6a6 | Sofia Papagiannaki | import_limit = new_grant.member_import_limit, |
1804 | 974ee6a6 | Sofia Papagiannaki | export_limit = new_grant.member_export_limit)) |
1805 | d6fdc91e | Georgios D. Tsoukalas | |
1806 | d2b32360 | Giorgos Korfiatis | return (sub_list, add_list)
|
1807 | 65360c65 | Georgios D. Tsoukalas | |
1808 | ee45eb81 | Giorgos Korfiatis | def set_sync(self): |
1809 | ee45eb81 | Giorgos Korfiatis | state = self.state
|
1810 | ee45eb81 | Giorgos Korfiatis | if state == self.PENDING: |
1811 | ee45eb81 | Giorgos Korfiatis | pending_application = self.pending_application
|
1812 | ee45eb81 | Giorgos Korfiatis | if pending_application is None: |
1813 | ee45eb81 | Giorgos Korfiatis | m = _("%s: attempt to sync an empty pending application") % (
|
1814 | ee45eb81 | Giorgos Korfiatis | self, state)
|
1815 | ee45eb81 | Giorgos Korfiatis | raise AssertionError(m) |
1816 | ee45eb81 | Giorgos Korfiatis | self.application = pending_application
|
1817 | ee45eb81 | Giorgos Korfiatis | self.pending_application = None |
1818 | ee45eb81 | Giorgos Korfiatis | self.pending_serial = None |
1819 | ee45eb81 | Giorgos Korfiatis | |
1820 | ee45eb81 | Giorgos Korfiatis | # project.application may have changed in the meantime,
|
1821 | ee45eb81 | Giorgos Korfiatis | # in which case we stay PENDING;
|
1822 | ee45eb81 | Giorgos Korfiatis | # we are safe to check due to select_for_update
|
1823 | ee45eb81 | Giorgos Korfiatis | if self.application == self.project.application: |
1824 | ee45eb81 | Giorgos Korfiatis | self.state = self.ACCEPTED |
1825 | ee45eb81 | Giorgos Korfiatis | self.save()
|
1826 | ee45eb81 | Giorgos Korfiatis | elif state == self.REMOVING: |
1827 | ee45eb81 | Giorgos Korfiatis | self.delete()
|
1828 | ee45eb81 | Giorgos Korfiatis | else:
|
1829 | ee45eb81 | Giorgos Korfiatis | m = _("%s: attempt to sync in state '%s'") % (self, state) |
1830 | ee45eb81 | Giorgos Korfiatis | raise AssertionError(m) |
1831 | ee45eb81 | Giorgos Korfiatis | |
1832 | 49b74233 | Georgios D. Tsoukalas | def reset_sync(self): |
1833 | 49b74233 | Georgios D. Tsoukalas | state = self.state
|
1834 | 49b74233 | Georgios D. Tsoukalas | if state in [self.PENDING, self.REMOVING]: |
1835 | 49b74233 | Georgios D. Tsoukalas | self.pending_application = None |
1836 | 49b74233 | Georgios D. Tsoukalas | self.pending_serial = None |
1837 | 49b74233 | Georgios D. Tsoukalas | self.save()
|
1838 | 49b74233 | Georgios D. Tsoukalas | else:
|
1839 | 49b74233 | Georgios D. Tsoukalas | m = _("%s: attempt to reset sync in state '%s'") % (self, state) |
1840 | 49b74233 | Georgios D. Tsoukalas | raise AssertionError(m) |
1841 | 49b74233 | Georgios D. Tsoukalas | |
1842 | ee45eb81 | Giorgos Korfiatis | class Serial(models.Model): |
1843 | ee45eb81 | Giorgos Korfiatis | serial = models.AutoField(primary_key=True)
|
1844 | ee45eb81 | Giorgos Korfiatis | |
1845 | ee45eb81 | Giorgos Korfiatis | def new_serial(): |
1846 | 5200e864 | Sofia Papagiannaki | s = Serial.objects.create() |
1847 | c70968bd | Giorgos Korfiatis | serial = s.serial |
1848 | c70968bd | Giorgos Korfiatis | s.delete() |
1849 | c70968bd | Giorgos Korfiatis | return serial
|
1850 | 82d7e9ef | Georgios D. Tsoukalas | |
1851 | 333f6a72 | Sofia Papagiannaki | def sync_finish_serials(serials_to_ack=None): |
1852 | 333f6a72 | Sofia Papagiannaki | if serials_to_ack is None: |
1853 | 333f6a72 | Sofia Papagiannaki | serials_to_ack = qh_query_serials([]) |
1854 | 333f6a72 | Sofia Papagiannaki | |
1855 | 333f6a72 | Sofia Papagiannaki | serials_to_ack = set(serials_to_ack)
|
1856 | d6fdc91e | Georgios D. Tsoukalas | sfu = ProjectMembership.objects.select_for_update() |
1857 | 333f6a72 | Sofia Papagiannaki | memberships = list(sfu.filter(pending_serial__isnull=False)) |
1858 | 333f6a72 | Sofia Papagiannaki | |
1859 | 60ca2f6f | Giorgos Korfiatis | if memberships:
|
1860 | 60ca2f6f | Giorgos Korfiatis | for membership in memberships: |
1861 | 60ca2f6f | Giorgos Korfiatis | serial = membership.pending_serial |
1862 | 60ca2f6f | Giorgos Korfiatis | # just make sure the project row is selected for update
|
1863 | 60ca2f6f | Giorgos Korfiatis | project = membership.project |
1864 | 60ca2f6f | Giorgos Korfiatis | if serial in serials_to_ack: |
1865 | 60ca2f6f | Giorgos Korfiatis | membership.set_sync() |
1866 | 60ca2f6f | Giorgos Korfiatis | else:
|
1867 | 60ca2f6f | Giorgos Korfiatis | membership.reset_sync() |
1868 | 60ca2f6f | Giorgos Korfiatis | |
1869 | 60ca2f6f | Giorgos Korfiatis | transaction.commit() |
1870 | 60ca2f6f | Giorgos Korfiatis | |
1871 | ee45eb81 | Giorgos Korfiatis | qh_ack_serials(list(serials_to_ack))
|
1872 | 333f6a72 | Sofia Papagiannaki | return len(memberships) |
1873 | 82d7e9ef | Georgios D. Tsoukalas | |
1874 | d6fdc91e | Georgios D. Tsoukalas | def sync_projects(): |
1875 | d6fdc91e | Georgios D. Tsoukalas | sync_finish_serials() |
1876 | 82d7e9ef | Georgios D. Tsoukalas | |
1877 | d6fdc91e | Georgios D. Tsoukalas | PENDING = ProjectMembership.PENDING |
1878 | d6fdc91e | Georgios D. Tsoukalas | REMOVING = ProjectMembership.REMOVING |
1879 | d6fdc91e | Georgios D. Tsoukalas | objects = ProjectMembership.objects.select_for_update() |
1880 | 82d7e9ef | Georgios D. Tsoukalas | |
1881 | d2b32360 | Giorgos Korfiatis | sub_quota, add_quota = [], [] |
1882 | 65360c65 | Georgios D. Tsoukalas | |
1883 | ee45eb81 | Giorgos Korfiatis | serial = new_serial() |
1884 | d6fdc91e | Georgios D. Tsoukalas | |
1885 | d6fdc91e | Georgios D. Tsoukalas | pending = objects.filter(state=PENDING) |
1886 | d6fdc91e | Georgios D. Tsoukalas | for membership in pending: |
1887 | d6fdc91e | Georgios D. Tsoukalas | |
1888 | d6fdc91e | Georgios D. Tsoukalas | if membership.pending_application:
|
1889 | d6fdc91e | Georgios D. Tsoukalas | m = "%s: impossible: pending_application is not None (%s)" % (
|
1890 | d6fdc91e | Georgios D. Tsoukalas | membership, membership.pending_application) |
1891 | d6fdc91e | Georgios D. Tsoukalas | raise AssertionError(m) |
1892 | d6fdc91e | Georgios D. Tsoukalas | if membership.pending_serial:
|
1893 | d6fdc91e | Georgios D. Tsoukalas | m = "%s: impossible: pending_serial is not None (%s)" % (
|
1894 | d6fdc91e | Georgios D. Tsoukalas | membership, membership.pending_serial) |
1895 | 65360c65 | Georgios D. Tsoukalas | raise AssertionError(m) |
1896 | b8f05f8d | Sofia Papagiannaki | |
1897 | ee45eb81 | Giorgos Korfiatis | membership.pending_application = membership.project.application |
1898 | d6fdc91e | Georgios D. Tsoukalas | membership.pending_serial = serial |
1899 | d2b32360 | Giorgos Korfiatis | membership.get_diff_quotas(sub_quota, add_quota) |
1900 | d6fdc91e | Georgios D. Tsoukalas | membership.save() |
1901 | 65360c65 | Georgios D. Tsoukalas | |
1902 | d6fdc91e | Georgios D. Tsoukalas | removing = objects.filter(state=REMOVING) |
1903 | d6fdc91e | Georgios D. Tsoukalas | for membership in removing: |
1904 | bfe23b13 | Sofia Papagiannaki | |
1905 | d6fdc91e | Georgios D. Tsoukalas | if membership.pending_application:
|
1906 | d6fdc91e | Georgios D. Tsoukalas | m = ("%s: impossible: removing pending_application is not None (%s)"
|
1907 | d6fdc91e | Georgios D. Tsoukalas | % (membership, membership.pending_application)) |
1908 | d6fdc91e | Georgios D. Tsoukalas | raise AssertionError(m) |
1909 | d6fdc91e | Georgios D. Tsoukalas | if membership.pending_serial:
|
1910 | d6fdc91e | Georgios D. Tsoukalas | m = "%s: impossible: pending_serial is not None (%s)" % (
|
1911 | d6fdc91e | Georgios D. Tsoukalas | membership, membership.pending_serial) |
1912 | d6fdc91e | Georgios D. Tsoukalas | raise AssertionError(m) |
1913 | d6fdc91e | Georgios D. Tsoukalas | |
1914 | d6fdc91e | Georgios D. Tsoukalas | membership.pending_serial = serial |
1915 | d2b32360 | Giorgos Korfiatis | membership.get_diff_quotas(sub_quota, add_quota, remove=True)
|
1916 | d6fdc91e | Georgios D. Tsoukalas | membership.save() |
1917 | d6fdc91e | Georgios D. Tsoukalas | |
1918 | d6fdc91e | Georgios D. Tsoukalas | transaction.commit() |
1919 | ee45eb81 | Giorgos Korfiatis | # ProjectApplication.approve() unblocks here
|
1920 | ee45eb81 | Giorgos Korfiatis | # and can set PENDING an already PENDING membership
|
1921 | ee45eb81 | Giorgos Korfiatis | # which has been scheduled to sync with the old project.application
|
1922 | ee45eb81 | Giorgos Korfiatis | # Need to check in ProjectMembership.set_sync()
|
1923 | ee45eb81 | Giorgos Korfiatis | |
1924 | 5cfd4acb | Sofia Papagiannaki | r = qh_add_quota(serial, sub_quota, add_quota) |
1925 | 333f6a72 | Sofia Papagiannaki | if r:
|
1926 | 333f6a72 | Sofia Papagiannaki | m = "cannot sync serial: %d" % serial
|
1927 | 333f6a72 | Sofia Papagiannaki | raise RuntimeError(m) |
1928 | 333f6a72 | Sofia Papagiannaki | |
1929 | 333f6a72 | Sofia Papagiannaki | sync_finish_serials([serial]) |
1930 | d6fdc91e | Georgios D. Tsoukalas | |
1931 | d6fdc91e | Georgios D. Tsoukalas | |
1932 | d6fdc91e | Georgios D. Tsoukalas | def trigger_sync(retries=3, retry_wait=1.0): |
1933 | d6fdc91e | Georgios D. Tsoukalas | cursor = connection.cursor() |
1934 | d6fdc91e | Georgios D. Tsoukalas | locked = True
|
1935 | d6fdc91e | Georgios D. Tsoukalas | try:
|
1936 | d6fdc91e | Georgios D. Tsoukalas | while 1: |
1937 | d6fdc91e | Georgios D. Tsoukalas | cursor.execute("SELECT pg_try_advisory_lock(1)")
|
1938 | d6fdc91e | Georgios D. Tsoukalas | r = cursor.fetchone() |
1939 | d6fdc91e | Georgios D. Tsoukalas | if r is None: |
1940 | d6fdc91e | Georgios D. Tsoukalas | m = "Impossible"
|
1941 | d6fdc91e | Georgios D. Tsoukalas | raise AssertionError(m) |
1942 | d6fdc91e | Georgios D. Tsoukalas | locked = r[0]
|
1943 | d6fdc91e | Georgios D. Tsoukalas | if locked:
|
1944 | d6fdc91e | Georgios D. Tsoukalas | break
|
1945 | d6fdc91e | Georgios D. Tsoukalas | |
1946 | d6fdc91e | Georgios D. Tsoukalas | retries -= 1
|
1947 | d6fdc91e | Georgios D. Tsoukalas | if retries <= 0: |
1948 | d6fdc91e | Georgios D. Tsoukalas | return False |
1949 | d6fdc91e | Georgios D. Tsoukalas | sleep(retry_wait) |
1950 | d6fdc91e | Georgios D. Tsoukalas | |
1951 | 4b451adb | Giorgos Korfiatis | transaction.commit() |
1952 | d6fdc91e | Georgios D. Tsoukalas | sync_projects() |
1953 | d6fdc91e | Georgios D. Tsoukalas | return True |
1954 | d6fdc91e | Georgios D. Tsoukalas | |
1955 | d6fdc91e | Georgios D. Tsoukalas | finally:
|
1956 | d6fdc91e | Georgios D. Tsoukalas | if locked:
|
1957 | d6fdc91e | Georgios D. Tsoukalas | cursor.execute("SELECT pg_advisory_unlock(1)")
|
1958 | d6fdc91e | Georgios D. Tsoukalas | cursor.fetchall() |
1959 | 4f22664f | Georgios D. Tsoukalas | |
1960 | e1a80257 | Sofia Papagiannaki | |
1961 | 0cc22d47 | Sofia Papagiannaki | class ProjectMembershipHistory(models.Model): |
1962 | 425e2e95 | Sofia Papagiannaki | reasons_list = ['ACCEPT', 'REJECT', 'REMOVE'] |
1963 | 425e2e95 | Sofia Papagiannaki | reasons = dict((k, v) for v, k in enumerate(reasons_list)) |
1964 | 425e2e95 | Sofia Papagiannaki | |
1965 | 425e2e95 | Sofia Papagiannaki | person = models.ForeignKey(AstakosUser) |
1966 | 425e2e95 | Sofia Papagiannaki | project = models.ForeignKey(Project) |
1967 | 425e2e95 | Sofia Papagiannaki | date = models.DateField(default=datetime.now) |
1968 | 425e2e95 | Sofia Papagiannaki | reason = models.IntegerField() |
1969 | 425e2e95 | Sofia Papagiannaki | serial = models.BigIntegerField() |
1970 | fc655b6f | Kostas Papadimitriou | |
1971 | 0cc22d47 | Sofia Papagiannaki | |
1972 | e1a80257 | Sofia Papagiannaki | def filter_queryset_by_property(q, property): |
1973 | e1a80257 | Sofia Papagiannaki | """
|
1974 | e1a80257 | Sofia Papagiannaki | Incorporate list comprehension for filtering querysets by property
|
1975 | e1a80257 | Sofia Papagiannaki | since Queryset.filter() operates on the database level.
|
1976 | e1a80257 | Sofia Papagiannaki | """
|
1977 | e1a80257 | Sofia Papagiannaki | return (p for p in q if getattr(p, property, False)) |
1978 | e1a80257 | Sofia Papagiannaki | |
1979 | e1a80257 | Sofia Papagiannaki | def get_alive_projects(): |
1980 | e1a80257 | Sofia Papagiannaki | return filter_queryset_by_property(
|
1981 | e1a80257 | Sofia Papagiannaki | Project.objects.all(), |
1982 | e1a80257 | Sofia Papagiannaki | 'is_alive'
|
1983 | e1a80257 | Sofia Papagiannaki | ) |
1984 | e1a80257 | Sofia Papagiannaki | |
1985 | e1a80257 | Sofia Papagiannaki | def get_active_projects(): |
1986 | e1a80257 | Sofia Papagiannaki | return filter_queryset_by_property(
|
1987 | e1a80257 | Sofia Papagiannaki | Project.objects.all(), |
1988 | e1a80257 | Sofia Papagiannaki | 'is_active'
|
1989 | e1a80257 | Sofia Papagiannaki | ) |
1990 | e1a80257 | Sofia Papagiannaki | |
1991 | e1a80257 | Sofia Papagiannaki | def _create_object(model, **kwargs): |
1992 | e1a80257 | Sofia Papagiannaki | o = model.objects.create(**kwargs) |
1993 | e1a80257 | Sofia Papagiannaki | o.save() |
1994 | e1a80257 | Sofia Papagiannaki | return o
|
1995 | e1a80257 | Sofia Papagiannaki | |
1996 | b22de10a | Sofia Papagiannaki | |
1997 | ff9290ec | Sofia Papagiannaki | def create_astakos_user(u): |
1998 | ff9290ec | Sofia Papagiannaki | try:
|
1999 | ff9290ec | Sofia Papagiannaki | AstakosUser.objects.get(user_ptr=u.pk) |
2000 | ff9290ec | Sofia Papagiannaki | except AstakosUser.DoesNotExist:
|
2001 | ff9290ec | Sofia Papagiannaki | extended_user = AstakosUser(user_ptr_id=u.pk) |
2002 | ff9290ec | Sofia Papagiannaki | extended_user.__dict__.update(u.__dict__) |
2003 | ff9290ec | Sofia Papagiannaki | extended_user.save() |
2004 | 67be1883 | Olga Brani | if not extended_user.has_auth_provider('local'): |
2005 | 67be1883 | Olga Brani | extended_user.add_auth_provider('local')
|
2006 | fc1e2f02 | Sofia Papagiannaki | except BaseException, e: |
2007 | fc1e2f02 | Sofia Papagiannaki | logger.exception(e) |
2008 | ff9290ec | Sofia Papagiannaki | |
2009 | 5ce3ce4f | Sofia Papagiannaki | |
2010 | fc1e2f02 | Sofia Papagiannaki | def fix_superusers(sender, **kwargs): |
2011 | fc1e2f02 | Sofia Papagiannaki | # Associate superusers with AstakosUser
|
2012 | ff9290ec | Sofia Papagiannaki | admins = User.objects.filter(is_superuser=True)
|
2013 | ff9290ec | Sofia Papagiannaki | for u in admins: |
2014 | ff9290ec | Sofia Papagiannaki | create_astakos_user(u) |
2015 | bfe23b13 | Sofia Papagiannaki | post_syncdb.connect(fix_superusers) |
2016 | ff9290ec | Sofia Papagiannaki | |
2017 | ff9290ec | Sofia Papagiannaki | |
2018 | fc1e2f02 | Sofia Papagiannaki | def user_post_save(sender, instance, created, **kwargs): |
2019 | aa4109d4 | Sofia Papagiannaki | if not created: |
2020 | aa4109d4 | Sofia Papagiannaki | return
|
2021 | fc1e2f02 | Sofia Papagiannaki | create_astakos_user(instance) |
2022 | bfe23b13 | Sofia Papagiannaki | post_save.connect(user_post_save, sender=User) |
2023 | ff9290ec | Sofia Papagiannaki | |
2024 | bf0c6de5 | Sofia Papagiannaki | |
2025 | 73fbaec4 | Sofia Papagiannaki | # def astakosuser_pre_save(sender, instance, **kwargs):
|
2026 | 73fbaec4 | Sofia Papagiannaki | # instance.aquarium_report = False
|
2027 | 73fbaec4 | Sofia Papagiannaki | # instance.new = False
|
2028 | 73fbaec4 | Sofia Papagiannaki | # try:
|
2029 | 73fbaec4 | Sofia Papagiannaki | # db_instance = AstakosUser.objects.get(id=instance.id)
|
2030 | 73fbaec4 | Sofia Papagiannaki | # except AstakosUser.DoesNotExist:
|
2031 | 73fbaec4 | Sofia Papagiannaki | # # create event
|
2032 | 73fbaec4 | Sofia Papagiannaki | # instance.aquarium_report = True
|
2033 | 73fbaec4 | Sofia Papagiannaki | # instance.new = True
|
2034 | 73fbaec4 | Sofia Papagiannaki | # else:
|
2035 | 73fbaec4 | Sofia Papagiannaki | # get = AstakosUser.__getattribute__
|
2036 | 73fbaec4 | Sofia Papagiannaki | # l = filter(lambda f: get(db_instance, f) != get(instance, f),
|
2037 | 73fbaec4 | Sofia Papagiannaki | # BILLING_FIELDS)
|
2038 | 73fbaec4 | Sofia Papagiannaki | # instance.aquarium_report = True if l else False
|
2039 | 73fbaec4 | Sofia Papagiannaki | # pre_save.connect(astakosuser_pre_save, sender=AstakosUser)
|
2040 | 73fbaec4 | Sofia Papagiannaki | |
2041 | 73fbaec4 | Sofia Papagiannaki | # def set_default_group(user):
|
2042 | 73fbaec4 | Sofia Papagiannaki | # try:
|
2043 | 73fbaec4 | Sofia Papagiannaki | # default = AstakosGroup.objects.get(name='default')
|
2044 | 73fbaec4 | Sofia Papagiannaki | # Membership(
|
2045 | 73fbaec4 | Sofia Papagiannaki | # group=default, person=user, date_joined=datetime.now()).save()
|
2046 | 73fbaec4 | Sofia Papagiannaki | # except AstakosGroup.DoesNotExist, e:
|
2047 | 73fbaec4 | Sofia Papagiannaki | # logger.exception(e)
|
2048 | fc1e2f02 | Sofia Papagiannaki | |
2049 | 5ce3ce4f | Sofia Papagiannaki | |
2050 | fc1e2f02 | Sofia Papagiannaki | def astakosuser_post_save(sender, instance, created, **kwargs): |
2051 | 73fbaec4 | Sofia Papagiannaki | # if instance.aquarium_report:
|
2052 | 73fbaec4 | Sofia Papagiannaki | # report_user_event(instance, create=instance.new)
|
2053 | fc1e2f02 | Sofia Papagiannaki | if not created: |
2054 | fc1e2f02 | Sofia Papagiannaki | return
|
2055 | 73fbaec4 | Sofia Papagiannaki | # set_default_group(instance)
|
2056 | fc1e2f02 | Sofia Papagiannaki | # TODO handle socket.error & IOError
|
2057 | fc1e2f02 | Sofia Papagiannaki | register_users((instance,)) |
2058 | bfe23b13 | Sofia Papagiannaki | post_save.connect(astakosuser_post_save, sender=AstakosUser) |
2059 | fc1e2f02 | Sofia Papagiannaki | |
2060 | 5ce3ce4f | Sofia Papagiannaki | |
2061 | bd4f356c | Sofia Papagiannaki | def resource_post_save(sender, instance, created, **kwargs): |
2062 | bd4f356c | Sofia Papagiannaki | if not created: |
2063 | bd4f356c | Sofia Papagiannaki | return
|
2064 | bd4f356c | Sofia Papagiannaki | register_resources((instance,)) |
2065 | bfe23b13 | Sofia Papagiannaki | post_save.connect(resource_post_save, sender=Resource) |
2066 | bfe23b13 | Sofia Papagiannaki | |
2067 | bfe23b13 | Sofia Papagiannaki | |
2068 | 73fbaec4 | Sofia Papagiannaki | # def on_quota_disturbed(sender, users, **kwargs):
|
2069 | 73fbaec4 | Sofia Papagiannaki | # # print '>>>', locals()
|
2070 | 73fbaec4 | Sofia Papagiannaki | # if not users:
|
2071 | 73fbaec4 | Sofia Papagiannaki | # return
|
2072 | 73fbaec4 | Sofia Papagiannaki | # send_quota(users)
|
2073 | 425e2e95 | Sofia Papagiannaki | #
|
2074 | 73fbaec4 | Sofia Papagiannaki | # quota_disturbed = Signal(providing_args=["users"])
|
2075 | 73fbaec4 | Sofia Papagiannaki | # quota_disturbed.connect(on_quota_disturbed)
|
2076 | 73fbaec4 | Sofia Papagiannaki | |
2077 | 73fbaec4 | Sofia Papagiannaki | |
2078 | 73fbaec4 | Sofia Papagiannaki | # def send_quota_disturbed(sender, instance, **kwargs):
|
2079 | 73fbaec4 | Sofia Papagiannaki | # users = []
|
2080 | 73fbaec4 | Sofia Papagiannaki | # extend = users.extend
|
2081 | 73fbaec4 | Sofia Papagiannaki | # if sender == Membership:
|
2082 | 73fbaec4 | Sofia Papagiannaki | # if not instance.group.is_enabled:
|
2083 | 73fbaec4 | Sofia Papagiannaki | # return
|
2084 | 73fbaec4 | Sofia Papagiannaki | # extend([instance.person])
|
2085 | 73fbaec4 | Sofia Papagiannaki | # elif sender == AstakosUserQuota:
|
2086 | 73fbaec4 | Sofia Papagiannaki | # extend([instance.user])
|
2087 | 73fbaec4 | Sofia Papagiannaki | # elif sender == AstakosGroupQuota:
|
2088 | 73fbaec4 | Sofia Papagiannaki | # if not instance.group.is_enabled:
|
2089 | 73fbaec4 | Sofia Papagiannaki | # return
|
2090 | 73fbaec4 | Sofia Papagiannaki | # extend(instance.group.astakosuser_set.all())
|
2091 | 73fbaec4 | Sofia Papagiannaki | # elif sender == AstakosGroup:
|
2092 | 73fbaec4 | Sofia Papagiannaki | # if not instance.is_enabled:
|
2093 | 73fbaec4 | Sofia Papagiannaki | # return
|
2094 | 73fbaec4 | Sofia Papagiannaki | # quota_disturbed.send(sender=sender, users=users)
|
2095 | 73fbaec4 | Sofia Papagiannaki | # post_delete.connect(send_quota_disturbed, sender=AstakosGroup)
|
2096 | 73fbaec4 | Sofia Papagiannaki | # post_delete.connect(send_quota_disturbed, sender=Membership)
|
2097 | 73fbaec4 | Sofia Papagiannaki | # post_save.connect(send_quota_disturbed, sender=AstakosUserQuota)
|
2098 | 73fbaec4 | Sofia Papagiannaki | # post_delete.connect(send_quota_disturbed, sender=AstakosUserQuota)
|
2099 | 73fbaec4 | Sofia Papagiannaki | # post_save.connect(send_quota_disturbed, sender=AstakosGroupQuota)
|
2100 | 73fbaec4 | Sofia Papagiannaki | # post_delete.connect(send_quota_disturbed, sender=AstakosGroupQuota)
|
2101 | c0b26605 | Sofia Papagiannaki | |
2102 | bfe23b13 | Sofia Papagiannaki | |
2103 | bfe23b13 | Sofia Papagiannaki | def renew_token(sender, instance, **kwargs): |
2104 | bfe23b13 | Sofia Papagiannaki | if not instance.auth_token: |
2105 | bfe23b13 | Sofia Papagiannaki | instance.renew_token() |
2106 | bf0c6de5 | Sofia Papagiannaki | pre_save.connect(renew_token, sender=AstakosUser) |
2107 | 2e90e3ec | Kostas Papadimitriou | pre_save.connect(renew_token, sender=Service) |