source: waeup/branches/ulif-layout/src/waeup/authentication.py @ 4606

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

Remove student login view and viewlet. They moved to browser
subpackage.

File size: 5.9 KB
Line 
1"""Authentication for WAeUP portals.
2"""
3import grok
4from zope import schema
5from zope.app.authentication.session import SessionCredentialsPlugin
6from zope.app.authentication.interfaces import (ICredentialsPlugin,
7                                                IAuthenticatorPlugin,
8                                                IPrincipalInfo,
9                                                IPasswordManager)
10from zope.app.security.interfaces import (IAuthentication,
11                                          IUnauthenticatedPrincipal,
12                                          ILogout)
13from zope.component import getUtility
14from zope.interface import Interface
15from zope.securitypolicy.interfaces import IPrincipalRoleManager
16from zope.securitypolicy.principalrole import principalRoleManager
17from waeup.interfaces import IWAeUPObject, IUserAccount
18from waeup.viewlets import Index, MainArea, LeftSidebar
19import waeup.permissions
20
21def setup_authentication(pau):
22    """Set up plugguble authentication utility.
23
24    Sets up an IAuthenticatorPlugin and
25    ICredentialsPlugin (for the authentication mechanism)
26    """
27    pau.credentialsPlugins = ['No Challenge if Authenticated', 'credentials']
28    pau.authenticatorPlugins = ['users']
29
30class WAeUPSessionCredentialsPlugin(grok.GlobalUtility,
31                                    SessionCredentialsPlugin):
32    grok.provides(ICredentialsPlugin)
33    grok.name('credentials')
34
35    loginpagename = 'login'
36    loginfield = 'form.login'
37    passwordfield = 'form.password'
38
39   
40class Logout(grok.Viewlet):
41    grok.viewletmanager(LeftSidebar)
42    grok.context(IWAeUPObject)
43    grok.order(3)
44    # grok.require('zope.Public') # XXX: Does not work in ftests!
45   
46    def update(self):
47        if 'form.logout' not in self.request.form.keys():
48            return
49        if not IUnauthenticatedPrincipal.providedBy(self.request.principal):
50            auth = getUtility(IAuthentication)
51            ILogout(auth).logout(self.request)
52            # We redirect to ourself, as we want this page be loaded
53            # without authentication (updating other viewlets on the
54            # page)
55            self.view.flash("You're logged out.")
56            self.view.redirect(self.view.url())
57
58class PrincipalInfo(object):
59    grok.implements(IPrincipalInfo)
60
61    def __init__(self, id, title, description):
62        self.id = id
63        self.title = title
64        self.description = description
65        self.credentialsPlugin = None
66        self.authenticatorPlugin = None
67
68class Account(grok.Model):
69    grok.implements(IUserAccount)
70
71
72    def __init__(self, name, password, title=None, description=None,
73                 roles = []):
74        self.name = name
75        if title is None:
76            title = name
77        if description is None:
78            description = title
79        self.title = title
80        self.description = description
81        self.setPassword(password)
82        self.setRoles(roles)
83
84    def setPassword(self, password):
85        passwordmanager = getUtility(IPasswordManager, 'SHA1')
86        self.password = passwordmanager.encodePassword(password)
87
88    def checkPassword(self, password):
89        passwordmanager = getUtility(IPasswordManager, 'SHA1')
90        return passwordmanager.checkPassword(self.password, password)
91
92    def getRoles(self):
93        prm = self._getPrincipalRoleManager()
94        roles = [x[0] for x in prm.getRolesForPrincipal(self.name)
95                 if x[0].startswith('waeup.')]
96        return roles
97   
98    def setRoles(self, roles):
99        prm = self._getPrincipalRoleManager()
100       
101        old_roles = self.getRoles()
102        for role in old_roles:
103            # Remove old roles, not to be set now...
104            if role.startswith('waeup.') and role not in roles:
105                prm.unsetRoleForPrincipal(role, self.name)
106
107        for role in roles:
108            prm.assignRoleToPrincipal(role, self.name)
109
110    roles = property(getRoles, setRoles)
111
112    def _getPrincipalRoleManager(self):
113        portal = grok.getSite()
114        if portal is not None:
115            return IPrincipalRoleManager(portal)
116        return principalRoleManager
117       
118   
119class UserAuthenticatorPlugin(grok.GlobalUtility):
120    grok.provides(IAuthenticatorPlugin)
121    grok.name('users')
122
123    def authenticateCredentials(self, credentials):
124        if not isinstance(credentials, dict):
125            return None
126        if not ('login' in credentials and 'password' in credentials):
127            return None
128        account = self.getAccount(credentials['login'])
129
130        if account is None:
131            return None
132        if not account.checkPassword(credentials['password']):
133            return None
134        return PrincipalInfo(id=account.name,
135                             title=account.name,
136                             description=account.name)
137
138    def principalInfo(self, id):
139        account = self.getAccount(id)
140        if account is None:
141            return None
142        return PrincipalInfo(id=account.name,
143                             title=account.name,
144                             description=account.name)
145
146    def getAccount(self, login):
147        # XXX: while developing, we only support a single user.
148        if login == 'grok':
149            return Account('grok', 'grok')
150
151        # ... look up the account object and return it ...
152        usercontainer = self.getUserContainer()
153        if usercontainer is None:
154            return
155        return usercontainer.get(login, None)
156
157    def addAccount(self, account):
158        usercontainer = self.getUserContainer()
159        if usercontainer is None:
160            return
161        # XXX: complain if name already exists...
162        usercontainer.addAccount(account)
163
164    def addUser(self, name, password, title=None, description=None):
165        usercontainer = self.getUserContainer()
166        if usercontainer is None:
167            return
168        usercontainer.addUser(name, password, title, description)
169       
170    def getUserContainer(self):
171        site = grok.getSite()
172        return getattr(site, 'users', None)
Note: See TracBrowser for help on using the repository browser.