Projet

Général

Profil

Télécharger (6,11 ko) Statistiques
| Branche: | Tag: | Révision:

root / mandaye / backends / ldap_back.py @ 4c755abe

1

    
2
import json
3
import ldap
4
import ldap.modlist
5
import random
6

    
7
from datetime import datetime
8

    
9
from mandaye import config
10
from mandaye.log import logger
11
from mandaye.backends.default import storage_conn
12

    
13
class Association(object):
14
    """
15
    association dictionary return by the following methods:
16
    {
17
        'id': '', # identifier of your association (must be unique)
18
        'sp_name': '', # name of the service provider (defined in the mappers)
19
        'sp_login': '', # login on the service provider
20
        'sp_post_values': '', # the post values for sp login form
21
        'idp_unique_id:': '', # the unique identifier of the identity provider (ex.: a saml NameID)
22
        'idp_name':  '', # identity provide name
23
        'last_connection':  datetime.datetime, # last connection with this association
24
        'creation_date':  datetime.datetime, # creation date of this association
25
    }
26
    """
27

    
28
    @staticmethod
29
    def ldap2association(ldap_object):
30
        return {
31
                'id': ldap_object['uniqueID'][0],
32
                'sp_name': ldap_object['spName'][0],
33
                'sp_login': ldap_object['spLogin'][0],
34
                'sp_post_values': json.loads(ldap_object['spPostValues'][0]),
35
                'idp_unique_id': ldap_object['idpUniqueID'][0],
36
                'idp_name': ldap_object['idpName'][0],
37
                'last_connection': datetime.strptime(
38
                    ldap_object['lastConnectionDate'][0][:14],
39
                    '%Y%m%d%H%M%S'),
40
                'creation_date': datetime.strptime(
41
                    ldap_object['creationDate'][0][:14],
42
                    '%Y%m%d%H%M%S'),
43
                }
44

    
45
    @staticmethod
46
    def get(sp_name, idp_unique_id, idp_name='default'):
47
        """ return a list of dict with associations matching all of this options """
48
        associations = []
49
        results = storage_conn.search_s(config.ldap_base_dn, ldap.SCOPE_ONELEVEL,
50
                filterstr='(&(objectClass=MandayeUser)(spName=%s)(idpUniqueID=%s)(idpName=%s))' % (sp_name, idp_unique_id, idp_name))
51
        for result in results:
52
            associations.append(Association.ldap2association(result[1]))
53
        return associations
54

    
55

    
56
    @staticmethod
57
    def get_by_id(asso_id):
58
        """ return a dict of the association with the id or None if it doesn't exist """
59
        results = storage_conn.search_s(config.ldap_base_dn, ldap.SCOPE_ONELEVEL,
60
                filterstr='(&(objectClass=MandayeUser)(uniqueID=%s))' %\
61
                        (asso_id))
62
        if results:
63
            return Association.ldap2association(results[0][1])
64
        return None
65

    
66
    @staticmethod
67
    def has_id(asso_id):
68
        """ check the given user is present in the directory """
69
        results = storage_conn.search_s(config.ldap_base_dn, ldap.SCOPE_ONELEVEL,
70
                filterstr='(&(objectClass=MandayeUser)(uniqueID=%s))' %\
71
                        (asso_id))
72
        if results:
73
            return True
74
        return False
75

    
76
    @staticmethod
77
    def update_or_create(sp_name, sp_login, sp_post_values, idp_unique_id,
78
            idp_name='default', creation_date=None, last_connection_date=None):
79
        """ update or create an associtaion which match the following values
80
        return the association id
81
        """
82
        results = storage_conn.search_s(config.ldap_base_dn, ldap.SCOPE_ONELEVEL,
83
                filterstr='(&(objectClass=MandayeUser)(spName=%s)(spLogin=%s)(idpUniqueID=%s)(idpName=%s))' %\
84
                        (sp_name, sp_login, idp_unique_id, idp_name))
85
        if not results:
86
            creation_date = creation_date or datetime.utcnow()
87
            last_connection_date = last_connection_date or datetime.utcnow()
88
            association = {'spName': str(sp_name),
89
                    'spLogin': str(sp_login),
90
                    'spPostValues': json.dumps(sp_post_values),
91
                    'idpUniqueID': str(idp_unique_id),
92
                    'idpName': str(idp_name),
93
                    'creationDate': creation_date.strftime('%Y%m%d%H%M%SZ'),
94
                    'lastConnectionDate': last_connection_date.strftime('%Y%m%d%H%M%SZ'),
95
                    'objectClass': 'MandayeUser'
96
                    }
97
            mod_list = ldap.modlist.addModlist(association)
98
            while True:
99
                unique_id = random.randint(1, 5000000)
100
                dn = "uniqueID=%s,%s" % (unique_id, config.ldap_base_dn)
101
                try:
102
                    result = storage_conn.add_s(dn, mod_list)
103
                except ldap.ALREADY_EXISTS:
104
                    continue
105
                break
106
            logger.info("New association %r with %r", sp_login, idp_unique_id)
107
            return unique_id
108
        else:
109
            dn = results[0][0]
110
            mod_list = [(ldap.MOD_REPLACE, 'spPostValues', json.dumps(sp_post_values))]
111
            storage_conn.modify_s(dn, mod_list)
112
            logger.info("Update post values for %r (%r)", sp_login, idp_unique_id)
113
        return results[0][1]['uniqueID'][0]
114

    
115
    @staticmethod
116
    def delete(asso_id):
117
        """ delete the association which has the following asso_id """
118
        dn = "uniqueID=%s,%s" % (asso_id, config.ldap_base_dn)
119
        storage_conn.delete_s(dn)
120
        logger.info('Delete %r association', dn)
121

    
122
    @staticmethod
123
    def get_last_connected(sp_name, idp_unique_id, idp_name='default'):
124
        """ get the last connecting association which match the parameters
125
        return a dict of the association
126
        """
127
        results = storage_conn.search_s(config.ldap_base_dn, ldap.SCOPE_ONELEVEL,
128
                filterstr='(&(objectClass=MandayeUser)(spName=%s)(idpUniqueID=%s)(idpName=%s))' % (sp_name, idp_unique_id, idp_name))
129
        if results:
130
            return Association.ldap2association(results[0][1])
131
        return None
132

    
133
    @staticmethod
134
    def update_last_connection(asso_id):
135
        """ update the association last connection time with the current time
136
        return a dict of the association
137
        """
138
        last_connection = datetime.utcnow().strftime("%Y%m%d%H%M%SZ")
139
        dn = "uniqueID=%s,%s" % (asso_id, config.ldap_base_dn)
140
        mod_list = [(ldap.MOD_REPLACE, 'lastConnectionDate', last_connection)]
141
        storage_conn.modify_s(dn, mod_list)
142

    
(3-3/4)