# # Copyright (c) 2009 Helmut Merz helmutm@cy55.de # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Specialized authentication components. $Id$ """ from persistent import Persistent from zope.app.container.contained import Contained from zope import component from zope.interface import Interface, implements from zope.app.authentication.interfaces import IAuthenticatorPlugin from zope.app.authentication.principalfolder import IInternalPrincipal from zope.app.authentication.principalfolder import PrincipalInfo from zope.app.principalannotation.interfaces import IPrincipalAnnotationUtility from zope.app.security.interfaces import IAuthentication from zope import schema from zope.traversing.api import getParent from cybertools.browser.loops.auth import LoopsSessionCredentialsPlugin \ as BaseSessionCredentialsPlugin from loops.organize.interfaces import IPresence from loops.util import _ class IPersonBasedAuthenticator(Interface): prefix = schema.TextLine( title=_("Prefix"), description=_( "Prefix to be added to all principal ids to assure " "that all ids are unique within the authentication service"), missing_value=u"", default=u'', readonly=True) class PersonBasedAuthenticator(Persistent, Contained): implements(IAuthenticatorPlugin, IPersonBasedAuthenticator) passwordKey = 'loops.organize.password' ignoreCase = True def __init__(self, prefix=''): self.prefix = unicode(prefix) def authenticateCredentials(self, credentials): if not isinstance(credentials, dict): return None login = credentials.get('login') password = credentials.get('password') if self.checkPassword(login, password): return PrincipalInfo(self.prefix + login, login, login, u'') return None def principalInfo(self, id): if id.startswith(self.prefix): login = id[len(self.prefix):] if login: return PrincipalInfo(id, login, login, u'') def checkPassword(self, login, password): if login and password: pa = self.getPrincipalAnnotations( getParent(self).prefix + self.prefix + login) if self.ignoreCase: password = password.lower() return pa.get(self.passwordKey) == password return None def setPassword(self, login, password): if self.ignoreCase: password = password.lower() pa = self.getPrincipalAnnotations( getParent(self).prefix + self.prefix + login) pa[self.passwordKey] = password def getPassword(self, login): pa = self.getPrincipalAnnotations( getParent(self).prefix + self.prefix + login) return pa.get(self.passwordKey) def getPrincipalAnnotations(self, id): utility = component.getUtility(IPrincipalAnnotationUtility) return utility.getAnnotationsById(id) def get(self, login): return InternalPrincipal(self, login) class LoopsSessionCredentialsPlugin(BaseSessionCredentialsPlugin): def logout(self, request): presence = component.getUtility(IPresence) presence.removePresentUser(request.principal.id) super(LoopsSessionCredentialsPlugin, self).logout(request) class InternalPrincipal(object): def __init__(self, auth, login): self.auth = auth self.login = login def checkPassword(self, password): return self.auth.checkPassword(self.login, password) def setPassword(self, passowrd): self.auth.setPassword(self.login, password)