8687.15.18
by Karl Fogel
Add the copyright header block to files under lib/canonical/. |
1 |
# Copyright 2009 Canonical Ltd. This software is licensed under the
|
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
3 |
||
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
4 |
"""
|
5 |
Custom Password widgets.
|
|
6 |
||
7 |
TODO: Consider folding this back into Zope3 -- StuartBishop 20050520
|
|
8 |
"""
|
|
9 |
||
10 |
__metaclass__ = type |
|
11 |
||
5534.1.1
by Carlos Perello Marin
Updated password widget to use a more clear approach |
12 |
from zope.app.form.browser import PasswordWidget |
13 |
from zope.app.form.browser.interfaces import ITextBrowserWidget |
|
14 |
from zope.app.form.interfaces import WidgetInputError |
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
15 |
from zope.component import getUtility |
5534.1.1
by Carlos Perello Marin
Updated password widget to use a more clear approach |
16 |
from zope.interface import implements |
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
17 |
from zope.schema.interfaces import ValidationError |
7849.16.59
by Sidnei da Silva
- Cleanup some more imports |
18 |
|
7849.16.4
by Sidnei da Silva
- Import ViewPageTemplateFile from z3c.pt everywhere |
19 |
from z3c.ptcompat import ViewPageTemplateFile |
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
20 |
|
2236
by Canonical.com Patch Queue Manager
[trivial] Remove canonical._ |
21 |
from canonical.launchpad import _ |
11882.2.2
by Jonathan Lange
Clear up a heck of a lot of imports from canonical.launchpad.interfaces. |
22 |
from canonical.launchpad.interfaces.launchpad import IPasswordEncryptor |
5534.1.1
by Carlos Perello Marin
Updated password widget to use a more clear approach |
23 |
from canonical.launchpad.webapp.interfaces import IMultiLineWidgetLayout |
24 |
||
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
25 |
|
26 |
class PasswordMismatch(ValidationError): |
|
2865.1.7
by Stuart Bishop
Improve PasswordChangeWidget validation, stopping a System Error from occuring |
27 |
__doc__ = _("Passwords do not match.") |
28 |
||
29 |
def __repr__(self): |
|
30 |
return repr(self.__doc__) |
|
31 |
||
32 |
||
33 |
class RequiredPasswordMissing(ValidationError): |
|
34 |
__doc__ = _("You must enter a password.") |
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
35 |
|
36 |
def __repr__(self): |
|
37 |
return repr(self.__doc__) |
|
38 |
||
39 |
||
40 |
class PasswordChangeWidget(PasswordWidget): |
|
41 |
"""A password change widget.
|
|
42 |
||
43 |
Text is not echoed to the user, and two text boxes are used to ensure
|
|
44 |
the password is entered correctly.
|
|
45 |
"""
|
|
5534.1.1
by Carlos Perello Marin
Updated password widget to use a more clear approach |
46 |
implements(ITextBrowserWidget, IMultiLineWidgetLayout) |
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
47 |
type = 'password change' |
5534.1.1
by Carlos Perello Marin
Updated password widget to use a more clear approach |
48 |
display_label = False |
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
49 |
|
50 |
__call__ = ViewPageTemplateFile('templates/passwordchange.pt') |
|
51 |
||
52 |
def hasInput(self): |
|
53 |
"""We always have input if there is an existing value
|
|
4785.3.7
by Jeroen Vermeulen
Removed whitespace at ends of lines |
54 |
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
55 |
No input indicates unchanged.
|
56 |
"""
|
|
57 |
if PasswordWidget.hasInput(self): |
|
58 |
return True |
|
59 |
||
60 |
# If we don't have input from the user, we lie because we will
|
|
61 |
# use the existing value.
|
|
62 |
return bool(self._getCurrentPassword()) |
|
63 |
||
64 |
def _getCurrentPassword(self): |
|
65 |
# Yesh... indirection up the wazoo to do something this simple.
|
|
66 |
# Returns the current password.
|
|
67 |
return self.context.get(self.context.context) or None |
|
68 |
||
69 |
def getInputValue(self): |
|
70 |
"""Ensure both text boxes contain the same value and inherited checks
|
|
71 |
||
4173.1.5
by Francis J. Lacoste
Upgrade canonical widgets to use IBrowserFormNG. |
72 |
>>> from canonical.launchpad.webapp.servers import (
|
73 |
... LaunchpadTestRequest)
|
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
74 |
>>> from zope.schema import Field
|
75 |
>>> field = Field(__name__='foo', title=u'Foo')
|
|
76 |
||
77 |
The widget will only return a value if both of the text boxes
|
|
78 |
contain the same value. It returns the value encrypted.
|
|
79 |
||
4173.1.5
by Francis J. Lacoste
Upgrade canonical widgets to use IBrowserFormNG. |
80 |
>>> request = LaunchpadTestRequest(form={
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
81 |
... 'field.foo': u'My Password', 'field.foo_dupe': u'My Password'})
|
82 |
>>> widget = PasswordChangeWidget(field, request)
|
|
83 |
>>> crypted_pw = widget.getInputValue()
|
|
84 |
>>> encryptor = getUtility(IPasswordEncryptor)
|
|
85 |
>>> encryptor.validate(u'My Password', crypted_pw)
|
|
86 |
True
|
|
87 |
||
4785.3.7
by Jeroen Vermeulen
Removed whitespace at ends of lines |
88 |
Otherwise it raises the exception required by IInputWidget
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
89 |
|
4173.1.5
by Francis J. Lacoste
Upgrade canonical widgets to use IBrowserFormNG. |
90 |
>>> request = LaunchpadTestRequest(form={
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
91 |
... 'field.foo': u'My Password', 'field.foo_dupe': u'No Match'})
|
92 |
>>> widget = PasswordChangeWidget(field, request)
|
|
93 |
>>> widget.getInputValue()
|
|
94 |
Traceback (most recent call last):
|
|
95 |
[...]
|
|
2865.1.9
by Stuart Bishop
Fix doctest |
96 |
WidgetInputError: ('foo', u'Foo', u'Passwords do not match.')
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
97 |
"""
|
4173.1.5
by Francis J. Lacoste
Upgrade canonical widgets to use IBrowserFormNG. |
98 |
value1 = self.request.form_ng.getOne(self.name, None) |
99 |
value2 = self.request.form_ng.getOne('%s_dupe' % self.name, None) |
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
100 |
if value1 != value2: |
101 |
self._error = WidgetInputError( |
|
102 |
self.context.__name__, self.label, PasswordMismatch() |
|
103 |
)
|
|
104 |
raise self._error |
|
105 |
||
106 |
# If the user hasn't entered a password, we use the existing one
|
|
2865.1.7
by Stuart Bishop
Improve PasswordChangeWidget validation, stopping a System Error from occuring |
107 |
# if it is there. If it is not there, we are creating a new password
|
108 |
# and we raise an error
|
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
109 |
if not value1: |
2865.1.7
by Stuart Bishop
Improve PasswordChangeWidget validation, stopping a System Error from occuring |
110 |
current_password = self._getCurrentPassword() |
111 |
if current_password: |
|
112 |
return current_password |
|
113 |
else: |
|
114 |
self._error = WidgetInputError( |
|
115 |
self.context.__name__, self.label, |
|
116 |
RequiredPasswordMissing() |
|
117 |
)
|
|
118 |
raise self._error |
|
1786
by Canonical.com Patch Queue Manager
[r=jamesh] Password Change Widget |
119 |
|
120 |
# Do any other validation
|
|
121 |
value = PasswordWidget.getInputValue(self) |
|
122 |
assert value == value1, 'Form system has changed' |
|
123 |
||
124 |
# If we have matching plaintext, encrypt it and return the password
|
|
125 |
encryptor = getUtility(IPasswordEncryptor) |
|
126 |
return encryptor.encrypt(value) |
|
127 |