Projet

Général

Profil

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

root / mandaye / backends / sql.py @ c62aae38

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
        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).\
83
                first()
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).\
96
                    filter(IDPUser.unique_id==idp_unique_id).\
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
111
                    )
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()
143
        if sp_user:
144
            return Association.sp_user2association(sp_user)
145
        else:
146
            return None
147

    
148
    @staticmethod
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)
159

    
(3-3/3)