1
|
|
2
|
import datetime
|
3
|
import ldap
|
4
|
import ldap.modlist
|
5
|
import random
|
6
|
|
7
|
from mandaye import config
|
8
|
from mandaye.log import logger
|
9
|
from mandaye.backends.default import storage_conn
|
10
|
|
11
|
class Association(object):
|
12
|
"""
|
13
|
association dictionary return by the following methods:
|
14
|
{
|
15
|
'id': '', # identifier of your association (must be unique)
|
16
|
'sp_name': '', # name of the service provider (defined in the mappers)
|
17
|
'sp_login': '', # login on the service provider
|
18
|
'sp_post_values': '', # the post values for sp login form
|
19
|
'idp_unique_id:': '', # the unique identifier of the identity provider (ex.: a saml NameID)
|
20
|
'idp_name': '', # identity provide name
|
21
|
'last_connection': datetime.datetime, # last connection with this association
|
22
|
'creation_date': datetime.datetime, # creation date of this association
|
23
|
}
|
24
|
"""
|
25
|
|
26
|
@staticmethod
|
27
|
def ldap2association(ldap_object):
|
28
|
return {
|
29
|
'id': ldap_object['uniqueID'][0],
|
30
|
'sp_name': ldap_object['spName'][0],
|
31
|
'sp_login': ldap_object['spLogin'][0],
|
32
|
'sp_post_values': ldap_object['spPostValues'][0],
|
33
|
'idp_unique_id': ldap_object['idpUniqueID'][0],
|
34
|
'idp_name': ldap_object['idpName'][0],
|
35
|
'last_connection': datetime.datetime.strptime(
|
36
|
ldap_object['lastConnectionDate'][0][:14],
|
37
|
'%Y%m%d%H%M%S'),
|
38
|
'creation_date': datetime.datetime.strptime(
|
39
|
ldap_object['creationDate'][0][:14],
|
40
|
'%Y%m%d%H%M%S'),
|
41
|
}
|
42
|
|
43
|
@staticmethod
|
44
|
def get(sp_name, idp_unique_id, idp_name='default'):
|
45
|
""" return a list of dict with associations matching all of this options """
|
46
|
associations = []
|
47
|
results = storage_conn.search_s(config.ldap_base_dn, ldap.SCOPE_ONELEVEL,
|
48
|
filterstr='(&(objectClass=MandayeUser)(spName=%s)(idpUniqueID=%s)(idpName=%s))' % (sp_name, idp_unique_id, idp_name))
|
49
|
for result in results:
|
50
|
associations.append(Association.ldap2association(result[1]))
|
51
|
return associations
|
52
|
|
53
|
|
54
|
@staticmethod
|
55
|
def get_by_id(asso_id):
|
56
|
""" return an dict of the association with the id or None if it doesn't exist """
|
57
|
results = storage_conn.search_s(config.ldap_base_dn, ldap.SCOPE_ONELEVEL,
|
58
|
filterstr='(&(objectClass=MandayeUser)(uniqueID=%s))' %\
|
59
|
(asso_id))
|
60
|
if results:
|
61
|
return Association.ldap2association(results[0][1])
|
62
|
return None
|
63
|
|
64
|
@staticmethod
|
65
|
def has_id(asso_id):
|
66
|
""" check the given user is present in the directory """
|
67
|
results = storage_conn.search_s(config.ldap_base_dn, ldap.SCOPE_ONELEVEL,
|
68
|
filterstr='(&(objectClass=MandayeUser)(uniqueID=%s))' %\
|
69
|
(asso_id))
|
70
|
if results:
|
71
|
return True
|
72
|
return False
|
73
|
|
74
|
@staticmethod
|
75
|
def update_or_create(sp_name, sp_login, sp_post_values, idp_unique_id, idp_name='default'):
|
76
|
""" update or create an associtaion which match the following values
|
77
|
return the association id
|
78
|
"""
|
79
|
results = storage_conn.search_s(config.ldap_base_dn, ldap.SCOPE_ONELEVEL,
|
80
|
filterstr='(&(objectClass=MandayeUser)(spName=%s)(spLogin=%s)(idpUniqueID=%s)(idpName=%s))' %\
|
81
|
(sp_name, sp_login, idp_unique_id, idp_name))
|
82
|
if not results:
|
83
|
association = {'spName': sp_name,
|
84
|
'spLogin': sp_login,
|
85
|
'spPostValues': sp_post_values,
|
86
|
'idpUniqueID': idp_unique_id,
|
87
|
'idpName': idp_name,
|
88
|
'creationDate': datetime.datetime.utcnow().strftime('%Y%m%d%H%M%SZ'),
|
89
|
'lastConnectionDate': datetime.datetime.utcnow().strftime('%Y%m%d%H%M%SZ'),
|
90
|
'objectClass': 'MandayeUser'
|
91
|
}
|
92
|
mod_list = ldap.modlist.addModlist(association)
|
93
|
while True:
|
94
|
unique_id = random.randint(1, 5000000)
|
95
|
dn = "uniqueID=%s,%s" % (unique_id, config.ldap_base_dn)
|
96
|
try:
|
97
|
result = storage_conn.add_s(dn, mod_list)
|
98
|
except ldap.ALREADY_EXISTS:
|
99
|
continue
|
100
|
break
|
101
|
logger.info("New association %r with %r", sp_login, idp_unique_id)
|
102
|
return unique_id
|
103
|
else:
|
104
|
dn = results[0][0]
|
105
|
mod_list = [(ldap.MOD_REPLACE, 'spPostValues', sp_post_values)]
|
106
|
storage_conn.modify_s(dn, mod_list)
|
107
|
logger.info("Update post values for %r (%r)", sp_login, idp_unique_id)
|
108
|
return results[0][1]['uniqueID'][0]
|
109
|
|
110
|
@staticmethod
|
111
|
def delete(asso_id):
|
112
|
""" delete the association which has the following asso_id """
|
113
|
dn = "uniqueID=%s,%s" % (asso_id, config.ldap_base_dn)
|
114
|
storage_conn.delete_s(dn)
|
115
|
logger.info('Delete %r association', dn)
|
116
|
|
117
|
@staticmethod
|
118
|
def get_last_connected(sp_name, idp_unique_id, idp_name='default'):
|
119
|
""" get the last connecting association which match the parameters
|
120
|
return a dict of the association
|
121
|
"""
|
122
|
results = storage_conn.search_s(config.ldap_base_dn, ldap.SCOPE_ONELEVEL,
|
123
|
filterstr='(&(objectClass=MandayeUser)(spName=%s)(idpUniqueID=%s)(idpName=%s))' % (sp_name, idp_unique_id, idp_name))
|
124
|
if results:
|
125
|
return Association.ldap2association(results[0][1])
|
126
|
return None
|
127
|
|
128
|
@staticmethod
|
129
|
def update_last_connection(asso_id):
|
130
|
""" update the association last connection time with the current time
|
131
|
return a dict of the association
|
132
|
"""
|
133
|
last_connection = datetime.datetime.utcnow().strftime("%Y%m%d%H%M%SZ")
|
134
|
dn = "uniqueID=%s,%s" % (asso_id, config.ldap_base_dn)
|
135
|
mod_list = [(ldap.MOD_REPLACE, 'lastConnectionDate', last_connection)]
|
136
|
storage_conn.modify_s(dn, mod_list)
|
137
|
|