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:
parent
498a099759
commit
cc3652db1c
4 changed files with 99 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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" />
|
||||
|
|
Loading…
Add table
Reference in a new issue