source: main/waeup.sirp/trunk/src/waeup/sirp/authentication.py @ 6030

Last change on this file since 6030 was 5901, checked in by uli, 14 years ago

Respect the data format returned by getUtilitiesFor (list of tuples,
not a simple list).

File size: 5.3 KB
Line 
1"""Authentication for WAeUP portals.
2"""
3import grok
4import waeup.sirp.permissions
5from zope.component import getUtility, getUtilitiesFor
6try:
7    from zope.pluggableauth.plugins.session import SessionCredentialsPlugin
8except ImportError:
9    # BBB
10    from zope.app.authentication.session import SessionCredentialsPlugin
11try:
12    from zope.pluggableauth.interfaces import (
13        ICredentialsPlugin, IAuthenticatorPlugin, IPrincipalInfo)
14    from zope.password.interfaces import IPasswordManager
15except ImportError:
16    # BBB
17    from zope.app.authentication.interfaces import (
18        ICredentialsPlugin, IAuthenticatorPlugin, IPrincipalInfo,
19        IPasswordManager)
20from zope.securitypolicy.interfaces import IPrincipalRoleManager
21from zope.securitypolicy.principalrole import principalRoleManager
22from waeup.sirp.interfaces import IUserAccount, IAuthPluginUtility
23
24def setup_authentication(pau):
25    """Set up plugguble authentication utility.
26
27    Sets up an IAuthenticatorPlugin and
28    ICredentialsPlugin (for the authentication mechanism)
29
30    Then looks for any external utilities that want to modify the PAU.
31    """
32    pau.credentialsPlugins = ['No Challenge if Authenticated', 'credentials']
33    pau.authenticatorPlugins = ['users']
34
35    # Give any third-party code and subpackages a chance to modify the PAU
36    auth_plugin_utilities = getUtilitiesFor(IAuthPluginUtility)
37    for name, util in auth_plugin_utilities:
38        util.register(pau)
39
40class WAeUPSessionCredentialsPlugin(grok.GlobalUtility,
41                                    SessionCredentialsPlugin):
42    grok.provides(ICredentialsPlugin)
43    grok.name('credentials')
44
45    loginpagename = 'login'
46    loginfield = 'form.login'
47    passwordfield = 'form.password'
48
49class PrincipalInfo(object):
50    grok.implements(IPrincipalInfo)
51
52    def __init__(self, id, title, description):
53        self.id = id
54        self.title = title
55        self.description = description
56        self.credentialsPlugin = None
57        self.authenticatorPlugin = None
58
59class Account(grok.Model):
60    grok.implements(IUserAccount)
61
62    def __init__(self, name, password, title=None, description=None,
63                 roles = []):
64        self.name = name
65        if title is None:
66            title = name
67        if description is None:
68            description = title
69        self.title = title
70        self.description = description
71        self.setPassword(password)
72        self.setRoles(roles)
73
74    def setPassword(self, password):
75        passwordmanager = getUtility(IPasswordManager, 'SHA1')
76        self.password = passwordmanager.encodePassword(password)
77
78    def checkPassword(self, password):
79        passwordmanager = getUtility(IPasswordManager, 'SHA1')
80        return passwordmanager.checkPassword(self.password, password)
81
82    def getRoles(self):
83        prm = self._getPrincipalRoleManager()
84        roles = [x[0] for x in prm.getRolesForPrincipal(self.name)
85                 if x[0].startswith('waeup.')]
86        return roles
87
88    def setRoles(self, roles):
89        prm = self._getPrincipalRoleManager()
90
91        old_roles = self.getRoles()
92        for role in old_roles:
93            # Remove old roles, not to be set now...
94            if role.startswith('waeup.') and role not in roles:
95                prm.unsetRoleForPrincipal(role, self.name)
96
97        for role in roles:
98            prm.assignRoleToPrincipal(role, self.name)
99
100    roles = property(getRoles, setRoles)
101
102    def _getPrincipalRoleManager(self):
103        portal = grok.getSite()
104        if portal is not None:
105            return IPrincipalRoleManager(portal)
106        return principalRoleManager
107
108class UserAuthenticatorPlugin(grok.GlobalUtility):
109    grok.provides(IAuthenticatorPlugin)
110    grok.name('users')
111
112    def authenticateCredentials(self, credentials):
113        if not isinstance(credentials, dict):
114            return None
115        if not ('login' in credentials and 'password' in credentials):
116            return None
117        account = self.getAccount(credentials['login'])
118
119        if account is None:
120            return None
121        if not account.checkPassword(credentials['password']):
122            return None
123        return PrincipalInfo(id=account.name,
124                             title=account.title,
125                             description=account.description)
126
127    def principalInfo(self, id):
128        account = self.getAccount(id)
129        if account is None:
130            return None
131        return PrincipalInfo(id=account.name,
132                             title=account.title,
133                             description=account.description)
134
135    def getAccount(self, login):
136        # ... look up the account object and return it ...
137        usercontainer = self.getUserContainer()
138        if usercontainer is None:
139            return
140        return usercontainer.get(login, None)
141
142    def addAccount(self, account):
143        usercontainer = self.getUserContainer()
144        if usercontainer is None:
145            return
146        # XXX: complain if name already exists...
147        usercontainer.addAccount(account)
148
149    def addUser(self, name, password, title=None, description=None):
150        usercontainer = self.getUserContainer()
151        if usercontainer is None:
152            return
153        usercontainer.addUser(name, password, title, description)
154
155    def getUserContainer(self):
156        site = grok.getSite()
157        return site['users']
Note: See TracBrowser for help on using the repository browser.