"""Authentication for WAeUP portals. """ import grok from zope.app.authentication.session import SessionCredentialsPlugin from zope.app.authentication.interfaces import (ICredentialsPlugin, IAuthenticatorPlugin, IPrincipalInfo, IPasswordManager) from zope.component import getUtility from zope.securitypolicy.interfaces import IPrincipalRoleManager from zope.securitypolicy.principalrole import principalRoleManager from waeup.interfaces import IUserAccount import waeup.permissions def setup_authentication(pau): """Set up plugguble authentication utility. Sets up an IAuthenticatorPlugin and ICredentialsPlugin (for the authentication mechanism) """ pau.credentialsPlugins = ['No Challenge if Authenticated', 'credentials'] pau.authenticatorPlugins = ['users'] class WAeUPSessionCredentialsPlugin(grok.GlobalUtility, SessionCredentialsPlugin): grok.provides(ICredentialsPlugin) grok.name('credentials') loginpagename = 'login' loginfield = 'form.login' passwordfield = 'form.password' 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): grok.implements(IUserAccount) def __init__(self, name, password, title=None, description=None, roles = []): self.name = name if title is None: title = name if description is None: description = title self.title = title self.description = description self.setPassword(password) self.setRoles(roles) 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) def getRoles(self): prm = self._getPrincipalRoleManager() roles = [x[0] for x in prm.getRolesForPrincipal(self.name) if x[0].startswith('waeup.')] return roles def setRoles(self, roles): prm = self._getPrincipalRoleManager() old_roles = self.getRoles() for role in old_roles: # Remove old roles, not to be set now... if role.startswith('waeup.') and role not in roles: prm.unsetRoleForPrincipal(role, self.name) for role in roles: prm.assignRoleToPrincipal(role, self.name) roles = property(getRoles, setRoles) def _getPrincipalRoleManager(self): portal = grok.getSite() if portal is not None: return IPrincipalRoleManager(portal) return principalRoleManager 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.title, description=account.description) def principalInfo(self, id): account = self.getAccount(id) if account is None: return None return PrincipalInfo(id=account.name, title=account.title, description=account.description) def getAccount(self, login): # ... look up the account object and return it ... usercontainer = self.getUserContainer() if usercontainer is None: return return usercontainer.get(login, None) def addAccount(self, account): usercontainer = self.getUserContainer() if usercontainer is None: return # XXX: complain if name already exists... usercontainer.addAccount(account) def addUser(self, name, password, title=None, description=None): usercontainer = self.getUserContainer() if usercontainer is None: return usercontainer.addUser(name, password, title, description) def getUserContainer(self): site = grok.getSite() return site['users']