[Checkins] SVN: PluggableAuthService/trunk/ - ZODBUserManager:
Extend the "notional IZODBUserManager interface"
Jens Vagelpohl
jens at dataflake.org
Sat Jun 24 07:01:17 EDT 2006
Log message for revision 68822:
- ZODBUserManager: Extend the "notional IZODBUserManager interface"
with the left-out updateUser facility and a corresponding
manage_updateUser method for ZMI use. Removed any responsibility
for updating a user's login from the updateUserPassword and
manage_updateUserPassword methods. This fixes the breakage
described in the collector issue below, and makes the ZMI view
for updating users work in a sane way.
(http://www.zope.org/Collectors/PAS/42)
Changed:
U PluggableAuthService/trunk/doc/CHANGES.txt
U PluggableAuthService/trunk/plugins/ZODBUserManager.py
U PluggableAuthService/trunk/plugins/tests/test_ZODBUserManager.py
U PluggableAuthService/trunk/plugins/www/zuUsers.zpt
-=-
Modified: PluggableAuthService/trunk/doc/CHANGES.txt
===================================================================
--- PluggableAuthService/trunk/doc/CHANGES.txt 2006-06-24 09:46:59 UTC (rev 68821)
+++ PluggableAuthService/trunk/doc/CHANGES.txt 2006-06-24 11:01:17 UTC (rev 68822)
@@ -4,6 +4,15 @@
Bugs Fixed
+ - ZODBUserManager: Extend the "notional IZODBUserManager interface"
+ with the left-out updateUser facility and a corresponding
+ manage_updateUser method for ZMI use. Removed any responsibility
+ for updating a user's login from the updateUserPassword and
+ manage_updateUserPassword methods. This fixes the breakage
+ described in the collector issue below, and makes the ZMI view
+ for updating users work in a sane way.
+ (http://www.zope.org/Collectors/PAS/42)
+
- CookieAuthHelper: If expireCookie was called and extractCredentials
was hit in the same request, the CookieAuthHelper would throw an
exception (http://www.zope.org/Collectors/PAS/43)
Modified: PluggableAuthService/trunk/plugins/ZODBUserManager.py
===================================================================
--- PluggableAuthService/trunk/plugins/ZODBUserManager.py 2006-06-24 09:46:59 UTC (rev 68821)
+++ PluggableAuthService/trunk/plugins/ZODBUserManager.py 2006-06-24 11:01:17 UTC (rev 68822)
@@ -287,6 +287,16 @@
view_name = createViewName('enumerateUsers')
self.ZCacheable_invalidate(view_name=view_name)
+ security.declarePrivate('updateUser')
+ def updateUser(self, user_id, login_name):
+
+ # The following raises a KeyError if the user_id is invalid
+ old_login = self.getLoginForUserId(user_id)
+
+ del self._login_to_userid[old_login]
+ self._login_to_userid[login_name] = user_id
+ self._userid_to_login[user_id] = login_name
+
security.declarePrivate( 'removeUser' )
def removeUser( self, user_id ):
@@ -306,18 +316,11 @@
self.ZCacheable_invalidate(view_name=view_name)
security.declarePrivate( 'updateUserPassword' )
- def updateUserPassword( self, user_id, login_name, password ):
+ def updateUserPassword( self, user_id, password ):
if self._user_passwords.get( user_id ) is None:
raise KeyError, 'Invalid user ID: %s' % user_id
- old_login_name = self._userid_to_login[ user_id ]
-
- if old_login_name != login_name:
- del self._login_to_userid[ old_login_name ]
- self._login_to_userid[ login_name ] = user_id
- self._userid_to_login[ user_id ] = login_name
-
if password:
digested = AuthEncoding.pw_encrypt( password )
self._user_passwords[ user_id ] = digested
@@ -377,7 +380,6 @@
security.declareProtected( ManageUsers, 'manage_updateUserPassword' )
def manage_updateUserPassword( self
, user_id
- , login_name
, password
, confirm
, RESPONSE=None
@@ -389,15 +391,28 @@
else:
- if not login_name:
- login_name = user_id
+ self.updateUserPassword( user_id, password )
- # XXX: validate 'user_id', 'login_name' against policies?
+ message = 'password+updated'
- self.updateUserPassword( user_id, login_name, password )
+ if RESPONSE is not None:
+ RESPONSE.redirect( '%s/manage_users?manage_tabs_message=%s'
+ % ( self.absolute_url(), message )
+ )
- message = 'password+updated'
+ security.declareProtected( ManageUsers, 'manage_updateUser' )
+ def manage_updateUser(self, user_id, login_name, RESPONSE=None):
+ """ Update a user's login name via the ZMI.
+ """
+ if not login_name:
+ login_name = user_id
+ # XXX: validate 'user_id', 'login_name' against policies?
+
+ self.updateUser(user_id, login_name)
+
+ message = 'Login+name+updated'
+
if RESPONSE is not None:
RESPONSE.redirect( '%s/manage_users?manage_tabs_message=%s'
% ( self.absolute_url(), message )
Modified: PluggableAuthService/trunk/plugins/tests/test_ZODBUserManager.py
===================================================================
--- PluggableAuthService/trunk/plugins/tests/test_ZODBUserManager.py 2006-06-24 09:46:59 UTC (rev 68821)
+++ PluggableAuthService/trunk/plugins/tests/test_ZODBUserManager.py 2006-06-24 11:01:17 UTC (rev 68822)
@@ -357,6 +357,50 @@
self.assertEqual( user_id, 'new_user' )
self.assertEqual( login, 'new_user at example.com' )
+ def test_updateUserPassword(self):
+
+ zum = self._makeOne()
+
+ # Create a user and make sure we can authenticate with it
+ zum.addUser( 'user1', 'user1 at example.com', 'password' )
+ info1 = { 'login' : 'user1 at example.com', 'password' : 'password' }
+ user_id, login = zum.authenticateCredentials(info1)
+ self.assertEqual(user_id, 'user1')
+ self.assertEqual(login, 'user1 at example.com')
+
+ # Give the user a new password; attempting to authenticate with the
+ # old password must fail
+ zum.updateUserPassword('user1', 'new_password')
+ self.failIf(zum.authenticateCredentials(info1))
+
+ # Try to authenticate with the new password, this must succeed.
+ info2 = { 'login' : 'user1 at example.com', 'password' : 'new_password' }
+ user_id, login = zum.authenticateCredentials(info2)
+ self.assertEqual(user_id, 'user1')
+ self.assertEqual(login, 'user1 at example.com')
+
+ def test_updateUser(self):
+
+ zum = self._makeOne()
+
+ # Create a user and make sure we can authenticate with it
+ zum.addUser( 'user1', 'user1 at example.com', 'password' )
+ info1 = { 'login' : 'user1 at example.com', 'password' : 'password' }
+ user_id, login = zum.authenticateCredentials(info1)
+ self.assertEqual(user_id, 'user1')
+ self.assertEqual(login, 'user1 at example.com')
+
+ # Give the user a new login; attempts to authenticate with the
+ # old login must fail.
+ zum.updateUser('user1', 'user1 at foobar.com')
+ self.failIf(zum.authenticateCredentials(info1))
+
+ # Try to authenticate with the new login, this must succeed.
+ info2 = { 'login' : 'user1 at foobar.com', 'password' : 'password' }
+ user_id, login = zum.authenticateCredentials(info2)
+ self.assertEqual(user_id, 'user1')
+ self.assertEqual(login, 'user1 at foobar.com')
+
def test_enumerateUsersWithOptionalMangling(self):
zum = self._makeOne()
Modified: PluggableAuthService/trunk/plugins/www/zuUsers.zpt
===================================================================
--- PluggableAuthService/trunk/plugins/www/zuUsers.zpt 2006-06-24 09:46:59 UTC (rev 68821)
+++ PluggableAuthService/trunk/plugins/www/zuUsers.zpt 2006-06-24 11:01:17 UTC (rev 68822)
@@ -126,11 +126,34 @@
</td>
</tr>
- <tbody metal:use-macro="here/manage_widgets/macros/authentication_widgets">
+ <tr valign="top">
+ <th align="right">
+ <div class="form-label">Login name:</div>
+ </th>
+ <td>
+ <div class="form-label" tal:content="login_name"> Login </div>
+ </td>
+ </tr>
- </tbody>
+ <tr valign="top">
+ <th align="right">
+ <div class="form-label">Password:</div>
+ </th>
+ <td>
+ <input type="password" name="password" size="20" value="password" />
+ </td>
+ </tr>
<tr valign="top">
+ <th align="right">
+ <div class="form-label">Confirm password:</div>
+ </th>
+ <td>
+ <input type="password" name="confirm" size="20" value="confirm" />
+ </td>
+ </tr>
+
+ <tr valign="top">
<td />
<td>
<input type="submit" value=" Update Password " />
@@ -160,10 +183,25 @@
<th align="right">
<div class="form-label">User ID:</div>
</th>
- <td tal:content="user_id">USER_ID</td>
+ <td>
+ <input type="hidden" name="user_id"
+ tal:attributes="value user_id" />
+ <div class="form-label" tal:content="user_id">USER_ID</div>
+ </td>
</tr>
<tr valign="top">
+ <th align="right">
+ <div class="form-label">Login name:</div>
+ </th>
+ <td>
+ <input type="text" name="login_name" size="40"
+ tal:attributes="value login_name"
+ />
+ </td>
+ </tr>
+
+ <tr valign="top">
<td />
<td>
<input type="submit" value=" Update User " />
More information about the Checkins
mailing list