Example #1
0
def includeme(config):
    # Register our login service
    config.register_service_factory(database_login_factory, IUserService)

    # Register our token services
    config.register_service_factory(TokenServiceFactory(name="password"),
                                    ITokenService,
                                    name="password")
    config.register_service_factory(TokenServiceFactory(name="email"),
                                    ITokenService,
                                    name="email")

    # Register our password breach detection service.
    config.register_service_factory(hibp_password_breach_factory,
                                    IPasswordBreachedService)

    # Register our authentication and authorization policies
    config.set_authentication_policy(
        MultiAuthenticationPolicy([
            SessionAuthenticationPolicy(callback=_authenticate),
            BasicAuthAuthenticationPolicy(check=_login_via_basic_auth),
        ]))
    config.set_authorization_policy(ACLAuthorizationPolicy())

    # Add a request method which will allow people to access the user object.
    config.add_request_method(_user, name="user", reify=True)

    # Register the rate limits that we're going to be using for our login
    # attempts
    config.register_service_factory(RateLimit("10 per 5 minutes"),
                                    IRateLimiter,
                                    name="user.login")
    config.register_service_factory(RateLimit("1000 per 5 minutes"),
                                    IRateLimiter,
                                    name="global.login")
Example #2
0
 def test_eq(self):
     assert RateLimit("1 per 5 minutes",
                      identifiers=["foo"]) == RateLimit("1 per 5 minutes",
                                                        identifiers=["foo"])
     assert RateLimit("1 per 5 minutes", identifiers=["foo"]) != RateLimit(
         "1 per 5 minutes", identifiers=["bar"])
     assert RateLimit("1 per 5 minutes", identifiers=["foo"]) != object()
Example #3
0
def test_includeme(monkeypatch):
    macaroon_authn_obj = pretend.stub()
    macaroon_authn_cls = pretend.call_recorder(lambda callback: macaroon_authn_obj)
    basic_authn_obj = pretend.stub()
    basic_authn_cls = pretend.call_recorder(lambda check: basic_authn_obj)
    session_authn_obj = pretend.stub()
    session_authn_cls = pretend.call_recorder(lambda callback: session_authn_obj)
    authn_obj = pretend.stub()
    authn_cls = pretend.call_recorder(lambda *a: authn_obj)
    authz_obj = pretend.stub()
    authz_cls = pretend.call_recorder(lambda *a, **kw: authz_obj)
    monkeypatch.setattr(accounts, "BasicAuthAuthenticationPolicy", basic_authn_cls)
    monkeypatch.setattr(accounts, "SessionAuthenticationPolicy", session_authn_cls)
    monkeypatch.setattr(accounts, "MacaroonAuthenticationPolicy", macaroon_authn_cls)
    monkeypatch.setattr(accounts, "MultiAuthenticationPolicy", authn_cls)
    monkeypatch.setattr(accounts, "ACLAuthorizationPolicy", authz_cls)
    monkeypatch.setattr(accounts, "MacaroonAuthorizationPolicy", authz_cls)

    config = pretend.stub(
        registry=pretend.stub(settings={}),
        register_service_factory=pretend.call_recorder(
            lambda factory, iface, name=None: None
        ),
        add_request_method=pretend.call_recorder(lambda f, name, reify: None),
        set_authentication_policy=pretend.call_recorder(lambda p: None),
        set_authorization_policy=pretend.call_recorder(lambda p: None),
        maybe_dotted=pretend.call_recorder(lambda path: path),
    )

    accounts.includeme(config)

    assert config.register_service_factory.calls == [
        pretend.call(database_login_factory, IUserService),
        pretend.call(
            TokenServiceFactory(name="password"), ITokenService, name="password"
        ),
        pretend.call(TokenServiceFactory(name="email"), ITokenService, name="email"),
        pretend.call(
            TokenServiceFactory(name="two_factor"), ITokenService, name="two_factor"
        ),
        pretend.call(
            HaveIBeenPwnedPasswordBreachedService.create_service,
            IPasswordBreachedService,
        ),
        pretend.call(RateLimit("10 per 5 minutes"), IRateLimiter, name="user.login"),
        pretend.call(
            RateLimit("1000 per 5 minutes"), IRateLimiter, name="global.login"
        ),
    ]
    assert config.add_request_method.calls == [
        pretend.call(accounts._user, name="user", reify=True)
    ]
    assert config.set_authentication_policy.calls == [pretend.call(authn_obj)]
    assert config.set_authorization_policy.calls == [pretend.call(authz_obj)]
    assert basic_authn_cls.calls == [pretend.call(check=accounts._basic_auth_login)]
    assert session_authn_cls.calls == [pretend.call(callback=accounts._authenticate)]
    assert authn_cls.calls == [
        pretend.call([session_authn_obj, basic_authn_obj, macaroon_authn_obj])
    ]
    assert authz_cls.calls == [pretend.call(), pretend.call(policy=authz_obj)]
