def test_via_basic_auth_compromised( self, monkeypatch, pyramid_request, pyramid_services ): send_email = pretend.call_recorder(lambda *a, **kw: None) monkeypatch.setattr( accounts, "send_password_compromised_email_hibp", send_email ) user = pretend.stub(id=2) service = pretend.stub( get_user=pretend.call_recorder(lambda user_id: user), find_userid=pretend.call_recorder(lambda username: 2), check_password=pretend.call_recorder( lambda userid, password, ip_address, tags=None: True ), is_disabled=pretend.call_recorder(lambda user_id: (False, None)), disable_password=pretend.call_recorder(lambda user_id, reason=None: None), ) breach_service = pretend.stub( check_password=pretend.call_recorder(lambda pw, tags=None: True), failure_message_plain="Bad Password!", ) pyramid_services.register_service(service, IUserService, None) pyramid_services.register_service( breach_service, IPasswordBreachedService, None ) pyramid_request.matched_route = pretend.stub(name="forklift.legacy.file_upload") with pytest.raises(BasicAuthBreachedPassword) as excinfo: accounts._basic_auth_login("myuser", "mypass", pyramid_request) assert excinfo.value.status == "401 Bad Password!" assert service.find_userid.calls == [pretend.call("myuser")] assert service.get_user.calls == [pretend.call(2)] assert service.is_disabled.calls == [pretend.call(2)] assert service.check_password.calls == [ pretend.call( 2, "mypass", "1.2.3.4", tags=["mechanism:basic_auth", "method:auth", "auth_method:basic"], ) ] assert breach_service.check_password.calls == [ pretend.call("mypass", tags=["method:auth", "auth_method:basic"]) ] assert service.disable_password.calls == [ pretend.call(2, reason=DisableReason.CompromisedPassword) ] assert send_email.calls == [pretend.call(pyramid_request, user)]
def test_with_disabled_user_compromised_pw(self, pyramid_request, pyramid_services): user = pretend.stub(id=1) service = pretend.stub( get_user=pretend.call_recorder(lambda user_id: user), find_userid=pretend.call_recorder(lambda username: 1), check_password=pretend.call_recorder( lambda userid, password, tags=None: False), is_disabled=pretend.call_recorder( lambda user_id: (True, DisableReason.CompromisedPassword)), ) pyramid_services.register_service(IUserService, None, service) pyramid_services.register_service( IPasswordBreachedService, None, pretend.stub(failure_message_plain="Bad Password!"), ) with pytest.raises(BasicAuthBreachedPassword) as excinfo: assert (accounts._basic_auth_login("myuser", "mypass", pyramid_request) is None) assert excinfo.value.status == "401 Bad Password!" assert service.find_userid.calls == [pretend.call("myuser")] assert service.get_user.calls == [pretend.call(1)] assert service.is_disabled.calls == [pretend.call(1)] assert service.check_password.calls == []
def test_with_disabled_user_compromised_pw(self, pyramid_request, pyramid_services): user = pretend.stub(id=1) service = pretend.stub( get_user=pretend.call_recorder(lambda user_id: user), find_userid=pretend.call_recorder(lambda username: 1), check_password=pretend.call_recorder( lambda userid, password, tags=None: False ), is_disabled=pretend.call_recorder( lambda user_id: (True, DisableReason.CompromisedPassword) ), ) pyramid_services.register_service(IUserService, None, service) pyramid_services.register_service( IPasswordBreachedService, None, pretend.stub(failure_message_plain="Bad Password!"), ) with pytest.raises(BasicAuthBreachedPassword) as excinfo: assert ( accounts._basic_auth_login("myuser", "mypass", pyramid_request) is None ) assert excinfo.value.status == "401 Bad Password!" assert service.find_userid.calls == [pretend.call("myuser")] assert service.get_user.calls == [pretend.call(1)] assert service.is_disabled.calls == [pretend.call(1)] assert service.check_password.calls == []
def test_with_disabled_user_no_reason(self, pyramid_request, pyramid_services): user = pretend.stub(id=1) service = pretend.stub( get_user=pretend.call_recorder(lambda user_id: user), find_userid=pretend.call_recorder(lambda username: 1), check_password=pretend.call_recorder( lambda userid, password, tags=None: False), is_disabled=pretend.call_recorder(lambda user_id: (True, None)), ) pyramid_services.register_service(IUserService, None, service) pyramid_services.register_service(IPasswordBreachedService, None, pretend.stub()) pyramid_request.matched_route = pretend.stub( name="forklift.legacy.file_upload") assert accounts._basic_auth_login("myuser", "mypass", pyramid_request) is None assert service.find_userid.calls == [pretend.call("myuser")] assert service.get_user.calls == [pretend.call(1)] assert service.is_disabled.calls == [pretend.call(1)] assert service.check_password.calls == [ pretend.call(1, "mypass", tags=["method:auth", "auth_method:basic"]) ]
def test_with_no_user(self, pyramid_request, pyramid_services): service = pretend.stub(find_userid=pretend.call_recorder(lambda username: None)) pyramid_services.register_service(IUserService, None, service) pyramid_services.register_service( IPasswordBreachedService, None, pretend.stub() ) assert accounts._basic_auth_login("myuser", "mypass", pyramid_request) is None assert service.find_userid.calls == [pretend.call("myuser")]
def test_via_basic_auth_compromised( self, monkeypatch, pyramid_request, pyramid_services ): send_email = pretend.call_recorder(lambda *a, **kw: None) monkeypatch.setattr( accounts, "send_password_compromised_email_hibp", send_email ) user = pretend.stub(id=2) service = pretend.stub( get_user=pretend.call_recorder(lambda user_id: user), find_userid=pretend.call_recorder(lambda username: 2), check_password=pretend.call_recorder( lambda userid, password, tags=None: True ), is_disabled=pretend.call_recorder(lambda user_id: (False, None)), disable_password=pretend.call_recorder(lambda user_id, reason=None: None), ) breach_service = pretend.stub( check_password=pretend.call_recorder(lambda pw, tags=None: True), failure_message_plain="Bad Password!", ) pyramid_services.register_service(IUserService, None, service) pyramid_services.register_service( IPasswordBreachedService, None, breach_service ) with pytest.raises(BasicAuthBreachedPassword) as excinfo: accounts._basic_auth_login("myuser", "mypass", pyramid_request) assert excinfo.value.status == "401 Bad Password!" assert service.find_userid.calls == [pretend.call("myuser")] assert service.get_user.calls == [pretend.call(2)] assert service.is_disabled.calls == [pretend.call(2)] assert service.check_password.calls == [ pretend.call(2, "mypass", tags=["method:auth", "auth_method:basic"]) ] assert breach_service.check_password.calls == [ pretend.call("mypass", tags=["method:auth", "auth_method:basic"]) ] assert service.disable_password.calls == [ pretend.call(2, reason=DisableReason.CompromisedPassword) ] assert send_email.calls == [pretend.call(pyramid_request, user)]
def test_with_no_user(self, pyramid_request, pyramid_services): service = pretend.stub(find_userid=pretend.call_recorder(lambda username: None)) pyramid_services.register_service(service, IUserService, None) pyramid_services.register_service( pretend.stub(), IPasswordBreachedService, None ) pyramid_request.matched_route = pretend.stub(name="forklift.legacy.file_upload") assert accounts._basic_auth_login("myuser", "mypass", pyramid_request) is None assert service.find_userid.calls == [pretend.call("myuser")]
def test_invalid_route(self, pyramid_request, pyramid_services): service = pretend.stub(find_userid=pretend.call_recorder(lambda username: None)) pyramid_services.register_service(service, IUserService, None) pyramid_services.register_service( pretend.stub(), IPasswordBreachedService, None ) pyramid_request.matched_route = pretend.stub(name="route_name") assert accounts._basic_auth_login("myuser", "mypass", pyramid_request) is None assert service.find_userid.calls == []
def test_with_valid_password(self, monkeypatch, pyramid_request, pyramid_services): principals = pretend.stub() authenticate = pretend.call_recorder(lambda userid, request: principals) monkeypatch.setattr(accounts, "_authenticate", authenticate) user = pretend.stub(id=2) service = pretend.stub( get_user=pretend.call_recorder(lambda user_id: user), find_userid=pretend.call_recorder(lambda username: 2), check_password=pretend.call_recorder( lambda userid, password, ip_address, tags=None: True ), update_user=pretend.call_recorder(lambda userid, last_login: None), is_disabled=pretend.call_recorder(lambda user_id: (False, None)), ) breach_service = pretend.stub( check_password=pretend.call_recorder(lambda pw, tags=None: False) ) pyramid_services.register_service(service, IUserService, None) pyramid_services.register_service( breach_service, IPasswordBreachedService, None ) pyramid_request.matched_route = pretend.stub(name="forklift.legacy.file_upload") now = datetime.datetime.utcnow() with freezegun.freeze_time(now): assert ( accounts._basic_auth_login("myuser", "mypass", pyramid_request) is principals ) assert service.find_userid.calls == [pretend.call("myuser")] assert service.get_user.calls == [pretend.call(2)] assert service.is_disabled.calls == [pretend.call(2)] assert service.check_password.calls == [ pretend.call( 2, "mypass", "1.2.3.4", tags=["mechanism:basic_auth", "method:auth", "auth_method:basic"], ) ] assert breach_service.check_password.calls == [ pretend.call("mypass", tags=["method:auth", "auth_method:basic"]) ] assert service.update_user.calls == [pretend.call(2, last_login=now)] assert authenticate.calls == [pretend.call(2, pyramid_request)]
def test_with_invalid_password(self, pyramid_request, pyramid_services): user = pretend.stub( id=1, record_event=pretend.call_recorder(lambda *a, **kw: None), ) service = pretend.stub( get_user=pretend.call_recorder(lambda user_id: user), find_userid=pretend.call_recorder(lambda username: 1), check_password=pretend.call_recorder( lambda userid, password, ip_address, tags=None: False ), is_disabled=pretend.call_recorder(lambda user_id: (False, None)), ) pyramid_services.register_service(service, IUserService, None) pyramid_services.register_service( pretend.stub(), IPasswordBreachedService, None ) pyramid_request.matched_route = pretend.stub(name="forklift.legacy.file_upload") pyramid_request.help_url = pretend.call_recorder(lambda **kw: "/the/help/url/") with pytest.raises(BasicAuthFailedPassword) as excinfo: assert ( accounts._basic_auth_login("myuser", "mypass", pyramid_request) is None ) assert excinfo.value.status == ( "403 Invalid or non-existent authentication information. " "See /the/help/url/ for more information." ) assert service.find_userid.calls == [pretend.call("myuser")] assert service.get_user.calls == [pretend.call(1)] assert service.is_disabled.calls == [pretend.call(1)] assert service.check_password.calls == [ pretend.call( 1, "mypass", "1.2.3.4", tags=["mechanism:basic_auth", "method:auth", "auth_method:basic"], ) ] assert user.record_event.calls == [ pretend.call( tag="account:login:failure", ip_address="1.2.3.4", additional={"reason": "invalid_password", "auth_method": "basic"}, ) ]
def test_with_valid_password(self, monkeypatch, pyramid_request, pyramid_services): principals = pretend.stub() authenticate = pretend.call_recorder(lambda userid, request: principals) monkeypatch.setattr(accounts, "_authenticate", authenticate) user = pretend.stub(id=2) service = pretend.stub( get_user=pretend.call_recorder(lambda user_id: user), find_userid=pretend.call_recorder(lambda username: 2), check_password=pretend.call_recorder( lambda userid, password, tags=None: True ), update_user=pretend.call_recorder(lambda userid, last_login: None), is_disabled=pretend.call_recorder(lambda user_id: (False, None)), ) breach_service = pretend.stub( check_password=pretend.call_recorder(lambda pw, tags=None: False) ) pyramid_services.register_service(IUserService, None, service) pyramid_services.register_service( IPasswordBreachedService, None, breach_service ) now = datetime.datetime.utcnow() with freezegun.freeze_time(now): assert ( accounts._basic_auth_login("myuser", "mypass", pyramid_request) is principals ) assert service.find_userid.calls == [pretend.call("myuser")] assert service.get_user.calls == [pretend.call(2)] assert service.is_disabled.calls == [pretend.call(2)] assert service.check_password.calls == [ pretend.call(2, "mypass", tags=["method:auth", "auth_method:basic"]) ] assert breach_service.check_password.calls == [ pretend.call("mypass", tags=["method:auth", "auth_method:basic"]) ] assert service.update_user.calls == [pretend.call(2, last_login=now)] assert authenticate.calls == [pretend.call(2, pyramid_request)]
def test_with_disabled_user_no_reason(self, pyramid_request, pyramid_services): user = pretend.stub(id=1) service = pretend.stub( get_user=pretend.call_recorder(lambda user_id: user), find_userid=pretend.call_recorder(lambda username: 1), check_password=pretend.call_recorder( lambda userid, password, tags=None: False ), is_disabled=pretend.call_recorder(lambda user_id: (True, None)), ) pyramid_services.register_service(IUserService, None, service) pyramid_services.register_service( IPasswordBreachedService, None, pretend.stub() ) assert accounts._basic_auth_login("myuser", "mypass", pyramid_request) is None assert service.find_userid.calls == [pretend.call("myuser")] assert service.get_user.calls == [pretend.call(1)] assert service.is_disabled.calls == [pretend.call(1)] assert service.check_password.calls == [ pretend.call(1, "mypass", tags=["method:auth", "auth_method:basic"]) ]