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'] |   >>> person = concepts['person'] | ||||||
| 
 | 
 | ||||||
|   >>> from loops.concept import Concept |   >>> from loops.concept import Concept | ||||||
|   >>> johnC = concepts['john'] = Concept(u'John') |   >>> from loops.setup import addAndConfigureObject | ||||||
|   >>> johnC.conceptType = person |   >>> johnC = addAndConfigureObject(concepts, Concept, 'john', title=u'John', | ||||||
|  |   ...                               conceptType=person) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Organizations: Persons (and Users), Institutions, Addresses... | 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. | store a persistent (internal) principal object. | ||||||
| 
 | 
 | ||||||
|   >>> from loops.organize.auth import PersonBasedAuthenticator |   >>> 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 | Security | ||||||
|  | @ -332,7 +345,6 @@ Tasks and Events | ||||||
| Task view with edit action | Task view with edit action | ||||||
| -------------------------- | -------------------------- | ||||||
| 
 | 
 | ||||||
|   >>> from loops.setup import addAndConfigureObject |  | ||||||
|   >>> from loops.organize.interfaces import ITask |   >>> from loops.organize.interfaces import ITask | ||||||
|   >>> task = addAndConfigureObject(concepts, Concept, 'task', title=u'Task', |   >>> task = addAndConfigureObject(concepts, Concept, 'task', title=u'Task', | ||||||
|   ...                              conceptType=type, typeInterface=ITask) |   ...                              conceptType=type, typeInterface=ITask) | ||||||
|  | @ -399,7 +411,7 @@ Send Email to Members | ||||||
|   >>> form.subject |   >>> form.subject | ||||||
|   u"loops Notification from '$site'" |   u"loops Notification from '$site'" | ||||||
|   >>> form.mailBody |   >>> 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 | Fin de partie | ||||||
|  |  | ||||||
|  | @ -25,17 +25,34 @@ $Id$ | ||||||
| from persistent import Persistent | from persistent import Persistent | ||||||
| from zope.app.container.contained import Contained | from zope.app.container.contained import Contained | ||||||
| from zope import component | 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.interfaces import IAuthenticatorPlugin | ||||||
| from zope.app.authentication.principalfolder import PrincipalInfo | from zope.app.authentication.principalfolder import PrincipalInfo | ||||||
| from zope.app.principalannotation.interfaces import IPrincipalAnnotationUtility | from zope.app.principalannotation.interfaces import IPrincipalAnnotationUtility | ||||||
| from zope.app.security.interfaces import IAuthentication | 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): | class PersonBasedAuthenticator(Persistent, Contained): | ||||||
| 
 | 
 | ||||||
|     implements(IAuthenticatorPlugin) |     implements(IAuthenticatorPlugin, IPersonBasedAuthenticator) | ||||||
|  | 
 | ||||||
|  |     passwordKey = 'loops.organize.password' | ||||||
| 
 | 
 | ||||||
|     def __init__(self, prefix=''): |     def __init__(self, prefix=''): | ||||||
|         self.prefix = unicode(prefix) |         self.prefix = unicode(prefix) | ||||||
|  | @ -45,11 +62,8 @@ class PersonBasedAuthenticator(Persistent, Contained): | ||||||
|             return None |             return None | ||||||
|         login = credentials.get('login') |         login = credentials.get('login') | ||||||
|         password = credentials.get('password') |         password = credentials.get('password') | ||||||
|         if not login or not password : |         if self.checkPassword(login, password): | ||||||
|             return None |             return PrincipalInfo(self.prefix + login, login, login, u'') | ||||||
|         id = self.prefix + login |  | ||||||
|         if self._checkPassword(id, password): |  | ||||||
|             return PrincipalInfo(id, login, login, u'') |  | ||||||
|         return None |         return None | ||||||
| 
 | 
 | ||||||
|     def principalInfo(self, id): |     def principalInfo(self, id): | ||||||
|  | @ -58,19 +72,35 @@ class PersonBasedAuthenticator(Persistent, Contained): | ||||||
|             if login: |             if login: | ||||||
|                 return PrincipalInfo(id, login, login, u'') |                 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): |     def setPassword(self, login, password): | ||||||
|         id = self.prefix + login |         pa = self.getPrincipalAnnotations( | ||||||
|         pa = self.getPrincipalAnnotations(id) |                         getParent(self).prefix + self.prefix + login) | ||||||
|         pa['loops.organize.password'] = password |         pa[self.passwordKey] = password | ||||||
| 
 | 
 | ||||||
|     @Lazy |     def getPrincipalAnnotations(self, id): | ||||||
|     def principalAnnotations(self): |         utility = component.getUtility(IPrincipalAnnotationUtility) | ||||||
|         return component.getUtility(IPrincipalAnnotationUtility) |         return utility.getAnnotationsById(id) | ||||||
| 
 | 
 | ||||||
|     def getPrincipalAnnotations(id): |     def get(self, login): | ||||||
|         return self.principalAnnotations.getAnnotationsById(id) |         return InternalPrincipal(self, login) | ||||||
| 
 | 
 | ||||||
|     def _checkPassword(self, id, password): | 
 | ||||||
|         pa = self.getPrincipalAnnotations(id) | class InternalPrincipal(object): | ||||||
|         return pa.get('loops.organize.password') == password | 
 | ||||||
|  |     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" |       class="loops.organize.browser.party.SendEmailForm" | ||||||
|       permission="zope.View" /> |       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> | </configure> | ||||||
|  |  | ||||||
|  | @ -48,6 +48,14 @@ | ||||||
|              interface="loops.organize.interfaces.IMemberRegistrationManager" /> |              interface="loops.organize.interfaces.IMemberRegistrationManager" /> | ||||||
|   </zope:class> |   </zope:class> | ||||||
| 
 | 
 | ||||||
|  |   <!-- authentication --> | ||||||
|  | 
 | ||||||
|  |   <zope:localUtility class="loops.organize.auth.PersonBasedAuthenticator"> | ||||||
|  |     <require | ||||||
|  |         permission="zope.ManageServices" | ||||||
|  |         attributes="prefix" /> | ||||||
|  |   </zope:localUtility> | ||||||
|  | 
 | ||||||
|   <!-- other adapters --> |   <!-- other adapters --> | ||||||
| 
 | 
 | ||||||
|   <zope:adapter factory="loops.organize.schema.PersonSchemaFactory" /> |   <zope:adapter factory="loops.organize.schema.PersonSchemaFactory" /> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 helmutm
						helmutm