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

zopefoundation / Products.PluggableAuthService / 10028140575

14 Jun 2024 03:56PM UTC coverage: 90.57% (+0.4%) from 90.185%
10028140575

push

github

web-flow
- Add support for Python 3.12.  - Drop support for Python 3.7. (#119)

1735 of 2189 branches covered (79.26%)

Branch coverage included in aggregate %.

20 of 24 new or added lines in 8 files covered. (83.33%)

1 existing line in 1 file now uncovered.

9588 of 10313 relevant lines covered (92.97%)

0.93 hits per line

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

98.0
/src/Products/PluggableAuthService/tests/test_PluggableAuthService.py
1
##############################################################################
2
#
3
# Copyright (c) 2001 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.SecurityManagement import newSecurityManager
1✔
18
from AccessControl.SecurityManagement import noSecurityManager
1✔
19
from AccessControl.SecurityManager import setSecurityPolicy
1✔
20
from Acquisition import Implicit
1✔
21
from Acquisition import aq_base
1✔
22
from OFS.ObjectManager import ObjectManager
1✔
23
from zExceptions import Unauthorized
1✔
24
from zope.interface import implementer
1✔
25

26
from ..interfaces.plugins import INotCompetentPlugin
1✔
27
from ..utils import directlyProvides
1✔
28
from .conformance import IUserFolder_conformance
1✔
29

30

31
class DummyPlugin(Implicit):
1✔
32
    pass
1✔
33

34

35
class FaultyRolesPlugin(DummyPlugin):
1✔
36

37
    def getRolesForPrincipal(self, principal, request=None):
1✔
38
        raise KeyError('intentional KeyError from FaultyRolesPlugin')
1✔
39

40

41
class DummyUserEnumerator(DummyPlugin):
1✔
42

43
    def __init__(self, user_id, login=None):
1✔
44

45
        self._user_id = self.PLUGINID = user_id
1✔
46

47
        if login is None:
1✔
48
            login = user_id
1✔
49

50
        self._login = login
1✔
51
        self.identifier = None
1✔
52

53
    def enumerateUsers(self, **kw):
1✔
54

55
        _id = self._user_id
1✔
56

57
        if self.identifier is not None:
1✔
58
            _id = f'{self.identifier}{self._user_id}'
1✔
59

60
        result = [{'id': _id, 'login': self._login,
1✔
61
                   'pluginid': self.PLUGINID}]
62

63
        # Both id and login can be strings or sequences.
64
        user_id = kw.get('id')
1✔
65
        if isinstance(user_id, str):
1✔
66
            user_id = [user_id]
1✔
67
        if user_id and _id in user_id:
1✔
68
            return tuple(result)
1✔
69

70
        login = kw.get('login')
1✔
71
        if isinstance(login, str):
1✔
72
            login = [login]
1✔
73
        if login and self._login in login:
1✔
74
            return tuple(result)
1✔
75

76
        return ()
1✔
77

78

79
class DummyMultiUserEnumerator(DummyPlugin):
1✔
80

81
    def __init__(self, pluginid, *users):
1✔
82

83
        self.PLUGINID = pluginid
1✔
84

85
        self.users = users
1✔
86

87
    def enumerateUsers(self, id=None, login=None, exact_match=False):
1✔
88

89
        results = []
1✔
90

91
        for info in self.users:
1✔
92
            id_match = False
1✔
93
            if id:
1!
94
                if exact_match:
×
95
                    if info['id'] == id:
×
96
                        id_match = True
×
97
                elif info['id'].find(id) != -1:
×
98
                    id_match = True
×
99
            else:
100
                id_match = True
1✔
101

102
            login_match = False
1✔
103
            if login:
1!
104
                if exact_match:
1✔
105
                    if info['login'] == login:
1✔
106
                        login_match = True
1✔
107
                elif info['login'].find(login) != -1:
1✔
108
                    login_match = True
1✔
109
            else:
110
                login_match = True
×
111

112
            if id_match and login_match:
1✔
113
                results.append(info)
1✔
114

115
        return tuple(results)
1✔
116

117
    def updateUser(self, user_id, login_name):
1✔
118
        for info in self.users:
1!
119
            if info['id'] == user_id:
1✔
120
                info['login'] = login_name
1✔
121
                return True
1✔
122

123
    def updateEveryLoginName(self, quit_on_first_error=True):
1✔
124
        # Let's lowercase all login names.
125
        for info in self.users:
1✔
126
            info['login'] = info['login'].lower()
1✔
127

128

129
class WantonUserEnumerator(DummyMultiUserEnumerator):
1✔
130
    def enumerateUsers(self, *args, **kw):
1✔
131
        # Always returns everybody.
132
        return self.users
1✔
133

134

135
class DummyGroupEnumerator(DummyPlugin):
1✔
136

137
    def __init__(self, group_id):
1✔
138

139
        self._group_id = self.PLUGINID = group_id
1✔
140
        self.identifier = None
1✔
141

142
    def enumerateGroups(self, id=None, exact_match=True, sort_by=None,
1✔
143
                        max_results=None, **kw):
144

145
        _id = self._group_id
1✔
146

147
        if self.identifier is not None:
1!
NEW
148
            _id = f'{self.identifier}{self._group_id}'
×
149

150
        result = [{'id': _id, 'pluginid': self.PLUGINID}]
1✔
151

152
        if id:
1✔
153
            if _id.find(id) >= 0:
1✔
154
                return tuple(result)
1✔
155
        return ()
1✔
156

157

158
class DummySuperEnumerator(DummyUserEnumerator, DummyGroupEnumerator):
1✔
159

160
    PLUGINID = 'super'
1✔
161

162
    def __init__(self, user_id, login, group_id):
1✔
163
        self._user_id = user_id
1✔
164
        self._login = login
1✔
165
        self._group_id = group_id
1✔
166
        self.identifier = None
1✔
167

168

169
class DummyGroupPlugin(DummyPlugin):
1✔
170

171
    def __init__(self, id, groups=()):
1✔
172

173
        self._id = id
1✔
174
        self._groups = groups
1✔
175

176
    def getGroupsForPrincipal(self, user, REQUEST=None):
1✔
177

178
        return self._groups
1✔
179

180

181
class DummyChallenger(DummyPlugin):
1✔
182

183
    def __init__(self, id):
1✔
184
        self.id = id
1✔
185

186
    def challenge(self, request, response):
1✔
187
        # Mark on the faux response that we have seen it:
188
        response.challenger = self
1✔
189
        return True
1✔
190

191

192
class DummyCredentialsStore(DummyPlugin):
1✔
193

194
    def __init__(self, id):
1✔
195
        self.id = id
1✔
196
        self.creds = {}
1✔
197

198
    def updateCredentials(self, request, response, login, password):
1✔
199
        self.creds[login] = password
1✔
200

201
    def resetCredentials(self, request, response):
1✔
202
        login = request['login']
1✔
203
        del self.creds[login]
1✔
204

205
    def extractCredentials(self, request):
1✔
206
        creds = {}
1✔
207
        login = request['login']
1✔
208

209
        if self.creds.get(login) is not None:
1✔
210
            creds['login'] = login
1✔
211
            creds['password'] = self.creds.get(login)
1✔
212

213
        return creds
1✔
214

215

216
class DummyBadChallenger(DummyChallenger):
1✔
217

218
    def challenge(self, request, response):
1✔
219
        # We don't play here.
220
        return False
1✔
221

222

223
class DummyReindeerChallenger(DummyChallenger):
1✔
224

225
    def challenge(self, request, response):
1✔
226
        reindeer_games = getattr(response, 'reindeer_games', [])
1✔
227
        reindeer_games.append(self.id)
1✔
228
        response.reindeer_games = reindeer_games
1✔
229
        return True
1✔
230

231

232
class DummyCounterChallenger(DummyChallenger):
1✔
233

234
    def __init__(self, id):
1✔
235
        self.id = id
1✔
236
        self.count = 0
1✔
237

238
    def challenge(self, request, response):
1✔
239
        self.count += 1
1✔
240
        return True
1✔
241

242

243
@implementer(INotCompetentPlugin)
1✔
244
class DummyNotCompetentPlugin(DummyPlugin):
1✔
245

246
    def __init__(self, id, type):
1✔
247
        self.id, self.type = id, type
1✔
248

249
    def getId(self): return id
1!
250

251
    def isNotCompetentToAuthenticate(self, request):
1✔
252
        if self.type is None:
1✔
253
            raise KeyError('purposeful `KeyError` by '
1✔
254
                           '`isNotCompetentToAuthenticate`')
255
        return self.type
1✔
256

257

258
class FauxRequest:
1✔
259

260
    form = property(lambda self: self)
1✔
261

262
    def __init__(self, steps=(), **kw):
1✔
263

264
        self.steps = steps
1✔
265
        self._dict = {}
1✔
266
        self._dict.update(kw)
1✔
267
        self._held = []
1✔
268

269
    def get(self, key, default=None):
1✔
270

271
        return self._dict.get(key, default)
1✔
272

273
    def __contains__(self, key):
1✔
274
        return key in self._dict
1✔
275

276
    def _authUserPW(self):
1✔
277
        form = self.get('form')
1✔
278
        return (form.get('login'), form.get('password'))
1✔
279

280
    def __getitem__(self, key):
1✔
281

282
        return self._dict[key]
1✔
283

284
    def __setitem__(self, key, value):
1✔
285

286
        self._dict[key] = value
1✔
287

288
    def _hold(self, something):
1✔
289
        self._held.append(something)
1✔
290

291

292
class FauxNotFoundError(Exception):
1✔
293

294
    pass
1✔
295

296

297
class FauxResponse:
1✔
298

299
    def __init__(self):
1✔
300
        self.headers = {}
1✔
301

302
    def notFoundError(self, message):
1✔
303
        raise FauxNotFoundError(message)
1✔
304

305
    def _unauthorized(self):
1✔
306
        self.challenger = self
1✔
307

308
    def unauthorized(self):
1✔
309
        self._unauthorized()
1✔
310
        raise Unauthorized('You can not do this!')
1✔
311

312
    def exception(self):
1✔
313
        self._unauthorized()
×
314
        return 'An error has occurred.'
×
315

316
    def redirect(self, *ignore, **ignored):
1✔
317
        pass
×
318

319
    def getHeader(self, header):
1✔
320
        return self.headers.get(header)
1✔
321

322
    def setHeader(self, header, value):
1✔
323
        self.headers[header] = value
1✔
324

325

326
class FauxObject(Implicit):
1✔
327

328
    def __init__(self, id=None):
1✔
329

330
        self._id = id
1✔
331

332
    def getId(self):
1✔
333

334
        return self._id
×
335

336
    def __repr__(self):
1✔
337

338
        return '<FauxObject: %s>' % self._id
×
339

340
    def publishable(self, *args, **kw):
1✔
341

342
        return f'Args: {args}\nKeywords: {kw}'
×
343

344
    def this(self):
1✔
345
        return self
1✔
346

347

348
class FauxContainer(FauxObject, ObjectManager):
1✔
349

350
    pass
1✔
351

352

353
class FauxRoot(FauxContainer):
1✔
354

355
    isTopLevelPrincipiaApplicationObject = 1
1✔
356

357
    def getPhysicalRoot(self):
1✔
358
        return self
1✔
359

360
    def getPhysicalPath(self):
1✔
361
        return ()
1✔
362

363

364
class FauxUser(Implicit):
1✔
365

366
    def __init__(self, id, name=None, roles={}, groups={}):
1✔
367

368
        self._id = id
1✔
369
        self._name = name
1✔
370
        self._roles = roles
1✔
371
        self._groups = groups
1✔
372

373
    def getId(self):
1✔
374

375
        return self._id
1✔
376

377
    def getUserName(self):
1✔
378

379
        return self._name
1✔
380

381
    def getRoles(self):
1✔
382

383
        return self._roles
×
384

385
    def getGroups(self):
1✔
386

387
        return list(self._groups.keys())
1✔
388

389
    def allowed(self, value, roles):
1✔
390

391
        for role in roles:
1✔
392
            if role in self._roles:
1✔
393
                return 1
1✔
394

395
        return 0
1✔
396

397
    def _addGroups(self, groups):
1✔
398
        for group in groups:
1✔
399
            self._groups[group] = 1
1✔
400

401
    def _addRoles(self, roles):
1✔
402
        for role in roles:
1✔
403
            self._roles[role] = 1
1✔
404

405
    def __repr__(self):
1✔
406

407
        return '<FauxUser: %s>' % self._id
×
408

409

410
def _extractLogin(request):
1✔
411

412
    return {'login': request['form'].get('login'),
1✔
413
            'password': request['form'].get('password')}
414

415

416
def _authLogin(credentials):
1✔
417

418
    return (credentials['login'], credentials['login'])
1✔
419

420

421
def _extractExtra(request):
1✔
422

423
    return {'user': request.get('extra'), 'salt': 'pepper'}
1✔
424

425

426
def _authExtra(credentials):
1✔
427

428
    return (credentials.get('salt') == 'pepper' and
1✔
429
            (credentials['user'], credentials['user']) or None)
430

431

432
class RequestCleaner:
1✔
433

434
    _request = None
1✔
435

436
    def _makeRequest(self, *args, **kw):
1✔
437
        request = self._request = FauxRequest(*args, **kw)
1✔
438
        return request
1✔
439

440
    def _clearRequest(self):
1✔
441
        if self._request is not None:
1✔
442
            self._request._held = []
1✔
443

444

445
class PluggableAuthServiceTests(unittest.TestCase, IUserFolder_conformance,
1✔
446
                                RequestCleaner):
447

448
    _oldSecurityPolicy = None
1✔
449

450
    def tearDown(self):
1✔
451

452
        self._clearRequest()
1✔
453

454
        if self._oldSecurityPolicy is not None:
1✔
455
            setSecurityPolicy(self._oldSecurityPolicy)
1✔
456

457
        noSecurityManager()
1✔
458

459
    def _getTargetClass(self):
1✔
460

461
        from ..PluggableAuthService import PluggableAuthService
1✔
462

463
        return PluggableAuthService
1✔
464

465
    def _makeOne(self, plugins=None, *args, **kw):
1✔
466

467
        zcuf = self._getTargetClass()(*args, **kw)
1✔
468

469
        if plugins is not None:
1✔
470
            zcuf._setObject('plugins', plugins)
1✔
471

472
        return zcuf
1✔
473

474
    def _makePlugins(self, plugin_type_info=None):
1✔
475

476
        from Products.PluginRegistry.PluginRegistry import PluginRegistry
1✔
477

478
        from ..PluggableAuthService import _PLUGIN_TYPE_INFO
1✔
479

480
        if plugin_type_info is None:
1!
481
            plugin_type_info = _PLUGIN_TYPE_INFO
1✔
482

483
        reg = PluginRegistry(plugin_type_info=plugin_type_info)
1✔
484
        reg._setId('plugins')
1✔
485
        reg._plugins = {}
1✔
486

487
        return reg
1✔
488

489
    def _makeTree(self):
1✔
490

491
        rc = FauxObject('rc')
1✔
492
        root = FauxRoot('root').__of__(rc)
1✔
493
        folder = FauxContainer('folder').__of__(root)
1✔
494
        object = FauxObject('object').__of__(folder)
1✔
495

496
        return rc, root, folder, object
1✔
497

498
    def _makeFaultyRolemaker(self):
1✔
499

500
        from ..interfaces.plugins import IRolesPlugin
1✔
501

502
        rolemaker = FaultyRolesPlugin()
1✔
503
        directlyProvides(rolemaker, IRolesPlugin)
1✔
504

505
        return rolemaker
1✔
506

507
    def _makeUserEnumerator(self, user_id, login=None):
1✔
508

509
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
510

511
        enumerator = DummyUserEnumerator(user_id, login)
1✔
512
        directlyProvides(enumerator, IUserEnumerationPlugin)
1✔
513

514
        return enumerator
1✔
515

516
    def _makeGroupEnumerator(self, group_id):
1✔
517

518
        from ..interfaces.plugins import IGroupEnumerationPlugin
1✔
519

520
        enumerator = DummyGroupEnumerator(group_id)
1✔
521
        directlyProvides(enumerator, IGroupEnumerationPlugin)
1✔
522

523
        return enumerator
1✔
524

525
    def _makeSuperEnumerator(self, user_id, login, group_id):
1✔
526

527
        from ..interfaces.plugins import IGroupEnumerationPlugin
1✔
528
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
529

530
        enumerator = DummySuperEnumerator(user_id, login, group_id)
1✔
531
        directlyProvides(enumerator,
1✔
532
                         IUserEnumerationPlugin, IGroupEnumerationPlugin)
533

534
        return enumerator
1✔
535

536
    def _makeGroupPlugin(self, id, groups=()):
1✔
537
        from ..interfaces.plugins import IGroupsPlugin
1✔
538

539
        gp = DummyGroupPlugin(id, groups=groups)
1✔
540
        directlyProvides(gp, IGroupsPlugin)
1✔
541
        return gp
1✔
542

543
    def _makeChallengePlugin(self, id, klass):
1✔
544
        from ..interfaces.plugins import IChallengePlugin
1✔
545

546
        cp = klass(id)
1✔
547
        directlyProvides(cp, IChallengePlugin)
1✔
548
        return cp
1✔
549

550
    def _makeMultiUserEnumerator(self, *users):
1✔
551
        # users should be something like this:
552
        # [{'id': 'Foo', 'login': 'foobar'},
553
        #  {'id': 'Bar', 'login': 'BAR'}]
554

555
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
556

557
        enumerator = DummyMultiUserEnumerator('enumerator', *users)
1✔
558
        directlyProvides(enumerator, IUserEnumerationPlugin)
1✔
559

560
        return enumerator
1✔
561

562
    def test_empty(self):
1✔
563

564
        zcuf = self._makeOne()
1✔
565

566
        self.assertEqual(zcuf.getId(), 'acl_users')
1✔
567

568
    def test_checkBeforeTraverse(self):
1✔
569

570
        rc, root, folder, object = self._makeTree()
1✔
571

572
        zcuf = self._makeOne()
1✔
573

574
        root._setObject('acl_users', zcuf)
1✔
575

576
        self.assertEqual(len(root.__before_traverse__), 1)
1✔
577

578
    def test__extractUserIds_simple(self):
1✔
579

580
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
581
        from ..interfaces.plugins import IExtractionPlugin
1✔
582

583
        plugins = self._makePlugins()
1✔
584
        zcuf = self._makeOne(plugins)
1✔
585

586
        login = DummyPlugin()
1✔
587
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
588
        login.extractCredentials = _extractLogin
1✔
589
        login.authenticateCredentials = _authLogin
1✔
590
        zcuf._setObject('login', login)
1✔
591

592
        plugins = zcuf._getOb('plugins')
1✔
593
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
594
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
595

596
        request = self._makeRequest(form={'login': 'foo',
1✔
597
                                          'password': 'bar'})
598

599
        user_ids = zcuf._extractUserIds(request=request,
1✔
600
                                        plugins=zcuf.plugins)
601

602
        self.assertEqual(len(user_ids), 1)
1✔
603
        self.assertEqual(user_ids[0][0], 'foo')
1✔
604

605
    def test__extractUserIds_one_extractor_two_authenticators(self):
1✔
606

607
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
608
        from ..interfaces.plugins import IExtractionPlugin
1✔
609

610
        plugins = self._makePlugins()
1✔
611
        zcuf = self._makeOne(plugins)
1✔
612

613
        login = DummyPlugin()
1✔
614
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
615
        login.extractCredentials = _extractLogin
1✔
616
        login.authenticateCredentials = _authLogin
1✔
617

618
        zcuf._setObject('login', login)
1✔
619

620
        always = DummyPlugin()
1✔
621
        directlyProvides(always, IAuthenticationPlugin)
1✔
622
        always.authenticateCredentials = lambda creds: ('baz', None)
1✔
623

624
        zcuf._setObject('always', always)
1✔
625

626
        plugins = zcuf._getOb('plugins')
1✔
627

628
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
629
        plugins.activatePlugin(IAuthenticationPlugin, 'always')
1✔
630
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
631

632
        request = self._makeRequest(form={'login': 'foo',
1✔
633
                                          'password': 'bar'})
634

635
        user_ids = zcuf._extractUserIds(request=request,
1✔
636
                                        plugins=zcuf.plugins)
637

638
        self.assertEqual(len(user_ids), 2)
1✔
639
        self.assertEqual(user_ids[0][0], 'baz')
1✔
640
        self.assertEqual(user_ids[1][0], 'foo')
1✔
641

642
    def test__extractUserIds_two_extractors_two_authenticators(self):
1✔
643

644
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
645
        from ..interfaces.plugins import IExtractionPlugin
1✔
646

647
        plugins = self._makePlugins()
1✔
648
        zcuf = self._makeOne(plugins)
1✔
649

650
        login = DummyPlugin()
1✔
651
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
652
        login.extractCredentials = _extractLogin
1✔
653
        login.authenticateCredentials = _authLogin
1✔
654

655
        zcuf._setObject('login', login)
1✔
656

657
        extra = DummyPlugin()
1✔
658
        directlyProvides(extra, IExtractionPlugin, IAuthenticationPlugin)
1✔
659
        extra.extractCredentials = _extractExtra
1✔
660
        extra.authenticateCredentials = _authExtra
1✔
661

662
        zcuf._setObject('extra', extra)
1✔
663

664
        plugins = zcuf._getOb('plugins')
1✔
665

666
        plugins.activatePlugin(IExtractionPlugin, 'extra')
1✔
667
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
668
        plugins.activatePlugin(IAuthenticationPlugin, 'extra')
1✔
669
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
670

671
        request = self._makeRequest(form={'login': 'foo',
1✔
672
                                          'password': 'bar'})
673

674
        user_ids = zcuf._extractUserIds(request=request,
1✔
675
                                        plugins=zcuf.plugins)
676

677
        self.assertEqual(len(user_ids), 1)
1✔
678
        self.assertEqual(user_ids[0][0], 'foo')
1✔
679

680
        request['extra'] = 'qux'
1✔
681

682
        user_ids = zcuf._extractUserIds(request=request,
1✔
683
                                        plugins=zcuf.plugins)
684

685
        self.assertEqual(len(user_ids), 2, user_ids)
1✔
686
        self.assertEqual(user_ids[0][0], 'qux')
1✔
687
        self.assertEqual(user_ids[1][0], 'foo')
1✔
688

689
    def test__extractUserIds_broken_extractor_before_good_extractor(self):
1✔
690

691
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
692
        from ..interfaces.plugins import IExtractionPlugin
1✔
693

694
        plugins = self._makePlugins()
1✔
695
        zcuf = self._makeOne(plugins)
1✔
696

697
        login = DummyPlugin()
1✔
698
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
699
        login.extractCredentials = _extractLogin
1✔
700
        login.authenticateCredentials = _authLogin
1✔
701

702
        zcuf._setObject('login', login)
1✔
703

704
        borked = DummyPlugin()
1✔
705
        directlyProvides(borked, IExtractionPlugin)
1✔
706
        borked.extractCredentials = lambda req: 'abc'
1✔
707

708
        zcuf._setObject('borked', borked)
1✔
709

710
        plugins = zcuf._getOb('plugins')
1✔
711

712
        plugins.activatePlugin(IExtractionPlugin, 'borked')   # 1
1✔
713
        plugins.activatePlugin(IExtractionPlugin, 'login')    # 2
1✔
714
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
715

716
        request = self._makeRequest(form={'login': 'foo',
1✔
717
                                          'password': 'bar'})
718

719
        user_ids = zcuf._extractUserIds(request=request,
1✔
720
                                        plugins=zcuf.plugins)
721

722
        self.assertEqual(len(user_ids), 1)
1✔
723
        self.assertEqual(user_ids[0][0], 'foo')
1✔
724

725
    def test__extractUserIds_broken_extractor_after_good_extractor(self):
1✔
726

727
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
728
        from ..interfaces.plugins import IExtractionPlugin
1✔
729

730
        plugins = self._makePlugins()
1✔
731
        zcuf = self._makeOne(plugins)
1✔
732

733
        login = DummyPlugin()
1✔
734
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
735
        login.extractCredentials = _extractLogin
1✔
736
        login.authenticateCredentials = _authLogin
1✔
737

738
        zcuf._setObject('login', login)
1✔
739

740
        borked = DummyPlugin()
1✔
741
        directlyProvides(borked, IExtractionPlugin)
1✔
742
        borked.extractCredentials = lambda req: 'abc'
1✔
743

744
        zcuf._setObject('borked', borked)
1✔
745

746
        plugins = zcuf._getOb('plugins')
1✔
747

748
        plugins.activatePlugin(IExtractionPlugin, 'login')    # 1
1✔
749
        plugins.activatePlugin(IExtractionPlugin, 'borked')   # 2
1✔
750
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
751

752
        request = self._makeRequest(form={'login': 'foo', 'password': 'bar'})
1✔
753
        user_ids = zcuf._extractUserIds(request=request, plugins=zcuf.plugins)
1✔
754

755
        self.assertEqual(len(user_ids), 1)
1✔
756
        self.assertEqual(user_ids[0][0], 'foo')
1✔
757

758
    def test__extractUserIds_authenticate_emergency_user_broken_extor(self):
1✔
759

760
        from AccessControl.users import UnrestrictedUser
1✔
761

762
        from .. import PluggableAuthService
1✔
763
        from ..interfaces.plugins import IExtractionPlugin
1✔
764

765
        old_eu = PluggableAuthService.emergency_user
1✔
766

767
        eu = UnrestrictedUser('foo', 'bar', ('manage',), ())
1✔
768

769
        PluggableAuthService.emergency_user = eu
1✔
770

771
        try:
1✔
772
            plugins = self._makePlugins()
1✔
773
            zcuf = self._makeOne(plugins)
1✔
774

775
            borked = DummyPlugin()
1✔
776
            directlyProvides(borked, IExtractionPlugin)
1✔
777
            borked.extractCredentials = lambda req: 'abc'
1✔
778

779
            zcuf._setObject('borked', borked)
1✔
780

781
            plugins = zcuf._getOb('plugins')
1✔
782

783
            plugins.activatePlugin(IExtractionPlugin, 'borked')
1✔
784

785
            request = self._makeRequest(form={'login': eu.getUserName(),
1✔
786
                                              'password': eu._getPassword()})
787

788
            user_ids = zcuf._extractUserIds(request=request,
1✔
789
                                            plugins=zcuf.plugins)
790

791
            self.assertEqual(len(user_ids), 1)
1✔
792
            self.assertEqual(user_ids[0][0], 'foo')
1✔
793
        finally:
794
            PluggableAuthService.emergency_user = old_eu
1✔
795

796
    def test__extractUserIds_broken_authicator_before_good_authenticator(self):
1✔
797

798
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
799
        from ..interfaces.plugins import IExtractionPlugin
1✔
800

801
        plugins = self._makePlugins()
1✔
802
        zcuf = self._makeOne(plugins)
1✔
803

804
        login = DummyPlugin()
1✔
805
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
806
        login.extractCredentials = _extractLogin
1✔
807
        login.authenticateCredentials = _authLogin
1✔
808

809
        zcuf._setObject('login', login)
1✔
810

811
        borked = DummyPlugin()
1✔
812
        directlyProvides(borked, IAuthenticationPlugin)
1✔
813
        borked.authenticateCredentials = lambda creds: creds['nonesuch']
1✔
814

815
        zcuf._setObject('borked', borked)
1✔
816

817
        plugins = zcuf._getOb('plugins')
1✔
818

819
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
820
        plugins.activatePlugin(IAuthenticationPlugin, 'borked')   # 1
1✔
821
        plugins.activatePlugin(IAuthenticationPlugin, 'login')    # 2
1✔
822

823
        request = self._makeRequest(form={'login': 'foo', 'password': 'bar'})
1✔
824
        user_ids = zcuf._extractUserIds(request=request, plugins=zcuf.plugins)
1✔
825

826
        self.assertEqual(len(user_ids), 1)
1✔
827
        self.assertEqual(user_ids[0][0], 'foo')
1✔
828

829
    def test__extractUserIds_broken_authicator_after_good_authenticator(self):
1✔
830

831
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
832
        from ..interfaces.plugins import IExtractionPlugin
1✔
833

834
        plugins = self._makePlugins()
1✔
835
        zcuf = self._makeOne(plugins)
1✔
836

837
        login = DummyPlugin()
1✔
838
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
839
        login.extractCredentials = _extractLogin
1✔
840
        login.authenticateCredentials = _authLogin
1✔
841

842
        zcuf._setObject('login', login)
1✔
843

844
        borked = DummyPlugin()
1✔
845
        directlyProvides(borked, IAuthenticationPlugin)
1✔
846
        borked.authenticateCredentials = lambda creds: creds['nonesuch']
1✔
847

848
        zcuf._setObject('borked', borked)
1✔
849

850
        plugins = zcuf._getOb('plugins')
1✔
851

852
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
853
        plugins.activatePlugin(IAuthenticationPlugin, 'login')    # 1
1✔
854
        plugins.activatePlugin(IAuthenticationPlugin, 'borked')   # 2
1✔
855

856
        request = self._makeRequest(form={'login': 'foo', 'password': 'bar'})
1✔
857

858
        user_ids = zcuf._extractUserIds(request=request, plugins=zcuf.plugins)
1✔
859

860
        self.assertEqual(len(user_ids), 1)
1✔
861
        self.assertEqual(user_ids[0][0], 'foo')
1✔
862

863
    def test__extractUserIds_authenticate_emrgncy_with_broken_authicator(self):
1✔
864

865
        from AccessControl.users import UnrestrictedUser
1✔
866

867
        from .. import PluggableAuthService
1✔
868
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
869
        from ..interfaces.plugins import IExtractionPlugin
1✔
870

871
        old_eu = PluggableAuthService.emergency_user
1✔
872

873
        eu = UnrestrictedUser('foo', 'bar', ('manage',), ())
1✔
874

875
        PluggableAuthService.emergency_user = eu
1✔
876

877
        try:
1✔
878
            plugins = self._makePlugins()
1✔
879
            zcuf = self._makeOne(plugins)
1✔
880

881
            login = DummyPlugin()
1✔
882
            directlyProvides(login, IExtractionPlugin)
1✔
883

884
            # Make the first attempt at emergency user authentication fail
885
            # (but not the extractor itself).
886
            login.extractCredentials = lambda req: {'login': '',
1✔
887
                                                    'password': ''}
888

889
            zcuf._setObject('login', login)
1✔
890

891
            borked = DummyPlugin()
1✔
892
            directlyProvides(borked, IAuthenticationPlugin)
1✔
893
            borked.authenticateCredentials = lambda creds: creds['nonesuch']
1✔
894

895
            zcuf._setObject('borked', borked)
1✔
896

897
            plugins = zcuf._getOb('plugins')
1✔
898

899
            plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
900
            plugins.activatePlugin(IAuthenticationPlugin, 'borked')
1✔
901

902
            request = self._makeRequest(form={'login': eu.getUserName(),
1✔
903
                                              'password': eu._getPassword()})
904

905
            user_ids = zcuf._extractUserIds(request=request,
1✔
906
                                            plugins=zcuf.plugins)
907

908
            self.assertEqual(len(user_ids), 1)
1✔
909
            self.assertEqual(user_ids[0][0], 'foo')
1✔
910
        finally:
911
            PluggableAuthService.emergency_user = old_eu
1✔
912

913
    def test__extractUserIds_emergency_user_always_wins(self):
1✔
914

915
        from AccessControl.users import UnrestrictedUser
1✔
916

917
        from .. import PluggableAuthService
1✔
918
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
919
        from ..interfaces.plugins import IExtractionPlugin
1✔
920

921
        old_eu = PluggableAuthService.emergency_user
1✔
922

923
        eu = UnrestrictedUser('foo', 'bar', ('manage',), ())
1✔
924

925
        PluggableAuthService.emergency_user = eu
1✔
926

927
        try:
1✔
928
            plugins = self._makePlugins()
1✔
929
            zcuf = self._makeOne(plugins)
1✔
930

931
            login = DummyPlugin()
1✔
932
            directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
933
            login.extractCredentials = lambda req: {'login': 'baz',
1✔
934
                                                    'password': ''}
935
            login.authenticateCredentials = _authLogin
1✔
936

937
            zcuf._setObject('login', login)
1✔
938

939
            plugins = zcuf._getOb('plugins')
1✔
940

941
            plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
942
            plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
943

944
            request = self._makeRequest(form={'login': eu.getUserName(),
1✔
945
                                              'password': eu._getPassword()})
946

947
            # This should authenticate the emergency user and not 'baz'
948
            user_ids = zcuf._extractUserIds(request=request,
1✔
949
                                            plugins=zcuf.plugins)
950

951
            self.assertEqual(len(user_ids), 1)
1✔
952
            self.assertEqual(user_ids[0][0], 'foo')
1✔
953
        finally:
954
            PluggableAuthService.emergency_user = old_eu
1✔
955

956
    def test__extractUserIds_transform(self):
1✔
957

958
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
959
        from ..interfaces.plugins import IExtractionPlugin
1✔
960

961
        plugins = self._makePlugins()
1✔
962
        zcuf = self._makeOne(plugins)
1✔
963

964
        login = DummyPlugin()
1✔
965
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
966
        login.extractCredentials = _extractLogin
1✔
967
        login.authenticateCredentials = _authLogin
1✔
968
        zcuf._setObject('login', login)
1✔
969
        # Make login names lowercase.  User ids are not affected, but
970
        # our dummy _authLogin simply reports a tuple with twice the
971
        # login name.
972
        zcuf.login_transform = 'lower'
1✔
973

974
        plugins = zcuf._getOb('plugins')
1✔
975
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
976
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
977

978
        # Mixed case here.
979
        request = self._makeRequest(form={'login': 'Foo', 'password': 'Bar'})
1✔
980
        user_ids = zcuf._extractUserIds(request=request, plugins=zcuf.plugins)
1✔
981

982
        self.assertEqual(len(user_ids), 1)
1✔
983
        # Lower case here.
984
        self.assertEqual(user_ids[0][0], 'foo')
1✔
985

986
    def test__extractUserIds_emergency_user_always_wins_in_transform(self):
1✔
987

988
        from AccessControl.users import UnrestrictedUser
1✔
989

990
        from .. import PluggableAuthService
1✔
991
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
992
        from ..interfaces.plugins import IExtractionPlugin
1✔
993

994
        old_eu = PluggableAuthService.emergency_user
1✔
995

996
        # Mixed case here.  We want to test if an emergency user with
997
        # mixed (or upper) case login name is found also when the
998
        # login_transform is to lower case the login.
999
        eu = UnrestrictedUser('Foo', 'Bar', ('manage',), ())
1✔
1000

1001
        PluggableAuthService.emergency_user = eu
1✔
1002

1003
        try:
1✔
1004
            plugins = self._makePlugins()
1✔
1005
            zcuf = self._makeOne(plugins)
1✔
1006

1007
            login = DummyPlugin()
1✔
1008
            directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
1009
            login.extractCredentials = lambda req: {'login': 'baz',
1✔
1010
                                                    'password': ''}
1011
            login.authenticateCredentials = _authLogin
1✔
1012

1013
            zcuf._setObject('login', login)
1✔
1014
            zcuf.login_transform = 'lower'
1✔
1015

1016
            plugins = zcuf._getOb('plugins')
1✔
1017

1018
            plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
1019
            plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
1020

1021
            request = self._makeRequest(form={'login': eu.getUserName(),
1✔
1022
                                              'password': eu._getPassword()})
1023

1024
            # This should authenticate the emergency user and not 'baz'
1025
            user_ids = zcuf._extractUserIds(request=request,
1✔
1026
                                            plugins=zcuf.plugins)
1027

1028
            self.assertEqual(len(user_ids), 1)
1✔
1029
            self.assertEqual(user_ids[0][0], 'Foo')
1✔
1030
        finally:
1031
            PluggableAuthService.emergency_user = old_eu
1✔
1032

1033
    def _isNotCompetent_test(self, decisions, result):
1✔
1034
        from ..interfaces.plugins import INotCompetentPlugin
1✔
1035

1036
        plugins = self._makePlugins()
1✔
1037
        zcuf = self._makeOne(plugins)
1✔
1038
        plugins = zcuf._getOb('plugins')  # acquisition wrap
1✔
1039

1040
        for i, decision in enumerate(decisions):
1✔
1041
            pid = 'nc_%d' % i
1✔
1042
            p = DummyNotCompetentPlugin(pid, decision)
1✔
1043
            zcuf._setObject(pid, p)
1✔
1044
            plugins.activatePlugin(INotCompetentPlugin, pid)
1✔
1045

1046
        self.assertEqual(zcuf._isNotCompetent(None, plugins), result)
1✔
1047

1048
    def test__isNotCompetent_empty(self):
1✔
1049
        self._isNotCompetent_test((), False)
1✔
1050

1051
    def test__isNotCompetent_False(self):
1✔
1052
        self._isNotCompetent_test((False,), False)
1✔
1053

1054
    def test__isNotCompetent_True(self):
1✔
1055
        self._isNotCompetent_test((True,), True)
1✔
1056

1057
    def test__isNotCompetent_True_False(self):
1✔
1058
        self._isNotCompetent_test((True, False), True)
1✔
1059

1060
    def test__isNotCompetent_False_True(self):
1✔
1061
        self._isNotCompetent_test((False, True), True)
1✔
1062

1063
    def test__isNotCompetent_Broken(self):
1✔
1064
        self._isNotCompetent_test((None,), False)
1✔
1065

1066
    def test__isNotCompetent_Broken_True(self):
1✔
1067
        self._isNotCompetent_test((None, True), True)
1✔
1068

1069
    def test__getObjectContext_no_steps(self):
1✔
1070

1071
        zcuf = self._makeOne()
1✔
1072
        request = self._makeRequest((), RESPONSE=FauxResponse())
1✔
1073

1074
        self.assertRaises(FauxNotFoundError,
1✔
1075
                          zcuf._getObjectContext, zcuf, request)
1076

1077
    def test__getObjectContext_simple(self):
1✔
1078

1079
        zcuf = self._makeOne()
1✔
1080

1081
        rc, root, folder, object = self._makeTree()
1✔
1082

1083
        local_index = FauxObject('index_html').__of__(object)
1✔
1084

1085
        request = self._makeRequest(('folder', 'object', 'index_html'),
1✔
1086
                                    RESPONSE=FauxResponse(),
1087
                                    PARENTS=[object, folder, root])
1088

1089
        published = local_index
1✔
1090

1091
        a, c, n, v = zcuf._getObjectContext(published, request)
1✔
1092

1093
        self.assertEqual(a, object)
1✔
1094
        self.assertEqual(c, object)
1✔
1095
        self.assertEqual(n, 'index_html')
1✔
1096
        self.assertEqual(v, published)
1✔
1097

1098
    def test__getObjectContext_method(self):
1✔
1099
        """It also works with a method on the object."""
1100
        zcuf = self._makeOne()
1✔
1101

1102
        rc, root, folder, object = self._makeTree()
1✔
1103

1104
        def faux_method(self):
1✔
1105
            pass
×
1106

1107
        FauxObject.meth = faux_method
1✔
1108
        local_index = FauxObject('index_html').__of__(object)
1✔
1109

1110
        request = self._makeRequest(
1✔
1111
            ('folder', 'object', 'index_html', 'meth'),
1112
            RESPONSE=FauxResponse(),
1113
            PARENTS=[local_index, object, folder, root])
1114

1115
        published = local_index.meth
1✔
1116

1117
        a, c, n, v = zcuf._getObjectContext(published, request)
1✔
1118

1119
        self.assertEqual(a, local_index)
1✔
1120
        self.assertEqual(c, published)
1✔
1121
        self.assertEqual(n, 'meth')
1✔
1122
        self.assertEqual(v, published)
1✔
1123

1124
    def test__getObjectContext_acquired_from_folder(self):
1✔
1125

1126
        zcuf = self._makeOne()
1✔
1127

1128
        rc, root, folder, object = self._makeTree()
1✔
1129

1130
        acquired_index = FauxObject('index_html').__of__(folder)
1✔
1131

1132
        request = self._makeRequest(('folder', 'object', 'index_html'),
1✔
1133
                                    RESPONSE=FauxResponse(),
1134
                                    PARENTS=[object, folder, root])
1135

1136
        published = acquired_index.__of__(object)
1✔
1137

1138
        a, c, n, v = zcuf._getObjectContext(published, request)
1✔
1139

1140
        self.assertEqual(a, object)
1✔
1141
        self.assertEqual(c, folder)
1✔
1142
        self.assertEqual(n, 'index_html')
1✔
1143
        self.assertEqual(v, published)
1✔
1144

1145
    def test__getObjectContext_acquired_from_root(self):
1✔
1146

1147
        zcuf = self._makeOne()
1✔
1148

1149
        rc, root, folder, object = self._makeTree()
1✔
1150

1151
        acquired_index = FauxObject('index_html').__of__(root)
1✔
1152

1153
        request = self._makeRequest(('folder', 'object', 'index_html'),
1✔
1154
                                    RESPONSE=FauxResponse(),
1155
                                    PARENTS=[object, folder, root])
1156

1157
        published = acquired_index.__of__(object)
1✔
1158

1159
        a, c, n, v = zcuf._getObjectContext(published, request)
1✔
1160

1161
        self.assertEqual(a, object)
1✔
1162
        self.assertEqual(c, root)
1✔
1163
        self.assertEqual(n, 'index_html')
1✔
1164
        self.assertEqual(v, published)
1✔
1165

1166
    def test__getObjectContext_acquired_from_rc(self):
1✔
1167

1168
        zcuf = self._makeOne()
1✔
1169

1170
        rc, root, folder, object = self._makeTree()
1✔
1171

1172
        acquired_index = FauxObject('index_html').__of__(rc)
1✔
1173

1174
        request = self._makeRequest(('folder', 'object', 'index_html'),
1✔
1175
                                    RESPONSE=FauxResponse(),
1176
                                    PARENTS=[object, folder, root])
1177

1178
        published = acquired_index.__of__(object)
1✔
1179

1180
        a, c, n, v = zcuf._getObjectContext(published, request)
1✔
1181

1182
        self.assertEqual(a, object)
1✔
1183
        self.assertEqual(c, root)
1✔
1184
        self.assertEqual(n, 'index_html')
1✔
1185
        self.assertEqual(v, published)
1✔
1186

1187
    def test__faultyRolemaker(self):
1✔
1188

1189
        from ..interfaces.plugins import IRolesPlugin
1✔
1190
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1191

1192
        plugins = self._makePlugins()
1✔
1193
        zcuf = self._makeOne(plugins)
1✔
1194

1195
        ue = self._makeUserEnumerator('foo')
1✔
1196
        zcuf._setObject('ue', ue)
1✔
1197

1198
        rm = self._makeFaultyRolemaker()
1✔
1199
        zcuf._setObject('rm', rm)
1✔
1200

1201
        plugins = zcuf._getOb('plugins')
1✔
1202

1203
        plugins.activatePlugin(IUserEnumerationPlugin, 'ue')
1✔
1204
        plugins.activatePlugin(IRolesPlugin, 'rm')
1✔
1205

1206
        try:
1✔
1207
            zcuf.getUser('foo')
1✔
1208
        except KeyError as e:
×
1209
            self.fail('exception should be caught by PAS: %s' % e)
1210

1211
    def test__verifyUser_no_plugins(self):
1✔
1212

1213
        plugins = self._makePlugins()
1✔
1214
        zcuf = self._makeOne(plugins)
1✔
1215

1216
        self.assertFalse(zcuf._verifyUser(zcuf.plugins, user_id='zope'))
1✔
1217

1218
    def test__verifyUser_one_plugin(self):
1✔
1219

1220
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1221

1222
        plugins = self._makePlugins()
1✔
1223
        zcuf = self._makeOne(plugins)
1✔
1224

1225
        foo = self._makeUserEnumerator('foo')
1✔
1226
        zcuf._setObject('foo', foo)
1✔
1227

1228
        plugins = zcuf._getOb('plugins')
1✔
1229

1230
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
1231

1232
        self.assertFalse(zcuf._verifyUser(zcuf.plugins, user_id='zope'))
1✔
1233
        self.assertTrue(zcuf._verifyUser(zcuf.plugins, user_id='foo'))
1✔
1234

1235
    def test__verifyUser_more_plugins(self):
1✔
1236

1237
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1238

1239
        plugins = self._makePlugins()
1✔
1240
        zcuf = self._makeOne(plugins)
1✔
1241

1242
        foo = self._makeUserEnumerator('foo')
1✔
1243
        zcuf._setObject('foo', foo)
1✔
1244

1245
        bar = self._makeUserEnumerator('bar')
1✔
1246
        zcuf._setObject('bar', bar)
1✔
1247

1248
        qux = self._makeUserEnumerator('qux')
1✔
1249
        zcuf._setObject('qux', qux)
1✔
1250

1251
        plugins = zcuf._getOb('plugins')
1✔
1252

1253
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
1254
        plugins.activatePlugin(IUserEnumerationPlugin, 'bar')
1✔
1255
        plugins.activatePlugin(IUserEnumerationPlugin, 'qux')
1✔
1256

1257
        self.assertFalse(zcuf._verifyUser(zcuf.plugins, user_id='zope'))
1✔
1258
        self.assertTrue(zcuf._verifyUser(zcuf.plugins, user_id='foo'))
1✔
1259
        self.assertTrue(zcuf._verifyUser(zcuf.plugins, user_id='bar'))
1✔
1260
        self.assertFalse(zcuf._verifyUser(zcuf.plugins, user_id='baz'))
1✔
1261
        self.assertTrue(zcuf._verifyUser(zcuf.plugins, user_id='qux'))
1✔
1262

1263
    def test__verifyUser_login(self):
1✔
1264

1265
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1266

1267
        plugins = self._makePlugins()
1✔
1268
        zcuf = self._makeOne(plugins)
1✔
1269

1270
        foo = self._makeUserEnumerator('foo')
1✔
1271
        zcuf._setObject('foo', foo)
1✔
1272

1273
        bar = self._makeUserEnumerator('bar', 'bar@example.com')
1✔
1274
        zcuf._setObject('bar', bar)
1✔
1275

1276
        plugins = zcuf._getOb('plugins')
1✔
1277

1278
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
1279
        plugins.activatePlugin(IUserEnumerationPlugin, 'bar')
1✔
1280

1281
        self.assertFalse(zcuf._verifyUser(zcuf.plugins, login='zope'))
1✔
1282
        self.assertTrue(zcuf._verifyUser(zcuf.plugins, login='foo'))
1✔
1283
        self.assertFalse(zcuf._verifyUser(zcuf.plugins, login='bar'))
1✔
1284
        self.assertTrue(zcuf._verifyUser(zcuf.plugins,
1✔
1285
                                         login='bar@example.com'))
1286

1287
    def test__verifyUser_login_userid(self):
1✔
1288

1289
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1290

1291
        plugins = self._makePlugins()
1✔
1292
        zcuf = self._makeOne(plugins)
1✔
1293

1294
        enumerator = DummyMultiUserEnumerator(
1✔
1295
            'enumerator',
1296
            {'id': 'foo', 'login': 'foobar'},
1297
            {'id': 'bar', 'login': 'foo'})
1298
        directlyProvides(enumerator, IUserEnumerationPlugin)
1✔
1299
        zcuf._setObject('enumerator', enumerator)
1✔
1300

1301
        plugins = zcuf._getOb('plugins')
1✔
1302

1303
        plugins.activatePlugin(IUserEnumerationPlugin, 'enumerator')
1✔
1304

1305
        self.assertTrue(
1✔
1306
            zcuf._verifyUser(plugins, login='foo')['id'] == 'bar')
1307
        self.assertTrue(
1✔
1308
            zcuf._verifyUser(plugins, login='foobar')['id'] == 'foo')
1309

1310
    def test__verifyUser_no_login_or_userid(self):
1✔
1311
        # setup cargo-culted from other tests...
1312
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1313
        plugins = self._makePlugins()
1✔
1314
        zcuf = self._makeOne(plugins)
1✔
1315

1316
        users = ({'id': 'foo', 'login': 'foobar'},
1✔
1317
                 {'id': 'bar', 'login': 'foo'})
1318
        enumerator = WantonUserEnumerator('enumerator', *users)
1✔
1319
        directlyProvides(enumerator, IUserEnumerationPlugin)
1✔
1320
        zcuf._setObject('enumerator', enumerator)
1✔
1321
        plugins = zcuf._getOb('plugins')
1✔
1322
        plugins.activatePlugin(IUserEnumerationPlugin, 'enumerator')
1✔
1323

1324
        # Our enumerator plugin normally returns something, even if
1325
        # you ask for a nonexistent user.
1326
        self.assertTrue(zcuf._verifyUser(plugins, login='qux') in users)
1✔
1327

1328
        # But with no criteria, we should always get None.
1329
        self.assertEqual(zcuf._verifyUser(plugins, login=None, user_id=None),
1✔
1330
                         None)
1331
        self.assertEqual(zcuf._verifyUser(plugins), None)
1✔
1332

1333
    def test__verifyUser_login_transform_lower(self):
1✔
1334

1335
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1336

1337
        plugins = self._makePlugins()
1✔
1338
        zcuf = self._makeOne(plugins)
1✔
1339
        zcuf.login_transform = 'lower'
1✔
1340

1341
        enumerator = DummyMultiUserEnumerator(
1✔
1342
            'enumerator',
1343
            {'id': 'Foo', 'login': 'foobar'},
1344
            {'id': 'Bar', 'login': 'BAR'})
1345
        directlyProvides(enumerator, IUserEnumerationPlugin)
1✔
1346
        zcuf._setObject('enumerator', enumerator)
1✔
1347

1348
        plugins = zcuf._getOb('plugins')
1✔
1349

1350
        plugins.activatePlugin(IUserEnumerationPlugin, 'enumerator')
1✔
1351

1352
        # No matter what we try as login parameter, it is always lower
1353
        # cased before verifying a user.
1354
        self.assertFalse(zcuf._verifyUser(plugins, login='BAR'))
1✔
1355
        self.assertFalse(zcuf._verifyUser(plugins, login='Bar'))
1✔
1356
        self.assertFalse(zcuf._verifyUser(plugins, login='bar'))
1✔
1357
        self.assertTrue(
1✔
1358
            zcuf._verifyUser(plugins, login='FOOBAR')['id'] == 'Foo')
1359
        self.assertTrue(
1✔
1360
            zcuf._verifyUser(plugins, login='Foobar')['id'] == 'Foo')
1361
        self.assertTrue(
1✔
1362
            zcuf._verifyUser(plugins, login='foobar')['id'] == 'Foo')
1363

1364
    def test__verifyUser_login_transform_upper(self):
1✔
1365

1366
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1367

1368
        plugins = self._makePlugins()
1✔
1369
        zcuf = self._makeOne(plugins)
1✔
1370
        zcuf.login_transform = 'upper'
1✔
1371

1372
        enumerator = DummyMultiUserEnumerator(
1✔
1373
            'enumerator',
1374
            {'id': 'Foo', 'login': 'foobar'},
1375
            {'id': 'Bar', 'login': 'BAR'})
1376
        directlyProvides(enumerator, IUserEnumerationPlugin)
1✔
1377
        zcuf._setObject('enumerator', enumerator)
1✔
1378

1379
        plugins = zcuf._getOb('plugins')
1✔
1380

1381
        plugins.activatePlugin(IUserEnumerationPlugin, 'enumerator')
1✔
1382

1383
        # No matter what we try as login parameter, it is always upper
1384
        # cased before verifying a user.
1385
        self.assertTrue(zcuf._verifyUser(plugins, login='BAR')['id'] == 'Bar')
1✔
1386
        self.assertTrue(zcuf._verifyUser(plugins, login='Bar')['id'] == 'Bar')
1✔
1387
        self.assertTrue(zcuf._verifyUser(plugins, login='bar')['id'] == 'Bar')
1✔
1388
        self.assertFalse(zcuf._verifyUser(plugins, login='FOOBAR'))
1✔
1389
        self.assertFalse(zcuf._verifyUser(plugins, login='Foobar'))
1✔
1390
        self.assertFalse(zcuf._verifyUser(plugins, login='foobar'))
1✔
1391

1392
    def test__findUser_no_plugins(self):
1✔
1393

1394
        plugins = self._makePlugins()
1✔
1395

1396
        zcuf = self._makeOne()
1✔
1397
        user = zcuf._findUser(plugins, 'someone')
1✔
1398

1399
        self.assertEqual(len(user.listPropertysheets()), 0)
1✔
1400

1401
    def test__findEmergencyUser_no_plugins(self):
1✔
1402

1403
        from AccessControl.users import UnrestrictedUser
1✔
1404

1405
        from .. import PluggableAuthService
1✔
1406

1407
        old_eu = PluggableAuthService.emergency_user
1✔
1408

1409
        eu = UnrestrictedUser('foo', 'bar', ('manage',), ())
1✔
1410

1411
        PluggableAuthService.emergency_user = eu
1✔
1412

1413
        plugins = self._makePlugins()
1✔
1414
        zcuf = self._makeOne()
1✔
1415
        zcuf._emergency_user = eu
1✔
1416
        user = zcuf._findUser(plugins, 'foo')
1✔
1417

1418
        self.assertEqual(aq_base(zcuf._getEmergencyUser()), aq_base(user))
1✔
1419

1420
        PluggableAuthService.emergency_user = old_eu
1✔
1421

1422
    def test__findUser_with_userfactory_plugin(self):
1✔
1423

1424
        from ..interfaces.plugins import IUserFactoryPlugin
1✔
1425

1426
        plugins = self._makePlugins()
1✔
1427
        zcuf = self._makeOne(plugins)
1✔
1428

1429
        bar = DummyPlugin()
1✔
1430
        directlyProvides(bar, IUserFactoryPlugin)
1✔
1431

1432
        def _makeUser(user_id, name):
1✔
1433
            user = FauxUser(user_id)
1✔
1434
            user._name = name
1✔
1435
            return user
1✔
1436

1437
        bar.createUser = _makeUser
1✔
1438

1439
        zcuf._setObject('bar', bar)
1✔
1440

1441
        plugins = zcuf._getOb('plugins')
1✔
1442

1443
        real_user = zcuf._findUser(plugins, 'someone', 'to watch over me')
1✔
1444
        self.assertFalse(real_user.__class__ is FauxUser)
1✔
1445

1446
        plugins.activatePlugin(IUserFactoryPlugin, 'bar')
1✔
1447

1448
        faux_user = zcuf._findUser(plugins, 'someone', 'to watch over me')
1✔
1449

1450
        self.assertEqual(faux_user.getId(), 'someone')
1✔
1451
        self.assertEqual(faux_user.getUserName(), 'to watch over me')
1✔
1452

1453
        self.assertTrue(faux_user.__class__ is FauxUser)
1✔
1454

1455
    def test__findUser_with_userfactory_plugin_and_transform(self):
1✔
1456

1457
        from ..interfaces.plugins import IUserFactoryPlugin
1✔
1458

1459
        plugins = self._makePlugins()
1✔
1460
        zcuf = self._makeOne(plugins)
1✔
1461
        zcuf.login_transform = 'lower'
1✔
1462

1463
        bar = DummyPlugin()
1✔
1464
        directlyProvides(bar, IUserFactoryPlugin)
1✔
1465

1466
        def _makeUser(user_id, name):
1✔
1467
            user = FauxUser(user_id)
1✔
1468
            user._name = name
1✔
1469
            return user
1✔
1470

1471
        bar.createUser = _makeUser
1✔
1472

1473
        zcuf._setObject('bar', bar)
1✔
1474

1475
        plugins = zcuf._getOb('plugins')
1✔
1476

1477
        real_user = zcuf._findUser(plugins, 'Mixed', 'Case')
1✔
1478
        self.assertFalse(real_user.__class__ is FauxUser)
1✔
1479

1480
        plugins.activatePlugin(IUserFactoryPlugin, 'bar')
1✔
1481

1482
        faux_user = zcuf._findUser(plugins, 'Mixed', 'Case')
1✔
1483

1484
        self.assertEqual(faux_user.getId(), 'Mixed')
1✔
1485
        # This is lower case:
1486
        self.assertEqual(faux_user.getUserName(), 'case')
1✔
1487

1488
        self.assertTrue(faux_user.__class__ is FauxUser)
1✔
1489

1490
    def test__findUser_with_plugins(self):
1✔
1491

1492
        from ..interfaces.plugins import IPropertiesPlugin
1✔
1493

1494
        plugins = self._makePlugins()
1✔
1495
        zcuf = self._makeOne(plugins)
1✔
1496

1497
        foo = DummyPlugin()
1✔
1498
        directlyProvides(foo, IPropertiesPlugin)
1✔
1499
        foo.getPropertiesForUser = lambda user, req: {'login': user.getId()}
1✔
1500

1501
        zcuf._setObject('foo', foo)
1✔
1502

1503
        bar = DummyPlugin()
1✔
1504
        directlyProvides(bar, IPropertiesPlugin)
1✔
1505
        bar.getPropertiesForUser = lambda user, req: {'a': 0, 'b': 'bar'}
1✔
1506

1507
        zcuf._setObject('bar', bar)
1✔
1508

1509
        plugins = zcuf._getOb('plugins')
1✔
1510

1511
        plugins.activatePlugin(IPropertiesPlugin, 'foo')
1✔
1512
        plugins.activatePlugin(IPropertiesPlugin, 'bar')
1✔
1513

1514
        user = zcuf._findUser(plugins, 'someone')
1✔
1515

1516
        sheet_ids = user.listPropertysheets()
1✔
1517
        self.assertEqual(len(sheet_ids), 2)
1✔
1518
        self.assertTrue('foo' in sheet_ids)
1✔
1519
        self.assertTrue('bar' in sheet_ids)
1✔
1520

1521
        foosheet = user['foo']
1✔
1522
        self.assertEqual(len(foosheet.propertyMap()), 1)
1✔
1523

1524
    def test__findUser_with_groups(self):
1✔
1525

1526
        from ..interfaces.plugins import IGroupsPlugin
1✔
1527

1528
        plugins = self._makePlugins()
1✔
1529
        zcuf = self._makeOne(plugins)
1✔
1530

1531
        foo = DummyPlugin()
1✔
1532
        directlyProvides(foo, IGroupsPlugin)
1✔
1533
        foo.getGroupsForPrincipal = lambda user, req: ('group1', 'group2')
1✔
1534

1535
        zcuf._setObject('foo', foo)
1✔
1536

1537
        plugins = zcuf._getOb('plugins')
1✔
1538

1539
        plugins.activatePlugin(IGroupsPlugin, 'foo')
1✔
1540

1541
        user = zcuf._findUser(plugins, 'someone')
1✔
1542

1543
        groups = user.getGroups()
1✔
1544
        self.assertEqual(len(groups), 2)
1✔
1545
        self.assertTrue('group1' in groups)
1✔
1546
        self.assertTrue('group2' in groups)
1✔
1547

1548
    def test__findUser_with_groups_ignoring_one(self):
1✔
1549

1550
        from ..interfaces.plugins import IGroupsPlugin
1✔
1551

1552
        plugins = self._makePlugins()
1✔
1553
        zcuf = self._makeOne(plugins)
1✔
1554

1555
        foo = DummyPlugin()
1✔
1556
        directlyProvides(foo, IGroupsPlugin)
1✔
1557
        foo.getGroupsForPrincipal = lambda user, req: ('group1', 'group2')
1✔
1558

1559
        bar = DummyPlugin()
1✔
1560
        directlyProvides(bar, IGroupsPlugin)
1✔
1561
        bar.getGroupsForPrincipal = lambda user, req: ('group3', 'group4')
1✔
1562

1563
        zcuf._setObject('foo', foo)
1✔
1564
        zcuf._setObject('bar', bar)
1✔
1565

1566
        plugins = zcuf._getOb('plugins')
1✔
1567

1568
        plugins.activatePlugin(IGroupsPlugin, 'foo')
1✔
1569
        plugins.activatePlugin(IGroupsPlugin, 'bar')
1✔
1570

1571
        user = zcuf._findUser(plugins, 'someone')
1✔
1572

1573
        groups = zcuf._getGroupsForPrincipal(user, plugins=plugins,
1✔
1574
                                             ignore_plugins=('bar',))
1575
        self.assertEqual(len(groups), 2)
1✔
1576
        self.assertFalse('bar:group3' in groups)
1✔
1577
        self.assertFalse('bar:group4' in groups)
1✔
1578

1579
    def test__authorizeUser_force_ok(self):
1✔
1580

1581
        zcuf = self._makeOne()
1✔
1582
        faux = FauxUser('faux')
1✔
1583

1584
        class PermissiveSP:
1✔
1585

1586
            def validate(self, user, accessed, container, name, value,
1✔
1587
                         roles=None):
1588
                return 1
1✔
1589

1590
        self._oldSecurityPolicy = setSecurityPolicy(PermissiveSP())
1✔
1591

1592
        self.assertTrue(zcuf._authorizeUser(faux,
1✔
1593
                                            accessed=FauxObject('a'),
1594
                                            container=FauxObject('c'),
1595
                                            name='name',
1596
                                            value=FauxObject('v'),
1597
                                            roles=()))
1598

1599
    def test__authorizeUser_force_no_way(self):
1✔
1600

1601
        zcuf = self._makeOne()
1✔
1602
        faux = FauxUser('faux')
1✔
1603

1604
        class ParanoidSP:
1✔
1605

1606
            def validate(self, user, accessed, container, name, value,
1✔
1607
                         roles=None):
1608
                return 0
1✔
1609

1610
        self._oldSecurityPolicy = setSecurityPolicy(ParanoidSP())
1✔
1611

1612
        self.assertFalse(zcuf._authorizeUser(faux,
1✔
1613
                                             accessed=FauxObject('a'),
1614
                                             container=FauxObject('c'),
1615
                                             name='name',
1616
                                             value=FauxObject('v'),
1617
                                             roles=()))
1618

1619
    def test__authorizeUser_use_ZSP_implied_roles_OK(self):
1✔
1620

1621
        zcuf = self._makeOne()
1✔
1622
        faux = FauxUser('faux')
1✔
1623
        object = FauxObject('object')
1✔
1624
        object.__roles__ = ('Anonymous',)
1✔
1625

1626
        self.assertTrue(zcuf._authorizeUser(faux,
1✔
1627
                                            accessed=FauxObject('a'),
1628
                                            container=FauxObject('c'),
1629
                                            name='name',
1630
                                            value=object))
1631

1632
    def test__authorizeUser_use_ZSP_implied_roles_fail(self):
1✔
1633

1634
        zcuf = self._makeOne()
1✔
1635
        faux = FauxUser('faux')
1✔
1636
        object = FauxObject('object')
1✔
1637
        object.__roles__ = ('Manager',)
1✔
1638

1639
        self.assertFalse(zcuf._authorizeUser(faux,
1✔
1640
                                             accessed=FauxObject('a'),
1641
                                             container=FauxObject('c'),
1642
                                             name='name',
1643
                                             value=object))
1644

1645
    def test__authorizeUser_use_ZSP_implied_roles_mgr(self):
1✔
1646

1647
        zcuf = self._makeOne()
1✔
1648
        mgr = FauxUser('mgr', roles=('Manager',))
1✔
1649
        object = FauxObject('object')
1✔
1650
        object.__roles__ = ('Manager',)
1✔
1651

1652
        self.assertTrue(zcuf._authorizeUser(mgr,
1✔
1653
                                            accessed=FauxObject('a'),
1654
                                            container=FauxObject('c'),
1655
                                            name='name',
1656
                                            value=object))
1657

1658
    def test__authorizeUser_use_ZSP_explicit_roles_OK(self):
1✔
1659

1660
        zcuf = self._makeOne()
1✔
1661
        faux = FauxUser('faux')
1✔
1662
        object = FauxObject('object')
1✔
1663

1664
        self.assertTrue(zcuf._authorizeUser(faux,
1✔
1665
                                            accessed=FauxObject('a'),
1666
                                            container=FauxObject('c'),
1667
                                            name='name',
1668
                                            value=object,
1669
                                            roles=('Anonymous',)))
1670

1671
    def test__authorizeUser_use_ZSP_explicit_roles_fail(self):
1✔
1672

1673
        zcuf = self._makeOne()
1✔
1674
        faux = FauxUser('faux')
1✔
1675
        object = FauxObject('object')
1✔
1676

1677
        self.assertFalse(zcuf._authorizeUser(faux,
1✔
1678
                                             accessed=FauxObject('a'),
1679
                                             container=FauxObject('c'),
1680
                                             name='name',
1681
                                             value=object,
1682
                                             roles=('Manager',)))
1683

1684
    def test__authorizeUser_use_ZSP_explicit_roles_mgr(self):
1✔
1685

1686
        zcuf = self._makeOne()
1✔
1687
        mgr = FauxUser('mgr', roles=('Manager',))
1✔
1688
        object = FauxObject('object')
1✔
1689

1690
        self.assertTrue(zcuf._authorizeUser(mgr,
1✔
1691
                                            accessed=FauxObject('a'),
1692
                                            container=FauxObject('c'),
1693
                                            name='name',
1694
                                            value=object,
1695
                                            roles=('Manager',)))
1696

1697
    def test_getUser_no_plugins(self):
1✔
1698

1699
        plugins = self._makePlugins()
1✔
1700
        zcuf = self._makeOne(plugins)
1✔
1701

1702
        self.assertEqual(zcuf.getUser('zope'), None)
1✔
1703

1704
    def test_getUser_with_plugins(self):
1✔
1705
        # !!! This will produce insane results when uniquifiers not present
1706

1707
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1708

1709
        plugins = self._makePlugins()
1✔
1710
        zcuf = self._makeOne(plugins)
1✔
1711

1712
        foo = self._makeUserEnumerator('foo')
1✔
1713
        zcuf._setObject('foo', foo)
1✔
1714

1715
        bar = self._makeUserEnumerator('bar', 'bar@example.com')
1✔
1716
        zcuf._setObject('bar', bar)
1✔
1717

1718
        plugins = zcuf._getOb('plugins')
1✔
1719

1720
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
1721
        plugins.activatePlugin(IUserEnumerationPlugin, 'bar')
1✔
1722

1723
        self.assertEqual(zcuf.getUser('zope'), None)
1✔
1724

1725
        user = zcuf.getUser('foo')
1✔
1726
        self.assertEqual(user.getId(), 'foo')
1✔
1727

1728
        self.assertEqual(zcuf.getUser('who_knows'), None)
1✔
1729

1730
        user = zcuf.getUser('bar@example.com')
1✔
1731
        self.assertEqual(user.getId(), 'bar')
1✔
1732

1733
    def test_getUser_with_uniquifying_plugins(self):
1✔
1734
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1735

1736
        plugins = self._makePlugins()
1✔
1737
        zcuf = self._makeOne(plugins)
1✔
1738

1739
        foo = self._makeUserEnumerator('foo')
1✔
1740
        foo.identifier = 'foo/'
1✔
1741
        zcuf._setObject('foo', foo)
1✔
1742

1743
        bar = self._makeUserEnumerator('bar', 'bar@example.com')
1✔
1744
        bar.identifier = 'bar+'
1✔
1745
        zcuf._setObject('bar', bar)
1✔
1746

1747
        plugins = zcuf._getOb('plugins')
1✔
1748

1749
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
1750
        plugins.activatePlugin(IUserEnumerationPlugin, 'bar')
1✔
1751

1752
        self.assertEqual(zcuf.getUser('zope'), None)
1✔
1753

1754
        user = zcuf.getUser('foo')
1✔
1755
        self.assertEqual(user.getId(), 'foo/foo')
1✔
1756

1757
        self.assertEqual(zcuf.getUser('who_knows'), None)
1✔
1758

1759
        user = zcuf.getUser('bar@example.com')
1✔
1760
        self.assertEqual(user.getId(), 'bar+bar')
1✔
1761

1762
    def test_getUser_id_and_name(self):
1✔
1763
        # Tests fetching a user by ID versus fetching by username.
1764
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1765

1766
        plugins = self._makePlugins()
1✔
1767
        zcuf = self._makeOne(plugins)
1✔
1768

1769
        bar = self._makeUserEnumerator('bar', 'bar@example.com')
1✔
1770
        bar.identifier = 'bar/'
1✔
1771
        zcuf._setObject('bar', bar)
1✔
1772

1773
        zcuf.plugins.activatePlugin(IUserEnumerationPlugin, 'bar')
1✔
1774
        # Fetch the new user by ID and name, and check we get the same.
1775
        user = zcuf.getUserById('bar/bar')
1✔
1776
        self.assertEqual(user.getId(), 'bar/bar')
1✔
1777
        self.assertEqual(user.getUserName(), 'bar@example.com')
1✔
1778

1779
        user2 = zcuf.getUser('bar@example.com')
1✔
1780
        self.assertEqual(user2.getId(), 'bar/bar')
1✔
1781
        self.assertEqual(user2.getUserName(), 'bar@example.com')
1✔
1782

1783
    def test_getUser_login_transform(self):
1✔
1784
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1785

1786
        plugins = self._makePlugins()
1✔
1787
        zcuf = self._makeOne(plugins)
1✔
1788
        zcuf.login_transform = 'lower'
1✔
1789

1790
        # The login_transform is applied in PAS, so we need to lower
1791
        # case the login ourselves in this test when passing it to a
1792
        # plugin.
1793
        bar = self._makeUserEnumerator('bar', 'bar@example.com')
1✔
1794
        bar.identifier = 'bar/'
1✔
1795
        zcuf._setObject('bar', bar)
1✔
1796

1797
        zcuf.plugins.activatePlugin(IUserEnumerationPlugin, 'bar')
1✔
1798
        # Fetch the new user by ID and name, and check we get the same.
1799
        user = zcuf.getUserById('bar/bar')
1✔
1800
        self.assertEqual(user.getId(), 'bar/bar')
1✔
1801
        self.assertEqual(user.getUserName(), 'bar@example.com')
1✔
1802

1803
        user2 = zcuf.getUser('bar@example.com')
1✔
1804
        self.assertEqual(user2.getId(), 'bar/bar')
1✔
1805
        self.assertEqual(user2.getUserName(), 'bar@example.com')
1✔
1806

1807
        user3 = zcuf.getUser('Bar@Example.Com')
1✔
1808
        self.assertEqual(user3.getId(), 'bar/bar')
1✔
1809
        self.assertEqual(user3.getUserName(), 'bar@example.com')
1✔
1810

1811
    def test_simple_getUserGroups_with_Groupplugin(self):
1✔
1812

1813
        from ..interfaces.plugins import IGroupsPlugin
1✔
1814

1815
        default_groups = ('Group A', 'Group B')
1✔
1816
        plugins = self._makePlugins()
1✔
1817
        zcuf = self._makeOne(plugins)
1✔
1818
        faux = FauxUser('faux')
1✔
1819

1820
        foo = self._makeGroupPlugin('foo', groups=default_groups)
1✔
1821
        zcuf._setObject('foo', foo)
1✔
1822

1823
        plugins = zcuf._getOb('plugins')
1✔
1824

1825
        plugins.activatePlugin(IGroupsPlugin, 'foo')
1✔
1826

1827
        groups = foo.getGroupsForPrincipal(faux)
1✔
1828
        for g in groups:
1✔
1829
            self.assertTrue(g in default_groups)
1✔
1830

1831
        faux._addGroups(groups)
1✔
1832

1833
        self.assertTrue('Group A' in faux.getGroups())
1✔
1834
        self.assertTrue('Group B' in faux.getGroups())
1✔
1835

1836
    def test_validate_simple_unauth(self):
1✔
1837

1838
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
1839
        from ..interfaces.plugins import IExtractionPlugin
1✔
1840
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1841

1842
        plugins = self._makePlugins()
1✔
1843
        zcuf = self._makeOne(plugins)
1✔
1844

1845
        login = DummyPlugin()
1✔
1846
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
1847
        login.extractCredentials = _extractLogin
1✔
1848
        login.authenticateCredentials = _authLogin
1✔
1849
        zcuf._setObject('login', login)
1✔
1850

1851
        foo = DummyPlugin()
1✔
1852
        directlyProvides(foo, IUserEnumerationPlugin)
1✔
1853
        foo.enumerateUsers = lambda id: id == 'foo' or None
1!
1854

1855
        zcuf._setObject('foo', foo)
1✔
1856

1857
        plugins = zcuf._getOb('plugins')
1✔
1858
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
1859
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
1860
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
1861

1862
        rc, root, folder, object = self._makeTree()
1✔
1863

1864
        index = FauxObject('index_html')
1✔
1865
        index.__roles__ = ('Hamlet',)
1✔
1866
        acquired_index = index.__of__(root).__of__(object)
1✔
1867

1868
        request = self._makeRequest(('folder', 'object', 'index_html'),
1✔
1869
                                    RESPONSE=FauxResponse(),
1870
                                    PARENTS=[object, folder, root],
1871
                                    PUBLISHED=acquired_index,
1872
                                    form={'login': 'foo', 'password': 'bar'})
1873

1874
        wrapped = zcuf.__of__(root)
1✔
1875
        validated = wrapped.validate(request)
1✔
1876
        self.assertEqual(validated, None)
1✔
1877

1878
    def test_validate_simple_anonymous(self):
1✔
1879

1880
        from AccessControl.SpecialUsers import nobody
1✔
1881

1882
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
1883
        from ..interfaces.plugins import IExtractionPlugin
1✔
1884
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1885

1886
        plugins = self._makePlugins()
1✔
1887
        zcuf = self._makeOne(plugins)
1✔
1888

1889
        login = DummyPlugin()
1✔
1890
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
1891
        login.extractCredentials = _extractLogin
1✔
1892
        login.authenticateCredentials = _authLogin
1✔
1893
        zcuf._setObject('login', login)
1✔
1894

1895
        foo = DummyPlugin()
1✔
1896
        directlyProvides(foo, IUserEnumerationPlugin)
1✔
1897
        foo.enumerateUsers = lambda id: id == 'foo' or None
1!
1898

1899
        zcuf._setObject('foo', foo)
1✔
1900

1901
        plugins = zcuf._getOb('plugins')
1✔
1902
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
1903
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
1904
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
1905

1906
        rc, root, folder, object = self._makeTree()
1✔
1907

1908
        index = FauxObject('index_html')
1✔
1909
        index.__roles__ = ('Anonymous',)
1✔
1910
        acquired_index = index.__of__(root).__of__(object)
1✔
1911

1912
        request = self._makeRequest(('folder', 'object', 'index_html'),
1✔
1913
                                    RESPONSE=FauxResponse(),
1914
                                    PARENTS=[object, folder, root],
1915
                                    PUBLISHED=acquired_index,
1916
                                    form={})
1917

1918
        wrapped = zcuf.__of__(root)
1✔
1919
        validated = wrapped.validate(request)
1✔
1920
        self.assertEqual(validated.getUserName(), nobody.getUserName())
1✔
1921

1922
    def test_validate_simple_authenticated(self):
1✔
1923

1924
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
1925
        from ..interfaces.plugins import IExtractionPlugin
1✔
1926
        from ..interfaces.plugins import IRolesPlugin
1✔
1927
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1928

1929
        plugins = self._makePlugins()
1✔
1930
        zcuf = self._makeOne(plugins)
1✔
1931

1932
        login = DummyPlugin()
1✔
1933
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
1934
        login.extractCredentials = _extractLogin
1✔
1935
        login.authenticateCredentials = _authLogin
1✔
1936
        zcuf._setObject('login', login)
1✔
1937

1938
        olivier = DummyPlugin()
1✔
1939
        directlyProvides(olivier, IUserEnumerationPlugin, IRolesPlugin)
1✔
1940
        olivier.enumerateUsers = lambda id: id == 'foo' or None
1!
1941
        olivier.getRolesForPrincipal = lambda user, req: (
1✔
1942
            user.getId() == 'olivier' and ('Hamlet',) or ())
1943

1944
        zcuf._setObject('olivier', olivier)
1✔
1945

1946
        plugins = zcuf._getOb('plugins')
1✔
1947
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
1948
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
1949
        plugins.activatePlugin(IUserEnumerationPlugin, 'olivier')
1✔
1950
        plugins.activatePlugin(IRolesPlugin, 'olivier')
1✔
1951

1952
        rc, root, folder, object = self._makeTree()
1✔
1953

1954
        index = FauxObject('index_html')
1✔
1955
        index.__roles__ = ('Hamlet',)
1✔
1956
        acquired_index = index.__of__(root).__of__(object)
1✔
1957

1958
        request = self._makeRequest(('folder', 'object', 'index_html'),
1✔
1959
                                    RESPONSE=FauxResponse(),
1960
                                    PARENTS=[object, folder, root],
1961
                                    PUBLISHED=acquired_index.__of__(object),
1962
                                    form={'login': 'olivier',
1963
                                          'password': 'arras'})
1964

1965
        wrapped = zcuf.__of__(root)
1✔
1966

1967
        validated = wrapped.validate(request)
1✔
1968
        self.assertEqual(validated.getUserName(), 'olivier')
1✔
1969

1970
    def test_validate_simple_authenticated_transform(self):
1✔
1971

1972
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
1973
        from ..interfaces.plugins import IExtractionPlugin
1✔
1974
        from ..interfaces.plugins import IRolesPlugin
1✔
1975
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
1976

1977
        plugins = self._makePlugins()
1✔
1978
        zcuf = self._makeOne(plugins)
1✔
1979

1980
        login = DummyPlugin()
1✔
1981
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
1982
        login.extractCredentials = _extractLogin
1✔
1983
        login.authenticateCredentials = _authLogin
1✔
1984
        zcuf._setObject('login', login)
1✔
1985
        # Lower case all logins.
1986
        zcuf.login_transform = 'lower'
1✔
1987

1988
        olivier = DummyPlugin()
1✔
1989
        directlyProvides(olivier, IUserEnumerationPlugin, IRolesPlugin)
1✔
1990
        olivier.enumerateUsers = lambda id: id == 'foo' or None
1!
1991
        olivier.getRolesForPrincipal = lambda user, req: (
1✔
1992
            user.getId() == 'olivier' and ('Hamlet',) or ())
1993

1994
        zcuf._setObject('olivier', olivier)
1✔
1995

1996
        plugins = zcuf._getOb('plugins')
1✔
1997
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
1998
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
1999
        plugins.activatePlugin(IUserEnumerationPlugin, 'olivier')
1✔
2000
        plugins.activatePlugin(IRolesPlugin, 'olivier')
1✔
2001

2002
        rc, root, folder, object = self._makeTree()
1✔
2003

2004
        index = FauxObject('index_html')
1✔
2005
        index.__roles__ = ('Hamlet',)
1✔
2006
        acquired_index = index.__of__(root).__of__(object)
1✔
2007

2008
        request = self._makeRequest(('folder', 'object', 'index_html'),
1✔
2009
                                    RESPONSE=FauxResponse(),
2010
                                    PARENTS=[object, folder, root],
2011
                                    PUBLISHED=acquired_index.__of__(object),
2012
                                    form={'login': 'OLIVIER',
2013
                                          'password': 'arras'})
2014

2015
        wrapped = zcuf.__of__(root)
1✔
2016

2017
        validated = wrapped.validate(request)
1✔
2018
        self.assertEqual(validated.getUserName(), 'olivier')
1✔
2019

2020
    def test_validate_with_anonymous_factory(self):
1✔
2021

2022
        from ..interfaces.plugins import IAnonymousUserFactoryPlugin
1✔
2023

2024
        def _makeAnon():
1✔
2025
            user = FauxUser(None,
1✔
2026
                            name='New Anonymous User',
2027
                            roles=(),
2028
                            groups={'All People Everywhere Ever': 1})
2029
            return user
1✔
2030

2031
        plugins = self._makePlugins()
1✔
2032
        zcuf = self._makeOne(plugins)
1✔
2033

2034
        anon = DummyPlugin()
1✔
2035
        directlyProvides(anon, IAnonymousUserFactoryPlugin)
1✔
2036
        anon.createAnonymousUser = _makeAnon
1✔
2037
        zcuf._setObject('anon', anon)
1✔
2038

2039
        plugins = zcuf._getOb('plugins')
1✔
2040
        plugins.activatePlugin(IAnonymousUserFactoryPlugin, 'anon')
1✔
2041

2042
        rc, root, folder, object = self._makeTree()
1✔
2043

2044
        index = FauxObject('index_html')
1✔
2045
        index.__roles__ = ('Anonymous',)
1✔
2046
        acquired_index = index.__of__(root).__of__(object)
1✔
2047

2048
        request = self._makeRequest(('folder', 'object', 'index_html'),
1✔
2049
                                    RESPONSE=FauxResponse(),
2050
                                    PARENTS=[object, folder, root],
2051
                                    PUBLISHED=acquired_index,
2052
                                    form={})
2053

2054
        root._setObject('acl_users', zcuf)
1✔
2055
        root_users = root.acl_users
1✔
2056

2057
        root_validated = root_users.validate(request)
1✔
2058
        self.assertEqual(root_validated.getUserName(), 'New Anonymous User')
1✔
2059
        self.assertEqual(root_validated.getGroups(),
1✔
2060
                         ['All People Everywhere Ever'])
2061

2062
    def _setup_for_authentication(self):
1✔
2063
        """return pas set up for authentication and associated request."""
2064

2065
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
2066
        from ..interfaces.plugins import IExtractionPlugin
1✔
2067
        from ..interfaces.plugins import IRolesPlugin
1✔
2068
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
2069

2070
        plugins = self._makePlugins()
1✔
2071
        zcuf = self._makeOne(plugins)
1✔
2072

2073
        login = DummyPlugin()
1✔
2074
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
2075
        login.extractCredentials = _extractLogin
1✔
2076
        login.authenticateCredentials = _authLogin
1✔
2077
        zcuf._setObject('login', login)
1✔
2078

2079
        nc = DummyNotCompetentPlugin('nc', True)
1✔
2080
        zcuf._setObject('nc', nc)
1✔
2081

2082
        olivier = DummyPlugin()
1✔
2083
        directlyProvides(olivier, IUserEnumerationPlugin, IRolesPlugin)
1✔
2084
        olivier.enumerateUsers = lambda id: id == 'foo' or None
1!
2085
        olivier.getRolesForPrincipal = lambda user, req: (
1✔
2086
            user.getId() == 'olivier' and ('Hamlet',) or ())
2087

2088
        zcuf._setObject('olivier', olivier)
1✔
2089

2090
        plugins = zcuf._getOb('plugins')
1✔
2091
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
2092
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
2093
        plugins.activatePlugin(IUserEnumerationPlugin, 'olivier')
1✔
2094
        plugins.activatePlugin(IRolesPlugin, 'olivier')
1✔
2095
        plugins.activatePlugin(INotCompetentPlugin, 'nc')
1✔
2096

2097
        rc, root, folder, object = self._makeTree()
1✔
2098

2099
        index = FauxObject('index_html')
1✔
2100
        index.__roles__ = ('Hamlet',)
1✔
2101
        acquired_index = index.__of__(root).__of__(object)
1✔
2102

2103
        request = self._makeRequest(('folder', 'object', 'index_html'),
1✔
2104
                                    RESPONSE=FauxResponse(),
2105
                                    PARENTS=[object, folder, root],
2106
                                    PUBLISHED=acquired_index.__of__(object),
2107
                                    form={'login': 'olivier',
2108
                                          'password': 'arras'})
2109

2110
        return zcuf, request
1✔
2111

2112
    def _NotCompetent_validate_check(self, is_top):
1✔
2113

2114
        zcuf, request = self._setup_for_authentication()
1✔
2115
        folder, root = request['PARENTS'][-2:]
1✔
2116

2117
        wrapped = zcuf.__of__(is_top and root or folder)
1✔
2118

2119
        return wrapped.validate(request)
1✔
2120

2121
    def test_validate_NotCompetent_isTop(self):
1✔
2122
        self.assertEqual(self._NotCompetent_validate_check(True).getUserName(),
1✔
2123
                         'olivier')
2124

2125
    def test_validate_NotCompetent_not_isTop(self):
1✔
2126
        self.assertEqual(self._NotCompetent_validate_check(False), None)
1✔
2127

2128
    def testAllowGroupsAttribute(self):
1✔
2129
        # Verify that __allow_groups__ gets set and removed
2130
        from OFS.Folder import Folder
1✔
2131
        f = Folder()
1✔
2132
        zcuf = self._makeOne()
1✔
2133
        f._setObject(zcuf.getId(), zcuf)
1✔
2134
        self.assertTrue(zcuf.getId() in f.objectIds())
1✔
2135
        self.assertTrue(aq_base(f.__allow_groups__) is aq_base(f.acl_users))
1✔
2136
        f._delObject(zcuf.getId())
1✔
2137
        self.assertTrue(not zcuf.getId() in f.objectIds())
1✔
2138

2139
    def test__setObject_no_ownership_fixup(self):
1✔
2140

2141
        from AccessControl.SpecialUsers import emergency_user
1✔
2142
        from OFS.Folder import Folder
1✔
2143

2144
        newSecurityManager(None, emergency_user)
1✔
2145

2146
        rc, root, folder, object = self._makeTree()
1✔
2147
        zcuf = self._makeOne()
1✔
2148
        folder._setObject('acl_users', zcuf)
1✔
2149
        zcuf = folder._getOb('acl_users')
1✔
2150

2151
        sub = Folder()
1✔
2152
        sub._setId('sub')
1✔
2153

2154
        zcuf._setObject('sub', sub)
1✔
2155

2156
    def test__setObject_arguments(self):
1✔
2157
        # Make sure the overridden definition matches the
2158
        # superclass definition
2159
        from OFS.Folder import Folder
1✔
2160
        zcuf = self._makeOne()
1✔
2161
        sub = Folder('sub')
1✔
2162
        zcuf._setObject('sub', sub, set_owner=False, suppress_events=True)
1✔
2163

2164
    def test__delOb_unregisters_plugin(self):
1✔
2165

2166
        from ..interfaces.plugins import IAuthenticationPlugin
1✔
2167
        from ..interfaces.plugins import IExtractionPlugin
1✔
2168
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
2169

2170
        plugins = self._makePlugins()
1✔
2171
        zcuf = self._makeOne(plugins)
1✔
2172

2173
        login = DummyPlugin()
1✔
2174
        directlyProvides(login, IExtractionPlugin, IAuthenticationPlugin)
1✔
2175
        login.extractCredentials = _extractLogin
1✔
2176
        login.authenticateCredentials = _authLogin
1✔
2177
        zcuf._setObject('login', login)
1✔
2178

2179
        foo = DummyPlugin()
1✔
2180
        directlyProvides(foo, IUserEnumerationPlugin)
1✔
2181
        foo.enumerateUsers = lambda id: id == 'foo' or None
1!
2182

2183
        zcuf._setObject('foo', foo)
1✔
2184

2185
        plugins = zcuf._getOb('plugins')
1✔
2186
        plugins.activatePlugin(IExtractionPlugin, 'login')
1✔
2187
        plugins.activatePlugin(IAuthenticationPlugin, 'login')
1✔
2188
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
2189

2190
        self.assertTrue(plugins.listPlugins(IExtractionPlugin))
1✔
2191
        self.assertTrue(plugins.listPlugins(IAuthenticationPlugin))
1✔
2192
        self.assertTrue(plugins.listPlugins(IUserEnumerationPlugin))
1✔
2193

2194
        zcuf._delOb('foo')
1✔
2195

2196
        self.assertTrue(plugins.listPlugins(IExtractionPlugin))
1✔
2197
        self.assertTrue(plugins.listPlugins(IAuthenticationPlugin))
1✔
2198
        self.assertFalse(plugins.listPlugins(IUserEnumerationPlugin))
1✔
2199

2200
        zcuf._delOb('login')
1✔
2201

2202
        self.assertFalse(plugins.listPlugins(IExtractionPlugin))
1✔
2203
        self.assertFalse(plugins.listPlugins(IAuthenticationPlugin))
1✔
2204
        self.assertFalse(plugins.listPlugins(IUserEnumerationPlugin))
1✔
2205

2206
    def test_searchUsers(self):
1✔
2207

2208
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
2209

2210
        plugins = self._makePlugins()
1✔
2211
        zcuf = self._makeOne(plugins)
1✔
2212

2213
        foo = self._makeUserEnumerator('foo')
1✔
2214
        zcuf._setObject('foo', foo)
1✔
2215

2216
        plugins = zcuf._getOb('plugins')
1✔
2217
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
2218

2219
        # Search by id
2220
        self.assertFalse(zcuf.searchUsers(id='zope'))
1✔
2221
        self.assertTrue(zcuf.searchUsers(id='foo'))
1✔
2222
        self.assertTrue(len(zcuf.searchUsers(id='foo')) == 1)
1✔
2223

2224
        # Search by login name
2225
        self.assertFalse(zcuf.searchUsers(name='zope'))
1✔
2226
        self.assertTrue(zcuf.searchUsers(name='foo'))
1✔
2227
        self.assertTrue(len(zcuf.searchUsers(name='foo')) == 1)
1✔
2228

2229
        # Login name can be a sequence
2230
        self.assertFalse(zcuf.searchUsers(name=['zope']))
1✔
2231
        self.assertTrue(zcuf.searchUsers(name=['foo']))
1✔
2232
        self.assertTrue(len(zcuf.searchUsers(name=['foo'])) == 1)
1✔
2233
        self.assertFalse(zcuf.searchUsers(name=('zope',)))
1✔
2234
        self.assertTrue(zcuf.searchUsers(name=('foo',)))
1✔
2235
        self.assertTrue(len(zcuf.searchUsers(name=('foo',))) == 1)
1✔
2236
        self.assertTrue(zcuf.searchUsers(name=('foo', 'bar')))
1✔
2237
        self.assertTrue(len(zcuf.searchUsers(name=('foo', 'bar'))) == 1)
1✔
2238

2239
    def test_searchUsers_transform(self):
1✔
2240

2241
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
2242

2243
        plugins = self._makePlugins()
1✔
2244
        zcuf = self._makeOne(plugins)
1✔
2245
        zcuf.login_transform = 'lower'
1✔
2246

2247
        # user id upper case, login name lower case
2248
        foo = self._makeUserEnumerator('FOO', 'foo')
1✔
2249
        zcuf._setObject('foo', foo)
1✔
2250
        bar = self._makeUserEnumerator('BAR', 'bar')
1✔
2251
        zcuf._setObject('bar', bar)
1✔
2252

2253
        plugins = zcuf._getOb('plugins')
1✔
2254
        # Note: we only activate 'foo' for now.
2255
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
2256

2257
        # Search by id
2258
        self.assertFalse(zcuf.searchUsers(id='ZOPE'))
1✔
2259
        self.assertTrue(zcuf.searchUsers(id='FOO'))
1✔
2260
        self.assertTrue(len(zcuf.searchUsers(id='FOO')) == 1)
1✔
2261

2262
        # Search by login name
2263
        self.assertFalse(zcuf.searchUsers(name='Zope'))
1✔
2264
        self.assertTrue(zcuf.searchUsers(name='Foo'))
1✔
2265
        self.assertTrue(len(zcuf.searchUsers(name='Foo')) == 1)
1✔
2266

2267
        # Login name can be a sequence
2268
        self.assertFalse(zcuf.searchUsers(name=['Zope']))
1✔
2269
        self.assertTrue(zcuf.searchUsers(name=['Foo']))
1✔
2270
        self.assertTrue(len(zcuf.searchUsers(name=['Foo'])) == 1)
1✔
2271
        self.assertFalse(zcuf.searchUsers(name=('Zope',)))
1✔
2272
        self.assertTrue(zcuf.searchUsers(name=('Foo',)))
1✔
2273
        self.assertTrue(len(zcuf.searchUsers(name=('Foo',))) == 1)
1✔
2274

2275
        # Search for more ids or names.
2276
        self.assertTrue(zcuf.searchUsers(id=['FOO', 'BAR', 'ZOPE']))
1✔
2277
        self.assertTrue(len(zcuf.searchUsers(id=['FOO', 'BAR', 'ZOPE'])) == 1)
1✔
2278
        self.assertTrue(zcuf.searchUsers(name=('Foo', 'Bar', 'Zope')))
1✔
2279
        expected = zcuf.searchUsers(name=('Foo', 'Bar', 'Zope'))
1✔
2280
        self.assertTrue(len(expected) == 1)
1✔
2281

2282
        # Activate the bar plugin and try again.
2283
        plugins.activatePlugin(IUserEnumerationPlugin, 'bar')
1✔
2284
        self.assertTrue(len(zcuf.searchUsers(id=['FOO', 'BAR', 'ZOPE'])) == 2)
1✔
2285
        expected = zcuf.searchUsers(name=('Foo', 'Bar', 'Zope'))
1✔
2286
        self.assertTrue(len(expected) == 2)
1✔
2287

2288
    def test_searchGroups(self):
1✔
2289

2290
        from ..interfaces.plugins import IGroupEnumerationPlugin
1✔
2291

2292
        plugins = self._makePlugins()
1✔
2293
        zcuf = self._makeOne(plugins)
1✔
2294

2295
        foo = self._makeGroupEnumerator('foo')
1✔
2296
        zcuf._setObject('foo', foo)
1✔
2297

2298
        plugins = zcuf._getOb('plugins')
1✔
2299
        plugins.activatePlugin(IGroupEnumerationPlugin, 'foo')
1✔
2300

2301
        self.assertFalse(zcuf.searchGroups(id='bar'))
1✔
2302
        self.assertTrue(zcuf.searchGroups(id='foo'))
1✔
2303
        self.assertEqual(len(zcuf.searchGroups(id='foo')), 1)
1✔
2304

2305
    def test_searchPrincipals(self):
1✔
2306

2307
        from ..interfaces.plugins import IGroupEnumerationPlugin
1✔
2308
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
2309

2310
        plugins = self._makePlugins()
1✔
2311
        zcuf = self._makeOne(plugins)
1✔
2312

2313
        foo = self._makeUserEnumerator('foo')
1✔
2314
        zcuf._setObject('foo', foo)
1✔
2315
        foobar = self._makeGroupEnumerator('foobar')
1✔
2316
        zcuf._setObject('foobar', foobar)
1✔
2317

2318
        plugins = zcuf._getOb('plugins')
1✔
2319
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
2320
        plugins.activatePlugin(IGroupEnumerationPlugin, 'foobar')
1✔
2321

2322
        self.assertFalse(zcuf.searchPrincipals(id='zope'))
1✔
2323
        self.assertTrue(len(zcuf.searchPrincipals(id='foo')) == 2)
1✔
2324

2325
    def test_searchPrincipalsWithSuperEnumerator(self):
1✔
2326

2327
        from ..interfaces.plugins import IGroupEnumerationPlugin
1✔
2328
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
2329

2330
        plugins = self._makePlugins()
1✔
2331
        zcuf = self._makeOne(plugins)
1✔
2332

2333
        s00per = self._makeSuperEnumerator('user', 'login', 'group')
1✔
2334
        zcuf._setObject('s00per', s00per)
1✔
2335

2336
        plugins = zcuf._getOb('plugins')
1✔
2337
        plugins.activatePlugin(IUserEnumerationPlugin, 's00per')
1✔
2338
        plugins.activatePlugin(IGroupEnumerationPlugin, 's00per')
1✔
2339

2340
        self.assertFalse(zcuf.searchPrincipals(id='zope'))
1✔
2341
        self.assertTrue(len(zcuf.searchPrincipals(id='user')) == 1)
1✔
2342
        self.assertTrue(len(zcuf.searchPrincipals(id='group')) == 1)
1✔
2343

2344
    def test_searchPrincipals_transform(self):
1✔
2345

2346
        from ..interfaces.plugins import IGroupEnumerationPlugin
1✔
2347
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
2348

2349
        plugins = self._makePlugins()
1✔
2350
        zcuf = self._makeOne(plugins)
1✔
2351
        zcuf.login_transform = 'lower'
1✔
2352

2353
        foo = self._makeUserEnumerator('foo')
1✔
2354
        zcuf._setObject('foo', foo)
1✔
2355
        foobar = self._makeGroupEnumerator('Foobar')
1✔
2356
        zcuf._setObject('foobar', foobar)
1✔
2357

2358
        plugins = zcuf._getOb('plugins')
1✔
2359
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
2360
        plugins.activatePlugin(IGroupEnumerationPlugin, 'foobar')
1✔
2361

2362
        self.assertFalse(zcuf.searchPrincipals(name='zope'))
1✔
2363
        # Note that groups are never found by name, only by id.
2364
        self.assertTrue(len(zcuf.searchPrincipals(name='foo')) == 1)
1✔
2365
        user1 = zcuf.searchPrincipals(name='foo')[0]
1✔
2366
        self.assertEqual(user1['principal_type'], 'user')
1✔
2367
        self.assertEqual(user1['id'], 'foo')
1✔
2368
        self.assertEqual(user1['login'], 'foo')
1✔
2369

2370
        # Search for mixed case.
2371
        self.assertTrue(len(zcuf.searchPrincipals(name='Foo')) == 1)
1✔
2372
        user2 = zcuf.searchPrincipals(name='Foo')[0]
1✔
2373
        self.assertEqual(user1, user2)
1✔
2374

2375
        # Search for upper case.
2376
        self.assertTrue(len(zcuf.searchPrincipals(name='FOO')) == 1)
1✔
2377
        user3 = zcuf.searchPrincipals(name='FOO')[0]
1✔
2378
        self.assertEqual(user1, user3)
1✔
2379

2380
    def test_updateLoginName(self):
1✔
2381

2382
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
2383

2384
        plugins = self._makePlugins()
1✔
2385
        zcuf = self._makeOne(plugins)
1✔
2386

2387
        foo = self._makeMultiUserEnumerator(
1✔
2388
            {'id': 'JOE', 'login': 'Joe'},
2389
            {'id': 'BART', 'login': 'Bart'})
2390
        zcuf._setObject('foo', foo)
1✔
2391

2392
        plugins = zcuf._getOb('plugins')
1✔
2393
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
2394

2395
        users = zcuf.searchUsers(login='Joe')
1✔
2396
        self.assertEqual(len(users), 1)
1✔
2397
        self.assertEqual(users[0]['id'], 'JOE')
1✔
2398
        self.assertEqual(users[0]['login'], 'Joe')
1✔
2399

2400
        # Change the login name.
2401
        zcuf.updateLoginName('JOE', 'James')
1✔
2402
        users = zcuf.searchUsers(login='James')
1✔
2403
        self.assertEqual(len(users), 1)
1✔
2404
        self.assertEqual(users[0]['id'], 'JOE')
1✔
2405
        self.assertEqual(users[0]['login'], 'James')
1✔
2406

2407
        # Try lowercase
2408
        zcuf.login_transform = 'lower'
1✔
2409
        zcuf.updateLoginName('JOE', 'James')
1✔
2410

2411
        users = zcuf.searchUsers(login='James')
1✔
2412
        self.assertEqual(len(users), 1)
1✔
2413
        self.assertEqual(users[0]['id'], 'JOE')
1✔
2414
        self.assertEqual(users[0]['login'], 'james')
1✔
2415

2416
        users = zcuf.searchUsers(login='james')
1✔
2417
        self.assertEqual(len(users), 1)
1✔
2418
        self.assertEqual(users[0]['id'], 'JOE')
1✔
2419
        self.assertEqual(users[0]['login'], 'james')
1✔
2420

2421
    def test_updateOwnLoginName(self):
1✔
2422

2423
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
2424

2425
        plugins = self._makePlugins()
1✔
2426
        zcuf = self._makeOne(plugins)
1✔
2427

2428
        foo = self._makeMultiUserEnumerator(
1✔
2429
            {'id': 'bart', 'login': 'bart'},
2430
            {'id': 'joe', 'login': 'joe'})
2431
        zcuf._setObject('foo', foo)
1✔
2432

2433
        plugins = zcuf._getOb('plugins')
1✔
2434
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
2435

2436
        users = zcuf.searchUsers(login='joe')
1✔
2437
        self.assertEqual(len(users), 1)
1✔
2438
        self.assertEqual(users[0]['id'], 'joe')
1✔
2439
        self.assertEqual(users[0]['login'], 'joe')
1✔
2440
        users = zcuf.searchUsers(login='bart')
1✔
2441
        self.assertEqual(len(users), 1)
1✔
2442
        self.assertEqual(users[0]['id'], 'bart')
1✔
2443
        self.assertEqual(users[0]['login'], 'bart')
1✔
2444

2445
        # Changing the login name will not work when you are not logged in.
2446
        zcuf.updateOwnLoginName('james')
1✔
2447
        users = zcuf.searchUsers(login='james')
1✔
2448
        self.assertEqual(len(users), 0)
1✔
2449

2450
        # Fake a login.
2451
        newSecurityManager(None, FauxUser('joe', 'joe'))
1✔
2452
        zcuf.updateOwnLoginName('james')
1✔
2453

2454
        users = zcuf.searchUsers(login='james')
1✔
2455
        self.assertEqual(len(users), 1)
1✔
2456
        self.assertEqual(users[0]['id'], 'joe')
1✔
2457
        self.assertEqual(users[0]['login'], 'james')
1✔
2458

2459
        # The login for bart has not changed.
2460
        users = zcuf.searchUsers(login='bart')
1✔
2461
        self.assertEqual(len(users), 1)
1✔
2462
        self.assertEqual(users[0]['id'], 'bart')
1✔
2463
        self.assertEqual(users[0]['login'], 'bart')
1✔
2464

2465
    def test_updateAllLoginNames(self):
1✔
2466

2467
        from ..interfaces.plugins import IUserEnumerationPlugin
1✔
2468

2469
        plugins = self._makePlugins()
1✔
2470
        zcuf = self._makeOne(plugins)
1✔
2471

2472
        foo = self._makeMultiUserEnumerator(
1✔
2473
            {'id': 'JOE', 'login': 'Joe'},
2474
            {'id': 'BART', 'login': 'Bart'})
2475
        zcuf._setObject('foo', foo)
1✔
2476

2477
        plugins = zcuf._getOb('plugins')
1✔
2478
        plugins.activatePlugin(IUserEnumerationPlugin, 'foo')
1✔
2479

2480
        users = foo.enumerateUsers(login='Joe')
1✔
2481
        self.assertEqual(len(users), 1)
1✔
2482
        self.assertEqual(users[0]['id'], 'JOE')
1✔
2483
        self.assertEqual(users[0]['login'], 'Joe')
1✔
2484
        users = foo.enumerateUsers(login='Bart')
1✔
2485
        self.assertEqual(len(users), 1)
1✔
2486

2487
        # Update all login names.  The dummy updater makes every login
2488
        # name lowercase.
2489
        zcuf.updateAllLoginNames()
1✔
2490

2491
        self.assertEqual(len(foo.enumerateUsers(login='Joe')), 0)
1✔
2492
        self.assertEqual(len(foo.enumerateUsers(login='joe')), 1)
1✔
2493
        self.assertEqual(len(foo.enumerateUsers(login='Bart')), 0)
1✔
2494
        self.assertEqual(len(foo.enumerateUsers(login='bart')), 1)
1✔
2495

2496
        # PAS applies the login_transform when searching for users.
2497
        zcuf.login_transform = 'lower'
1✔
2498
        self.assertEqual(len(zcuf.searchUsers(login='Joe')), 1)
1✔
2499
        self.assertEqual(len(zcuf.searchUsers(login='joe')), 1)
1✔
2500
        self.assertEqual(len(zcuf.searchUsers(login='Bart')), 1)
1✔
2501
        self.assertEqual(len(zcuf.searchUsers(login='bart')), 1)
1✔
2502

2503
    def test_no_challenger(self):
1✔
2504
        # make sure that the response's _unauthorized gets propogated
2505
        # if no challengers exist (or have fired)
2506
        plugins = self._makePlugins()
1✔
2507
        zcuf = self._makeOne(plugins)
1✔
2508
        response = FauxResponse()
1✔
2509
        request = self._makeRequest(RESPONSE=response)
1✔
2510
        zcuf.REQUEST = request
1✔
2511

2512
        # First call the userfolders before_traverse hook, to set things up:
2513
        zcuf(self, request)
1✔
2514
        # Call unauthorized to make sure Unauthorized is raised.
2515
        self.assertRaises(Unauthorized, response.unauthorized)
1✔
2516
        # Since no challengers are in play, we end up calling
2517
        # response._unauthorized(), which sets '.challenger' on
2518
        # response
2519
        self.assertTrue(isinstance(response.challenger, FauxResponse))
1✔
2520

2521
    def test_challenge(self):
1✔
2522
        from ..interfaces.plugins import IChallengePlugin
1✔
2523
        plugins = self._makePlugins()
1✔
2524
        zcuf = self._makeOne(plugins)
1✔
2525
        challenger = self._makeChallengePlugin('challenger', DummyChallenger)
1✔
2526
        zcuf._setObject('challenger', challenger)
1✔
2527
        plugins = zcuf._getOb('plugins')
1✔
2528
        plugins.activatePlugin(IChallengePlugin, 'challenger')
1✔
2529

2530
        response = FauxResponse()
1✔
2531
        request = self._makeRequest(RESPONSE=response)
1✔
2532
        zcuf.REQUEST = request
1✔
2533

2534
        # First call the userfolders before_traverse hook, to set things up:
2535
        zcuf(self, request)
1✔
2536
        # Call unauthorized to make sure Unauthorized is raised.
2537
        self.assertRaises(Unauthorized, response.unauthorized)
1✔
2538
        # Since we have one challenger in play, we end up calling
2539
        # PluggableAuthService._unauthorized(), which allows the
2540
        # challengers to play. DummyChallenger sets '.challenger' on
2541
        # response
2542
        self.assertTrue(isinstance(response.challenger, DummyChallenger))
1✔
2543

2544
    def test_daisy_chain_challenge(self):
1✔
2545
        # make sure that nested PASes each get a chance to challenge a
2546
        # given response
2547
        from ..interfaces.plugins import IChallengePlugin
1✔
2548
        rc, root, folder, object = self._makeTree()
1✔
2549
        response = FauxResponse()
1✔
2550
        request = self._makeRequest(RESPONSE=response)
1✔
2551
        root.REQUEST = request
1✔
2552

2553
        plugins = self._makePlugins()
1✔
2554
        zcuf = self._makeOne(plugins)
1✔
2555
        root._setObject('acl_users', zcuf)
1✔
2556
        zcuf = root._getOb('acl_users')
1✔
2557

2558
        challenger = self._makeChallengePlugin('challenger', DummyChallenger)
1✔
2559
        zcuf._setObject('challenger', challenger)
1✔
2560
        zcuf.plugins.activatePlugin(IChallengePlugin, 'challenger')
1✔
2561

2562
        # Emulate publishing traverse through the root
2563
        zcuf(root, request)
1✔
2564

2565
        inner_plugins = self._makePlugins()
1✔
2566
        inner_zcuf = self._makeOne(inner_plugins)
1✔
2567
        folder._setObject('acl_users', inner_zcuf)
1✔
2568
        inner_zcuf = folder._getOb('acl_users')
1✔
2569

2570
        bad_challenger = self._makeChallengePlugin('bad_challenger',
1✔
2571
                                                   DummyBadChallenger)
2572
        inner_zcuf._setObject('bad_challenger', bad_challenger)
1✔
2573
        inner_zcuf.plugins.activatePlugin(IChallengePlugin, 'bad_challenger')
1✔
2574

2575
        # Emulate publishing traverse through the subfolder
2576
        inner_zcuf(folder, request)
1✔
2577

2578
        # Call unauthorized to make sure Unauthorized is raised.
2579
        self.assertRaises(Unauthorized, response.unauthorized)
1✔
2580

2581
        # Since we have two challengers in play, we end up calling
2582
        # PluggableAuthService._unauthorized(), which allows the
2583
        # challengers to play. DummyChallenger sets '.challenger' on
2584
        # response
2585
        self.assertTrue(isinstance(response.challenger, DummyChallenger))
1✔
2586

2587
    def test_challenge_multi_protocols(self):
1✔
2588
        from ..interfaces.plugins import IChallengePlugin
1✔
2589
        plugins = self._makePlugins()
1✔
2590
        zcuf = self._makeOne(plugins)
1✔
2591

2592
        dasher = self._makeChallengePlugin('dasher', DummyReindeerChallenger)
1✔
2593
        dasher.protocol = 'Reindeer Games Participant'
1✔
2594
        zcuf._setObject('dasher', dasher)
1✔
2595

2596
        dancer = self._makeChallengePlugin('dancer', DummyReindeerChallenger)
1✔
2597
        dancer.protocol = 'Reindeer Games Participant'
1✔
2598
        zcuf._setObject('dancer', dancer)
1✔
2599

2600
        rudolph = self._makeChallengePlugin('rudolph', DummyReindeerChallenger)
1✔
2601
        rudolph.protocol = ('They never let poor Rudolph...'
1✔
2602
                            ' join in any Reindeer Games')
2603
        zcuf._setObject('rudolph', rudolph)
1✔
2604

2605
        plugins = zcuf._getOb('plugins')
1✔
2606
        plugins.activatePlugin(IChallengePlugin, 'dasher')
1✔
2607
        plugins.activatePlugin(IChallengePlugin, 'dancer')
1✔
2608
        plugins.activatePlugin(IChallengePlugin, 'rudolph')
1✔
2609

2610
        response = FauxResponse()
1✔
2611
        request = self._makeRequest(RESPONSE=response)
1✔
2612
        zcuf.REQUEST = request
1✔
2613

2614
        # First call the userfolders before_traverse hook, to set things up:
2615
        zcuf(self, request)
1✔
2616

2617
        # Call unauthorized to make sure Unauthorized is raised.
2618
        self.assertRaises(Unauthorized, response.unauthorized)
1✔
2619

2620
        # Since we have multiple challengers in play, we end up
2621
        # calling PluggableAuthService._unauthorized(), which allows
2622
        # the challengers to play. However, because of the ordering of
2623
        # the plugins, only "Reindeer Games Participant" challengers
2624
        # will play
2625
        self.assertEqual(response.reindeer_games, ['dasher', 'dancer'])
1✔
2626

2627
    def test_dont_call_challenge_twice(self):
1✔
2628
        from ..interfaces.plugins import IChallengePlugin
1✔
2629
        plugins = self._makePlugins()
1✔
2630
        zcuf = self._makeOne(plugins)
1✔
2631

2632
        counter = self._makeChallengePlugin('counter', DummyCounterChallenger)
1✔
2633
        zcuf._setObject('counter', counter)
1✔
2634

2635
        plugins = zcuf._getOb('plugins')
1✔
2636
        plugins.activatePlugin(IChallengePlugin, 'counter')
1✔
2637

2638
        response = FauxResponse()
1✔
2639
        request = self._makeRequest(RESPONSE=response)
1✔
2640
        zcuf.REQUEST = request
1✔
2641

2642
        zcuf(self, request)
1✔
2643

2644
        self.assertRaises(Unauthorized, response.unauthorized)
1✔
2645

2646
        self.assertEqual(counter.count, 1)
1✔
2647

2648
    def test_logout(self):
1✔
2649
        from ..interfaces.plugins import ICredentialsResetPlugin
1✔
2650
        from ..interfaces.plugins import ICredentialsUpdatePlugin
1✔
2651
        from ..interfaces.plugins import IExtractionPlugin
1✔
2652
        plugins = self._makePlugins()
1✔
2653
        zcuf = self._makeOne(plugins)
1✔
2654
        creds_store = DummyCredentialsStore('creds')
1✔
2655
        zcuf._setObject('creds', creds_store)
1✔
2656
        creds_store = zcuf._getOb('creds')
1✔
2657

2658
        plugins = zcuf._getOb('plugins')
1✔
2659
        directlyProvides(creds_store, IExtractionPlugin,
1✔
2660
                         ICredentialsUpdatePlugin, ICredentialsResetPlugin)
2661
        plugins.activatePlugin(IExtractionPlugin, 'creds')
1✔
2662
        plugins.activatePlugin(ICredentialsUpdatePlugin, 'creds')
1✔
2663
        plugins.activatePlugin(ICredentialsResetPlugin, 'creds')
1✔
2664

2665
        response = FauxResponse()
1✔
2666
        request = self._makeRequest(RESPONSE=response)
1✔
2667
        zcuf.REQUEST = request
1✔
2668

2669
        # Put a user in the credentials store
2670
        creds_store.updateCredentials(request, response, 'foo', 'bar')
1✔
2671
        request['login'] = 'foo'
1✔
2672
        request['HTTP_REFERER'] = ''
1✔
2673
        extracted = creds_store.extractCredentials(request)
1✔
2674
        self.assertFalse(len(extracted.keys()) == 0)
1✔
2675

2676
        # Now call the logout method - the credentials should go away
2677
        newSecurityManager(None, FauxUser('foo', 'foo'))
1✔
2678
        zcuf.logout(request)
1✔
2679
        extracted = creds_store.extractCredentials(request)
1✔
2680
        self.assertTrue(len(extracted.keys()) == 0)
1✔
2681

2682
    def test_applyTransform(self):
1✔
2683
        zcuf = self._makeOne()
1✔
2684
        self.assertEqual(zcuf.applyTransform(' User '), ' User ')
1✔
2685
        zcuf.login_transform = 'lower'
1✔
2686
        self.assertEqual(zcuf.applyTransform(' User '), 'user')
1✔
2687
        self.assertEqual(zcuf.applyTransform(' User '), 'user')
1✔
2688
        self.assertEqual(zcuf.applyTransform(''), '')
1✔
2689
        self.assertEqual(zcuf.applyTransform(None), None)
1✔
2690
        self.assertEqual(zcuf.applyTransform([' User ']), ['user'])
1✔
2691
        self.assertEqual(zcuf.applyTransform(('User', ' joe  ', 'Diana')),
1✔
2692
                         ('user', 'joe', 'diana'))
2693
        self.assertRaises(TypeError, zcuf.applyTransform, 123)
1✔
2694
        zcuf.login_transform = 'upper'
1✔
2695
        self.assertEqual(zcuf.applyTransform(' User '), 'USER')
1✔
2696
        # Let's not fail just because a user has accidentally left a
2697
        # space at the end of the login_transform name.  That could
2698
        # lead to hard-to-debug behaviour.
2699
        zcuf.login_transform = ' upper  '
1✔
2700
        self.assertEqual(zcuf.applyTransform(' User '), 'USER')
1✔
2701
        # We would want to test what happens when the login_transform
2702
        # attribute is not there, but the following only removes it
2703
        # from the instance, not the class.  Oh well.
2704
        del zcuf.login_transform
1✔
2705
        self.assertEqual(zcuf.applyTransform(' User '), ' User ')
1✔
2706
        zcuf.login_transform = 'nonexisting'
1✔
2707
        self.assertEqual(zcuf.applyTransform(' User '), ' User ')
1✔
2708

2709
    def test_get_login_transform_method(self):
1✔
2710
        zcuf = self._makeOne()
1✔
2711
        self.assertEqual(zcuf._get_login_transform_method(), None)
1✔
2712
        zcuf.login_transform = 'lower'
1✔
2713
        self.assertEqual(zcuf._get_login_transform_method(), zcuf.lower)
1✔
2714
        zcuf.login_transform = 'upper'
1✔
2715
        self.assertEqual(zcuf._get_login_transform_method(), zcuf.upper)
1✔
2716
        # Let's not fail just because a user has accidentally left a
2717
        # space at the end of the login_transform name.  That could
2718
        # lead to hard-to-debug behaviour.
2719
        zcuf.login_transform = ' upper  '
1✔
2720
        self.assertEqual(zcuf._get_login_transform_method(), zcuf.upper)
1✔
2721
        # We would want to test what happens when the login_transform
2722
        # attribute is not there, but the following only removes it
2723
        # from the instance, not the class.  Oh well.
2724
        del zcuf.login_transform
1✔
2725
        self.assertEqual(zcuf._get_login_transform_method(), None)
1✔
2726
        zcuf.login_transform = 'nonexisting'
1✔
2727
        self.assertEqual(zcuf._get_login_transform_method(), None)
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