@@ -40,7 +40,7 @@ def test_invalid_route(self, pyramid_request, pyramid_services):
40
40
pretend .stub (), IPasswordBreachedService , None
41
41
)
42
42
pyramid_request .matched_route = pretend .stub (name = "route_name" )
43
- assert accounts ._basic_auth_login ("myuser" , "mypass" , pyramid_request ) is None
43
+ assert accounts ._basic_auth_check ("myuser" , "mypass" , pyramid_request ) is None
44
44
assert service .find_userid .calls == []
45
45
46
46
def test_with_no_user (self , pyramid_request , pyramid_services ):
@@ -50,7 +50,7 @@ def test_with_no_user(self, pyramid_request, pyramid_services):
50
50
pretend .stub (), IPasswordBreachedService , None
51
51
)
52
52
pyramid_request .matched_route = pretend .stub (name = "forklift.legacy.file_upload" )
53
- assert accounts ._basic_auth_login ("myuser" , "mypass" , pyramid_request ) is None
53
+ assert accounts ._basic_auth_check ("myuser" , "mypass" , pyramid_request ) is None
54
54
assert service .find_userid .calls == [pretend .call ("myuser" )]
55
55
56
56
def test_with_invalid_password (self , pyramid_request , pyramid_services ):
@@ -75,7 +75,7 @@ def test_with_invalid_password(self, pyramid_request, pyramid_services):
75
75
76
76
with pytest .raises (BasicAuthFailedPassword ) as excinfo :
77
77
assert (
78
- accounts ._basic_auth_login ("myuser" , "mypass" , pyramid_request ) is None
78
+ accounts ._basic_auth_check ("myuser" , "mypass" , pyramid_request ) is None
79
79
)
80
80
81
81
assert excinfo .value .status == (
@@ -122,7 +122,7 @@ def test_with_disabled_user_no_reason(self, pyramid_request, pyramid_services):
122
122
123
123
with pytest .raises (BasicAuthFailedPassword ) as excinfo :
124
124
assert (
125
- accounts ._basic_auth_login ("myuser" , "mypass" , pyramid_request ) is None
125
+ accounts ._basic_auth_check ("myuser" , "mypass" , pyramid_request ) is None
126
126
)
127
127
128
128
assert excinfo .value .status == (
@@ -169,7 +169,7 @@ def test_with_disabled_user_compromised_pw(self, pyramid_request, pyramid_servic
169
169
170
170
with pytest .raises (BasicAuthBreachedPassword ) as excinfo :
171
171
assert (
172
- accounts ._basic_auth_login ("myuser" , "mypass" , pyramid_request ) is None
172
+ accounts ._basic_auth_check ("myuser" , "mypass" , pyramid_request ) is None
173
173
)
174
174
175
175
assert excinfo .value .status == "401 Bad Password!"
@@ -183,7 +183,7 @@ def test_with_valid_password(self, monkeypatch, pyramid_request, pyramid_service
183
183
authenticate = pretend .call_recorder (lambda userid , request : principals )
184
184
monkeypatch .setattr (accounts , "_authenticate" , authenticate )
185
185
186
- user = pretend .stub (id = 2 )
186
+ user = pretend .stub (id = 2 , has_two_factor = False )
187
187
service = pretend .stub (
188
188
get_user = pretend .call_recorder (lambda user_id : user ),
189
189
find_userid = pretend .call_recorder (lambda username : 2 ),
@@ -208,7 +208,7 @@ def test_with_valid_password(self, monkeypatch, pyramid_request, pyramid_service
208
208
209
209
with freezegun .freeze_time (now ):
210
210
assert (
211
- accounts ._basic_auth_login ("myuser" , "mypass" , pyramid_request )
211
+ accounts ._basic_auth_check ("myuser" , "mypass" , pyramid_request )
212
212
is principals
213
213
)
214
214
@@ -259,7 +259,7 @@ def test_via_basic_auth_compromised(
259
259
pyramid_request .matched_route = pretend .stub (name = "forklift.legacy.file_upload" )
260
260
261
261
with pytest .raises (BasicAuthBreachedPassword ) as excinfo :
262
- accounts ._basic_auth_login ("myuser" , "mypass" , pyramid_request )
262
+ accounts ._basic_auth_check ("myuser" , "mypass" , pyramid_request )
263
263
264
264
assert excinfo .value .status == "401 Bad Password!"
265
265
assert service .find_userid .calls == [pretend .call ("myuser" )]
@@ -280,6 +280,64 @@ def test_via_basic_auth_compromised(
280
280
]
281
281
assert send_email .calls == [pretend .call (pyramid_request , user )]
282
282
283
+ def test_via_basic_auth_2fa_enabled (
284
+ self , monkeypatch , pyramid_request , pyramid_services
285
+ ):
286
+ principals = pretend .stub ()
287
+ authenticate = pretend .call_recorder (lambda userid , request : principals )
288
+ monkeypatch .setattr (accounts , "_authenticate" , authenticate )
289
+ send_email = pretend .call_recorder (lambda * a , ** kw : None )
290
+ monkeypatch .setattr (
291
+ accounts , "send_basic_auth_with_two_factor_email" , send_email
292
+ )
293
+
294
+ user = pretend .stub (id = 2 , has_two_factor = True )
295
+ service = pretend .stub (
296
+ get_user = pretend .call_recorder (lambda user_id : user ),
297
+ find_userid = pretend .call_recorder (lambda username : 2 ),
298
+ check_password = pretend .call_recorder (
299
+ lambda userid , password , tags = None : True
300
+ ),
301
+ is_disabled = pretend .call_recorder (lambda user_id : (False , None )),
302
+ disable_password = pretend .call_recorder (lambda user_id , reason = None : None ),
303
+ update_user = pretend .call_recorder (lambda userid , last_login : None ),
304
+ )
305
+ breach_service = pretend .stub (
306
+ check_password = pretend .call_recorder (lambda pw , tags = None : False )
307
+ )
308
+
309
+ pyramid_services .register_service (service , IUserService , None )
310
+ pyramid_services .register_service (
311
+ breach_service , IPasswordBreachedService , None
312
+ )
313
+
314
+ pyramid_request .matched_route = pretend .stub (name = "forklift.legacy.file_upload" )
315
+
316
+ now = datetime .datetime .utcnow ()
317
+
318
+ with freezegun .freeze_time (now ):
319
+ assert (
320
+ accounts ._basic_auth_check ("myuser" , "mypass" , pyramid_request )
321
+ is principals
322
+ )
323
+
324
+ assert service .find_userid .calls == [pretend .call ("myuser" )]
325
+ assert service .get_user .calls == [pretend .call (2 )]
326
+ assert service .is_disabled .calls == [pretend .call (2 )]
327
+ assert service .check_password .calls == [
328
+ pretend .call (
329
+ 2 ,
330
+ "mypass" ,
331
+ tags = ["mechanism:basic_auth" , "method:auth" , "auth_method:basic" ],
332
+ )
333
+ ]
334
+ assert breach_service .check_password .calls == [
335
+ pretend .call ("mypass" , tags = ["method:auth" , "auth_method:basic" ])
336
+ ]
337
+ assert send_email .calls == [pretend .call (pyramid_request , user )]
338
+ assert service .update_user .calls == [pretend .call (2 , last_login = now )]
339
+ assert authenticate .calls == [pretend .call (2 , pyramid_request )]
340
+
283
341
284
342
class TestAuthenticate :
285
343
@pytest .mark .parametrize (
@@ -372,6 +430,17 @@ def test_route_matched_name_ok(self, monkeypatch):
372
430
assert authenticate_obj .calls == [pretend .call (1 , request )]
373
431
374
432
433
+ class TestMacaroonAuthenticate :
434
+ def test_macaroon_authenticate (self , monkeypatch ):
435
+ authenticate_obj = pretend .call_recorder (lambda * a , ** kw : True )
436
+ monkeypatch .setattr (accounts , "_authenticate" , authenticate_obj )
437
+ request = pretend .stub (
438
+ matched_route = pretend .stub (name = "includes.current-user-indicator" )
439
+ )
440
+ assert accounts ._macaroon_authenticate (1 , request ) is True
441
+ assert authenticate_obj .calls == [pretend .call (1 , request )]
442
+
443
+
375
444
class TestUser :
376
445
def test_with_user (self ):
377
446
user = pretend .stub ()
@@ -466,7 +535,7 @@ def test_includeme(monkeypatch):
466
535
]
467
536
assert config .set_authentication_policy .calls == [pretend .call (authn_obj )]
468
537
assert config .set_authorization_policy .calls == [pretend .call (authz_obj )]
469
- assert basic_authn_cls .calls == [pretend .call (check = accounts ._basic_auth_login )]
538
+ assert basic_authn_cls .calls == [pretend .call (check = accounts ._basic_auth_check )]
470
539
assert session_authn_cls .calls == [
471
540
pretend .call (callback = accounts ._session_authenticate )
472
541
]
0 commit comments