1
|
|
2
|
import copy
|
3
|
|
4
|
from datetime import datetime
|
5
|
|
6
|
from mandaye.backends.default import storage_conn
|
7
|
from mandaye.log import logger
|
8
|
from mandaye.models import IDPUser, SPUser, ServiceProvider
|
9
|
|
10
|
class Association(object):
|
11
|
"""
|
12
|
association dictionnary return by the following methods:
|
13
|
{
|
14
|
'id': '', # identifier of your association (must be unique)
|
15
|
'sp_name': '', # name of the service provider (defined in the mappers)
|
16
|
'sp_login': '', # login on the service provider
|
17
|
'sp_post_values': '', # the post values for sp login form
|
18
|
'idp_unique_id:': '', # the unique identifier of the identity provider (ex.: a saml NameID)
|
19
|
'idp_name': '', # identity provide name
|
20
|
'last_connection': datetime.datetime, # last connection with this association
|
21
|
'creation_date': datetime.datetime, # creation date of this association
|
22
|
}
|
23
|
"""
|
24
|
|
25
|
@staticmethod
|
26
|
def sp_user2association(sp_user):
|
27
|
return {
|
28
|
'id': sp_user.id,
|
29
|
'sp_name': sp_user.service_provider.name,
|
30
|
'sp_login': sp_user.login,
|
31
|
'sp_post_values': sp_user.post_values,
|
32
|
'idp_unique_id': sp_user.idp_user.unique_id,
|
33
|
'idp_name': sp_user.idp_user.idp_id,
|
34
|
'last_connection': sp_user.last_connection,
|
35
|
'creation_date': sp_user.creation_date
|
36
|
}
|
37
|
|
38
|
|
39
|
@staticmethod
|
40
|
def get(sp_name, idp_unique_id, idp_name='default'):
|
41
|
""" return a list of dict with associations that matching all of this options """
|
42
|
associations = []
|
43
|
sp_users = storage_conn.query(SPUser).\
|
44
|
join(IDPUser).\
|
45
|
join(ServiceProvider).\
|
46
|
filter(ServiceProvider.name==sp_name).\
|
47
|
filter(IDPUser.unique_id==idp_unique_id).\
|
48
|
filter(IDPUser.idp_id==idp_name).\
|
49
|
all()
|
50
|
for sp_user in sp_users:
|
51
|
association = Association.sp_user2association(sp_user)
|
52
|
associations.append(association)
|
53
|
return associations
|
54
|
|
55
|
@staticmethod
|
56
|
def get_by_id(asso_id):
|
57
|
""" return an dict of the association with the id or None if it doesn't exist """
|
58
|
sp_user = storage_conn.query(SPUser).\
|
59
|
filter(SPUser.id==asso_id).first()
|
60
|
if sp_user:
|
61
|
return Association.sp_user2association(sp_user)
|
62
|
return None
|
63
|
|
64
|
@staticmethod
|
65
|
def has_id(asso_id):
|
66
|
""" return a boolean """
|
67
|
if storage_conn.query(SPUser).\
|
68
|
filter(SPUser.id==asso_id).\
|
69
|
count():
|
70
|
return True
|
71
|
return False
|
72
|
|
73
|
@staticmethod
|
74
|
def update_or_create(sp_name, sp_login, sp_post_values, idp_unique_id,
|
75
|
idp_name='default', creation_date=None, last_connection_date=None):
|
76
|
""" update or create an associtaion which match the following values
|
77
|
return the association id
|
78
|
"""
|
79
|
sp_user = storage_conn.query(SPUser).\
|
80
|
join(IDPUser).\
|
81
|
join(ServiceProvider).\
|
82
|
filter(SPUser.login==sp_login).\
|
83
|
filter(ServiceProvider.name==sp_name).\
|
84
|
filter(IDPUser.unique_id==idp_unique_id).\
|
85
|
filter(IDPUser.idp_id==idp_name).\
|
86
|
first()
|
87
|
if sp_user:
|
88
|
sp_user.post_values = sp_post_values
|
89
|
storage_conn.add(sp_user)
|
90
|
logger.info('Modify association for %r (%r)', sp_login, idp_unique_id)
|
91
|
else:
|
92
|
service_provider = storage_conn.query(ServiceProvider).\
|
93
|
filter(ServiceProvider.name==sp_name).first()
|
94
|
if not service_provider:
|
95
|
logger.info('New service provider %r', sp_name)
|
96
|
service_provider = ServiceProvider(name=sp_name)
|
97
|
storage_conn.add(service_provider)
|
98
|
idp_user = storage_conn.query(IDPUser).\
|
99
|
filter(IDPUser.unique_id==idp_unique_id).\
|
100
|
filter(IDPUser.idp_id==idp_name).\
|
101
|
first()
|
102
|
if not idp_user:
|
103
|
logger.info('New IDP user %r', idp_unique_id)
|
104
|
idp_user = IDPUser(
|
105
|
unique_id=idp_unique_id,
|
106
|
idp_id=idp_name
|
107
|
)
|
108
|
storage_conn.add(idp_user)
|
109
|
creation_date = creation_date or datetime.utcnow()
|
110
|
last_connection_date = last_connection_date or datetime.utcnow()
|
111
|
sp_user = SPUser(
|
112
|
login=sp_login,
|
113
|
post_values=sp_post_values,
|
114
|
idp_user=idp_user,
|
115
|
service_provider=service_provider,
|
116
|
creation_date=creation_date,
|
117
|
last_connection=last_connection_date
|
118
|
)
|
119
|
storage_conn.add(sp_user)
|
120
|
try:
|
121
|
storage_conn.commit()
|
122
|
except:
|
123
|
logger.error("update_or_create transaction failed so we rollback")
|
124
|
storage_conn.rollback()
|
125
|
raise
|
126
|
logger.info('New association %r with %r', sp_login, idp_unique_id)
|
127
|
return sp_user.id
|
128
|
|
129
|
@staticmethod
|
130
|
def delete(asso_id):
|
131
|
""" delete the association which has the following asso_id """
|
132
|
sp_user = storage_conn.query(SPUser).get(asso_id)
|
133
|
if not sp_user:
|
134
|
logger.warning("Association deletion failed: sp user %r doesn't exist", asso_id)
|
135
|
return
|
136
|
logger.info("Disassociate account %r (%r)", sp_user.login, sp_user.idp_user.unique_id)
|
137
|
storage_conn.delete(sp_user)
|
138
|
|
139
|
@staticmethod
|
140
|
def get_last_connected(sp_name, idp_unique_id, idp_name='default'):
|
141
|
""" get the last connecting association which match the parameters
|
142
|
return a dict of the association
|
143
|
"""
|
144
|
sp_user = storage_conn.query(SPUser).\
|
145
|
join(IDPUser).\
|
146
|
join(ServiceProvider).\
|
147
|
filter(ServiceProvider.name==sp_name).\
|
148
|
filter(IDPUser.unique_id==idp_unique_id).\
|
149
|
filter(IDPUser.idp_id==idp_name).\
|
150
|
order_by(SPUser.last_connection.desc()).\
|
151
|
first()
|
152
|
if sp_user:
|
153
|
return Association.sp_user2association(sp_user)
|
154
|
else:
|
155
|
return None
|
156
|
|
157
|
@staticmethod
|
158
|
def update_last_connection(asso_id):
|
159
|
""" update the association last conenction time with the current time
|
160
|
return None
|
161
|
"""
|
162
|
sp_user = storage_conn.query(SPUser).get(asso_id)
|
163
|
if not sp_user:
|
164
|
logger.warning("Update last connecting failed: sp user %r doesn't exist", asso_id)
|
165
|
return
|
166
|
sp_user.last_connection = datetime.now()
|
167
|
storage_conn.add(sp_user)
|
168
|
|