Example #4
0
def includeme(config):
    # Register our login service
    config.register_service_factory(database_login_factory, IUserService)
    config.register_service_factory(user_token_factory, IUserTokenService)

    # Register our authentication and authorization policies
    config.set_authentication_policy(
        MultiAuthenticationPolicy([
            SessionAuthenticationPolicy(callback=_authenticate),
            BasicAuthAuthenticationPolicy(check=_login),
        ]),
    )
    config.set_authorization_policy(ACLAuthorizationPolicy())

    # Add a request method which will allow people to access the user object.
    config.add_request_method(_user, name="user", reify=True)

    # Register the rate limits that we're going to be using for our login
    # attempts
    config.register_service_factory(
        RateLimit("10 per 5 minutes"),
        IRateLimiter,
        name="user.login",
    )
    config.register_service_factory(
        RateLimit("1000 per 5 minutes"),
        IRateLimiter,
        name="global.login",
    )
Example #5
0
def includeme(config):
    # Register our login service
    config.register_service_factory(database_login_factory, IUserService)

    # Register our token services
    config.register_service_factory(
        TokenServiceFactory(name="password"), ITokenService, name="password"
    )
    config.register_service_factory(
        TokenServiceFactory(name="email"), ITokenService, name="email"
    )
    config.register_service_factory(
        TokenServiceFactory(name="two_factor"), ITokenService, name="two_factor"
    )

    # Register our password breach detection service.
    breached_pw_class = config.maybe_dotted(
        config.registry.settings.get(
            "breached_passwords.backend", HaveIBeenPwnedPasswordBreachedService
        )
    )
    config.register_service_factory(
        breached_pw_class.create_service, IPasswordBreachedService
    )

    # Register our authentication and authorization policies
    config.set_authentication_policy(
        MultiAuthenticationPolicy(
            [
                SessionAuthenticationPolicy(callback=_authenticate),
                BasicAuthAuthenticationPolicy(check=_basic_auth_login),
                MacaroonAuthenticationPolicy(callback=_authenticate),
            ]
        )
    )
    config.set_authorization_policy(
        MacaroonAuthorizationPolicy(policy=ACLAuthorizationPolicy())
    )

    # Add a request method which will allow people to access the user object.
    config.add_request_method(_user, name="user", reify=True)

    # Register the rate limits that we're going to be using for our login
    # attempts
    config.register_service_factory(
        RateLimit("10 per 5 minutes"), IRateLimiter, name="user.login"
    )
    config.register_service_factory(
        RateLimit("1000 per 5 minutes"), IRateLimiter, name="global.login"
    )
Example #6
0
def includeme(config):
    ratelimit_string = config.registry.settings.get(
        "warehouse.xmlrpc.client.ratelimit_string"
    )
    config.register_service_factory(
        RateLimit(ratelimit_string), IRateLimiter, name="xmlrpc.client"
    )
Example #7
0
def includeme(config):
    config.add_view_deriver(reauth_view, over="rendered_view", under="decorated_view")

    user_oidc_registration_ratelimit_string = config.registry.settings.get(
        "warehouse.manage.oidc.user_registration_ratelimit_string"
    )
    config.register_service_factory(
        RateLimit(user_oidc_registration_ratelimit_string),
        IRateLimiter,
        name="user_oidc.provider.register",
    )

    ip_oidc_registration_ratelimit_string = config.registry.settings.get(
        "warehouse.manage.oidc.ip_registration_ratelimit_string"
    )
    config.register_service_factory(
        RateLimit(ip_oidc_registration_ratelimit_string),
        IRateLimiter,
        name="ip_oidc.provider.register",
    )
