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

Last change on this file since 6006 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
RevLine 
[4073]1"""Authentication for WAeUP portals.
2"""
3import grok
[5055]4import waeup.sirp.permissions
[5900]5from zope.component import getUtility, getUtilitiesFor
[5055]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)
[4129]20from zope.securitypolicy.interfaces import IPrincipalRoleManager
21from zope.securitypolicy.principalrole import principalRoleManager
[5900]22from waeup.sirp.interfaces import IUserAccount, IAuthPluginUtility
[4073]23
24def setup_authentication(pau):
25    """Set up plugguble authentication utility.
26
27    Sets up an IAuthenticatorPlugin and
28    ICredentialsPlugin (for the authentication mechanism)
[5900]29
30    Then looks for any external utilities that want to modify the PAU.
[4073]31    """
[4576]32    pau.credentialsPlugins = ['No Challenge if Authenticated', 'credentials']
[4073]33    pau.authenticatorPlugins = ['users']
34
[5900]35    # Give any third-party code and subpackages a chance to modify the PAU
36    auth_plugin_utilities = getUtilitiesFor(IAuthPluginUtility)
[5901]37    for name, util in auth_plugin_utilities:
[5900]38        util.register(pau)
39
[4073]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):
[4109]60    grok.implements(IUserAccount)
[4129]61
[4125]62    def __init__(self, name, password, title=None, description=None,
63                 roles = []):
[4073]64        self.name = name
[4087]65        if title is None:
66            title = name
67        if description is None:
68            description = title
69        self.title = title
70        self.description = description
[4073]71        self.setPassword(password)
[4129]72        self.setRoles(roles)
[4073]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
[4129]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
[5055]87
[4129]88    def setRoles(self, roles):
89        prm = self._getPrincipalRoleManager()
[5055]90
[4129]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
[5055]107
[4073]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,
[4612]124                             title=account.title,
125                             description=account.description)
[4073]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,
[4612]132                             title=account.title,
133                             description=account.description)
[4073]134
135    def getAccount(self, login):
[4087]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
[4091]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)
[5055]154
[4087]155    def getUserContainer(self):
156        site = grok.getSite()
[4743]157        return site['users']
Note: See TracBrowser for help on using the repository browser.