member registration using composer.schema
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2101 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
4239a58a87
commit
ddd81b7d16
5 changed files with 80 additions and 83 deletions
|
@ -12,7 +12,6 @@ Let's do some basic set up
|
||||||
>>> site = placefulSetUp(True)
|
>>> site = placefulSetUp(True)
|
||||||
|
|
||||||
>>> from zope import component, interface
|
>>> from zope import component, interface
|
||||||
>>> from zope.app import zapi
|
|
||||||
|
|
||||||
and setup a simple loops site with a concept manager and some concepts
|
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
|
(with all the type machinery, what in real life is done via standard
|
||||||
|
|
|
@ -6,42 +6,25 @@ loops - Linked Objects for Organization and Processing Services
|
||||||
|
|
||||||
Note: This packages depends on cybertools.organize.
|
Note: This packages depends on cybertools.organize.
|
||||||
|
|
||||||
Let's do some basic set up
|
Let's do some basic setup
|
||||||
|
|
||||||
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
||||||
>>> site = placefulSetUp(True)
|
>>> site = placefulSetUp(True)
|
||||||
|
|
||||||
>>> from zope import component, interface
|
>>> from zope import component, interface
|
||||||
>>> from zope.app import zapi
|
|
||||||
|
|
||||||
and setup a simple loops site with a concept manager and some concepts
|
and set up a simple loops site with a concept manager and some concepts
|
||||||
(with all the type machinery, what in real life is done via standard
|
(with all the type machinery, what in real life is done via standard
|
||||||
ZCML setup):
|
ZCML setup):
|
||||||
|
|
||||||
>>> from cybertools.relation.interfaces import IRelationRegistry
|
|
||||||
>>> from cybertools.relation.registry import DummyRelationRegistry
|
|
||||||
>>> relations = DummyRelationRegistry()
|
|
||||||
>>> component.provideUtility(relations)
|
|
||||||
|
|
||||||
>>> from cybertools.typology.interfaces import IType
|
|
||||||
>>> from loops.interfaces import IConcept, ITypeConcept
|
|
||||||
>>> from loops.type import ConceptType, TypeConcept
|
|
||||||
>>> component.provideAdapter(ConceptType, (IConcept,), IType)
|
|
||||||
>>> component.provideAdapter(TypeConcept, (IConcept,), ITypeConcept)
|
|
||||||
|
|
||||||
>>> from loops.interfaces import ILoops
|
|
||||||
>>> from loops.setup import ISetupManager
|
|
||||||
>>> from loops.organize.setup import SetupManager
|
>>> from loops.organize.setup import SetupManager
|
||||||
>>> component.provideAdapter(SetupManager, (ILoops,), ISetupManager,
|
>>> component.provideAdapter(SetupManager, name='organize')
|
||||||
... name='organize')
|
>>> from loops.tests.setup import TestSite
|
||||||
|
>>> t = TestSite(site)
|
||||||
|
>>> concepts, resources, views = t.setup()
|
||||||
|
|
||||||
>>> from loops.base import Loops
|
>>> from loops import util
|
||||||
>>> loopsRoot = site['loops'] = Loops()
|
>>> loopsRoot = site['loops']
|
||||||
>>> loopsId = relations.getUniqueIdForObject(loopsRoot)
|
>>> loopsId = util.getUidForObject(loopsRoot)
|
||||||
|
|
||||||
>>> from loops.setup import SetupManager
|
|
||||||
>>> setup = SetupManager(loopsRoot)
|
|
||||||
>>> concepts, resources, views = setup.setup()
|
|
||||||
|
|
||||||
>>> type = concepts['type']
|
>>> type = concepts['type']
|
||||||
>>> person = concepts['person']
|
>>> person = concepts['person']
|
||||||
|
@ -56,6 +39,7 @@ Organizations: Persons (and Users), Institutions, Addresses...
|
||||||
|
|
||||||
The classes used in this package are just adapters to IConcept.
|
The classes used in this package are just adapters to IConcept.
|
||||||
|
|
||||||
|
>>> from loops.interfaces import IConcept
|
||||||
>>> from loops.organize.interfaces import IPerson
|
>>> from loops.organize.interfaces import IPerson
|
||||||
>>> from loops.organize.party import Person
|
>>> from loops.organize.party import Person
|
||||||
>>> component.provideAdapter(Person, (IConcept,), IPerson)
|
>>> component.provideAdapter(Person, (IConcept,), IPerson)
|
||||||
|
@ -192,7 +176,6 @@ and register an IMemberRegistrationManager adapter for the loops root object:
|
||||||
>>> menu.nodeType = 'menu'
|
>>> menu.nodeType = 'menu'
|
||||||
|
|
||||||
>>> from loops.organize.member import MemberRegistrationManager
|
>>> from loops.organize.member import MemberRegistrationManager
|
||||||
>>> from loops.organize.interfaces import IMemberRegistrationManager
|
|
||||||
>>> component.provideAdapter(MemberRegistrationManager)
|
>>> component.provideAdapter(MemberRegistrationManager)
|
||||||
|
|
||||||
Now we can enter the registration info for a new member (after having made
|
Now we can enter the registration info for a new member (after having made
|
||||||
|
@ -205,18 +188,24 @@ sure that a principal object can be served by a corresponding factory):
|
||||||
... 'password': u'quack',
|
... 'password': u'quack',
|
||||||
... 'passwordConfirm': u'quack',
|
... 'passwordConfirm': u'quack',
|
||||||
... 'lastName': u'Sawyer',
|
... 'lastName': u'Sawyer',
|
||||||
... 'firstName': u'Tom'}
|
... 'firstName': u'Tom',
|
||||||
|
... 'email': u'tommy@sawyer.com',
|
||||||
|
... 'action': 'update',}
|
||||||
|
|
||||||
and register it
|
and register it.
|
||||||
|
|
||||||
>>> from zope.publisher.browser import TestRequest
|
>>> from zope.publisher.browser import TestRequest
|
||||||
>>> request = TestRequest()
|
>>> request = TestRequest(form=data)
|
||||||
>>> from loops.organize.browser import MemberRegistration
|
>>> from loops.organize.browser import MemberRegistration
|
||||||
>>> regView = MemberRegistration(menu, request, testing=True)
|
>>> regView = MemberRegistration(menu, request)
|
||||||
>>> personAdapter = regView.register(data)
|
>>> regView.update()
|
||||||
|
False
|
||||||
|
|
||||||
>>> personAdapter.context.__name__, personAdapter.lastName, personAdapter.userId
|
>>> from loops.common import adapted
|
||||||
(u'person.newuser', u'Sawyer', u'loops.newuser')
|
>>> person = concepts['person.newuser']
|
||||||
|
>>> pa = adapted(person)
|
||||||
|
>>> pa.lastName, pa.userId
|
||||||
|
(u'Sawyer', u'loops.newuser')
|
||||||
|
|
||||||
Now we can also retrieve it from the authentication utility:
|
Now we can also retrieve it from the authentication utility:
|
||||||
|
|
||||||
|
|
|
@ -33,16 +33,18 @@ from zope.formlib.form import Form as FormlibForm, FormFields, action
|
||||||
from zope.formlib.namedtemplate import NamedTemplate
|
from zope.formlib.namedtemplate import NamedTemplate
|
||||||
from zope.i18nmessageid import MessageFactory
|
from zope.i18nmessageid import MessageFactory
|
||||||
|
|
||||||
|
from cybertools.composer.interfaces import IInstance
|
||||||
from cybertools.composer.schema.browser.common import schema_macros
|
from cybertools.composer.schema.browser.common import schema_macros
|
||||||
from cybertools.composer.schema.browser.form import Form
|
from cybertools.composer.schema.browser.form import Form, CreateForm
|
||||||
from cybertools.composer.schema.schema import FormState, FormError
|
from cybertools.composer.schema.schema import FormState, FormError
|
||||||
from cybertools.typology.interfaces import IType
|
from cybertools.typology.interfaces import IType
|
||||||
from loops.browser.concept import ConceptView
|
from loops.browser.concept import ConceptView
|
||||||
from loops.browser.node import NodeView
|
from loops.browser.node import NodeView
|
||||||
from loops.browser.concept import ConceptRelationView
|
from loops.browser.concept import ConceptRelationView
|
||||||
|
from loops.concept import Concept
|
||||||
from loops.organize.interfaces import ANNOTATION_KEY, IMemberRegistrationManager
|
from loops.organize.interfaces import ANNOTATION_KEY, IMemberRegistrationManager
|
||||||
from loops.organize.interfaces import IMemberRegistration, IPasswordChange
|
from loops.organize.interfaces import IMemberRegistration, IPasswordChange
|
||||||
from loops.organize.party import getPersonForUser
|
from loops.organize.party import getPersonForUser, Person
|
||||||
from loops.organize.util import getInternalPrincipal
|
from loops.organize.util import getInternalPrincipal
|
||||||
import loops.browser.util
|
import loops.browser.util
|
||||||
from loops.util import _
|
from loops.util import _
|
||||||
|
@ -75,64 +77,75 @@ class PasswordWidget(BasePasswordWidget):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
class MemberRegistration(NodeView, FormlibForm):
|
class MemberRegistration(NodeView, CreateForm):
|
||||||
|
|
||||||
|
interface = IMemberRegistration
|
||||||
|
message = _(u'You have been registered.')
|
||||||
|
|
||||||
|
formErrors = dict(
|
||||||
|
confirm_nomatch=FormError(_(u'Password and password confirmation do not match.')),
|
||||||
|
)
|
||||||
|
|
||||||
form_fields = FormFields(IMemberRegistration).omit('age')
|
|
||||||
form_fields['password'].custom_widget = PasswordWidget
|
|
||||||
template = loops.browser.util.dataform
|
|
||||||
label = _(u'Member Registration')
|
label = _(u'Member Registration')
|
||||||
|
label_submit = _(u'Register')
|
||||||
def __init__(self, context, request, testing=False):
|
|
||||||
super(MemberRegistration, self).__init__(context, request)
|
|
||||||
if not testing:
|
|
||||||
self.setUpWidgets()
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def macro(self):
|
def macro(self):
|
||||||
return self.template.macros['content']
|
return schema_macros.macros['form']
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def item(self):
|
def item(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def schema(self):
|
||||||
|
schema = super(MemberRegistration, self).schema
|
||||||
|
if 'birthDate' in schema.fields:
|
||||||
|
del schema.fields['birthDate']
|
||||||
|
return schema
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def object(self):
|
||||||
|
return Person(Concept())
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
# see cybertools.browser.view.GenericView.update()
|
form = self.request.form
|
||||||
NodeView.update(self)
|
if not form.get('action'):
|
||||||
Form.update(self)
|
return True
|
||||||
return True
|
instance = component.getAdapter(self.object, IInstance, name='editor')
|
||||||
|
instance.template = self.schema
|
||||||
@action(_(u'Register'))
|
self.formState = formState = instance.applyTemplate(data=form,
|
||||||
def handle_register_action(self, action, data):
|
fieldHandlers=self.fieldHandlers)
|
||||||
print 'register'
|
if formState.severity > 0:
|
||||||
self.register(data)
|
# show form again
|
||||||
|
return True
|
||||||
def register(self, data=None):
|
|
||||||
form = data or self.request.form
|
|
||||||
pw = form.get('password')
|
pw = form.get('password')
|
||||||
if form.get('passwordConfirm') != pw:
|
if form.get('passwordConfirm') != pw:
|
||||||
raise ValueError(u'Password and password confirmation do not match.')
|
fi = formState.fieldInstances['password']
|
||||||
|
fi.setError('confirm_nomatch', self.formErrors)
|
||||||
|
formState.severity = max(formState.severity, fi.severity)
|
||||||
|
return True
|
||||||
login = form.get('loginName')
|
login = form.get('loginName')
|
||||||
regMan = IMemberRegistrationManager(self.context.getLoopsRoot())
|
regMan = IMemberRegistrationManager(self.context.getLoopsRoot())
|
||||||
person = regMan.register(login, pw,
|
self.object = regMan.register(login, pw,
|
||||||
form.get('lastName'),
|
form.get('lastName'), form.get('firstName'))
|
||||||
form.get('firstName'))
|
msg = self.message
|
||||||
message = _(u'You have been registered and can now login.')
|
|
||||||
self.request.response.redirect('%s/login.html?login=%s&message=%s'
|
self.request.response.redirect('%s/login.html?login=%s&message=%s'
|
||||||
% (self.url, login, message))
|
% (self.url, login, msg))
|
||||||
return person
|
return False
|
||||||
|
|
||||||
|
|
||||||
class PasswordChange(NodeView, Form):
|
class PasswordChange(NodeView, Form):
|
||||||
|
|
||||||
interface = IPasswordChange
|
interface = IPasswordChange
|
||||||
message = u'Your password has been changed.'
|
message = _(u'Your password has been changed.')
|
||||||
|
|
||||||
formErrors = dict(
|
formErrors = dict(
|
||||||
confirm_nomatch=FormError(u'Password and password confirmation do not match.'),
|
confirm_nomatch=FormError(_(u'Password and password confirmation do not match.')),
|
||||||
wrong_oldpw=FormError(u'Your old password was not entered correctly.'),
|
wrong_oldpw=FormError(_(u'Your old password was not entered correctly.')),
|
||||||
)
|
)
|
||||||
|
|
||||||
label = label_submit = u'Change Password'
|
label = label_submit = _(u'Change Password')
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def macro(self):
|
def macro(self):
|
||||||
|
|
|
@ -99,12 +99,8 @@ class IPasswordEntry(Interface):
|
||||||
passwordConfirm = schema.Password(title=_(u'Confirm password'),
|
passwordConfirm = schema.Password(title=_(u'Confirm password'),
|
||||||
description=_(u'Please repeat the password.'),
|
description=_(u'Please repeat the password.'),
|
||||||
required=True,)
|
required=True,)
|
||||||
|
password.nostore = True
|
||||||
#@interface.invariant
|
passwordConfirm.nostore = True
|
||||||
#def passwordMatchConfirm(data):
|
|
||||||
# if data.password != data.passwordConfirm:
|
|
||||||
# raise interface.Invalid(_(u'Password and password confirmation '
|
|
||||||
# 'do not match.'))
|
|
||||||
|
|
||||||
|
|
||||||
class IPasswordChange(IPasswordEntry):
|
class IPasswordChange(IPasswordEntry):
|
||||||
|
@ -118,10 +114,11 @@ class IMemberRegistration(IBasePerson, IPasswordEntry):
|
||||||
""" Schema for registering a new member (user + person).
|
""" Schema for registering a new member (user + person).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
loginName = LoginName(
|
loginName = schema.TextLine(
|
||||||
title=_(u'User ID'),
|
title=_(u'User ID'),
|
||||||
description=_(u'Enter a user id.'),
|
description=_(u'Enter a user id.'),
|
||||||
required=True,)
|
required=True,)
|
||||||
|
loginName.nostore = True
|
||||||
|
|
||||||
|
|
||||||
class IMemberRegistrationManager(Interface):
|
class IMemberRegistrationManager(Interface):
|
||||||
|
|
|
@ -43,6 +43,7 @@ from loops.interfaces import IConcept
|
||||||
from loops.organize.interfaces import IPerson, ANNOTATION_KEY
|
from loops.organize.interfaces import IPerson, ANNOTATION_KEY
|
||||||
from loops.common import AdapterBase
|
from loops.common import AdapterBase
|
||||||
from loops.type import TypeInterfaceSourceList
|
from loops.type import TypeInterfaceSourceList
|
||||||
|
from loops import util
|
||||||
|
|
||||||
|
|
||||||
# register type interfaces - (TODO: use a function for this)
|
# register type interfaces - (TODO: use a function for this)
|
||||||
|
@ -62,8 +63,7 @@ def getPersonForUser(context, request=None, principal=None):
|
||||||
return pa
|
return pa
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
return pa.get(component.getUtility(
|
return pa.get(util.getUidForObject(loops))
|
||||||
IRelationRegistry, context=context).getUniqueIdForObject(loops))
|
|
||||||
|
|
||||||
|
|
||||||
class Person(AdapterBase, BasePerson):
|
class Person(AdapterBase, BasePerson):
|
||||||
|
@ -88,8 +88,8 @@ class Person(AdapterBase, BasePerson):
|
||||||
% (zapi.getName(person), userId))
|
% (zapi.getName(person), userId))
|
||||||
pa = annotations(principal)
|
pa = annotations(principal)
|
||||||
#pa[ANNOTATION_KEY] = self.context
|
#pa[ANNOTATION_KEY] = self.context
|
||||||
intIds = component.getUtility(IRelationRegistry, context=self.context)
|
#intIds = component.getUtility(IRelationRegistry, context=self.context)
|
||||||
loopsId = intIds.getUniqueIdForObject(self.context.getLoopsRoot())
|
loopsId = util.getUidForObject(self.context.getLoopsRoot())
|
||||||
ann = pa.get(ANNOTATION_KEY)
|
ann = pa.get(ANNOTATION_KEY)
|
||||||
if ann is None:
|
if ann is None:
|
||||||
ann = pa[ANNOTATION_KEY] = PersistentMapping()
|
ann = pa[ANNOTATION_KEY] = PersistentMapping()
|
||||||
|
@ -109,8 +109,7 @@ class Person(AdapterBase, BasePerson):
|
||||||
pa[ANNOTATION_KEY] = None
|
pa[ANNOTATION_KEY] = None
|
||||||
else:
|
else:
|
||||||
if ann is not None:
|
if ann is not None:
|
||||||
intIds = component.getUtility(IRelationRegistry, context=self.context)
|
loopsId = util.getUidForObject(self.context.getLoopsRoot())
|
||||||
loopsId = intIds.getUniqueIdForObject(self.context.getLoopsRoot())
|
|
||||||
ann[loopsId] = None
|
ann[loopsId] = None
|
||||||
|
|
||||||
def getPhoneNumbers(self):
|
def getPhoneNumbers(self):
|
||||||
|
|
Loading…
Add table
Reference in a new issue