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)
|
||||
|
||||
>>> 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
|
||||
|
|
|
@ -6,42 +6,25 @@ loops - Linked Objects for Organization and Processing Services
|
|||
|
||||
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
|
||||
>>> 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
|
||||
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
|
||||
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
|
||||
>>> component.provideAdapter(SetupManager, (ILoops,), ISetupManager,
|
||||
... name='organize')
|
||||
>>> component.provideAdapter(SetupManager, name='organize')
|
||||
>>> from loops.tests.setup import TestSite
|
||||
>>> t = TestSite(site)
|
||||
>>> concepts, resources, views = t.setup()
|
||||
|
||||
>>> from loops.base import Loops
|
||||
>>> loopsRoot = site['loops'] = Loops()
|
||||
>>> loopsId = relations.getUniqueIdForObject(loopsRoot)
|
||||
|
||||
>>> from loops.setup import SetupManager
|
||||
>>> setup = SetupManager(loopsRoot)
|
||||
>>> concepts, resources, views = setup.setup()
|
||||
>>> from loops import util
|
||||
>>> loopsRoot = site['loops']
|
||||
>>> loopsId = util.getUidForObject(loopsRoot)
|
||||
|
||||
>>> type = concepts['type']
|
||||
>>> person = concepts['person']
|
||||
|
@ -56,6 +39,7 @@ Organizations: Persons (and Users), Institutions, Addresses...
|
|||
|
||||
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.party import Person
|
||||
>>> component.provideAdapter(Person, (IConcept,), IPerson)
|
||||
|
@ -192,7 +176,6 @@ and register an IMemberRegistrationManager adapter for the loops root object:
|
|||
>>> menu.nodeType = 'menu'
|
||||
|
||||
>>> from loops.organize.member import MemberRegistrationManager
|
||||
>>> from loops.organize.interfaces import IMemberRegistrationManager
|
||||
>>> component.provideAdapter(MemberRegistrationManager)
|
||||
|
||||
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',
|
||||
... 'passwordConfirm': u'quack',
|
||||
... '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
|
||||
>>> request = TestRequest()
|
||||
>>> request = TestRequest(form=data)
|
||||
>>> from loops.organize.browser import MemberRegistration
|
||||
>>> regView = MemberRegistration(menu, request, testing=True)
|
||||
>>> personAdapter = regView.register(data)
|
||||
>>> regView = MemberRegistration(menu, request)
|
||||
>>> regView.update()
|
||||
False
|
||||
|
||||
>>> personAdapter.context.__name__, personAdapter.lastName, personAdapter.userId
|
||||
(u'person.newuser', u'Sawyer', u'loops.newuser')
|
||||
>>> from loops.common import adapted
|
||||
>>> 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:
|
||||
|
||||
|
|
|
@ -33,16 +33,18 @@ from zope.formlib.form import Form as FormlibForm, FormFields, action
|
|||
from zope.formlib.namedtemplate import NamedTemplate
|
||||
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.form import Form
|
||||
from cybertools.composer.schema.browser.form import Form, CreateForm
|
||||
from cybertools.composer.schema.schema import FormState, FormError
|
||||
from cybertools.typology.interfaces import IType
|
||||
from loops.browser.concept import ConceptView
|
||||
from loops.browser.node import NodeView
|
||||
from loops.browser.concept import ConceptRelationView
|
||||
from loops.concept import Concept
|
||||
from loops.organize.interfaces import ANNOTATION_KEY, IMemberRegistrationManager
|
||||
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
|
||||
import loops.browser.util
|
||||
from loops.util import _
|
||||
|
@ -75,64 +77,75 @@ class PasswordWidget(BasePasswordWidget):
|
|||
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')
|
||||
|
||||
def __init__(self, context, request, testing=False):
|
||||
super(MemberRegistration, self).__init__(context, request)
|
||||
if not testing:
|
||||
self.setUpWidgets()
|
||||
label_submit = _(u'Register')
|
||||
|
||||
@Lazy
|
||||
def macro(self):
|
||||
return self.template.macros['content']
|
||||
return schema_macros.macros['form']
|
||||
|
||||
@Lazy
|
||||
def item(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):
|
||||
# see cybertools.browser.view.GenericView.update()
|
||||
NodeView.update(self)
|
||||
Form.update(self)
|
||||
return True
|
||||
|
||||
@action(_(u'Register'))
|
||||
def handle_register_action(self, action, data):
|
||||
print 'register'
|
||||
self.register(data)
|
||||
|
||||
def register(self, data=None):
|
||||
form = data or self.request.form
|
||||
form = self.request.form
|
||||
if not form.get('action'):
|
||||
return True
|
||||
instance = component.getAdapter(self.object, IInstance, name='editor')
|
||||
instance.template = self.schema
|
||||
self.formState = formState = instance.applyTemplate(data=form,
|
||||
fieldHandlers=self.fieldHandlers)
|
||||
if formState.severity > 0:
|
||||
# show form again
|
||||
return True
|
||||
pw = form.get('password')
|
||||
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')
|
||||
regMan = IMemberRegistrationManager(self.context.getLoopsRoot())
|
||||
person = regMan.register(login, pw,
|
||||
form.get('lastName'),
|
||||
form.get('firstName'))
|
||||
message = _(u'You have been registered and can now login.')
|
||||
self.object = regMan.register(login, pw,
|
||||
form.get('lastName'), form.get('firstName'))
|
||||
msg = self.message
|
||||
self.request.response.redirect('%s/login.html?login=%s&message=%s'
|
||||
% (self.url, login, message))
|
||||
return person
|
||||
% (self.url, login, msg))
|
||||
return False
|
||||
|
||||
|
||||
class PasswordChange(NodeView, Form):
|
||||
|
||||
interface = IPasswordChange
|
||||
message = u'Your password has been changed.'
|
||||
message = _(u'Your password has been changed.')
|
||||
|
||||
formErrors = dict(
|
||||
confirm_nomatch=FormError(u'Password and password confirmation do not match.'),
|
||||
wrong_oldpw=FormError(u'Your old password was not entered correctly.'),
|
||||
confirm_nomatch=FormError(_(u'Password and password confirmation do not match.')),
|
||||
wrong_oldpw=FormError(_(u'Your old password was not entered correctly.')),
|
||||
)
|
||||
|
||||
label = label_submit = u'Change Password'
|
||||
label = label_submit = _(u'Change Password')
|
||||
|
||||
@Lazy
|
||||
def macro(self):
|
||||
|
|
|
@ -99,12 +99,8 @@ class IPasswordEntry(Interface):
|
|||
passwordConfirm = schema.Password(title=_(u'Confirm password'),
|
||||
description=_(u'Please repeat the password.'),
|
||||
required=True,)
|
||||
|
||||
#@interface.invariant
|
||||
#def passwordMatchConfirm(data):
|
||||
# if data.password != data.passwordConfirm:
|
||||
# raise interface.Invalid(_(u'Password and password confirmation '
|
||||
# 'do not match.'))
|
||||
password.nostore = True
|
||||
passwordConfirm.nostore = True
|
||||
|
||||
|
||||
class IPasswordChange(IPasswordEntry):
|
||||
|
@ -118,10 +114,11 @@ class IMemberRegistration(IBasePerson, IPasswordEntry):
|
|||
""" Schema for registering a new member (user + person).
|
||||
"""
|
||||
|
||||
loginName = LoginName(
|
||||
loginName = schema.TextLine(
|
||||
title=_(u'User ID'),
|
||||
description=_(u'Enter a user id.'),
|
||||
required=True,)
|
||||
loginName.nostore = True
|
||||
|
||||
|
||||
class IMemberRegistrationManager(Interface):
|
||||
|
|
|
@ -43,6 +43,7 @@ from loops.interfaces import IConcept
|
|||
from loops.organize.interfaces import IPerson, ANNOTATION_KEY
|
||||
from loops.common import AdapterBase
|
||||
from loops.type import TypeInterfaceSourceList
|
||||
from loops import util
|
||||
|
||||
|
||||
# register type interfaces - (TODO: use a function for this)
|
||||
|
@ -62,8 +63,7 @@ def getPersonForUser(context, request=None, principal=None):
|
|||
return pa
|
||||
else:
|
||||
return None
|
||||
return pa.get(component.getUtility(
|
||||
IRelationRegistry, context=context).getUniqueIdForObject(loops))
|
||||
return pa.get(util.getUidForObject(loops))
|
||||
|
||||
|
||||
class Person(AdapterBase, BasePerson):
|
||||
|
@ -88,8 +88,8 @@ class Person(AdapterBase, BasePerson):
|
|||
% (zapi.getName(person), userId))
|
||||
pa = annotations(principal)
|
||||
#pa[ANNOTATION_KEY] = self.context
|
||||
intIds = component.getUtility(IRelationRegistry, context=self.context)
|
||||
loopsId = intIds.getUniqueIdForObject(self.context.getLoopsRoot())
|
||||
#intIds = component.getUtility(IRelationRegistry, context=self.context)
|
||||
loopsId = util.getUidForObject(self.context.getLoopsRoot())
|
||||
ann = pa.get(ANNOTATION_KEY)
|
||||
if ann is None:
|
||||
ann = pa[ANNOTATION_KEY] = PersistentMapping()
|
||||
|
@ -109,8 +109,7 @@ class Person(AdapterBase, BasePerson):
|
|||
pa[ANNOTATION_KEY] = None
|
||||
else:
|
||||
if ann is not None:
|
||||
intIds = component.getUtility(IRelationRegistry, context=self.context)
|
||||
loopsId = intIds.getUniqueIdForObject(self.context.getLoopsRoot())
|
||||
loopsId = util.getUidForObject(self.context.getLoopsRoot())
|
||||
ann[loopsId] = None
|
||||
|
||||
def getPhoneNumbers(self):
|
||||
|
|
Loading…
Add table
Reference in a new issue