"""Authentication for WAeUP portals. """ import grok from zope import schema from zope.app.authentication.session import SessionCredentialsPlugin from zope.app.authentication.interfaces import (ICredentialsPlugin, IAuthenticatorPlugin, IPrincipalInfo, IPasswordManager) from zope.app.security.interfaces import (IAuthentication, IUnauthenticatedPrincipal, ILogout) from zope.component import getUtility from zope.interface import Interface from waeup.interfaces import IWAeUPObject from waeup.viewlets import Index, MainArea, LeftSidebar def setup_authentication(pau): """Set up plugguble authentication utility. Sets up an IAuthenticatorPlugin and ICredentialsPlugin (for the authentication mechanism) """ pau.credentialsPlugins = ['credentials'] pau.authenticatorPlugins = ['users'] class WAeUPSessionCredentialsPlugin(grok.GlobalUtility, SessionCredentialsPlugin): grok.provides(ICredentialsPlugin) grok.name('credentials') loginpagename = 'login' loginfield = 'form.login' passwordfield = 'form.password' class Login(grok.View): grok.context(IWAeUPObject) grok.require('zope.Public') def update(self, SUBMIT=None): self.camefrom = self.request.form.get('camefrom', '') if SUBMIT is not None: self.redirect(self.camefrom) class LoginMain(grok.Viewlet): grok.viewletmanager(MainArea) grok.context(IWAeUPObject) grok.view(Login) class Logout(grok.Viewlet): grok.viewletmanager(LeftSidebar) grok.context(IWAeUPObject) grok.order(3) grok.require('zope.Public') def update(self): if 'form.logout' not in self.request.form.keys(): return if not IUnauthenticatedPrincipal.providedBy(self.request.principal): auth = getUtility(IAuthentication) ILogout(auth).logout(self.request) # We redirect to ourself, as we want this page be loaded # without authentication (updating other viewlets on the # page) self.view.redirect(self.view.url()) class PrincipalInfo(object): grok.implements(IPrincipalInfo) def __init__(self, id, title, description): self.id = id self.title = title self.description = description self.credentialsPlugin = None self.authenticatorPlugin = None class Account(grok.Model): def __init__(self, name, password): self.name = name self.setPassword(password) def setPassword(self, password): passwordmanager = getUtility(IPasswordManager, 'SHA1') self.password = passwordmanager.encodePassword(password) def checkPassword(self, password): passwordmanager = getUtility(IPasswordManager, 'SHA1') return passwordmanager.checkPassword(self.password, password) class UserAuthenticatorPlugin(grok.GlobalUtility): grok.provides(IAuthenticatorPlugin) grok.name('users') def authenticateCredentials(self, credentials): if not isinstance(credentials, dict): return None if not ('login' in credentials and 'password' in credentials): return None account = self.getAccount(credentials['login']) if account is None: return None if not account.checkPassword(credentials['password']): return None return PrincipalInfo(id=account.name, title=account.name, description=account.name) def principalInfo(self, id): account = self.getAccount(id) if account is None: return None return PrincipalInfo(id=account.name, title=account.name, description=account.name) def getAccount(self, login): # XXX: while developing, we only support a single user. if login == 'grok': return Account('grok', 'grok') return #... look up the account object and return it ...