Example #8
0
    def test_basic(self):
        limiter_obj = pretend.stub()
        limiter_class = pretend.call_recorder(lambda *a, **kw: limiter_obj)

        context = pretend.stub()
        request = pretend.stub(registry={"ratelimiter.storage": pretend.stub()})

        result = RateLimit(
            "1 per 5 minutes", identifiers=["foo"], limiter_class=limiter_class
        )(context, request)

        assert result is limiter_obj
        assert limiter_class.calls == [
            pretend.call(
                request.registry["ratelimiter.storage"],
                limit="1 per 5 minutes",
                identifiers=["foo"],
            )
        ]
Example #9
0
    def test_basic(self, pyramid_request, metrics):
        limiter_obj = pretend.stub()
        limiter_class = pretend.call_recorder(lambda *a, **kw: limiter_obj)

        context = pretend.stub()
        pyramid_request.registry["ratelimiter.storage"] = pretend.stub()

        result = RateLimit("1 per 5 minutes",
                           identifiers=["foo"],
                           limiter_class=limiter_class)(context,
                                                        pyramid_request)

        assert result is limiter_obj
        assert limiter_class.calls == [
            pretend.call(
                pyramid_request.registry["ratelimiter.storage"],
                limit="1 per 5 minutes",
                identifiers=["foo"],
                metrics=metrics,
            )
        ]
Example #10
0
def includeme(config):
    # Register our login service
    config.register_service_factory(database_login_factory, IUserService)

    # Register our token services
    config.register_service_factory(TokenServiceFactory(name="password"),
                                    ITokenService,
                                    name="password")
    config.register_service_factory(TokenServiceFactory(name="email"),
                                    ITokenService,
                                    name="email")
    config.register_service_factory(TokenServiceFactory(name="two_factor"),
                                    ITokenService,
                                    name="two_factor")

    # Register our password breach detection service.
    breached_pw_class = config.maybe_dotted(
        config.registry.settings.get("breached_passwords.backend",
                                     HaveIBeenPwnedPasswordBreachedService))
    config.register_service_factory(breached_pw_class.create_service,
                                    IPasswordBreachedService)

    # Register our security policies (AuthN + AuthZ)
    authz_policy = TwoFactorAuthorizationPolicy(
        policy=MacaroonAuthorizationPolicy(policy=ACLAuthorizationPolicy()))
    config.set_security_policy(
        MultiSecurityPolicy(
            [
                SessionSecurityPolicy(),
                BasicAuthSecurityPolicy(),
                MacaroonSecurityPolicy(),
            ],
            authz_policy,
        ))

    # Add a request method which will allow people to access the user object.
    config.add_request_method(_user, name="user", reify=True)

    # Register the rate limits that we're going to be using for our login
    # attempts and account creation
    user_login_ratelimit_string = config.registry.settings.get(
        "warehouse.account.user_login_ratelimit_string")
    config.register_service_factory(RateLimit(user_login_ratelimit_string),
                                    IRateLimiter,
                                    name="user.login")
    ip_login_ratelimit_string = config.registry.settings.get(
        "warehouse.account.ip_login_ratelimit_string")
    config.register_service_factory(RateLimit(ip_login_ratelimit_string),
                                    IRateLimiter,
                                    name="ip.login")
    global_login_ratelimit_string = config.registry.settings.get(
        "warehouse.account.global_login_ratelimit_string")
    config.register_service_factory(RateLimit(global_login_ratelimit_string),
                                    IRateLimiter,
                                    name="global.login")
    email_add_ratelimit_string = config.registry.settings.get(
        "warehouse.account.email_add_ratelimit_string")
    config.register_service_factory(RateLimit(email_add_ratelimit_string),
                                    IRateLimiter,
                                    name="email.add")
    password_reset_ratelimit_string = config.registry.settings.get(
        "warehouse.account.password_reset_ratelimit_string")
    config.register_service_factory(RateLimit(password_reset_ratelimit_string),
                                    IRateLimiter,
                                    name="password.reset")
