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

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

Add method to add users via authenticator plugin.

File size: 5.2 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 waeup.interfaces import IWAeUPObject
16from waeup.viewlets import Index, MainArea, LeftSidebar
17import waeup.permissions
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)
39    # grok.require('zope.Public') # XXX: Does not work in ftests!
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)
55    # grok.require('zope.Public') # XXX: Does not work in ftests!
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):
79    def __init__(self, name, password, title=None, description=None):
80        self.name = name
81        if title is None:
82            title = name
83        if description is None:
84            description = title
85        self.title = title
86        self.description = description
87        self.setPassword(password)
88
89    def setPassword(self, password):
90        passwordmanager = getUtility(IPasswordManager, 'SHA1')
91        self.password = passwordmanager.encodePassword(password)
92
93    def checkPassword(self, password):
94        passwordmanager = getUtility(IPasswordManager, 'SHA1')
95        return passwordmanager.checkPassword(self.password, password)
96
97 
98class UserAuthenticatorPlugin(grok.GlobalUtility):
99    grok.provides(IAuthenticatorPlugin)
100    grok.name('users')
101
102    def authenticateCredentials(self, credentials):
103        if not isinstance(credentials, dict):
104            return None
105        if not ('login' in credentials and 'password' in credentials):
106            return None
107        account = self.getAccount(credentials['login'])
108
109        if account is None:
110            return None
111        if not account.checkPassword(credentials['password']):
112            return None
113        return PrincipalInfo(id=account.name,
114                             title=account.name,
115                             description=account.name)
116
117    def principalInfo(self, id):
118        account = self.getAccount(id)
119        if account is None:
120            return None
121        return PrincipalInfo(id=account.name,
122                             title=account.name,
123                             description=account.name)
124
125    def getAccount(self, login):
126        # XXX: while developing, we only support a single user.
127        if login == 'grok':
128            return Account('grok', 'grok')
129
130        # ... look up the account object and return it ...
131        usercontainer = self.getUserContainer()
132        if usercontainer is None:
133            return
134        return usercontainer.get(login, None)
135
136    def addAccount(self, account):
137        usercontainer = self.getUserContainer()
138        if usercontainer is None:
139            return
140        # XXX: complain if name already exists...
141        usercontainer.addAccount(account)
142
143    def addUser(self, name, password, title=None, description=None):
144        usercontainer = self.getUserContainer()
145        if usercontainer is None:
146            return
147        usercontainer.addUser(name, password, title, description)
148       
149    def getUserContainer(self):
150        site = grok.getSite()
151        return getattr(site, 'users', None)
Note: See TracBrowser for help on using the repository browser.