Révision c62aae38
Ajouté par Jérôme Schneider il y a plus de 9 ans
mandaye/backends/sql.py | ||
---|---|---|
1 | 1 |
|
2 |
import copy |
|
3 |
|
|
2 | 4 |
from datetime import datetime |
3 | 5 |
|
4 |
from mandaye.db import sql_session
|
|
6 |
from mandaye.backends.default import storage_conn
|
|
5 | 7 |
from mandaye.log import logger |
6 | 8 |
from mandaye.models import IDPUser, SPUser, ServiceProvider |
7 | 9 |
|
8 |
class ManagerIDPUserSQL: |
|
9 |
|
|
10 |
@staticmethod |
|
11 |
def get(unique_id, idp_id='default'): |
|
12 |
idp_user = sql_session().query(IDPUser).\ |
|
13 |
filter_by(unique_id=unique_id, |
|
14 |
idp_id='default').all() |
|
15 |
if len(idp_user) > 1: |
|
16 |
logger.critical('ManagerIDPUserSQL.get %s not unique' % unique_id) |
|
17 |
raise MandayeException( |
|
18 |
'ManagerIDPUserSQL.get : %s is not unique' % unique_id) |
|
19 |
if idp_user: |
|
20 |
return idp_user[0] |
|
21 |
else: |
|
22 |
return None |
|
23 |
|
|
24 |
@staticmethod |
|
25 |
def create(unique_id, idp_id='default'): |
|
26 |
logger.info('Add idp user %s in db' % (unique_id)) |
|
27 |
idp_user = IDPUser( |
|
28 |
unique_id=unique_id, |
|
29 |
idp_id=idp_id) |
|
30 |
sql_session().add(idp_user) |
|
31 |
return idp_user |
|
32 |
|
|
33 |
@staticmethod |
|
34 |
def get_or_create(unique_id, idp_id='default'): |
|
35 |
idp_user= ManagerIDPUserSQL.get(unique_id, idp_id) |
|
36 |
if idp_user: |
|
37 |
return idp_user |
|
38 |
else: |
|
39 |
return ManagerIDPUserSQL.create(unique_id, idp_id) |
|
40 |
|
|
41 |
@staticmethod |
|
42 |
def delete(idp_user): |
|
43 |
logger.info('Delete in db idp user %s' % idp_user.unique_id) |
|
44 |
sql_session().delete(idp_user) |
|
45 |
sql_session().commit() |
|
46 |
|
|
47 |
@staticmethod |
|
48 |
def save(): |
|
49 |
sql_session().commit() |
|
50 |
|
|
51 |
class ManagerSPUserSQL: |
|
52 |
|
|
53 |
@staticmethod |
|
54 |
def get(login, idp_user, service_provider): |
|
55 |
return sql_session().query(SPUser).\ |
|
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='dafault'): |
|
41 |
""" return a list of dict with associations that matching all of this options """ |
|
42 |
associations = [] |
|
43 |
sp_users = storage_conn.query(SPUser).\ |
|
56 | 44 |
join(IDPUser).\ |
57 | 45 |
join(ServiceProvider).\ |
58 |
filter(SPUser.login==login).\ |
|
59 |
filter(SPUser.idp_user==idp_user).\ |
|
60 |
filter(SPUser.service_provider==service_provider).\ |
|
61 |
first() |
|
62 |
|
|
63 |
@staticmethod |
|
64 |
def get_by_id(id): |
|
65 |
return sql_session().query(SPUser).\ |
|
66 |
filter(SPUser.id==id).first() |
|
67 |
|
|
68 |
@staticmethod |
|
69 |
def get_last_connected(idp_user, service_provider): |
|
70 |
return sql_session().query(SPUser).\ |
|
71 |
filter(SPUser.idp_user==idp_user).\ |
|
72 |
filter(SPUser.service_provider==service_provider).\ |
|
73 |
order_by(SPUser.last_connection.desc()).\ |
|
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 |
return Association.sp_user2association(sp_user) |
|
61 |
|
|
62 |
@staticmethod |
|
63 |
def has_id(asso_id): |
|
64 |
""" return a boolean """ |
|
65 |
if storage_conn.query(SPUser).\ |
|
66 |
filter(SPUser.id==asso_id).\ |
|
67 |
count(): |
|
68 |
return True |
|
69 |
return False |
|
70 |
|
|
71 |
@staticmethod |
|
72 |
def update_or_create(sp_name, sp_login, sp_post_values, idp_unique_id, idp_name='default'): |
|
73 |
""" update or create an associtaion which match the following values |
|
74 |
return the association id |
|
75 |
""" |
|
76 |
sp_user = storage_conn.query(SPUser).\ |
|
77 |
join(IDPUser).\ |
|
78 |
join(ServiceProvider).\ |
|
79 |
filter(SPUser.login==sp_login).\ |
|
80 |
filter(ServiceProvider.name==sp_name).\ |
|
81 |
filter(IDPUser.unique_id==idp_unique_id).\ |
|
82 |
filter(IDPUser.idp_id==idp_name).\ |
|
74 | 83 |
first() |
75 |
@staticmethod |
|
76 |
def get_sp_users(idp_unique_id, service_provider_name): |
|
77 |
return sql_session().query(SPUser).\ |
|
78 |
join(IDPUser).\ |
|
79 |
join(ServiceProvider).\ |
|
84 |
if sp_user: |
|
85 |
sp_user.post_values = sp_post_values |
|
86 |
storage_conn.add(sp_user) |
|
87 |
logger.info('Modify association for %r (%r)', sp_login, idp_unique_id) |
|
88 |
else: |
|
89 |
service_provider = storage_conn.query(ServiceProvider).\ |
|
90 |
filter(ServiceProvider.name==sp_name).first() |
|
91 |
if not service_provider: |
|
92 |
logger.info('New service provider %r', sp_name) |
|
93 |
service_provider = ServiceProvider(name=sp_name) |
|
94 |
storage_conn.add(service_provider) |
|
95 |
idp_user = storage_conn.query(IDPUser).\ |
|
80 | 96 |
filter(IDPUser.unique_id==idp_unique_id).\ |
81 |
filter(ServiceProvider.name==service_provider_name).\ |
|
82 |
order_by(SPUser.last_connection.desc()).\ |
|
83 |
all() |
|
84 |
|
|
85 |
@staticmethod |
|
86 |
def create(login, post_values, idp_user, service_provider): |
|
87 |
sp_user = SPUser( |
|
88 |
login = login, |
|
89 |
post_values = post_values, |
|
90 |
idp_user = idp_user, |
|
91 |
service_provider = service_provider |
|
97 |
filter(IDPUser.idp_id==idp_name).\ |
|
98 |
first() |
|
99 |
if not idp_user: |
|
100 |
logger.info('New IDP user %r', idp_unique_id) |
|
101 |
idp_user = IDPUser( |
|
102 |
unique_id=idp_unique_id, |
|
103 |
idp_id=idp_name |
|
104 |
) |
|
105 |
storage_conn.add(idp_user) |
|
106 |
sp_user = SPUser( |
|
107 |
login=sp_login, |
|
108 |
post_values=sp_post_values, |
|
109 |
idp_user=idp_user, |
|
110 |
service_provider=service_provider |
|
92 | 111 |
) |
93 |
logger.info('New association: %s with %s on site %s' % \ |
|
94 |
(login, idp_user.unique_id, service_provider.name)) |
|
95 |
sql_session().add(sp_user) |
|
96 |
sql_session().commit() |
|
97 |
logger.debug('New SP user %s in db' % (login)) |
|
98 |
return sp_user |
|
99 |
|
|
100 |
@staticmethod |
|
101 |
def get_or_create(login, post_values, idp_user, service_provider): |
|
102 |
sp_user = ManagerSPUserSQL.get(login, idp_user, service_provider) |
|
112 |
storage_conn.add(sp_user) |
|
113 |
try: |
|
114 |
storage_conn.commit() |
|
115 |
except: |
|
116 |
logger.error("update_or_create transaction failed so we rollback") |
|
117 |
storage_conn.rollback() |
|
118 |
raise |
|
119 |
logger.info('New association %r with %r', sp_login, idp_unique_id) |
|
120 |
return sp_user.id |
|
121 |
|
|
122 |
@staticmethod |
|
123 |
def delete(asso_id): |
|
124 |
""" delete the association which has the following asso_id """ |
|
125 |
sp_user = storage_conn.query(SPUser).get(asso_id) |
|
126 |
if not sp_user: |
|
127 |
logger.warning("Association deletion failed: sp user %r doesn't exist", asso_id) |
|
128 |
return |
|
129 |
logger.info("Disassociate account %r (%r)", sp_user.login, sp_user.idp_user.unique_id) |
|
130 |
storage_conn.delete(sp_user) |
|
131 |
|
|
132 |
@staticmethod |
|
133 |
def get_last_connected(sp_name, idp_unique_id, idp_name='default'): |
|
134 |
""" get the last connecting association which match the parameters |
|
135 |
return a dict of the association |
|
136 |
""" |
|
137 |
sp_user = storage_conn.query(SPUser).\ |
|
138 |
filter(ServiceProvider.name==sp_name).\ |
|
139 |
filter(IDPUser.unique_id==idp_unique_id).\ |
|
140 |
filter(IDPUser.idp_id==idp_name).\ |
|
141 |
order_by(SPUser.last_connection.desc()).\ |
|
142 |
first() |
|
103 | 143 |
if sp_user: |
104 |
return sp_user |
|
105 |
else: |
|
106 |
return ManagerSPUserSQL.create(login, post_values, |
|
107 |
idp_user, service_provider) |
|
108 |
@staticmethod |
|
109 |
def all(): |
|
110 |
return sql_session().query(SPUser).all() |
|
111 |
|
|
112 |
@staticmethod |
|
113 |
def delete(sp_user): |
|
114 |
logger.debug('Disassociate account %s' % sp_user.login) |
|
115 |
sql_session().delete(sp_user) |
|
116 |
sql_session().commit() |
|
117 |
|
|
118 |
@staticmethod |
|
119 |
def save(): |
|
120 |
sql_session().commit() |
|
121 |
|
|
122 |
class ManagerServiceProviderSQL: |
|
123 |
|
|
124 |
@staticmethod |
|
125 |
def get(name): |
|
126 |
sp = sql_session().query(ServiceProvider).\ |
|
127 |
filter_by(name=name) |
|
128 |
if sp: |
|
129 |
return sp.first() |
|
144 |
return Association.sp_user2association(sp_user) |
|
130 | 145 |
else: |
131 | 146 |
return None |
132 | 147 |
|
133 | 148 |
@staticmethod |
134 |
def create(name): |
|
135 |
logger.info('Add %s service provider into the db' % name) |
|
136 |
sp = ServiceProvider(name=name) |
|
137 |
sql_session().add(sp) |
|
138 |
sql_session().commit() |
|
139 |
return sp |
|
140 |
|
|
141 |
@staticmethod |
|
142 |
def get_or_create(name): |
|
143 |
sp = ManagerServiceProviderSQL.get(name) |
|
144 |
if sp: |
|
145 |
return sp |
|
146 |
else: |
|
147 |
return ManagerServiceProviderSQL.create(name) |
|
148 |
|
|
149 |
@staticmethod |
|
150 |
def delete(service_provider): |
|
151 |
logger.debug('Delete service provider %s' % service_provider.name) |
|
152 |
sql_session().delete(service_provider) |
|
153 |
sql_session().commit() |
|
154 |
|
|
155 |
@staticmethod |
|
156 |
def save(): |
|
157 |
sql_session().commit() |
|
158 |
|
|
159 |
ManagerServiceProvider = ManagerServiceProviderSQL |
|
160 |
ManagerIDPUser = ManagerIDPUserSQL |
|
161 |
ManagerSPUser = ManagerSPUserSQL |
|
149 |
def update_last_connection(asso_id): |
|
150 |
""" update the association last conenction time with the current time |
|
151 |
return None |
|
152 |
""" |
|
153 |
sp_user = storage_conn.query(SPUser).get(asso_id) |
|
154 |
if not sp_user: |
|
155 |
logger.warning("Update last connecting failed: sp user %r doesn't exist", asso_id) |
|
156 |
return |
|
157 |
sp_user.last_connection = datetime.now() |
|
158 |
storage_conn.add(sp_user) |
|
162 | 159 |
|
Formats disponibles : Unified diff
backends: complete rewrite of the interface
The old interface was to specific for sqlalchemy this new one allow to
write new backends
WARNING: this commit could break compability for some filter which uses
the old interface