summaryrefslogtreecommitdiffstats
path: root/idp/extra/modules/store.py
blob: c2dc654fa649ae02303248be16fc8508730d1834 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
import sys

try:
    import ldap
    import ldap.async
    import ldap.modlist
except ImportError:
    pass

import lasso

from quixote import get_session

from qommon.form import *
from qommon.storage import StorableObject

from authentic import identities

import directory

class IdentitiesStorePratic:
    label = N_('Pr@tic Directory')
    admin_keys = ('pratic_ldap_url', 'pratic_ldap_base')

    def is_bootstrapping(self):
        return False

    def fill_admin_form(self, form, data_source):
        form.add(StringWidget, 'pratic_ldap_url', title = _('LDAP URL'), required = True,
                hint = htmltext(_('Example: <tt>ldap://directory.example.com</tt>')),
                value = data_source.get('pratic_ldap_url', ''))
        form.add(StringWidget, 'pratic_ldap_base', title = _('LDAP Base'), required = True,
                hint = htmltext(_('Example: <tt>dc=example, dc=com</tt>')),
                value = data_source.get('pratic_ldap_base', ''))

    def load_identities(self):
        pass

    def get_identity_for_account(self, username, password, collectivity):
        store = directory.get_store()
        ldap_conn = ldap.initialize(store.pratic_ldap_url)
        uid = 'uid=%s,%s' % (username, collectivity)
        try:
            ldap_conn.simple_bind_s(uid, password)
        except ldap.INVALID_CREDENTIALS:
            return None

        return self.get_identity(uid)

    
    def get_identity_for_name_identifier(self, name_identifier):
        for i in MiniIdentityPratic.values():
            if not (i.lasso_dump or i.lasso_proxy_dump):
                continue
            if not ((name_identifier in (i.lasso_dump or '')) or (
                        name_identifier in (i.lasso_proxy_dump or ''))):
                continue # shortcut so it doesn't do the whole thing if not necessary
            identity = lasso.Identity.newFromDump(i.lasso_dump)
            for p in identity.providerIds:
                federation = identity.getFederation(p)
                if federation.localNameIdentifier and \
                        federation.localNameIdentifier.content == name_identifier:
                    return self.get_identity(i.id)
                if federation.remoteNameIdentifier and \
                        federation.remoteNameIdentifier.content == name_identifier:
                    return self.get_identity(i.id)

            if i.lasso_proxy_dump:
                identity = lasso.Identity.newFromDump(i.lasso_proxy_dump)
                for p in identity.providerIds:
                    federation = identity.getFederation(p)
                    if federation.localNameIdentifier and \
                            federation.localNameIdentifier.content == name_identifier:
                        return i
                    if federation.remoteNameIdentifier and \
                            federation.remoteNameIdentifier.content == name_identifier:
                        return i

        return None

    def init_session(self, session, password):
        session.pratic_ldap_password = password

    _ldap_conn = None
    def get_ldap_conn(self):
        if self._ldap_conn:
            return self._ldap_conn

        store = directory.get_store()
        self._ldap_conn = ldap.initialize(store.pratic_ldap_url)

        session = get_session()
        if session and hasattr(session, 'pratic_ldap_password'):
            uid = session.user
            password = session.pratic_ldap_password
            try:
                self._ldap_conn.simple_bind_s(uid, password)
            except ldap.INVALID_CREDENTIALS:
                pass # XXX?

        return self._ldap_conn
    ldap_conn = property(get_ldap_conn)

    def connect(self, session):
        if session and session.user:
            # bind to the LDAP directory so it can access its attributes
            try:
                self.ldap_conn.simple_bind_s(session.user,
                        session.pratic_ldap_password)
            except ldap.INVALID_CREDENTIALS:
                return

    def get_identity(self, uid):
        try:
            identity = MiniIdentityPratic.get(uid)
        except KeyError:
            identity = MiniIdentityPratic(id = uid)

        return identity

    def save(self, identity):
        identity.store()


class MiniIdentityPratic(StorableObject):
    _names = 'pratic_identities'
    lasso_dump = None
    lasso_proxy_dump = None
    resource_id = None

    def is_admin(self):
        return ',ou=admin,' in str(self.id)

    def is_local_admin(self):
        if not 'ou=' in str(self.id):
            return False
        store = directory.get_store()
        ldap_conn = ldap.initialize(store.pratic_ldap_url)
        try:
            record = ldap_conn.search_s(str(self.id), ldap.SCOPE_BASE)[0][1]
        except:
            return False
        return 'TRUE' in record.get('cdg59isAdmin', [])

    def get_display_name(self):
        return self.id[:self.id.index(',')]
    display_name = property(get_display_name)
    
    def get_collectivity(self):
        collectivity_ou = self.id[self.id.index(',')+1:]
        collectivity_ou = collectivity_ou[:collectivity_ou.index(',')].strip().split('=')[1]
        return directory.get_collectivity(collectivity_ou)

    def get_attributes(self):
        agent = self.get_as_agent()
        attributes = {}
        for k in ('username', 'cn', 'mail'):
            v = getattr(agent, k)
            if v is None:
                continue
            attributes[k] = v
        if agent.cdg59isAdmin:
            attributes['local-admin'] = 'true'
        if self.is_admin():
            attributes['super-admin'] = 'true'
        else:
            attributes['collectivity'] = self.get_collectivity().ou
        return attributes
    attributes = property(get_attributes)

    _agent = None
    def get_as_agent(self):
        if self._agent:
            return self._agent
        store = directory.get_store()
        ldap_conn = ldap.initialize(store.pratic_ldap_url)
        record = ldap_conn.search_s(self.id, ldap.SCOPE_BASE)[0]
        print 'record:', record
        self._agent = directory.Agent(record)
        return self._agent

    # don't pickle _agent cache
    def __getstate__(self):
        odict = self.__dict__
        if odict.has_key('_agent'):
            del odict['_agent']
        return odict

    def __setstate__(self, dict):
        self.__dict__ = dict
        self._agent = None


identities.stores['pratic'] = IdentitiesStorePratic