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

Last change on this file since 5050 was 4920, checked in by uli, 15 years ago

Make unit tests run again with the new package layout.

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