Projet

Général

Profil

Télécharger (5,88 ko) Statistiques
| Branche: | Tag: | Révision:

root / mandaye / backends / ldap_back.py @ 5294fd40

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

    
(3-3/4)