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

View file

@ -16,8 +16,7 @@
<tbody><tr><td colspan="5" style="padding-right: 15px">
<div id="form.fields">
<!--<metal:fields use-macro="view/template/macros/fields" />-->
<metal:fields use-macro="view/schemaMacros/fields" />
<metal:fields use-macro="view/fieldRenderers/fields" />
</div>
</td></tr></tbody>
@ -65,7 +64,7 @@
<tbody><tr><td colspan="5">
<div id="form.fields">
<!--<metal:fields use-macro="view/template/macros/fields" />-->
<metal:fields use-macro="view/schemaMacros/fields" />
<metal:fields use-macro="view/fieldRenderers/fields" />
</div>
</td></tr></tbody>
@ -83,37 +82,6 @@
</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">
<tbody id="form.assignments">
<tr tal:repeat="type view/presetTypesForAssignment">

View file

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

View file

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

View file

@ -24,17 +24,18 @@ $Id$
"""
from zope import interface, component
from zope.app import zapi
from zope.app.authentication.principalfolder import InternalPrincipal
from zope.app.form.browser.textwidgets import PasswordWidget as BasePasswordWidget
from zope.app.form.interfaces import WidgetInputError
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.app.principalannotation import annotations
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.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 loops.browser.concept import ConceptView
from loops.browser.node import NodeView
@ -74,23 +75,7 @@ class PasswordWidget(BasePasswordWidget):
return value
class OldPasswordWidget(BasePasswordWidget):
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):
class MemberRegistration(NodeView, FormlibForm):
form_fields = FormFields(IMemberRegistration).omit('age')
form_fields['password'].custom_widget = PasswordWidget
@ -139,50 +124,64 @@ class MemberRegistration(NodeView, Form):
class PasswordChange(NodeView, Form):
form_fields = FormFields(IPasswordChange).select(
'oldPassword', 'password', 'passwordConfirm')
form_fields['oldPassword'].custom_widget = OldPasswordWidget
form_fields['password'].custom_widget = PasswordWidget
template = loops.browser.util.dataform
label = _(u'Change Password')
interface = IPasswordChange
message = u'Your password has been changed.'
def __init__(self, context, request, testing=False):
super(PasswordChange, self).__init__(context, request)
if not testing:
self.setUpWidgets()
formErrors = dict(
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'
@Lazy
def macro(self):
return self.template.macros['content']
return schema_macros.macros['form']
@Lazy
def item(self):
return self
@Lazy
def data(self):
data = dict(oldPassword=u'', password=u'', passwordConfirm=u'')
data = {}
return data
def update(self):
# see cybertools.browser.view.GenericView.update()
NodeView.update(self)
Form.update(self)
form = self.request.form
if not form.get('action'):
return True
formState = self.formState = self.validate(form)
if formState.severity > 0:
return True
@action(_(u'Change Password'))
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')
if form.get('passwordConfirm') != pw:
raise ValueError(u'Password and password confirmation do not match.')
pwConfirm = form.get('passwordConfirm')
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())
principal = self.request.principal
result = regMan.changePassword(principal, oldPw, pw)
if not result:
raise ValueError(u'Your old password was not entered correctly.')
message = _(u'Your password has been changed.')
self.request.response.redirect('%s?message=%s'
% (self.url, message))
#self.request.response.redirect('%s/logout.html?message=%s'
# % (self.url, message))
fi = formState.fieldInstances['oldPassword']
fi.setError('wrong_oldpw', self.formErrors)
formState.severity = max(formState.severity, fi.severity)
return True
url = '%s?messsage=%s' % (self.url, self.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)))
class Password(schema.Password):
def _validate(self, pw):
super(Password, self)._validate(pw)
class IPerson(IBasePerson):
""" Resembles a human being with a name (first and last name),
a birth date, and a set of addresses. This interface only
@ -99,7 +93,7 @@ class IPerson(IBasePerson):
class IPasswordEntry(Interface):
password = Password(title=_(u'Password'),
password = schema.Password(title=_(u'Password'),
description=_(u'Enter password.'),
required=True,)
passwordConfirm = schema.Password(title=_(u'Confirm password'),