• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / Products.PluggableAuthService / 5303493172

pending completion
5303493172

push

github

web-flow
Drop support for Python 2.7, 3.5, 3.6. (#116)

* Drop zserver extra in setup.py. Thus dropping FTP support.
* Drop support for Zope < 5.
Co-authored-by: Jens Vagelpohl <jens@plyp.com>

1288 of 1745 branches covered (73.81%)

Branch coverage included in aggregate %.

127 of 127 new or added lines in 30 files covered. (100.0%)

9619 of 10349 relevant lines covered (92.95%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.38
/src/Products/PluggableAuthService/tests/test_UserFolder.py
1
##############################################################################
2
#
3
# Copyright (c) 2006 Zope Foundation and Contributors
4
#
5
# This software is subject to the provisions of the Zope Public License,
6
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this
7
# distribution.
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
# FOR A PARTICULAR PURPOSE.
12
#
13
##############################################################################
14

15
import unittest
1✔
16

17
from AccessControl import Unauthorized
1✔
18
from AccessControl.Permissions import add_folders as AddFolders
1✔
19
from AccessControl.Permissions import view as View
1✔
20
from zope import event
1✔
21
from zope.component import adapter
1✔
22
from zope.component import provideHandler
1✔
23
from ZPublisher.utils import basic_auth_encode
1✔
24

25
from ..events import CredentialsUpdated
1✔
26
from ..events import PASEventNotify
1✔
27
from ..events import userCredentialsUpdatedHandler
1✔
28
from ..interfaces.events import IPrincipalCreatedEvent
1✔
29
from ..PluggableAuthService import PluggableAuthService
1✔
30
from ..tests import pastc
1✔
31

32

33
@adapter(IPrincipalCreatedEvent)
1✔
34
def userCreatedHandler(event):
1✔
35
    pas = event.principal.aq_parent
1✔
36
    if not hasattr(pas, 'events'):
1✔
37
        pas.events = []
1✔
38

39
    pas.events.append(event)
1✔
40

41

42
class UserFolderTests(pastc.PASTestCase):
1✔
43

44
    def afterSetUp(self):
1✔
45
        # Set up roles and a user
46
        self.uf = self.folder.acl_users
1✔
47
        self.folder._addRole('role1')
1✔
48
        self.folder.manage_role('role1', [View])
1✔
49
        self.uf.roles.addRole('role1')
1✔
50
        self.folder._addRole('role2')
1✔
51
        self.folder.manage_role('role2', [View])
1✔
52
        self.uf.roles.addRole('role2')
1✔
53
        self.uf._doAddUser('user1', 'secret', ['role1'], [])
1✔
54
        # Set up a published object accessible to user
55
        self.folder.addDTMLMethod('doc', file='the document')
1✔
56
        self.doc = self.folder.doc
1✔
57
        self.doc.manage_permission(View, ['role1'], acquire=0)
1✔
58
        # Rig the REQUEST so it looks like we traversed to doc
59
        self.app.REQUEST['PUBLISHED'] = self.doc
1✔
60
        self.app.REQUEST['PARENTS'] = [self.app, self.folder]
1✔
61
        self.app.REQUEST.steps = list(self.doc.getPhysicalPath())
1✔
62
        self.basic = basic_auth_encode('user1', 'secret')
1✔
63
        # Make sure we are not logged in
64
        self.logout()
1✔
65

66
    def testGetUser(self):
1✔
67
        self.assertNotEqual(self.uf.getUser('user1'), None)
1✔
68

69
    def testGetBadUser(self):
1✔
70
        self.assertEqual(self.uf.getUser('user2'), None)
1✔
71

72
    def testGetUserById(self):
1✔
73
        self.assertNotEqual(self.uf.getUserById('user1'), None)
1✔
74

75
    def testGetBadUserById(self):
1✔
76
        self.assertEqual(self.uf.getUserById('user2'), None)
1✔
77

78
    @unittest.expectedFailure
1✔
79
    def testGetUsers(self):
1✔
80
        # Fails because of NotImplementedError
81
        users = self.uf.getUsers()
1✔
82
        self.assertTrue(users)
×
83
        self.assertEqual(users[0].getUserName(), 'user1')
×
84

85
    @unittest.expectedFailure
1✔
86
    def testGetUserNames(self):
1✔
87
        # Fails because of NotImplementedError
88
        names = self.uf.getUserNames()
1✔
89
        self.assertTrue(names)
×
90
        self.assertEqual(names[0], 'user1')
×
91

92
    @unittest.expectedFailure
1✔
93
    def testIdentify(self):
1✔
94
        # Fails because of NotImplementedError
95
        name, password = self.uf.identify(self.basic)
1✔
96
        self.assertEqual(name, 'user1')
×
97
        self.assertEqual(password, 'secret')
×
98

99
    def testGetRoles(self):
1✔
100
        user = self.uf.getUser('user1')
1✔
101
        self.assertTrue('role1' in user.getRoles())
1✔
102
        self.assertFalse('role2' in user.getRoles())
1✔
103

104
    def testGetRolesInContext(self):
1✔
105
        user = self.uf.getUser('user1')
1✔
106
        self.folder.manage_addLocalRoles('user1', ['role2'])
1✔
107
        roles = user.getRolesInContext(self.folder)
1✔
108
        self.assertTrue('role1' in roles)
1✔
109
        self.assertTrue('role2' in roles)
1✔
110

111
    def testHasRole(self):
1✔
112
        user = self.uf.getUser('user1')
1✔
113
        self.assertTrue(user.has_role('role1', self.folder))
1✔
114

115
    def testHasLocalRole(self):
1✔
116
        user = self.uf.getUser('user1')
1✔
117
        self.assertFalse(user.has_role('role2', self.folder))
1✔
118
        self.folder.manage_addLocalRoles('user1', ['role2'])
1✔
119
        self.assertTrue(user.has_role('role2', self.folder))
1✔
120

121
    def testHasPermission(self):
1✔
122
        user = self.uf.getUser('user1')
1✔
123
        self.assertTrue(user.has_permission(View, self.folder))
1✔
124
        self.assertFalse(user.has_permission(AddFolders, self.folder))
1✔
125
        self.folder.manage_role('role1', [AddFolders])
1✔
126
        self.assertTrue(user.has_permission(AddFolders, self.folder))
1✔
127

128
    def testHasLocalRolePermission(self):
1✔
129
        user = self.uf.getUser('user1')
1✔
130
        self.folder.manage_role('role2', [AddFolders])
1✔
131
        self.assertFalse(user.has_permission(AddFolders, self.folder))
1✔
132
        self.folder.manage_addLocalRoles('user1', ['role2'])
1✔
133
        self.assertTrue(user.has_permission(AddFolders, self.folder))
1✔
134

135
    @unittest.expectedFailure
1✔
136
    def testAuthenticate(self):
1✔
137
        # Fails because of NotImplementedError
138
        user = self.uf.getUser('user1')
1✔
139
        self.assertTrue(user.authenticate('secret', self.app.REQUEST))
1✔
140

141
    def testValidate(self):
1✔
142
        # ???: PAS validate ignores auth argument
143
        self.app.REQUEST._auth = self.basic
1✔
144
        user = self.uf.validate(self.app.REQUEST, self.basic, ['role1'])
1✔
145
        self.assertNotEqual(user, None)
1✔
146
        self.assertEqual(user.getUserName(), 'user1')
1✔
147

148
    def testNotValidateWithoutAuth(self):
1✔
149
        # ???: PAS validate ignores auth argument
150
        user = self.uf.validate(self.app.REQUEST, '', ['role1'])
1✔
151
        self.assertEqual(user, None)
1✔
152

153
    def testValidateWithoutRoles(self):
1✔
154
        # Note - calling uf.validate without specifying roles will cause
155
        # the security machinery to determine the needed roles by looking
156
        # at the object itself (or its container). I'm putting this note
157
        # in to clarify because the original test expected failure but it
158
        # really should have expected success, since the user and the
159
        # object being checked both have the role 'role1', even though no
160
        # roles are passed explicitly to the userfolder validate method.
161
        # ???: PAS validate ignores auth argument
162
        self.app.REQUEST._auth = self.basic
1✔
163
        user = self.uf.validate(self.app.REQUEST, self.basic)
1✔
164
        self.assertEqual(user.getUserName(), 'user1')
1✔
165

166
    def testNotValidateWithEmptyRoles(self):
1✔
167
        # ???: PAS validate ignores auth argument
168
        self.app.REQUEST._auth = self.basic
1✔
169
        user = self.uf.validate(self.app.REQUEST, self.basic, [])
1✔
170
        self.assertEqual(user, None)
1✔
171

172
    def testNotValidateWithWrongRoles(self):
1✔
173
        # ???: PAS validate ignores auth argument
174
        self.app.REQUEST._auth = self.basic
1✔
175
        user = self.uf.validate(self.app.REQUEST, self.basic, ['role2'])
1✔
176
        self.assertEqual(user, None)
1✔
177

178
    def testAllowAccessToUser(self):
1✔
179
        self.login('user1')
1✔
180
        try:
1✔
181
            self.folder.restrictedTraverse('doc')
1✔
182
        except Unauthorized:
×
183
            self.fail('Unauthorized')
184

185
    def testDenyAccessToAnonymous(self):
1✔
186
        self.assertRaises(Unauthorized, self.folder.restrictedTraverse, 'doc')
1✔
187

188
    def testMaxListUsers(self):
1✔
189
        # create a folder-ish thing which contains a roleManager,
190
        # then put an acl_users object into the folde-ish thing
191

192
        class Folderish(PluggableAuthService):
1✔
193
            def __init__(self, size, count):
1✔
194
                self.maxlistusers = size
1✔
195
                self.users = []
1✔
196
                self.acl_users = self
1✔
197
                self.__allow_groups__ = self
1✔
198
                for i in range(count):
1✔
199
                    self.users.append('Nobody')
1✔
200

201
            def getUsers(self):
1✔
202
                return self.users
1✔
203

204
            def user_names(self):
1✔
205
                return self.getUsers()
1✔
206

207
        tinyFolderOver = Folderish(15, 20)
1✔
208
        tinyFolderUnder = Folderish(15, 10)
1✔
209

210
        assert tinyFolderOver.maxlistusers == 15
1✔
211
        assert tinyFolderUnder.maxlistusers == 15
1✔
212
        assert len(tinyFolderOver.user_names()) == 20
1✔
213
        assert len(tinyFolderUnder.user_names()) == 10
1✔
214

215
        with self.assertRaises(OverflowError):
1✔
216
            tinyFolderOver.get_valid_userids()
1✔
217

218
        try:
1✔
219
            tinyFolderUnder.get_valid_userids()
1✔
220
        except OverflowError:
×
221
            self.fail('Raised overflow error erroneously')
222

223
    def test__doAddUser_with_not_yet_encrypted_passwords(self):
1✔
224
        # See collector #1869 && #1926
225
        from AuthEncoding.AuthEncoding import is_encrypted
1✔
226

227
        USER_ID = 'not_yet_encrypted'
1✔
228
        PASSWORD = 'password'
1✔
229

230
        self.assertFalse(is_encrypted(PASSWORD))
1✔
231

232
        self.uf._doAddUser(USER_ID, PASSWORD, [], [])
1✔
233

234
        uid_and_info = self.uf.users.authenticateCredentials(
1✔
235
            {'login': USER_ID, 'password': PASSWORD})
236

237
        self.assertEqual(uid_and_info, (USER_ID, USER_ID))
1✔
238

239
    def test__doAddUser_with_preencrypted_passwords(self):
1✔
240
        # See collector #1869 && #1926
241
        from AuthEncoding.AuthEncoding import pw_encrypt
1✔
242

243
        USER_ID = 'already_encrypted'
1✔
244
        PASSWORD = 'password'
1✔
245

246
        ENCRYPTED = pw_encrypt(PASSWORD)
1✔
247

248
        self.uf._doAddUser(USER_ID, ENCRYPTED, [], [])
1✔
249

250
        uid_and_info = self.uf.users.authenticateCredentials(
1✔
251
            {'login': USER_ID, 'password': PASSWORD})
252

253
        self.assertEqual(uid_and_info, (USER_ID, USER_ID))
1✔
254

255

256
class UserTests(pastc.PASTestCase):
1✔
257

258
    def afterSetUp(self):
1✔
259
        self.uf = self.folder.acl_users
1✔
260
        self.uf._doAddUser('chris', '123', ['Manager'], [])
1✔
261
        self.user = self.uf.getUser('chris')
1✔
262

263
    def testGetUserName(self):
1✔
264
        f = self.user
1✔
265
        self.assertEqual(f.getUserName(), 'chris')
1✔
266

267
    def testGetUserId(self):
1✔
268
        f = self.user
1✔
269
        self.assertEqual(f.getId(), 'chris')
1✔
270

271
    def testBaseUserGetIdEqualGetName(self):
1✔
272
        # this is true for the default user type, but will not
273
        # always be true for extended user types going forward (post-2.6)
274
        f = self.user
1✔
275
        self.assertEqual(f.getId(), f.getUserName())
1✔
276

277
    @unittest.expectedFailure
1✔
278
    def testGetPassword(self):
1✔
279
        # fails because of NotImplementedError
280
        f = self.user
1✔
281
        self.assertEqual(f._getPassword(), '123')
1✔
282

283
    def testGetRoles(self):
1✔
284
        f = self.user
1✔
285
        self.assertEqual(set(f.getRoles()), {'Authenticated', 'Manager'})
1✔
286

287
    def testGetDomains(self):
1✔
288
        f = self.user
1✔
289
        self.assertEqual(f.getDomains(), ())
1✔
290

291

292
class UserEvents(pastc.PASTestCase):
1✔
293

294
    def afterSetUp(self):
1✔
295
        # Set up roles and a user
296
        self.uf = self.folder.acl_users
1✔
297
        self.folder._addRole('role1')
1✔
298
        self.folder.manage_role('role1', [View])
1✔
299
        self.uf.roles.addRole('role1')
1✔
300
        self.folder._addRole('role2')
1✔
301
        self.uf._doAddUser('user1', 'secret', ['role1'], [])
1✔
302

303
    def testUserCreationEvent(self):
1✔
304
        provideHandler(userCreatedHandler)
1✔
305
        self.uf.events = []
1✔
306

307
        self.uf._doAddUser('event1', 'secret', ['role1'], [])
1✔
308

309
        self.assertEqual(len(self.uf.events), 1)
1✔
310
        event = self.uf.events[0]
1✔
311
        self.assertTrue(IPrincipalCreatedEvent.providedBy(event))
1✔
312
        self.assertEqual(event.principal.getUserName(), 'event1')
1✔
313
        self.assertEqual(event.principal.getId(), 'event1')
1✔
314

315
    def testCredentialsEvent(self):
1✔
316
        import functools
1✔
317
        provideHandler(PASEventNotify)
1✔
318
        provideHandler(userCredentialsUpdatedHandler)
1✔
319

320
        def wrap(self, *args):
1✔
321
            self._data.append(args)
1✔
322
            return self._original(*args)
1✔
323

324
        self.uf._data = []
1✔
325
        self.uf._original = self.uf.updateCredentials
1✔
326
        self.uf.updateCredentials = functools.partial(wrap, self.uf)
1✔
327
        self.assertEqual(len(self.uf._data), 0)
1✔
328
        event.notify(CredentialsUpdated(self.uf.getUserById('user_id'),
1✔
329
                                        'testpassword'))
330
        self.assertEqual(self.uf._data[0][2], 'user_login')
1✔
331
        self.assertEqual(self.uf._data[0][3], 'testpassword')
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc