use composer.schema for password change form

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2090 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-10-07 15:19:30 +00:00
parent 55ed5b433d
commit 7496a39bbb
6 changed files with 73 additions and 105 deletions

View file

@ -43,6 +43,7 @@ from cybertools.browser.form import FormController
from cybertools.composer.interfaces import IInstance from cybertools.composer.interfaces import IInstance
from cybertools.composer.schema.interfaces import ISchemaFactory from cybertools.composer.schema.interfaces import ISchemaFactory
from cybertools.composer.schema.browser.common import schema_macros, schema_edit_macros from cybertools.composer.schema.browser.common import schema_macros, schema_edit_macros
from cybertools.composer.schema.schema import FormState
from cybertools.typology.interfaces import IType, ITypeManager from cybertools.typology.interfaces import IType, ITypeManager
from loops.common import adapted from loops.common import adapted
from loops.concept import Concept, ResourceRelation from loops.concept import Concept, ResourceRelation
@ -61,12 +62,11 @@ from loops.versioning.interfaces import IVersionable
# forms # forms
class ObjectForm(NodeView): class ObjectForm(NodeView):
""" Abstract base class for forms. """ Abstract base class for resource or concept forms using Dojo dialog.
""" """
template = ViewPageTemplateFile('form_macros.pt') template = ViewPageTemplateFile('form_macros.pt')
formState = FormState() # dummy, don't update!
_isSetUp = False
def __init__(self, context, request): def __init__(self, context, request):
super(ObjectForm, self).__init__(context, request) super(ObjectForm, self).__init__(context, request)
@ -79,12 +79,12 @@ class ObjectForm(NodeView):
def typeInterface(self): def typeInterface(self):
return IType(self.context).typeInterface or ITextDocument return IType(self.context).typeInterface or ITextDocument
@property @Lazy
def schemaMacros(self): def fieldRenderers(self):
return schema_macros.macros return schema_macros.macros
@property @Lazy
def schemaEditMacros(self): def fieldEditRenderers(self):
return schema_edit_macros.macros return schema_edit_macros.macros
@Lazy @Lazy
@ -211,7 +211,7 @@ class CreateObjectForm(ObjectForm, Form):
class InnerForm(CreateObjectForm): class InnerForm(CreateObjectForm):
@property @property
def macro(self): return self.schemaMacros['fields'] def macro(self): return self.fieldRenderers['fields']
# processing form input # processing form input

View file

@ -16,8 +16,7 @@
<tbody><tr><td colspan="5" style="padding-right: 15px"> <tbody><tr><td colspan="5" style="padding-right: 15px">
<div id="form.fields"> <div id="form.fields">
<!--<metal:fields use-macro="view/template/macros/fields" />--> <metal:fields use-macro="view/fieldRenderers/fields" />
<metal:fields use-macro="view/schemaMacros/fields" />
</div> </div>
</td></tr></tbody> </td></tr></tbody>
@ -65,7 +64,7 @@
<tbody><tr><td colspan="5"> <tbody><tr><td colspan="5">
<div id="form.fields"> <div id="form.fields">
<!--<metal:fields use-macro="view/template/macros/fields" />--> <!--<metal:fields use-macro="view/template/macros/fields" />-->
<metal:fields use-macro="view/schemaMacros/fields" /> <metal:fields use-macro="view/fieldRenderers/fields" />
</div> </div>
</td></tr></tbody> </td></tr></tbody>
@ -83,37 +82,6 @@
</metal:block> </metal:block>
<metal:fields define-macro="fields"
tal:define="show view/update">
<tal:show condition="show">
<div id="form_fields"
tal:define="dummy view/setUp">
<table width="100%">
<tr tal:repeat="widget view/widgets">
<td class="label" width="10%"
tal:define="hint widget/hint">
<label tal:attributes="for widget/name">
<span class="required" tal:condition="widget/required"
>*</span><span tal:content="widget/label">label</span>
</label>
</td>
<td class="field" colspan="4" width="90%"
tal:define="hint widget/hint">
<div class="widget" tal:content="structure widget">
<input type="text" />
</div>
<div class="error"
tal:condition="widget/error">
<span tal:replace="structure widget/error">error</span>
</div>
</td>
</tr>
</table>
</div>
</tal:show>
</metal:fields>
<metal:assignments define-macro="assignments"> <metal:assignments define-macro="assignments">
<tbody id="form.assignments"> <tbody id="form.assignments">
<tr tal:repeat="type view/presetTypesForAssignment"> <tr tal:repeat="type view/presetTypesForAssignment">

