Projet

Général

Profil

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

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

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

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

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

    
157
    @staticmethod
158
    def update_last_connection(asso_id):
159
        """ update the association last conenction time with the current time
160
        return None
161
        """
162
        sp_user = storage_conn.query(SPUser).get(asso_id)
163
        if not sp_user:
164
            logger.warning("Update last connecting failed: sp user %r doesn't exist", asso_id)
165
            return
166
        sp_user.last_connection = datetime.now()
167
        storage_conn.add(sp_user)
168

    
(4-4/4)