Projet

Général

Profil

« Précédent | Suivant » 

Révision c62aae38

Ajouté par Jérôme Schneider il y a plus de 9 ans

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

Voir les différences:

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