View file

@ -401,6 +401,7 @@
<adapter factory="cybertools.composer.schema.field.FileUploadFieldInstance" <adapter factory="cybertools.composer.schema.field.FileUploadFieldInstance"
name="fileupload" /> name="fileupload" />
<adapter factory="cybertools.composer.schema.factory.SchemaFactory" />
<adapter factory="loops.schema.ResourceSchemaFactory" /> <adapter factory="loops.schema.ResourceSchemaFactory" />
<adapter factory="loops.schema.ResourceSchemaFactory" <adapter factory="loops.schema.ResourceSchemaFactory"
for="loops.interfaces.IResource" /> for="loops.interfaces.IResource" />

View file

@ -229,9 +229,10 @@ Change Password
>>> data = {'oldPassword': u'tiger', >>> data = {'oldPassword': u'tiger',
... 'password': u'lion', ... 'password': u'lion',
... 'passwordConfirm': u'lion'} ... 'passwordConfirm': u'lion',
... 'action': 'update'}
>>> request = TestRequest() >>> request = TestRequest(form=data)
We need a principal for testing the login stuff: We need a principal for testing the login stuff:
@ -239,10 +240,15 @@ We need a principal for testing the login stuff:
>>> principal = InternalPrincipal('scott', 'tiger', 'Scotty') >>> principal = InternalPrincipal('scott', 'tiger', 'Scotty')
>>> request.setPrincipal(principal) >>> request.setPrincipal(principal)
>>> from loops.organize.browser import PasswordChange >>> from cybertools.composer.schema.factory import SchemaFactory
>>> pwcView = PasswordChange(menu, request, testing=True) >>> from cybertools.composer.schema.field import FieldInstance
>>> pwcView.changePassword(data) >>> component.provideAdapter(SchemaFactory)
>>> component.provideAdapter(FieldInstance)
>>> from loops.organize.browser import PasswordChange
>>> pwcView = PasswordChange(menu, request)
>>> pwcView.update()
False
Fin de partie Fin de partie
============= =============

View file

