[Zope3-checkins] SVN: Zope3/trunk/ - Fixed password widget to allow
users to not change
Christian Theune
ct at gocept.com
Thu Dec 7 11:42:03 EST 2006
Log message for revision 71484:
- Fixed password widget to allow users to not change
their password when being confronted with a password field.
Changed:
U Zope3/trunk/doc/CHANGES.txt
U Zope3/trunk/src/zope/app/form/browser/tests/test_textwidget.py
U Zope3/trunk/src/zope/app/form/browser/textwidgets.py
U Zope3/trunk/src/zope/schema/_bootstrapfields.py
U Zope3/trunk/src/zope/schema/tests/test_strfield.py
-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt 2006-12-07 16:12:16 UTC (rev 71483)
+++ Zope3/trunk/doc/CHANGES.txt 2006-12-07 16:42:02 UTC (rev 71484)
@@ -149,6 +149,9 @@
Bug fixes
+ - Fixed behaviour of PasswordWidget to allow users not changing their
+ password when a password already exists.
+
- Fileresources now also set the Cache-control headers on 304
responses. This speeds up page loads a lot on pages with many
resources.
Modified: Zope3/trunk/src/zope/app/form/browser/tests/test_textwidget.py
===================================================================
--- Zope3/trunk/src/zope/app/form/browser/tests/test_textwidget.py 2006-12-07 16:12:16 UTC (rev 71483)
+++ Zope3/trunk/src/zope/app/form/browser/tests/test_textwidget.py 2006-12-07 16:42:02 UTC (rev 71484)
@@ -22,6 +22,7 @@
from zope.schema import TextLine
from zope.publisher.browser import TestRequest
+from zope.schema import Password
from zope.app.form.interfaces import IInputWidget
from zope.app.form.browser import TextWidget
@@ -316,6 +317,7 @@
class PasswordDisplayWidgetTest(BrowserWidgetTest):
_WidgetFactory = PasswordWidget
+ _FieldFactory = Password
# It uses the default DisplayWidget
def testRender(self):
@@ -325,6 +327,16 @@
'value=""', 'size="20"')
self.verifyResult(self._widget(), check_list)
+ def testUnchangedPassword(self):
+ # The password hasn't been set yet, so an empty string
+ # is regarded as an empty field.
+ self.assertEquals(None, self._widget._toFieldValue(''))
+ # Now the password has been filled in, so the empty string
+ # is regarded as the special value for UNCHANGED_PASSWORD.
+ self._widget.context.context.foo = u'existing password'
+ self.assertEquals(self._widget.context.UNCHANGED_PASSWORD,
+ self._widget._toFieldValue(''))
+
class FileDisplayWidgetTest(BrowserWidgetTest):
_WidgetFactory = FileWidget
Modified: Zope3/trunk/src/zope/app/form/browser/textwidgets.py
===================================================================
--- Zope3/trunk/src/zope/app/form/browser/textwidgets.py 2006-12-07 16:12:16 UTC (rev 71483)
+++ Zope3/trunk/src/zope/app/form/browser/textwidgets.py 2006-12-07 16:42:02 UTC (rev 71484)
@@ -388,10 +388,20 @@
size=self.displayWidth,
extra=self.extra)
+ def _toFieldValue(self, input):
+ try:
+ existing = self.context.get(self.context.context)
+ except AttributeError:
+ existing = False
+ if (not input) and existing:
+ return self.context.UNCHANGED_PASSWORD
+ return super(PasswordWidget, self)._toFieldValue(input)
+
def hidden(self):
raise NotImplementedError(
'Cannot get a hidden tag for a password field')
+
class FileWidget(TextWidget):
"""File Widget"""
Modified: Zope3/trunk/src/zope/schema/_bootstrapfields.py
===================================================================
--- Zope3/trunk/src/zope/schema/_bootstrapfields.py 2006-12-07 16:12:16 UTC (rev 71483)
+++ Zope3/trunk/src/zope/schema/_bootstrapfields.py 2006-12-07 16:42:02 UTC (rev 71484)
@@ -300,9 +300,37 @@
def constraint(self, value):
return '\n' not in value and '\r' not in value
+
class Password(TextLine):
"""A text field containing a text used as a password."""
+ UNCHANGED_PASSWORD = object()
+
+ def set(self, context, value):
+ """Update the password.
+
+ We use a special marker value that a widget can use
+ to tell us that the password didn't change. This is
+ needed to support edit forms that don't display the
+ existing password and want to work together with
+ encryption.
+
+ """
+ if value is self.UNCHANGED_PASSWORD:
+ return
+ super(Password, self).set(context, value)
+
+ def validate(self, value):
+ try:
+ existing = bool(self.get(self.context))
+ except AttributeError:
+ existing = False
+ if value is self.UNCHANGED_PASSWORD and existing:
+ # Allow the UNCHANGED_PASSWORD value, if a password is set already
+ return
+ return super(Password, self).validate(value)
+
+
class Bool(Field):
"""A field representing a Bool."""
_type = type(True)
Modified: Zope3/trunk/src/zope/schema/tests/test_strfield.py
===================================================================
--- Zope3/trunk/src/zope/schema/tests/test_strfield.py 2006-12-07 16:12:16 UTC (rev 71483)
+++ Zope3/trunk/src/zope/schema/tests/test_strfield.py 2006-12-07 16:42:02 UTC (rev 71484)
@@ -16,8 +16,8 @@
$Id$
"""
from unittest import TestSuite, main, makeSuite
-from zope.schema import Bytes, BytesLine, Text, TextLine
-from zope.schema.interfaces import ValidationError
+from zope.schema import Bytes, BytesLine, Text, TextLine, Password
+from zope.schema.interfaces import ValidationError, WrongType
from zope.schema.interfaces import RequiredMissing, InvalidValue
from zope.schema.interfaces import TooShort, TooLong, ConstraintNotSatisfied
from zope.schema.tests.test_field import FieldTestBase
@@ -119,6 +119,33 @@
field.validate,
self._convert('hello\nworld'))
+class PasswordTest(SingleLine, TextTest):
+ _Field_Factory = Password
+
+ def test_existingValue(self):
+ class Dummy(object):
+ password = None
+ dummy = Dummy()
+
+ field = self._Field_Factory(title=u'Str field', description=u'',
+ readonly=False, required=True, __name__='password')
+ field = field.bind(dummy)
+
+ # Using UNCHANGED_PASSWORD is not allowed if no password was set yet
+ self.assertRaises(WrongType, field.validate, field.UNCHANGED_PASSWORD)
+
+ dummy.password = 'asdf'
+ field.validate(field.UNCHANGED_PASSWORD)
+
+ # Using a normal value, the field gets updated
+ field.set(dummy, u'test')
+ self.assertEquals(u'test', dummy.password)
+
+ # Using UNCHANGED_PASSWORD the field is not updated.
+ field.set(dummy, field.UNCHANGED_PASSWORD)
+ self.assertEquals(u'test', dummy.password)
+
+
class LineTest(SingleLine, BytesTest):
_Field_Factory = BytesLine
@@ -132,6 +159,7 @@
makeSuite(TextTest),
makeSuite(LineTest),
makeSuite(TextLineTest),
+ makeSuite(PasswordTest),
))
if __name__ == '__main__':
More information about the Zope3-Checkins
mailing list