source: waeup/branches/ulif-rewrite/src/waeup/authentication.py @ 4109

Last change on this file since 4109 was 4109, checked in by uli, 16 years ago

Let Account implement IUserAccount.

File size: 5.2 KB
RevLine 
[4073]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
[4109]15from waeup.interfaces import IWAeUPObject, IUserAccount
[4073]16from waeup.viewlets import Index, MainArea, LeftSidebar
[4075]17import waeup.permissions
[4073]18
19def setup_authentication(pau):
20    """Set up plugguble authentication utility.
21
22    Sets up an IAuthenticatorPlugin and
23    ICredentialsPlugin (for the authentication mechanism)
24    """
25    pau.credentialsPlugins = ['credentials']
26    pau.authenticatorPlugins = ['users']
27
28class WAeUPSessionCredentialsPlugin(grok.GlobalUtility,
29                                    SessionCredentialsPlugin):
30    grok.provides(ICredentialsPlugin)
31    grok.name('credentials')
32
33    loginpagename = 'login'
34    loginfield = 'form.login'
35    passwordfield = 'form.password'
36
37class Login(grok.View):
38    grok.context(IWAeUPObject)
[4075]39    # grok.require('zope.Public') # XXX: Does not work in ftests!
[4073]40
41    def update(self, SUBMIT=None):
42        self.camefrom = self.request.form.get('camefrom', '')
43        if SUBMIT is not None:
44            self.redirect(self.camefrom)
45           
46class LoginMain(grok.Viewlet):
47    grok.viewletmanager(MainArea)
48    grok.context(IWAeUPObject)
49    grok.view(Login)
50
51class Logout(grok.Viewlet):
52    grok.viewletmanager(LeftSidebar)
53    grok.context(IWAeUPObject)
54    grok.order(3)
[4075]55    # grok.require('zope.Public') # XXX: Does not work in ftests!
[4073]56   
57    def update(self):
58        if 'form.logout' not in self.request.form.keys():
59            return
60        if not IUnauthenticatedPrincipal.providedBy(self.request.principal):
61            auth = getUtility(IAuthentication)
62            ILogout(auth).logout(self.request)
63            # We redirect to ourself, as we want this page be loaded
64            # without authentication (updating other viewlets on the
65            # page)
66            self.view.redirect(self.view.url())
67
68class PrincipalInfo(object):
69    grok.implements(IPrincipalInfo)
70
71    def __init__(self, id, title, description):
72        self.id = id
73        self.title = title
74        self.description = description
75        self.credentialsPlugin = None
76        self.authenticatorPlugin = None
77
78class Account(grok.Model):
[4109]79    grok.implements(IUserAccount)
80   
[4087]81    def __init__(self, name, password, title=None, description=None):
[4073]82        self.name = name
[4087]83        if title is None:
84            title = name
85        if description is None:
86            description = title
87        self.title = title
88        self.description = description
[4073]89        self.setPassword(password)
90
91    def setPassword(self, password):
92        passwordmanager = getUtility(IPasswordManager, 'SHA1')
93        self.password = passwordmanager.encodePassword(password)
94
95    def checkPassword(self, password):
96        passwordmanager = getUtility(IPasswordManager, 'SHA1')
97        return passwordmanager.checkPassword(self.password, password)
98
99 
100class UserAuthenticatorPlugin(grok.GlobalUtility):
101    grok.provides(IAuthenticatorPlugin)
102    grok.name('users')
103
104    def authenticateCredentials(self, credentials):
105        if not isinstance(credentials, dict):
106            return None
107        if not ('login' in credentials and 'password' in credentials):
108            return None
109        account = self.getAccount(credentials['login'])
110
111        if account is None:
112            return None
113        if not account.checkPassword(credentials['password']):
114            return None
115        return PrincipalInfo(id=account.name,
116                             title=account.name,
117                             description=account.name)
118
119    def principalInfo(self, id):
120        account = self.getAccount(id)
121        if account is None:
122            return None
123        return PrincipalInfo(id=account.name,
124                             title=account.name,
125                             description=account.name)
126
127    def getAccount(self, login):
128        # XXX: while developing, we only support a single user.
129        if login == 'grok':
130            return Account('grok', 'grok')
[4087]131
132        # ... look up the account object and return it ...
133        usercontainer = self.getUserContainer()
134        if usercontainer is None:
135            return
136        return usercontainer.get(login, None)
137
138    def addAccount(self, account):
139        usercontainer = self.getUserContainer()
140        if usercontainer is None:
141            return
142        # XXX: complain if name already exists...
143        usercontainer.addAccount(account)
144
[4091]145    def addUser(self, name, password, title=None, description=None):
146        usercontainer = self.getUserContainer()
147        if usercontainer is None:
148            return
149        usercontainer.addUser(name, password, title, description)
150       
[4087]151    def getUserContainer(self):
152        site = grok.getSite()
[4091]153        return getattr(site, 'users', None)
Note: See TracBrowser for help on using the repository browser.