@ -24,17 +24,18 @@ $Id$
""" """
from zope import interface, component from zope import interface, component
from zope.app import zapi
from zope.app.authentication.principalfolder import InternalPrincipal from zope.app.authentication.principalfolder import InternalPrincipal
from zope.app.form.browser.textwidgets import PasswordWidget as BasePasswordWidget from zope.app.form.browser.textwidgets import PasswordWidget as BasePasswordWidget
from zope.app.form.interfaces import WidgetInputError from zope.app.form.interfaces import WidgetInputError
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.app.principalannotation import annotations from zope.app.principalannotation import annotations
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope.formlib.form import Form, FormFields, action 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.schema.browser.common import schema_macros
from cybertools.composer.schema.browser.form import Form
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
@ -74,23 +75,7 @@ class PasswordWidget(BasePasswordWidget):
return value return value
class OldPasswordWidget(BasePasswordWidget): class MemberRegistration(NodeView, FormlibForm):
def getInputValue(self):
value = super(OldPasswordWidget, self).getInputValue()
if value:
principal = self.request.principal
if not isinstance(principal, InternalPrincipal):
principal = getInternalPrincipal(principal.id)
if not principal.checkPassword(value):
v = _(u'Your old password was not entered correctly.')
self._error = WidgetInputError(
self.context.__name__, self.label, v)
raise self._error
return value
class MemberRegistration(NodeView, Form):
form_fields = FormFields(IMemberRegistration).omit('age') form_fields = FormFields(IMemberRegistration).omit('age')
form_fields['password'].custom_widget = PasswordWidget form_fields['password'].custom_widget = PasswordWidget
@ -139,50 +124,64 @@ class MemberRegistration(NodeView, Form):
class PasswordChange(NodeView, Form): class PasswordChange(NodeView, Form):
form_fields = FormFields(IPasswordChange).select( interface = IPasswordChange
'oldPassword', 'password', 'passwordConfirm') message = u'Your password has been changed.'
form_fields['oldPassword'].custom_widget = OldPasswordWidget
form_fields['password'].custom_widget = PasswordWidget
template = loops.browser.util.dataform
label = _(u'Change Password')
def __init__(self, context, request, testing=False): formErrors = dict(
super(PasswordChange, self).__init__(context, request) confirm_nomatch=FormError(u'Password and password confirmation do not match.'),
if not testing: wrong_oldpw=FormError(u'Your old password was not entered correctly.'),
self.setUpWidgets() )
label = label_submit = u'Change Password'
@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 data(self):
data = dict(oldPassword=u'', password=u'', passwordConfirm=u'')
data = {}
return data
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 formState = self.formState = self.validate(form)
if formState.severity > 0:
@action(_(u'Change Password')) return True
def handle_change_password_action(self, action, data):
self.changePassword(data)
def changePassword(self, data=None):
form = data or self.request.form
oldPw = form.get('oldPassword')
pw = form.get('password') pw = form.get('password')
if form.get('passwordConfirm') != pw: pwConfirm = form.get('passwordConfirm')
raise ValueError(u'Password and password confirmation do not match.') if pw != pwConfirm:
fi = formState.fieldInstances['password']
fi.setError('confirm_nomatch', self.formErrors)
formState.severity = max(formState.severity, fi.severity)
return True
oldPw = form.get('oldPassword')
regMan = IMemberRegistrationManager(self.context.getLoopsRoot()) regMan = IMemberRegistrationManager(self.context.getLoopsRoot())
principal = self.request.principal principal = self.request.principal
result = regMan.changePassword(principal, oldPw, pw) result = regMan.changePassword(principal, oldPw, pw)
if not result: if not result:
raise ValueError(u'Your old password was not entered correctly.') fi = formState.fieldInstances['oldPassword']
message = _(u'Your password has been changed.') fi.setError('wrong_oldpw', self.formErrors)
self.request.response.redirect('%s?message=%s' formState.severity = max(formState.severity, fi.severity)
% (self.url, message)) return True
#self.request.response.redirect('%s/logout.html?message=%s' url = '%s?messsage=%s' % (self.url, self.message)
# % (self.url, message)) self.request.response.redirect(url)
return False
def validate(self, data):
formState = FormState()
for f in self.schema.fields:
fi = f.getFieldInstance()
value = data.get(f.name)
fi.validate(value, data)
formState.fieldInstances.append(fi)
formState.severity = max(formState.severity, fi.severity)
return formState

View file

@ -77,12 +77,6 @@ class LoginName(schema.TextLine):
mapping=dict(userId=userId))) mapping=dict(userId=userId)))
class Password(schema.Password):
def _validate(self, pw):
super(Password, self)._validate(pw)
class IPerson(IBasePerson): class IPerson(IBasePerson):
""" Resembles a human being with a name (first and last name), """ Resembles a human being with a name (first and last name),
a birth date, and a set of addresses. This interface only a birth date, and a set of addresses. This interface only
@ -99,7 +93,7 @@ class IPerson(IBasePerson):
class IPasswordEntry(Interface): class IPasswordEntry(Interface):
password = Password(title=_(u'Password'), password = schema.Password(title=_(u'Password'),
description=_(u'Enter password.'), description=_(u'Enter password.'),
required=True,) required=True,)
passwordConfirm = schema.Password(title=_(u'Confirm password'), passwordConfirm = schema.Password(title=_(u'Confirm password'),