Пример #1
0
    def __init__(self, proxy_auth=False):
        """
        Initialise a security policy.

        :param proxy_auth: Replace the default `CookiePolicy` for the UI with
            the `RemoteUserPolicy`.
        """
        self._bearer_token_policy = BearerTokenPolicy()
        self._http_basic_auth_policy = AuthClientPolicy()
        self._identity_cache = RequestLocalCache(self._load_identity)

        self._ui_policy = RemoteUserPolicy() if proxy_auth else CookiePolicy()
Пример #2
0
    def test_identify_without_forwarded_user(self, pyramid_request,
                                             auth_client):
        pyramid_request.headers["X-Forwarded-User"] = None

        identity = AuthClientPolicy().identity(pyramid_request)

        assert identity == Identity.from_models(auth_client=auth_client)
Пример #3
0
    def test_identity(self, pyramid_request, auth_client, user_service):
        pyramid_request.headers["X-Forwarded-User"] = sentinel.forwarded_user

        identity = AuthClientPolicy().identity(pyramid_request)

        user_service.fetch.assert_called_once_with(sentinel.forwarded_user)
        assert identity == Identity.from_models(
            auth_client=auth_client, user=user_service.fetch.return_value)
Пример #4
0
    def test_identify_returns_None_if_forwarded_userid_is_invalid(
            self, user_service, pyramid_request):
        user_service.fetch.side_effect = InvalidUserId(sentinel.invalid_id)

        assert AuthClientPolicy().identity(pyramid_request) is None
Пример #5
0
    def test_identify_returns_None_if_forwarded_user_is_not_found(
            self, user_service, pyramid_request):
        user_service.fetch.return_value = None

        assert AuthClientPolicy().identity(pyramid_request) is None
Пример #6
0
    def test_identify_returns_None_if_auth_client_secrets_do_not_match(
            self, auth_client, pyramid_request):
        self.set_http_credentials(pyramid_request, auth_client.id,
                                  "WRONG SECRET")

        assert AuthClientPolicy().identity(pyramid_request) is None
Пример #7
0
    def test_identify_returns_None_if_auth_client_secret_is_None(
            self, auth_client, pyramid_request):
        auth_client.secret = None

        assert AuthClientPolicy().identity(pyramid_request) is None
Пример #8
0
    def test_identify_returns_None_if_auth_client_not_client_type(
            self, auth_client, pyramid_request):
        auth_client.grant_type = None

        assert AuthClientPolicy().identity(pyramid_request) is None
Пример #9
0
    def test_identify_returns_None_if_auth_client_not_secret(
            self, auth_client, pyramid_request):
        self.set_http_credentials(pyramid_request, "NOT A UUID",
                                  auth_client.secret)

        assert AuthClientPolicy().identity(pyramid_request) is None
Пример #10
0
    def test_identity_returns_None_if_auth_client_missing(
            self, pyramid_request, auth_client, db_session):
        db_session.delete(auth_client)
        db_session.flush()

        assert AuthClientPolicy().identity(pyramid_request) is None
Пример #11
0
    def test_identity_returns_None_without_credentials(self, pyramid_request):
        pyramid_request.headers["Authorization"] = None

        assert AuthClientPolicy().identity(pyramid_request) is None
Пример #12
0
    def test_handles_rejects_no_route(self, pyramid_request):
        pyramid_request.matched_route = None

        assert not AuthClientPolicy.handles(pyramid_request)
Пример #13
0
    def test_handles_rejects_unknown_routes(self, pyramid_request):
        pyramid_request.matched_route.name = "not.recognised"

        assert not AuthClientPolicy.handles(pyramid_request)
Пример #14
0
    def test_handles(self, pyramid_request, route_name, method):
        pyramid_request.matched_route.name = route_name
        pyramid_request.method = method

        assert AuthClientPolicy.handles(pyramid_request)
Пример #15
0
    def test_identify_returns_None_on_forwarded_userid_authority_mismatch(
            self, user, auth_client, pyramid_request):
        user.authority = "not" + auth_client.authority

        assert AuthClientPolicy().identity(pyramid_request) is None
Пример #16
0
class SecurityPolicy(IdentityBasedPolicy):
    """
    The security policy for `h`.

    This delegates to various different policies depending on the situation.
    """
    def __init__(self, proxy_auth=False):
        """
        Initialise a security policy.

        :param proxy_auth: Replace the default `CookiePolicy` for the UI with
            the `RemoteUserPolicy`.
        """
        self._bearer_token_policy = BearerTokenPolicy()
        self._http_basic_auth_policy = AuthClientPolicy()
        self._identity_cache = RequestLocalCache(self._load_identity)

        self._ui_policy = RemoteUserPolicy() if proxy_auth else CookiePolicy()

    def remember(self, request, userid, **kw):
        """Get the correct headers to remember the given user."""

        self._identity_cache.clear(request)

        return self._call_sub_policies("remember", request, userid, **kw)

    def forget(self, request):
        """Get the correct headers to forget the current login."""

        self._identity_cache.clear(request)

        return self._call_sub_policies("forget", request)

    def identity(self, request) -> Optional[Identity]:
        """
        Get an Identity object for valid credentials.

        :param request: Pyramid request to inspect
        """
        return self._identity_cache.get_or_create(request)

    def _load_identity(self, request):
        return self._call_sub_policies("identity", request)

    def _call_sub_policies(self, method, request, *args, **kwargs):
        """
        Delegate calls to the correct set of security policies.

        :param method: Method to call (like `identity()` or `forget()`)
        :param request: Pyramid request object
        :param args: Args to pass to the method
        :param kwargs: Kwargs to pass to the method
        :return: The response from the correct sub-policy
        """

        if not self._is_api_request(request):
            # This is usually the cookie policy for UI things
            return getattr(self._ui_policy, method)(request, *args, **kwargs)

        # Then we try the bearer header (or `access_token` GET param)
        result = getattr(self._bearer_token_policy, method)(request, *args,
                                                            **kwargs)

        if not result and self._http_basic_auth_policy.handles(request):
            # Only then do we look for auth clients authenticating with basic
            # HTTP auth credentials
            return getattr(self._http_basic_auth_policy,
                           method)(request, *args, **kwargs)

        return result

    @staticmethod
    def _is_api_request(request):
        return request.path.startswith("/api") and request.path not in [
            "/api/token",
            "/api/badge",
        ]