Ejemplo n.º 1
0
def _basic_auth_login(username, password, request):
    login_service = request.find_service(IUserService, context=None)
    breach_service = request.find_service(IPasswordBreachedService,
                                          context=None)

    userid = login_service.find_userid(username)
    if userid is not None:
        user = login_service.get_user(userid)
        is_disabled, disabled_for = login_service.is_disabled(user.id)
        if is_disabled and disabled_for == DisableReason.CompromisedPassword:
            # This technically violates the contract a little bit, this function is
            # meant to return None if the user cannot log in. However we want to present
            # a different error message than is normal when we're denying the log in
            # becasue of a compromised password. So to do that, we'll need to raise a
            # HTTPError that'll ultimately get returned to the client. This is OK to do
            # here because we've already successfully authenticated the credentials, so
            # it won't screw up the fall through to other authentication mechanisms
            # (since we wouldn't have fell through to them anyways).
            raise _format_exc_status(BasicAuthBreachedPassword(),
                                     breach_service.failure_message_plain)
        elif login_service.check_password(
                user.id, password, tags=["method:auth", "auth_method:basic"]):
            if breach_service.check_password(
                    password, tags=["method:auth", "auth_method:basic"]):
                send_password_compromised_email(request, user)
                login_service.disable_password(
                    user.id, reason=DisableReason.CompromisedPassword)
                raise _format_exc_status(BasicAuthBreachedPassword(),
                                         breach_service.failure_message_plain)
            else:
                login_service.update_user(
                    user.id, last_login=datetime.datetime.utcnow())
                return _authenticate(user.id, request)
Ejemplo n.º 2
0
def _basic_auth_check(username, password, request):
    request.authentication_method = AuthenticationMethod.BASIC_AUTH

    # Basic authentication can only be used for uploading
    if request.matched_route.name not in ["forklift.legacy.file_upload"]:
        return

    login_service = request.find_service(IUserService, context=None)
    breach_service = request.find_service(IPasswordBreachedService,
                                          context=None)

    userid = login_service.find_userid(username)
    if userid is not None:
        user = login_service.get_user(userid)
        is_disabled, disabled_for = login_service.is_disabled(user.id)
        if is_disabled and disabled_for == DisableReason.CompromisedPassword:
            # This technically violates the contract a little bit, this function is
            # meant to return None if the user cannot log in. However we want to present
            # a different error message than is normal when we're denying the log in
            # because of a compromised password. So to do that, we'll need to raise a
            # HTTPError that'll ultimately get returned to the client. This is OK to do
            # here because we've already successfully authenticated the credentials, so
            # it won't screw up the fall through to other authentication mechanisms
            # (since we wouldn't have fell through to them anyways).
            raise _format_exc_status(BasicAuthBreachedPassword(),
                                     breach_service.failure_message_plain)
        elif login_service.check_password(
                user.id,
                password,
                tags=[
                    "mechanism:basic_auth", "method:auth", "auth_method:basic"
                ],
        ):
            if breach_service.check_password(
                    password, tags=["method:auth", "auth_method:basic"]):
                send_password_compromised_email_hibp(request, user)
                login_service.disable_password(
                    user.id, reason=DisableReason.CompromisedPassword)
                raise _format_exc_status(BasicAuthBreachedPassword(),
                                         breach_service.failure_message_plain)

            login_service.update_user(user.id,
                                      last_login=datetime.datetime.utcnow())
            return _authenticate(user.id, request)
        else:
            user.record_event(
                tag="account:login:failure",
                ip_address=request.remote_addr,
                additional={
                    "reason": "invalid_password",
                    "auth_method": "basic"
                },
            )
            raise _format_exc_status(
                BasicAuthFailedPassword(),
                "Invalid or non-existent authentication information. "
                "See {projecthelp} for more information.".format(
                    projecthelp=request.help_url(_anchor="invalid-auth")),
            )
Ejemplo n.º 3
0
@pytest.mark.parametrize(
    ("path", "expected"),
    [("/foo/bar/", True), ("/static/wat/", False),
     ("/_debug_toolbar/thing/", False)],
)
def test_activate_hook(path, expected):
    request = pretend.stub(path=path)
    assert config.activate_hook(request) == expected


@pytest.mark.parametrize(
    ("exc_info", "expected"),
    [
        (None, False),
        ((ValueError, ValueError(), None), True),
        ((BasicAuthBreachedPassword, BasicAuthBreachedPassword(), None),
         False),
    ],
)
def test_commit_veto(exc_info, expected):
    request = pretend.stub(exc_info=exc_info)
    response = pretend.stub()

    assert bool(config.commit_veto(request, response)) == expected


@pytest.mark.parametrize("route_kw", [None, {}, {"foo": "bar"}])
def test_template_view(route_kw):
    configobj = pretend.stub(
        add_route=pretend.call_recorder(lambda *a, **kw: None),
        add_view=pretend.call_recorder(lambda *a, **kw: None),