Beispiel #1
0
    def test_via_basic_auth_compromised(self, monkeypatch, pyramid_request,
                                        pyramid_services):
        send_email = pretend.call_recorder(lambda *a, **kw: None)
        monkeypatch.setattr(security_policy,
                            "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(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:
            _basic_auth_check("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=[
                    "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)]
Beispiel #2
0
    def test_with_disabled_user_frozen(self, pyramid_request,
                                       pyramid_services):
        user = pretend.stub(
            id=1,
            record_event=pretend.call_recorder(lambda *a, **kw: None),
            is_frozen=True,
        )
        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.AccountFrozen)),
        )
        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(HTTPUnauthorized) as excinfo:
            assert _basic_auth_check("myuser", "mypass",
                                     pyramid_request) is None

        assert excinfo.value.status == "401 Account is frozen."
        assert service.find_userid.calls == [pretend.call("myuser")]
        assert service.get_user.calls == [pretend.call(1)]
        assert service.is_disabled.calls == [pretend.call(1)]
Beispiel #3
0
    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(service, IUserService, None)
        pyramid_services.register_service(
            pretend.stub(failure_message_plain="Bad Password!"),
            IPasswordBreachedService,
            None,
        )
        pyramid_request.matched_route = pretend.stub(
            name="forklift.legacy.file_upload")

        with pytest.raises(BasicAuthBreachedPassword) as excinfo:
            assert _basic_auth_check("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 == []
Beispiel #4
0
 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 _basic_auth_check("myuser", "mypass", pyramid_request) is False
     assert service.find_userid.calls == []
Beispiel #5
0
 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 _basic_auth_check("myuser", "mypass", pyramid_request) is False
     assert service.find_userid.calls == [pretend.call("myuser")]
Beispiel #6
0
    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, 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 _basic_auth_check("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",
                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"
                },
            )
        ]
Beispiel #7
0
    def test_with_valid_password(self, monkeypatch, pyramid_request,
                                 pyramid_services):
        user = pretend.stub(id=2, has_two_factor=False)
        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(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 _basic_auth_check("myuser", "mypass",
                                     pyramid_request) is True

        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=[
                    "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)]