forked from benadida/helios-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodels.py
174 lines (127 loc) · 4.8 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
"""
Data Objects for user authentication
GAE
Ben Adida
"""
from django.db import models
from auth_systems import AUTH_SYSTEMS
from jsonfield import JSONField
# an exception to catch when a user is no longer authenticated
class AuthenticationExpired(Exception):
pass
class User(models.Model):
user_type = models.CharField(max_length=50)
user_id = models.CharField(max_length=100)
name = models.CharField(max_length=200, null=True)
# other properties
info = JSONField()
# access token information
token = JSONField(null = True)
# administrator
admin_p = models.BooleanField(default=False)
class Meta:
unique_together = (('user_type', 'user_id'),)
app_label = 'helios_auth'
@classmethod
def _get_type_and_id(cls, user_type, user_id):
return "%s:%s" % (user_type, user_id)
@property
def type_and_id(self):
return self._get_type_and_id(self.user_type, self.user_id)
@classmethod
def get_by_type_and_id(cls, user_type, user_id):
return cls.objects.get(user_type = user_type, user_id = user_id)
@classmethod
def update_or_create(cls, user_type, user_id, name=None, info=None, token=None):
obj, created_p = cls.objects.get_or_create(user_type = user_type, user_id = user_id, defaults = {'name': name, 'info':info, 'token':token})
if not created_p:
# special case the password: don't replace it if it exists
if obj.info.has_key('password'):
info['password'] = obj.info['password']
obj.info = info
obj.name = name
obj.token = token
obj.save()
return obj
def can_update_status(self):
if not AUTH_SYSTEMS.has_key(self.user_type):
return False
return AUTH_SYSTEMS[self.user_type].STATUS_UPDATES
def can_create_election(self):
"""
Certain auth systems can choose to limit election creation
to certain users.
"""
if not AUTH_SYSTEMS.has_key(self.user_type):
return False
return AUTH_SYSTEMS[self.user_type].can_create_election(self.user_id, self.info)
def update_status_template(self):
if not self.can_update_status():
return None
return AUTH_SYSTEMS[self.user_type].STATUS_UPDATE_WORDING_TEMPLATE
def update_status(self, status):
if AUTH_SYSTEMS.has_key(self.user_type):
AUTH_SYSTEMS[self.user_type].update_status(self.user_id, self.info, self.token, status)
def send_message(self, subject, body):
if AUTH_SYSTEMS.has_key(self.user_type):
subject = subject.split("\n")[0]
AUTH_SYSTEMS[self.user_type].send_message(self.user_id, self.name, self.info, subject, body)
def send_notification(self, message):
if AUTH_SYSTEMS.has_key(self.user_type):
if hasattr(AUTH_SYSTEMS[self.user_type], 'send_notification'):
AUTH_SYSTEMS[self.user_type].send_notification(self.user_id, self.info, message)
def is_eligible_for(self, eligibility_case):
"""
Check if this user is eligible for this particular eligibility case, which looks like
{'auth_system': 'cas', 'constraint': [{}, {}, {}]}
and the constraints are OR'ed together
"""
if eligibility_case['auth_system'] != self.user_type:
return False
# no constraint? Then eligible!
if not eligibility_case.has_key('constraint'):
return True
# from here on we know we match the auth system, but do we match one of the constraints?
auth_system = AUTH_SYSTEMS[self.user_type]
# does the auth system allow for checking a constraint?
if not hasattr(auth_system, 'check_constraint'):
return False
for constraint in eligibility_case['constraint']:
# do we match on this constraint?
if auth_system.check_constraint(constraint=constraint, user = self):
return True
# no luck
return False
def __eq__(self, other):
if other:
return self.type_and_id == other.type_and_id
else:
return False
@property
def pretty_name(self):
if self.name:
return self.name
if self.info.has_key('name'):
return self.info['name']
return self.user_id
@property
def public_url(self):
if AUTH_SYSTEMS.has_key(self.user_type):
if hasattr(AUTH_SYSTEMS[self.user_type], 'public_url'):
return AUTH_SYSTEMS[self.user_type].public_url(self.user_id)
return None
def _display_html(self, size):
public_url = self.public_url
if public_url:
name_display = '<a href="%s">%s</a>' % (public_url, self.pretty_name)
else:
name_display = self.pretty_name
return """<img class="%s-logo" src="/static/auth/login-icons/%s.png" alt="%s" /> %s""" % (
size, self.user_type, self.user_type, name_display)
@property
def display_html_small(self):
return self._display_html('small')
@property
def display_html_big(self):
return self._display_html('big')