new authenticator plug-in: virtual principals, based on person objects (work in progress)

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3270 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2009-03-09 13:44:04 +00:00
parent 498a099759
commit cc3652db1c
4 changed files with 99 additions and 23 deletions

View file

@ -33,8 +33,9 @@ ZCML setup):
>>> person = concepts['person']
>>> from loops.concept import Concept
>>> johnC = concepts['john'] = Concept(u'John')
>>> johnC.conceptType = person
>>> from loops.setup import addAndConfigureObject
>>> johnC = addAndConfigureObject(concepts, Concept, 'john', title=u'John',
... conceptType=person)
Organizations: Persons (and Users), Institutions, Addresses...
@ -237,6 +238,18 @@ The person-based authenticator provides authentication without having to
store a persistent (internal) principal object.
>>> from loops.organize.auth import PersonBasedAuthenticator
>>> pbAuth = PersonBasedAuthenticator('persons.')
>>> pau['persons'] = pbAuth
>>> pau.authenticatorPlugins = ('loops', 'persons',)
>>> eddieC = addAndConfigureObject(concepts, Concept, 'eddie', title=u'Eddie',
... conceptType=person)
>>> eddie = adapted(eddieC)
>>> eddie.userId = 'persons.eddie'
>>> pbAuth.setPassword('eddie', 'secret')
>>> pbAuth.authenticateCredentials(dict(login='eddie', password='secret'))
PrincipalInfo(u'persons.eddie')
Security
@ -332,7 +345,6 @@ Tasks and Events
Task view with edit action
--------------------------
>>> from loops.setup import addAndConfigureObject
>>> from loops.organize.interfaces import ITask
>>> task = addAndConfigureObject(concepts, Concept, 'task', title=u'Task',
... conceptType=type, typeInterface=ITask)
@ -399,7 +411,7 @@ Send Email to Members
>>> form.subject
u"loops Notification from '$site'"
>>> form.mailBody
u'\n\nEvent #1\nhttp://127.0.0.1/loops/views/menu/.target95\n\n'
u'\n\nEvent #1\nhttp://127.0.0.1/loops/views/menu/.target97\n\n'
Fin de partie

View file

@ -25,17 +25,34 @@ $Id$
from persistent import Persistent
from zope.app.container.contained import Contained
from zope import component
from zope.interface import implements
from zope.interface import Interface, implements
from zope.app.authentication.interfaces import IAuthenticatorPlugin
from zope.app.authentication.principalfolder import PrincipalInfo
from zope.app.principalannotation.interfaces import IPrincipalAnnotationUtility
from zope.app.security.interfaces import IAuthentication
from zope.cachedescriptors.property import Lazy
from zope import schema
from zope.traversing.api import getParent
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)
implements(IAuthenticatorPlugin, IPersonBasedAuthenticator)
passwordKey = 'loops.organize.password'
def __init__(self, prefix=''):
self.prefix = unicode(prefix)
@ -45,11 +62,8 @@ class PersonBasedAuthenticator(Persistent, Contained):
return None
login = credentials.get('login')
password = credentials.get('password')
if not login or not password :
return None
id = self.prefix + login
if self._checkPassword(id, password):
return PrincipalInfo(id, login, login, u'')
if self.checkPassword(login, password):
return PrincipalInfo(self.prefix + login, login, login, u'')
return None
def principalInfo(self, id):
@ -58,19 +72,35 @@ class PersonBasedAuthenticator(Persistent, Contained):
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)
return pa.get(self.passwordKey) == password
return None
def setPassword(self, login, password):
id = self.prefix + login
pa = self.getPrincipalAnnotations(id)
pa['loops.organize.password'] = password
pa = self.getPrincipalAnnotations(
getParent(self).prefix + self.prefix + login)
pa[self.passwordKey] = password
@Lazy
def principalAnnotations(self):
return component.getUtility(IPrincipalAnnotationUtility)
def getPrincipalAnnotations(self, id):
utility = component.getUtility(IPrincipalAnnotationUtility)
return utility.getAnnotationsById(id)
def getPrincipalAnnotations(id):
return self.principalAnnotations.getAnnotationsById(id)
def get(self, login):
return InternalPrincipal(self, login)
def _checkPassword(self, id, password):
pa = self.getPrincipalAnnotations(id)
return pa.get('loops.organize.password') == password
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)

View file

@ -62,4 +62,30 @@
class="loops.organize.browser.party.SendEmailForm"
permission="zope.View" />
<!-- authentication -->
<browser:addform
schema="loops.organize.auth.IPersonBasedAuthenticator"
label="Add Person-based Authenticator"
content_factory="loops.organize.auth.PersonBasedAuthenticator"
keyword_arguments="prefix"
name="AddPersonBasedAuthenticator.html"
permission="zope.ManageServices"
/>
<browser:addMenuItem
title="Person-based Authenticator"
description="An authentication plugin for loops Persons"
class="loops.organize.auth.PersonBasedAuthenticator"
permission="zope.ManageServices"
view="AddPersonBasedAuthenticator.html" />
<browser:schemadisplay
schema="loops.organize.auth.IPersonBasedAuthenticator"
label="Authenticator Prefix"
name="prefix.html"
fields="prefix"
permission="zope.ManageServices"
menu="zmi_views" title="Prefix" />
</configure>

View file

@ -48,6 +48,14 @@
interface="loops.organize.interfaces.IMemberRegistrationManager" />
</zope:class>
<!-- authentication -->
<zope:localUtility class="loops.organize.auth.PersonBasedAuthenticator">
<require
permission="zope.ManageServices"
attributes="prefix" />
</zope:localUtility>
<!-- other adapters -->
<zope:adapter factory="loops.organize.schema.PersonSchemaFactory" />