Back to index

plone3  3.1.7
test_UserFolder.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2006 Zope Corporation and Contributors. All Rights
00004 # Reserved.
00005 #
00006 # This software is subject to the provisions of the Zope Public License,
00007 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this
00008 # distribution.
00009 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00010 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00011 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00012 # FOR A PARTICULAR PURPOSE.
00013 #
00014 ##############################################################################
00015 
00016 import os, sys, base64, unittest
00017 
00018 from Products.PluggableAuthService.tests import pastc
00019 
00020 from AccessControl import Unauthorized
00021 from AccessControl.Permissions import view as View
00022 from AccessControl.Permissions import add_folders as AddFolders
00023 
00024 from Products.PluggableAuthService.PluggableAuthService import PluggableAuthService
00025 
00026 from zope import event
00027 from zope.component import adapter
00028 from zope.component import provideHandler
00029 from Products.PluggableAuthService.interfaces.events import IPrincipalCreatedEvent
00030 from Products.PluggableAuthService.events import CredentialsUpdated
00031 from Products.PluggableAuthService.events import PASEventNotify
00032 from Products.PluggableAuthService.events import userCredentialsUpdatedHandler
00033 
00034 @adapter(IPrincipalCreatedEvent)
00035 def userCreatedHandler(event):
00036     pas = event.principal.aq_parent
00037     if not hasattr(pas, 'events'):
00038         pas.events = []
00039 
00040     pas.events.append(event)
00041 
00042 
00043 class UserFolderTests(pastc.PASTestCase):
00044 
00045     def afterSetUp(self):
00046         # Set up roles and a user
00047         self.uf = self.folder.acl_users
00048         self.folder._addRole('role1')
00049         self.folder.manage_role('role1', [View])
00050         self.uf.roles.addRole('role1')
00051         self.folder._addRole('role2')
00052         self.folder.manage_role('role2', [View])
00053         self.uf.roles.addRole('role2')
00054         self.uf._doAddUser('user1', 'secret', ['role1'], [])
00055         # Set up a published object accessible to user
00056         self.folder.addDTMLMethod('doc', file='the document')
00057         self.doc = self.folder.doc
00058         self.doc.manage_permission(View, ['role1'], acquire=0)
00059         # Rig the REQUEST so it looks like we traversed to doc
00060         self.app.REQUEST['PUBLISHED'] = self.doc
00061         self.app.REQUEST['PARENTS'] = [self.app, self.folder]
00062         self.app.REQUEST.steps = list(self.doc.getPhysicalPath())
00063         self.basic = 'Basic %s' % base64.encodestring('user1:secret').rstrip()
00064         # Make sure we are not logged in
00065         self.logout()
00066 
00067     def testGetUser(self):
00068         self.failIfEqual(self.uf.getUser('user1'), None)
00069 
00070     def testGetBadUser(self):
00071         self.assertEqual(self.uf.getUser('user2'), None)
00072 
00073     def testGetUserById(self):
00074         self.failIfEqual(self.uf.getUserById('user1'), None)
00075 
00076     def testGetBadUserById(self):
00077         self.assertEqual(self.uf.getUserById('user2'), None)
00078 
00079     def NOTIMPLEMENTED_testGetUsers(self):
00080         users = self.uf.getUsers()
00081         self.failUnless(users)
00082         self.assertEqual(users[0].getUserName(), 'user1')
00083 
00084     def NOTIMPLEMENTED_testGetUserNames(self):
00085         names = self.uf.getUserNames()
00086         self.failUnless(names)
00087         self.assertEqual(names[0], 'user1')
00088 
00089     def NOTIMPLEMENTED_testIdentify(self):
00090         name, password = self.uf.identify(self.basic)
00091         self.assertEqual(name, 'user1')
00092         self.assertEqual(password, 'secret')
00093 
00094     def testGetRoles(self):
00095         user = self.uf.getUser('user1')
00096         self.failUnless('role1' in user.getRoles())
00097         self.failIf('role2' in user.getRoles())
00098 
00099     def testGetRolesInContext(self):
00100         user = self.uf.getUser('user1')
00101         self.folder.manage_addLocalRoles('user1', ['role2'])
00102         roles = user.getRolesInContext(self.folder)
00103         self.failUnless('role1' in roles)
00104         self.failUnless('role2' in roles)
00105 
00106     def testHasRole(self):
00107         user = self.uf.getUser('user1')
00108         self.failUnless(user.has_role('role1', self.folder))
00109 
00110     def testHasLocalRole(self):
00111         user = self.uf.getUser('user1')
00112         self.failIf(user.has_role('role2', self.folder))
00113         self.folder.manage_addLocalRoles('user1', ['role2'])
00114         self.failUnless(user.has_role('role2', self.folder))
00115 
00116     def testHasPermission(self):
00117         user = self.uf.getUser('user1')
00118         self.failUnless(user.has_permission(View, self.folder))
00119         self.failIf(user.has_permission(AddFolders, self.folder))
00120         self.folder.manage_role('role1', [AddFolders])
00121         self.failUnless(user.has_permission(AddFolders, self.folder))
00122 
00123     def testHasLocalRolePermission(self):
00124         user = self.uf.getUser('user1')
00125         self.folder.manage_role('role2', [AddFolders])
00126         self.failIf(user.has_permission(AddFolders, self.folder))
00127         self.folder.manage_addLocalRoles('user1', ['role2'])
00128         self.failUnless(user.has_permission(AddFolders, self.folder))
00129 
00130     def NOTIMPLEMENTED_testAuthenticate(self):
00131         user = self.uf.getUser('user1')
00132         self.failUnless(user.authenticate('secret', self.app.REQUEST))
00133 
00134     def testValidate(self):
00135         # XXX: PAS validate ignores auth argument
00136         self.app.REQUEST._auth = self.basic
00137         user = self.uf.validate(self.app.REQUEST, self.basic, ['role1'])
00138         self.failIfEqual(user, None)
00139         self.assertEqual(user.getUserName(), 'user1')
00140 
00141     def testNotValidateWithoutAuth(self):
00142         # XXX: PAS validate ignores auth argument
00143         user = self.uf.validate(self.app.REQUEST, '', ['role1'])
00144         self.assertEqual(user, None)
00145 
00146     def testValidateWithoutRoles(self):
00147         # Note - calling uf.validate without specifying roles will cause
00148         # the security machinery to determine the needed roles by looking
00149         # at the object itself (or its container). I'm putting this note
00150         # in to clarify because the original test expected failure but it
00151         # really should have expected success, since the user and the
00152         # object being checked both have the role 'role1', even though no
00153         # roles are passed explicitly to the userfolder validate method.
00154         # XXX: PAS validate ignores auth argument
00155         self.app.REQUEST._auth = self.basic
00156         user = self.uf.validate(self.app.REQUEST, self.basic)
00157         self.assertEqual(user.getUserName(), 'user1')
00158 
00159     def testNotValidateWithEmptyRoles(self):
00160         # XXX: PAS validate ignores auth argument
00161         self.app.REQUEST._auth = self.basic
00162         user = self.uf.validate(self.app.REQUEST, self.basic, [])
00163         self.assertEqual(user, None)
00164 
00165     def testNotValidateWithWrongRoles(self):
00166         # XXX: PAS validate ignores auth argument
00167         self.app.REQUEST._auth = self.basic
00168         user = self.uf.validate(self.app.REQUEST, self.basic, ['role2'])
00169         self.assertEqual(user, None)
00170 
00171     def testAllowAccessToUser(self):
00172         self.login('user1')
00173         try:
00174             self.folder.restrictedTraverse('doc')
00175         except Unauthorized:
00176             self.fail('Unauthorized')
00177 
00178     def testDenyAccessToAnonymous(self):
00179         self.assertRaises(Unauthorized, self.folder.restrictedTraverse, 'doc')
00180 
00181     def testMaxListUsers(self):
00182         # create a folder-ish thing which contains a roleManager,
00183         # then put an acl_users object into the folde-ish thing
00184 
00185         class Folderish(PluggableAuthService):
00186             def __init__(self, size, count):
00187                 self.maxlistusers = size
00188                 self.users = []
00189                 self.acl_users = self
00190                 self.__allow_groups__ = self
00191                 for i in xrange(count):
00192                     self.users.append("Nobody")
00193 
00194             def getUsers(self):
00195                 return self.users
00196 
00197             def user_names(self):
00198                 return self.getUsers()
00199 
00200 
00201         tinyFolderOver = Folderish(15, 20)
00202         tinyFolderUnder = Folderish(15, 10)
00203 
00204         assert tinyFolderOver.maxlistusers == 15
00205         assert tinyFolderUnder.maxlistusers == 15
00206         assert len(tinyFolderOver.user_names()) == 20
00207         assert len(tinyFolderUnder.user_names()) == 10
00208 
00209         try:
00210             list = tinyFolderOver.get_valid_userids()
00211             assert 0, "Did not raise overflow error"
00212         except OverflowError:
00213             pass
00214 
00215         try:
00216             list = tinyFolderUnder.get_valid_userids()
00217             pass
00218         except OverflowError:
00219             assert 0, "Raised overflow error erroneously"
00220 
00221     def test__doAddUser_with_not_yet_encrypted_passwords(self):
00222         # See collector #1869 && #1926
00223         from AccessControl.AuthEncoding import is_encrypted
00224 
00225         USER_ID = 'not_yet_encrypted'
00226         PASSWORD = 'password'
00227 
00228         self.failIf(is_encrypted(PASSWORD))
00229 
00230         self.uf._doAddUser(USER_ID, PASSWORD, [], [])
00231 
00232         uid_and_info = self.uf.users.authenticateCredentials(
00233                                 { 'login': USER_ID
00234                                 , 'password': PASSWORD
00235                                 })
00236 
00237         self.assertEqual(uid_and_info, (USER_ID, USER_ID))
00238 
00239     def test__doAddUser_with_preencrypted_passwords(self):
00240         # See collector #1869 && #1926
00241         from AccessControl.AuthEncoding import pw_encrypt
00242 
00243         USER_ID = 'already_encrypted'
00244         PASSWORD = 'password'
00245 
00246         ENCRYPTED = pw_encrypt(PASSWORD)
00247 
00248         self.uf._doAddUser(USER_ID, ENCRYPTED, [], [])
00249 
00250         uid_and_info = self.uf.users.authenticateCredentials(
00251                                 { 'login': USER_ID
00252                                 , 'password': PASSWORD
00253                                 })
00254 
00255         self.assertEqual(uid_and_info, (USER_ID, USER_ID))
00256 
00257     def test_manage_zmi_logout(self):
00258         request = self.app.REQUEST
00259         response = request.RESPONSE
00260         self.folder.manage_zmi_logout(request, response)
00261         self.assertEqual(response.status, 401)
00262         self.assertEqual(response.headers.get('WWW-Authenticate'),
00263                          'basic realm="%s"' % response.realm)
00264 
00265 
00266 class UserTests(pastc.PASTestCase):
00267 
00268     def afterSetUp(self):
00269         self.uf = self.folder.acl_users
00270         self.uf._doAddUser('chris', '123', ['Manager'], [])
00271         self.user = self.uf.getUser('chris')
00272 
00273     def testGetUserName(self):
00274         f = self.user
00275         self.assertEqual(f.getUserName(), 'chris')
00276 
00277     def testGetUserId(self):
00278         f = self.user
00279         self.assertEqual(f.getId(), 'chris')
00280 
00281     def testBaseUserGetIdEqualGetName(self):
00282         # this is true for the default user type, but will not
00283         # always be true for extended user types going forward (post-2.6)
00284         f = self.user
00285         self.assertEqual(f.getId(), f.getUserName())
00286 
00287     def NOTIMPLEMENTED_testGetPassword(self):
00288         f = self.user
00289         self.assertEqual(f._getPassword(), '123')
00290 
00291     def testGetRoles(self):
00292         f = self.user
00293         # XXX: PAS returns roles as list
00294         #self.assertEqual(f.getRoles(), ('Manager', 'Authenticated'))
00295         self.assertEqual(f.getRoles(), ['Manager', 'Authenticated'])
00296 
00297     def testGetDomains(self):
00298         f = self.user
00299         self.assertEqual(f.getDomains(), ())
00300 
00301 
00302 class UserEvents(pastc.PASTestCase):
00303 
00304     def afterSetUp(self):
00305         # Set up roles and a user
00306         self.uf = self.folder.acl_users
00307         self.folder._addRole('role1')
00308         self.folder.manage_role('role1', [View])
00309         self.uf.roles.addRole('role1')
00310         self.folder._addRole('role2')
00311         self.uf._doAddUser('user1', 'secret', ['role1'], [])
00312 
00313     def testUserCreationEvent(self):
00314         provideHandler(userCreatedHandler)
00315         self.uf.events = []
00316 
00317         self.uf._doAddUser('event1', 'secret', ['role1'], [])
00318 
00319         self.assertEqual(len(self.uf.events), 1)
00320         event = self.uf.events[0]
00321         self.failUnless(IPrincipalCreatedEvent.providedBy(event))
00322         self.assertEqual(event.principal.getUserName(), 'event1')
00323         self.assertEqual(event.principal.getId(), 'event1')
00324 
00325     def testCredentialsEvent(self):
00326         provideHandler(PASEventNotify)
00327         provideHandler(userCredentialsUpdatedHandler)
00328         def wrap(self, *args):
00329             self._data.append(args)
00330             return self._original(*args)
00331         self.uf._data=[]
00332         self.uf._original=self.uf.updateCredentials
00333         self.uf.updateCredentials=wrap
00334         event.notify(CredentialsUpdated(self.uf.getUserById("user1"), "testpassword"))
00335         self.assertEqual(len(self.uf._data), 1)
00336         self.assertEqual(self.uf._data[0][2], "user1")
00337         self.assertEqual(self.uf._data[0][3], "testpassword")
00338 
00339 
00340 
00341 def test_suite():
00342     suite = unittest.TestSuite()
00343     suite.addTest(unittest.makeSuite(UserFolderTests))
00344     suite.addTest(unittest.makeSuite(UserTests))
00345     suite.addTest(unittest.makeSuite(UserEvents))
00346     return suite
00347 
00348 if __name__ == '__main__':
00349     unittest.main(defaultTest='test_suite')