[Checkins] SVN: Products.PluggableAuthService/branches/shh-17-masquerading/ Apply user masquerading patch to PAS 1.7.
Stefan H. Holek
stefan at epy.co.at
Tue Jun 21 05:23:16 EDT 2011
Log message for revision 121963:
Apply user masquerading patch to PAS 1.7.
Changed:
U Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/PluggableAuthService.py
A Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/doc/masquerading.txt
U Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/pastc.py
U Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_MoreCaching.py
U Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_PluggableAuthService.py
A Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_masquerading.py
U Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/utils.py
A Products.PluggableAuthService/branches/shh-17-masquerading/setup.cfg
-=-
Modified: Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/PluggableAuthService.py
===================================================================
--- Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/PluggableAuthService.py 2011-06-21 09:13:19 UTC (rev 121962)
+++ Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/PluggableAuthService.py 2011-06-21 09:23:16 UTC (rev 121963)
@@ -70,6 +70,8 @@
from .utils import createViewName
from .utils import createKeywords
from .utils import classImplements
+from .utils import masquerading
+from .utils import splitmasq
security = ModuleSecurityInfo(
'Products.PluggableAuthService.PluggableAuthService' )
@@ -595,14 +597,41 @@
for authenticator_id, auth in authenticators:
try:
+ # Masquerading: Authenticate auth_user
+ auth_user_credentials = credentials.copy()
+
+ login = credentials.get('login', '')
+
+ auth_user_login, role_user_login = splitmasq( login )
+
+ if role_user_login is not None:
+ auth_user_credentials['login'] = auth_user_login
+
uid_and_info = auth.authenticateCredentials(
- credentials )
+ auth_user_credentials )
if uid_and_info is None:
continue
user_id, info = uid_and_info
+ if role_user_login is not None:
+
+ # Masquerading: Check if auth_user is allowed to masquerade
+ if self._canMasquerade( plugins, user_id, info, request ):
+ logger.info('Masquerading allowed: %s', login)
+ else:
+ logger.warn('Masquerading denied: %s', login)
+ continue
+
+ # Masquerading: Return role_user
+ role_user_info = self._verifyUser( plugins, login=role_user_login )
+
+ if role_user_info is None:
+ continue
+
+ user_id, info = role_user_info['id'], role_user_info['login']
+
except _SWALLOWABLE_PLUGIN_EXCEPTIONS:
reraise(auth)
msg = 'AuthenticationPlugin %s error' % (
@@ -703,6 +732,25 @@
return PropertiedUser( user_id, name ).__of__( self )
+ security.declarePrivate( '_canMasquerade' )
+ def _canMasquerade( self, plugins, user_id, name=None, request=None ):
+
+ """ Return True if masquerading is enabled and user_id has the
+ Manager or Masquerader role.
+ """
+ if not masquerading():
+ return False
+
+ user = self._findUser( plugins, user_id, name, request )
+
+ if user is not None:
+ roles = user.getRoles()
+
+ if 'Manager' in roles or 'Masquerader' in roles:
+ return True
+
+ return False
+
security.declarePrivate( '_findUser' )
def _findUser( self, plugins, user_id, name=None, request=None ):
@@ -768,6 +816,11 @@
# plugin enumerators.
return None
+ # Masquerading: Lookup role_user
+ auth_user_login, role_user_login = splitmasq( login )
+ if role_user_login is not None:
+ login = role_user_login
+
criteria = {'exact_match': True}
if user_id is not None:
Added: Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/doc/masquerading.txt
===================================================================
--- Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/doc/masquerading.txt (rev 0)
+++ Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/doc/masquerading.txt 2011-06-21 09:23:16 UTC (rev 121963)
@@ -0,0 +1,11 @@
+Masquerading
+============
+
+If the environment variable ``PAS_MASQUERADING`` is set to ``on``, masquerading
+is enabled.
+
+Then, logging in as AUTHUSER/ROLEUSER (e.g. 'admin/jdoe') authenticates against
+AUTHUSER but returns ROLEUSER. As a security precaution, AUTHUSER must have
+the Manager or the Masquerader role.
+
+Note: AUTHUSER and ROLEUSER must live in the same user folder.
Property changes on: Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/doc/masquerading.txt
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/pastc.py
===================================================================
--- Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/pastc.py 2011-06-21 09:13:19 UTC (rev 121962)
+++ Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/pastc.py 2011-06-21 09:23:16 UTC (rev 121963)
@@ -23,15 +23,20 @@
from Testing.ZopeTestCase import user_password
from Testing.ZopeTestCase import user_role
-from base64 import encodestring
-user_auth = encodestring('%s:%s' % (user_name, user_password)).rstrip()
-
from Products.PluggableAuthService.interfaces.plugins import \
IAuthenticationPlugin, IUserEnumerationPlugin, IRolesPlugin, \
IRoleEnumerationPlugin, IRoleAssignerPlugin, \
+ IGroupsPlugin, IGroupEnumerationPlugin, \
IChallengePlugin, IExtractionPlugin, IUserAdderPlugin
+from base64 import encodestring
+def mkauth(name, password):
+ return encodestring('%s:%s' % (name, password)).rstrip()
+
+user_auth = mkauth(user_name, user_password)
+
+
class PASTestCase(ZopeTestCase.ZopeTestCase):
"""ZopeTestCase with a PAS instead of the default user folder
"""
@@ -45,6 +50,7 @@
factory.addHTTPBasicAuthHelper('http_auth')
factory.addZODBUserManager('users')
factory.addZODBRoleManager('roles')
+ factory.addZODBGroupManager('groups')
plugins = pas.plugins
plugins.activatePlugin(IChallengePlugin, 'http_auth')
plugins.activatePlugin(IExtractionPlugin, 'http_auth')
@@ -54,6 +60,8 @@
plugins.activatePlugin(IRolesPlugin, 'roles')
plugins.activatePlugin(IRoleAssignerPlugin, 'roles')
plugins.activatePlugin(IRoleEnumerationPlugin, 'roles')
+ plugins.activatePlugin(IGroupsPlugin, 'groups')
+ plugins.activatePlugin(IGroupEnumerationPlugin, 'groups')
def _setupUser(self):
"""Creates the default user."""
Modified: Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_MoreCaching.py
===================================================================
--- Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_MoreCaching.py 2011-06-21 09:13:19 UTC (rev 121962)
+++ Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_MoreCaching.py 2011-06-21 09:23:16 UTC (rev 121963)
@@ -282,7 +282,6 @@
password = 'secret'
factory = self.pas.manage_addProduct['PluggableAuthService']
- factory.addZODBGroupManager( 'groups' )
self.pas._doAddUser(user_id, password, [], [])
groups = self.pas.groups
groups.addGroup( group_id )
@@ -297,7 +296,6 @@
password = 'secret'
factory = self.pas.manage_addProduct['PluggableAuthService']
- factory.addZODBGroupManager( 'groups' )
self.pas._doAddUser(user_id, password, [], [])
groups = self.pas.groups
groups.addGroup( group_id )
Modified: Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_PluggableAuthService.py
===================================================================
--- Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_PluggableAuthService.py 2011-06-21 09:13:19 UTC (rev 121962)
+++ Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_PluggableAuthService.py 2011-06-21 09:23:16 UTC (rev 121963)
@@ -1513,7 +1513,7 @@
zcuf = self._makeOne( plugins )
foo = self._makeUserEnumerator( 'foo' )
- foo.identifier = 'foo/'
+ foo.identifier = 'foo:'
zcuf._setObject( 'foo', foo )
bar = self._makeUserEnumerator( 'bar', 'bar at example.com' )
@@ -1528,7 +1528,7 @@
self.assertEqual( zcuf.getUser( 'zope' ), None )
user = zcuf.getUser( 'foo' )
- self.assertEqual( user.getId(), 'foo/foo' )
+ self.assertEqual( user.getId(), 'foo:foo' )
self.assertEqual( zcuf.getUser( 'who_knows' ), None )
@@ -1544,17 +1544,17 @@
zcuf = self._makeOne( plugins )
bar = self._makeUserEnumerator( 'bar', 'bar at example.com' )
- bar.identifier = 'bar/'
+ bar.identifier = 'bar:'
zcuf._setObject( 'bar', bar )
zcuf.plugins.activatePlugin(IUserEnumerationPlugin, 'bar')
# Fetch the new user by ID and name, and check we get the same.
- user = zcuf.getUserById('bar/bar')
- self.assertEqual( user.getId(), 'bar/bar')
+ user = zcuf.getUserById('bar:bar')
+ self.assertEqual( user.getId(), 'bar:bar')
self.assertEqual( user.getUserName(), 'bar at example.com' )
user2 = zcuf.getUser('bar at example.com')
- self.assertEqual( user2.getId(), 'bar/bar')
+ self.assertEqual( user2.getId(), 'bar:bar')
self.assertEqual( user2.getUserName(), 'bar at example.com' )
def test_simple_getUserGroups_with_Groupplugin(self):
Added: Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_masquerading.py
===================================================================
--- Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_masquerading.py (rev 0)
+++ Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_masquerading.py 2011-06-21 09:23:16 UTC (rev 121963)
@@ -0,0 +1,371 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors. All Rights
+# Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this
+# distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+
+from base64 import decodestring
+from urllib import unquote
+
+from Testing.ZopeTestCase import Functional
+
+from Products.PluggableAuthService.tests import pastc
+
+from Products.PluggableAuthService.interfaces.plugins import IChallengePlugin
+from Products.PluggableAuthService.interfaces.plugins import IExtractionPlugin
+from Products.PluggableAuthService.interfaces.plugins import ICredentialsUpdatePlugin
+from Products.PluggableAuthService.interfaces.plugins import ICredentialsResetPlugin
+
+from Products.PluggableAuthService.utils import masquerading
+from Products.PluggableAuthService.utils import splitmasq
+
+from AccessControl.SecurityManagement import getSecurityManager
+from AccessControl.Permissions import view as View
+
+
+class SplitMasqTests(unittest.TestCase):
+
+ def testSimpleId(self):
+ self.assertEqual(splitmasq('fred'), ('fred', None))
+
+ def testMasqueradingId(self):
+ self.assertEqual(splitmasq('fred/wilma'), ('fred', 'wilma'))
+
+ def testStartsWithSlash(self):
+ self.assertEqual(splitmasq('/fred'), ('/fred', None))
+
+ def testEndsWithSlash(self):
+ self.assertEqual(splitmasq('fred/'), ('fred/', None))
+
+ def testSpuriousSlash(self):
+ self.assertEqual(splitmasq('fred//wilma'), ('fred', '/wilma'))
+
+ def testSpuriousId(self):
+ self.assertEqual(splitmasq('fred/wilma/pebbles'), ('fred', 'wilma/pebbles'))
+
+ def testNoneId(self):
+ self.assertEqual(splitmasq(None), (None, None))
+
+ def testEmptyId(self):
+ self.assertEqual(splitmasq(''), ('', None))
+
+
+class MasqueradingTests(pastc.PASTestCase):
+
+ def afterSetUp(self):
+ self.pas = self.folder.acl_users
+
+ # Create a masquerading user (Manager)
+ self.pas.users.addUser('fred_id', 'fred', 'r0ck')
+ self.pas.roles.assignRoleToPrincipal('Manager', 'fred_id')
+
+ # Create a masquerading user (Masquerader)
+ self.pas.users.addUser('barney_id', 'barney', 'p4per')
+ self.pas.roles.addRole('Masquerader')
+ self.pas.roles.assignRoleToPrincipal('Masquerader', 'barney_id')
+
+ # Create a masquerading user (Masquerader via group)
+ self.pas.users.addUser('pebbles_id', 'pebbles', 'sci55ors')
+ self.pas.groups.addGroup('flintstone_id', 'flintstone')
+ self.pas.groups.addPrincipalToGroup('pebbles_id', 'flintstone_id')
+ self.pas.roles.assignRoleToPrincipal('Masquerader', 'flintstone_id')
+
+ # Create a masqueraded user
+ self.pas.users.addUser('wilma_id', 'wilma', 'geheim')
+ self.pas.roles.assignRoleToPrincipal(pastc.user_role, 'wilma_id')
+
+ # Create a protected document
+ self.folder.manage_addDTMLMethod('doc', file='the document')
+ self.doc = self.folder.doc
+ self.doc.manage_permission(View, [pastc.user_role], acquire=False)
+
+ # Rig the request so it looks like we traversed to doc
+ request = self.app.REQUEST
+ request['PUBLISHED'] = self.doc
+ request['PARENTS'] = [self.folder, self.app]
+ request.steps = list(self.doc.getPhysicalPath())
+
+ # Start out as Anonymous User
+ self.logout()
+
+ # Enable masquerading
+ masquerading(True)
+
+ def afterClear(self):
+ # Disable masquerading
+ masquerading(False)
+
+ def test__extractUserIds_Manager(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('fred/wilma', 'r0ck')
+
+ uids = self.pas._extractUserIds(request, self.pas.plugins)
+ self.assertEqual(len(uids), 1)
+
+ user_id, info = uids[0]
+ self.assertEqual(user_id, 'wilma_id')
+ self.assertEqual(info, 'wilma')
+
+ def test__extractUserIds_Masquerader(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('barney/wilma', 'p4per')
+
+ uids = self.pas._extractUserIds(request, self.pas.plugins)
+ self.assertEqual(len(uids), 1)
+
+ user_id, info = uids[0]
+ self.assertEqual(user_id, 'wilma_id')
+ self.assertEqual(info, 'wilma')
+
+ def test__extractUserIds_Masquerader_via_group(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('pebbles/wilma', 'sci55ors')
+
+ uids = self.pas._extractUserIds(request, self.pas.plugins)
+ self.assertEqual(len(uids), 1)
+
+ user_id, info = uids[0]
+ self.assertEqual(user_id, 'wilma_id')
+ self.assertEqual(info, 'wilma')
+
+ def test__extractUserIds_masquerading_disabled(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('fred/wilma', 'r0ck')
+
+ masquerading(False)
+
+ uids = self.pas._extractUserIds(request, self.pas.plugins)
+ self.assertEqual(len(uids), 0)
+
+ def test__extractUserIds_masquerading_denied(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('wilma/fred', 'geheim')
+
+ uids = self.pas._extractUserIds(request, self.pas.plugins)
+ self.assertEqual(len(uids), 0)
+
+ def test__extractUserIds_bad_role_user(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('fred/betty', 'r0ck')
+
+ uids = self.pas._extractUserIds(request, self.pas.plugins)
+ self.assertEqual(len(uids), 0)
+
+ def test__verifyUser_by_login(self):
+ info = self.pas._verifyUser(self.pas.plugins, login='fred/wilma')
+ self.assertEqual(info['id'], 'wilma_id')
+ self.assertEqual(info['login'], 'wilma')
+
+ def test__verifyUser_bad_role_user(self):
+ info = self.pas._verifyUser(self.pas.plugins, login='fred/betty')
+ self.assertEqual(info, None)
+
+ def test_validate_Manager(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('fred/wilma', 'r0ck')
+
+ user = self.pas.validate(request)
+ self.failIfEqual(user, None)
+ self.assertEqual(user.getId(), 'wilma_id')
+ self.assertEqual(user.getUserName(), 'wilma')
+ self.assertEqual(user.getRoles(), ['Authenticated', pastc.user_role])
+
+ user = getSecurityManager().getUser()
+ self.failIfEqual(user, None)
+ self.assertEqual(user.getId(), 'wilma_id')
+ self.assertEqual(user.getUserName(), 'wilma')
+ self.assertEqual(user.getRoles(), ['Authenticated', pastc.user_role])
+
+ def test_validate_Masquerader(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('barney/wilma', 'p4per')
+
+ user = self.pas.validate(request)
+ self.failIfEqual(user, None)
+ self.assertEqual(user.getId(), 'wilma_id')
+ self.assertEqual(user.getUserName(), 'wilma')
+ self.assertEqual(user.getRoles(), ['Authenticated', pastc.user_role])
+
+ user = getSecurityManager().getUser()
+ self.failIfEqual(user, None)
+ self.assertEqual(user.getId(), 'wilma_id')
+ self.assertEqual(user.getUserName(), 'wilma')
+ self.assertEqual(user.getRoles(), ['Authenticated', pastc.user_role])
+
+ def test_validate_Masquerader_via_group(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('pebbles/wilma', 'sci55ors')
+
+ user = self.pas.validate(request)
+ self.failIfEqual(user, None)
+ self.assertEqual(user.getId(), 'wilma_id')
+ self.assertEqual(user.getUserName(), 'wilma')
+ self.assertEqual(user.getRoles(), ['Authenticated', pastc.user_role])
+
+ user = getSecurityManager().getUser()
+ self.failIfEqual(user, None)
+ self.assertEqual(user.getId(), 'wilma_id')
+ self.assertEqual(user.getUserName(), 'wilma')
+ self.assertEqual(user.getRoles(), ['Authenticated', pastc.user_role])
+
+ def test_validate_masquerading_disabled(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('fred/wilma', 'r0ck')
+
+ masquerading(False)
+
+ user = self.pas.validate(request)
+ self.assertEqual(user, None)
+
+ user = getSecurityManager().getUser()
+ self.failIfEqual(user, None)
+ self.assertEqual(user.getId(), None)
+ self.assertEqual(user.getUserName(), 'Anonymous User')
+ self.assertEqual(user.getRoles(), ('Anonymous',))
+
+ def test_validate_masquerading_denied(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('wilma/fred', 'geheim')
+
+ user = self.pas.validate(request)
+ self.assertEqual(user, None)
+
+ user = getSecurityManager().getUser()
+ self.failIfEqual(user, None)
+ self.assertEqual(user.getId(), None)
+ self.assertEqual(user.getUserName(), 'Anonymous User')
+ self.assertEqual(user.getRoles(), ('Anonymous',))
+
+ def test_validate_bad_role_user(self):
+ request = self.app.REQUEST
+ request._auth = 'Basic %s' % pastc.mkauth('fred/betty', 'r0ck')
+
+ user = self.pas.validate(request)
+ self.assertEqual(user, None)
+
+ user = getSecurityManager().getUser()
+ self.failIfEqual(user, None)
+ self.assertEqual(user.getId(), None)
+ self.assertEqual(user.getUserName(), 'Anonymous User')
+ self.assertEqual(user.getRoles(), ('Anonymous',))
+
+
+class BasicAuthTests(Functional, pastc.PASTestCase):
+
+ def afterSetUp(self):
+ self.pas = self.folder.acl_users
+ # Create a masquerading user (Manager)
+ self.pas.users.addUser('fred_id', 'fred', 'r0ck')
+ self.pas.roles.assignRoleToPrincipal('Manager', 'fred_id')
+ # Create a masqueraded user
+ self.pas.users.addUser('wilma_id', 'wilma', 'geheim')
+ self.pas.roles.assignRoleToPrincipal(pastc.user_role, 'wilma_id')
+ # Create a protected document
+ self.folder.manage_addDTMLMethod('doc', file='the document')
+ self.doc = self.folder.doc
+ self.doc.manage_permission(View, [pastc.user_role], acquire=False)
+ # Enable masquerading
+ masquerading(True)
+
+ def afterClear(self):
+ # Disable masquerading
+ masquerading(False)
+
+ def testCredentials(self):
+ doc_path = self.doc.absolute_url_path()
+
+ name = 'fred/wilma'
+ password = 'r0ck'
+
+ credentials = '%s:%s' % (name, password)
+
+ response = self.publish(doc_path)
+ self.assertEqual(response.getStatus(), 401)
+
+ response = self.publish(doc_path, basic=credentials)
+ self.assertEqual(response.getStatus(), 200)
+
+
+class CookieAuthTests(BasicAuthTests):
+
+ def afterSetUp(self):
+ BasicAuthTests.afterSetUp(self)
+ # Add a cookie_auth plugin
+ factory = self.pas.manage_addProduct['PluggableAuthService']
+ factory.addCookieAuthHelper('cookie_auth')
+ self.cookie_auth = self.pas.cookie_auth
+ # Activate it
+ plugins = self.pas.plugins
+ plugins.activatePlugin(IChallengePlugin, 'cookie_auth')
+ plugins.movePluginsUp(IChallengePlugin, ['cookie_auth'])
+ plugins.activatePlugin(IExtractionPlugin, 'cookie_auth')
+ plugins.activatePlugin(ICredentialsUpdatePlugin, 'cookie_auth')
+ plugins.activatePlugin(ICredentialsResetPlugin, 'cookie_auth')
+
+ def testCredentials(self):
+ doc_path = self.doc.absolute_url_path()
+ doc_url = self.doc.absolute_url()
+
+ cookie_auth_path = self.cookie_auth.absolute_url_path()
+ cookie_auth_url = self.cookie_auth.absolute_url()
+
+ name = 'fred/wilma'
+ password = 'r0ck'
+
+ # Accessing doc sends us to login_form
+ response = self.publish(doc_path)
+ self.assertEqual(response.getStatus(), 302)
+
+ location = response.getHeader('Location')
+ location, came_from = location.split('?')
+ self.assertEqual(location, cookie_auth_url+'/login_form')
+
+ # Fill the form and submit
+ login_path = cookie_auth_path+'/login'
+ credentials = '?__ac_name=%s&__ac_password=%s&%s' % (name, password, came_from)
+
+ # We are logged in and sent back to where we came_from
+ response = self.publish(login_path+credentials)
+ self.assertEqual(response.getStatus(), 302)
+
+ location = response.getHeader('Location')
+ self.assertEqual(location, doc_url)
+
+ # We also receive an auth cookie
+ cookie_name = self.cookie_auth.cookie_name
+ cookie_value = response.getCookie(cookie_name)['value']
+
+ name, password = decodestring(unquote(cookie_value)).split(':')
+ name = name.decode('hex')
+ password = password.decode('hex')
+
+ self.assertEqual(name, 'fred/wilma')
+ self.assertEqual(password, 'r0ck')
+
+ # Which we can then use to access doc
+ response = self.publish(doc_path, extra={cookie_name: cookie_value})
+ self.assertEqual(response.getStatus(), 200)
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(SplitMasqTests),
+ unittest.makeSuite(MasqueradingTests),
+ unittest.makeSuite(BasicAuthTests),
+ unittest.makeSuite(CookieAuthTests),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
+
Property changes on: Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/tests/test_masquerading.py
___________________________________________________________________
Added: svn:keywords
+ Id
Added: svn:eol-style
+ native
Modified: Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/utils.py
===================================================================
--- Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/utils.py 2011-06-21 09:13:19 UTC (rev 121962)
+++ Products.PluggableAuthService/branches/shh-17-masquerading/Products/PluggableAuthService/utils.py 2011-06-21 09:23:16 UTC (rev 121963)
@@ -187,3 +187,24 @@
return {'keywords': keywords.hexdigest()}
+
+#
+# Masquerading helpers
+#
+_ENVAR = 'PAS_MASQUERADING'
+
+def masquerading( enabled=None ):
+ value = os.environ.get(_ENVAR, 'off')
+ if enabled is not None:
+ os.environ[_ENVAR] = enabled and 'on' or 'off'
+ return value == 'on'
+
+_MASQ = '/'
+
+def splitmasq( user_id ):
+ if user_id is not None:
+ split = user_id.split(_MASQ, 1)
+ if len(split) == 2 and '' not in split:
+ return tuple(split)
+ return user_id, None
+
Added: Products.PluggableAuthService/branches/shh-17-masquerading/setup.cfg
===================================================================
--- Products.PluggableAuthService/branches/shh-17-masquerading/setup.cfg (rev 0)
+++ Products.PluggableAuthService/branches/shh-17-masquerading/setup.cfg 2011-06-21 09:23:16 UTC (rev 121963)
@@ -0,0 +1,6 @@
+[egg_info]
+tag_build = -jarn.masquerading
+tag_svn_revision = true
+[egg_info]
+tag_build = -jarn.masquerading
+tag_svn_revision = true
Property changes on: Products.PluggableAuthService/branches/shh-17-masquerading/setup.cfg
___________________________________________________________________
Added: svn:eol-style
+ native
More information about the checkins
mailing list