Projet

Général

Profil

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

root / mandaye / backends / sql.py @ 9dbbb15b

1

    
2
import copy
3

    
4
from datetime import datetime
5

    
6
from mandaye.backends.default import storage_conn
7
from mandaye.log import logger
8
from mandaye.models import IDPUser, SPUser, ServiceProvider
9

    
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).\
44
                join(IDPUser).\
45
                join(ServiceProvider).\
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
        if sp_user:
61
            return Association.sp_user2association(sp_user)
62
        return None
63

    
64
    @staticmethod
65
    def has_id(asso_id):
66
        """ return a boolean """
67
        if storage_conn.query(SPUser).\
68
                filter(SPUser.id==asso_id).\
69
                count():
70
            return True
71
        return False
72

    
73
    @staticmethod
74
    def update_or_create(sp_name, sp_login, sp_post_values, idp_unique_id, idp_name='default'):
75
        """ update or create an associtaion which match the following values
76
        return the association id
77
        """
78
        sp_user = storage_conn.query(SPUser).\
79
                join(IDPUser).\
80
                join(ServiceProvider).\
81
                filter(SPUser.login==sp_login).\
82
                filter(ServiceProvider.name==sp_name).\
83
                filter(IDPUser.unique_id==idp_unique_id).\
84
                filter(IDPUser.idp_id==idp_name).\
85
                first()
86
        if sp_user:
87
            sp_user.post_values = sp_post_values
88
            storage_conn.add(sp_user)
89
            logger.info('Modify association for %r (%r)', sp_login, idp_unique_id)
90
        else:
91
            service_provider = storage_conn.query(ServiceProvider).\
92
                    filter(ServiceProvider.name==sp_name).first()
93
            if not service_provider:
94
                logger.info('New service provider %r', sp_name)
95
                service_provider = ServiceProvider(name=sp_name)
96
                storage_conn.add(service_provider)
97
            idp_user = storage_conn.query(IDPUser).\
98
                    filter(IDPUser.unique_id==idp_unique_id).\
99
                    filter(IDPUser.idp_id==idp_name).\
100
                    first()
101
            if not idp_user:
102
                logger.info('New IDP user %r', idp_unique_id)
103
                idp_user = IDPUser(
104
                        unique_id=idp_unique_id,
105
                        idp_id=idp_name
106
                        )
107
                storage_conn.add(idp_user)
108
            sp_user = SPUser(
109
                    login=sp_login,
110
                    post_values=sp_post_values,
111
                    idp_user=idp_user,
112
                    service_provider=service_provider
113
                    )
114
            storage_conn.add(sp_user)
115
            try:
116
                storage_conn.commit()
117
            except:
118
                logger.error("update_or_create transaction failed so we rollback")
119
                storage_conn.rollback()
120
                raise
121
            logger.info('New association %r with %r', sp_login, idp_unique_id)
122
        return sp_user.id
123

    
124
    @staticmethod
125
    def delete(asso_id):
126
        """ delete the association which has the following asso_id """
127
        sp_user = storage_conn.query(SPUser).get(asso_id)
128
        if not sp_user:
129
            logger.warning("Association deletion failed: sp user %r doesn't exist", asso_id)
130
            return
131
        logger.info("Disassociate account %r (%r)", sp_user.login, sp_user.idp_user.unique_id)
132
        storage_conn.delete(sp_user)
133

    
134
    @staticmethod
135
    def get_last_connected(sp_name, idp_unique_id, idp_name='default'):
136
        """ get the last connecting association which match the parameters
137
        return a dict of the association
138
        """
139
        sp_user = storage_conn.query(SPUser).\
140
                filter(ServiceProvider.name==sp_name).\
141
                filter(IDPUser.unique_id==idp_unique_id).\
142
                filter(IDPUser.idp_id==idp_name).\
143
                order_by(SPUser.last_connection.desc()).\
144
                first()
145
        if sp_user:
146
            return Association.sp_user2association(sp_user)
147
        else:
148
            return None
149

    
150
    @staticmethod
151
    def update_last_connection(asso_id):
152
        """ update the association last conenction time with the current time
153
        return None
154
        """
155
        sp_user = storage_conn.query(SPUser).get(asso_id)
156
        if not sp_user:
157
            logger.warning("Update last connecting failed: sp user %r doesn't exist", asso_id)
158
            return
159
        sp_user.last_connection = datetime.now()
160
        storage_conn.add(sp_user)
161

    
(3-3/3)