Example #11
0
def test_includeme(monkeypatch):
    authz_obj = pretend.stub()
    authz_cls = pretend.call_recorder(lambda *a, **kw: authz_obj)
    monkeypatch.setattr(accounts, "ACLAuthorizationPolicy", authz_cls)
    monkeypatch.setattr(accounts, "MacaroonAuthorizationPolicy", authz_cls)
    monkeypatch.setattr(accounts, "TwoFactorAuthorizationPolicy", authz_cls)

    multi_policy_obj = pretend.stub()
    multi_policy_cls = pretend.call_recorder(
        lambda ps, authz: multi_policy_obj)
    monkeypatch.setattr(accounts, "MultiSecurityPolicy", multi_policy_cls)

    session_policy_obj = pretend.stub()
    session_policy_cls = pretend.call_recorder(lambda: session_policy_obj)
    monkeypatch.setattr(accounts, "SessionSecurityPolicy", session_policy_cls)

    basic_policy_obj = pretend.stub()
    basic_policy_cls = pretend.call_recorder(lambda: basic_policy_obj)
    monkeypatch.setattr(accounts, "BasicAuthSecurityPolicy", basic_policy_cls)

    macaroon_policy_obj = pretend.stub()
    macaroon_policy_cls = pretend.call_recorder(lambda: macaroon_policy_obj)
    monkeypatch.setattr(accounts, "MacaroonSecurityPolicy",
                        macaroon_policy_cls)

    config = pretend.stub(
        registry=pretend.stub(
            settings={
                "warehouse.account.user_login_ratelimit_string":
                "10 per 5 minutes",
                "warehouse.account.ip_login_ratelimit_string":
                "10 per 5 minutes",
                "warehouse.account.global_login_ratelimit_string":
                "1000 per 5 minutes",
                "warehouse.account.email_add_ratelimit_string": "2 per day",
                "warehouse.account.password_reset_ratelimit_string":
                "5 per day",
            }),
        register_service_factory=pretend.call_recorder(
            lambda factory, iface, name=None: None),
        add_request_method=pretend.call_recorder(lambda f, name, reify: None),
        set_security_policy=pretend.call_recorder(lambda p: None),
        maybe_dotted=pretend.call_recorder(lambda path: path),
        add_route_predicate=pretend.call_recorder(lambda name, cls: None),
    )

    accounts.includeme(config)

    assert config.register_service_factory.calls == [
        pretend.call(database_login_factory, IUserService),
        pretend.call(TokenServiceFactory(name="password"),
                     ITokenService,
                     name="password"),
        pretend.call(TokenServiceFactory(name="email"),
                     ITokenService,
                     name="email"),
        pretend.call(TokenServiceFactory(name="two_factor"),
                     ITokenService,
                     name="two_factor"),
        pretend.call(
            HaveIBeenPwnedPasswordBreachedService.create_service,
            IPasswordBreachedService,
        ),
        pretend.call(RateLimit("10 per 5 minutes"),
                     IRateLimiter,
                     name="user.login"),
        pretend.call(RateLimit("10 per 5 minutes"),
                     IRateLimiter,
                     name="ip.login"),
        pretend.call(RateLimit("1000 per 5 minutes"),
                     IRateLimiter,
                     name="global.login"),
        pretend.call(RateLimit("2 per day"), IRateLimiter, name="email.add"),
        pretend.call(RateLimit("5 per day"),
                     IRateLimiter,
                     name="password.reset"),
    ]
    assert config.add_request_method.calls == [
        pretend.call(accounts._user, name="user", reify=True)
    ]
    assert config.set_security_policy.calls == [pretend.call(multi_policy_obj)]
    assert multi_policy_cls.calls == [
        pretend.call(
            [session_policy_obj, basic_policy_obj, macaroon_policy_obj],
            authz_obj)
    ]