
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1220 fd906abe-77d9-0310-91a1-e0d9ade77398
238 lines
8 KiB
Text
238 lines
8 KiB
Text
===============================================================
|
|
loops - Linked Objects for Organization and Processing Services
|
|
===============================================================
|
|
|
|
($Id$)
|
|
|
|
Note: This packages depends on cybertools.organize.
|
|
|
|
Let's do some basic set up
|
|
|
|
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
|
>>> site = placefulSetUp(True)
|
|
|
|
>>> from zope import component, interface
|
|
>>> from zope.app import zapi
|
|
|
|
and setup a simple loops site with a concept manager and some concepts
|
|
(with all the type machinery, what in real life is done via standard
|
|
ZCML setup):
|
|
|
|
>>> from loops import Loops
|
|
>>> from loops.concept import ConceptManager, Concept
|
|
>>> from loops.interfaces import IConcept, ITypeConcept
|
|
|
|
>>> loopsRoot = site['loops'] = Loops()
|
|
|
|
>>> from cybertools.relation.interfaces import IRelationRegistry
|
|
>>> from cybertools.relation.registry import DummyRelationRegistry
|
|
>>> relations = DummyRelationRegistry()
|
|
>>> component.provideUtility(relations, IRelationRegistry)
|
|
|
|
>>> from cybertools.typology.interfaces import IType
|
|
>>> from loops.type import ConceptType, TypeConcept
|
|
>>> component.provideAdapter(ConceptType, (IConcept,), IType)
|
|
>>> component.provideAdapter(TypeConcept, (IConcept,), ITypeConcept)
|
|
|
|
>>> loopsRoot['concepts'] = ConceptManager()
|
|
>>> concepts = loopsRoot['concepts']
|
|
|
|
>>> concepts['hasType'] = Concept(u'has type')
|
|
>>> concepts['type'] = Concept(u'Type')
|
|
>>> type = concepts['type']
|
|
>>> type.conceptType = type
|
|
|
|
>>> from loops.organize.interfaces import IPerson
|
|
>>> concepts['person'] = Concept(u'Person')
|
|
>>> person = concepts['person']
|
|
>>> person.conceptType = type
|
|
>>> ITypeConcept(person).typeInterface = IPerson
|
|
|
|
>>> johnC = Concept(u'John')
|
|
>>> concepts['john'] = johnC
|
|
>>> johnC.conceptType = person
|
|
|
|
|
|
Organizations: Persons (and Users), Institutions, Addresses...
|
|
==============================================================
|
|
|
|
The classes used in this package are just adapters to IConcept.
|
|
|
|
>>> from loops.organize.party import Person
|
|
>>> component.provideAdapter(Person, (IConcept,), IPerson)
|
|
|
|
>>> john = IPerson(johnC)
|
|
>>> john.title
|
|
u'John'
|
|
>>> john.firstName = u'John'
|
|
>>> johnC._firstName
|
|
u'John'
|
|
>>> john.lastName is None
|
|
True
|
|
>>> john.someOtherAttribute
|
|
Traceback (most recent call last):
|
|
...
|
|
AttributeError: someOtherAttribute
|
|
|
|
We can use the age calculations from the base Person class:
|
|
|
|
>>> from datetime import date
|
|
>>> john.birthDate = date(1980, 3, 26)
|
|
>>> john.ageAt(date(2006, 5, 12))
|
|
26
|
|
>>> john.age >= 26
|
|
True
|
|
|
|
A person can be associated with a user of the system by setting the
|
|
userId attribute; this will also register the person concept in the
|
|
corresponding principal annotations so that there is a fast way to find
|
|
the person(s) belonging to a user/principal.
|
|
|
|
For testing, we first have to provide the needed utilities and settings
|
|
(in real life this is all done during Zope startup):
|
|
|
|
>>> from zope.app.security.interfaces import IAuthentication
|
|
>>> from zope.app.security.principalregistry import PrincipalRegistry
|
|
>>> auth = PrincipalRegistry()
|
|
>>> component.provideUtility(auth, IAuthentication)
|
|
|
|
>>> from zope.app.principalannotation.interfaces import IPrincipalAnnotationUtility
|
|
>>> from zope.app.principalannotation import PrincipalAnnotationUtility
|
|
>>> principalAnnotations = PrincipalAnnotationUtility()
|
|
>>> component.provideUtility(principalAnnotations, IPrincipalAnnotationUtility)
|
|
|
|
>>> principal = auth.definePrincipal('users.john', u'John', login='john')
|
|
|
|
>>> john.userId = 'users.john'
|
|
|
|
>>> annotations = principalAnnotations.getAnnotationsById('users.john')
|
|
>>> from loops.organize.party import ANNOTATION_KEY
|
|
>>> annotations.get(ANNOTATION_KEY) == johnC
|
|
True
|
|
|
|
Change a userId assignment:
|
|
|
|
>>> principal = auth.definePrincipal('users.johnny', u'Johnny', login='johnny')
|
|
>>> john.userId = 'users.johnny'
|
|
|
|
>>> annotations = principalAnnotations.getAnnotationsById('users.johnny')
|
|
>>> annotations.get(ANNOTATION_KEY) == johnC
|
|
True
|
|
>>> annotations = principalAnnotations.getAnnotationsById('users.john')
|
|
>>> annotations.get(ANNOTATION_KEY) is None
|
|
True
|
|
|
|
>>> john.userId = None
|
|
>>> annotations = principalAnnotations.getAnnotationsById('users.johnny')
|
|
>>> annotations.get(ANNOTATION_KEY) is None
|
|
True
|
|
|
|
Deleting a person with a userId assigned removes the corresponding
|
|
principal annotation:
|
|
|
|
>>> from zope.app.container.interfaces import IObjectRemovedEvent
|
|
>>> from zope.app.container.contained import ObjectRemovedEvent
|
|
>>> from zope.event import notify
|
|
>>> from zope.interface import Interface
|
|
>>> from loops.organize.party import removePersonReferenceFromPrincipal
|
|
>>> from zope.app.testing import ztapi
|
|
>>> ztapi.subscribe([IConcept, IObjectRemovedEvent], None,
|
|
... removePersonReferenceFromPrincipal)
|
|
|
|
>>> john.userId = 'users.john'
|
|
>>> annotations = principalAnnotations.getAnnotationsById('users.john')
|
|
>>> annotations.get(ANNOTATION_KEY) == johnC
|
|
True
|
|
|
|
>>> del concepts['john']
|
|
>>> annotations = principalAnnotations.getAnnotationsById('users.john')
|
|
>>> annotations.get(ANNOTATION_KEY) is None
|
|
True
|
|
|
|
If we try to assign a userId of a principal that already has a person
|
|
concept assigned we should get an error:
|
|
|
|
>>> john.userId = 'users.john'
|
|
|
|
>>> marthaC = Concept(u'Martha')
|
|
>>> concepts['martha'] = marthaC
|
|
>>> marthaC.conceptType = person
|
|
>>> martha = IPerson(marthaC)
|
|
|
|
>>> martha.userId = 'users.john'
|
|
Traceback (most recent call last):
|
|
...
|
|
ValueError: ...
|
|
|
|
|
|
Member Registrations
|
|
====================
|
|
|
|
The member registration needs the whole pluggable authentication stuff
|
|
with a principal folder:
|
|
|
|
>>> from zope.app.appsetup.bootstrap import ensureUtility
|
|
>>> from zope.app.authentication.authentication import PluggableAuthentication
|
|
>>> ensureUtility(site, IAuthentication, '', PluggableAuthentication,
|
|
... copy_to_zlog=False)
|
|
''
|
|
>>> pau = component.getUtility(IAuthentication, context=site)
|
|
|
|
>>> from zope.app.component.site import UtilityRegistration
|
|
>>> from zope.app.authentication.principalfolder import PrincipalFolder
|
|
>>> from zope.app.authentication.interfaces import IAuthenticatorPlugin
|
|
>>> pFolder = PrincipalFolder('loops.')
|
|
>>> pau['loops'] = pFolder
|
|
>>> reg = UtilityRegistration('loops', IAuthenticatorPlugin, pFolder)
|
|
>>> pau.registrationManager.addRegistration(reg)
|
|
'UtilityRegistration'
|
|
>>> reg.status = u'Active'
|
|
>>> pau.authenticatorPlugins = ('loops',)
|
|
|
|
In addition, we have to create at least one node in the view space
|
|
and register an IMemberRegistrationManager adapter for the loops root object:
|
|
|
|
>>> from loops.view import ViewManager, Node
|
|
>>> views = loopsRoot['views'] = ViewManager()
|
|
>>> menu = views['menu'] = Node('Home')
|
|
>>> menu.nodeType = 'menu'
|
|
|
|
>>> from loops.organize.member import MemberRegistrationManager
|
|
>>> from loops.organize.interfaces import IMemberRegistrationManager
|
|
>>> from loops.interfaces import ILoops
|
|
>>> component.provideAdapter(MemberRegistrationManager)
|
|
|
|
Now we can enter the registration info for a new member (after having made
|
|
sure that a principal object can be served by a corresponding factory):
|
|
|
|
>>> from zope.app.authentication.principalfolder import FoundPrincipalFactory
|
|
>>> component.provideAdapter(FoundPrincipalFactory)
|
|
|
|
>>> form = {'field.userId': u'newuser',
|
|
... 'field.passwd': u'quack',
|
|
... 'field.passwdConfirm': u'quack',
|
|
... 'field.lastName': u'Sawyer',
|
|
... 'field.firstName': u'Tom'}
|
|
>>> from zope.publisher.browser import TestRequest
|
|
>>> request = TestRequest(form=form)
|
|
|
|
and register it
|
|
|
|
>>> from loops.organize.browser import MemberRegistration
|
|
>>> regView = MemberRegistration(menu, request)
|
|
>>> personAdapter = regView.register()
|
|
|
|
>>> personAdapter.context.__name__, personAdapter.lastName, personAdapter.userId
|
|
(u'newuser', u'Sawyer', u'loops.newuser')
|
|
|
|
Now we can also retrieve it from the authentication utility:
|
|
|
|
>>> pau.getPrincipal('loops.newuser').title
|
|
u'Tom Sawyer'
|
|
|
|
|
|
Fin de partie
|
|
=============
|
|
|
|
>>> placefulTearDown()
|
|
|