예제 #1
0
class MySecurityPolicy:
    def __init__(self, secret):
        self.authtkt = AuthTktCookieHelper(secret)
        self.identity_cache = RequestLocalCache(self.load_identity)

    def load_identity(self, request):
        identity = self.authtkt.identify(request)
        if identity is None:
            return None

        userid = identity['userid']
        user = request.dbsession.query(models.User).get(userid)
        return user

    def identity(self, request):
        return self.identity_cache.get_or_create(request)

    def authenticated_userid(self, request):
        user = self.identity(request)
        if user is not None:
            return user.id

    def remember(self, request, userid, **kw):
        return self.authtkt.remember(request, userid, **kw)

    def forget(self, request, **kw):
        return self.authtkt.forget(request, **kw)
예제 #2
0
class BearerTokenPolicy(IdentityBasedPolicy):
    """
    A Bearer token authentication policy.

    This policy uses a bearer token which is validated against Token objects
    in the DB. This can come from the Bearer token header or in the case of
    Websocket requests with the GET parameter `access_token`.

    We use this for our API and Websocket requests.
    """

    def __init__(self):
        self._identity_cache = RequestLocalCache(self._load_identity)

    def identity(self, request):
        """
        Get an Identity object for valid credentials.

        Validate the token from the request by matching them to Token records
        in the DB.

        :param request: Pyramid request to inspect
        :returns: An `Identity` object if the login is authenticated or None
        """

        return self._identity_cache.get_or_create(request)

    def _load_identity(self, request):
        token_svc = request.find_service(name="auth_token")
        token_str = None

        # We only ever want to read the access token from GET parameters for
        # websocket requests
        if self._is_ws_request(request):
            token_str = request.GET.get("access_token", None)

        # We currently only accept a real bearer token in our API calls, but
        # it's conceivable the WS spec will one day change to accept this:
        # See: https://github.com/whatwg/html/issues/3062
        if token_str is None:
            token_str = token_svc.get_bearer_token(request)

        if token_str is None:
            return None

        token = token_svc.validate(token_str)
        if token is None:
            return None

        user = request.find_service(name="user").fetch(token.userid)
        if user is None:
            return None

        return Identity.from_models(user=user)

    @staticmethod
    def _is_ws_request(request):
        return request.path == "/ws"
예제 #3
0
class MySecurityPolicy:
    def __init__(self, secret):
        self.authtkt = AuthTktCookieHelper(secret)
        self.identity_cache = RequestLocalCache(self.load_identity)
        self.acl = ACLHelper()

    def load_identity(self, request):
        identity = self.authtkt.identify(request)
        if identity is None:
            return None

        userid = identity['userid']
        user = request.dbsession.query(models.User).get(userid)
        return user

    def identity(self, request):
        return self.identity_cache.get_or_create(request)

    def authenticated_userid(self, request):
        user = self.identity(request)
        if user is not None:
            return user.id

    def remember(self, request, userid, **kw):
        return self.authtkt.remember(request, userid, **kw)

    def forget(self, request, **kw):
        return self.authtkt.forget(request, **kw)

    def permits(self, request, context, permission):
        principals = self.effective_principals(request)
        return self.acl.permits(context, principals, permission)

    def effective_principals(self, request):
        principals = [Everyone]
        user = self.identity(request)
        if user is not None:
            principals.append(Authenticated)
            principals.append('u:' + str(user.id))
            principals.append('role:' + user.role)
        return principals
예제 #4
0
파일: combined.py 프로젝트: kaydoh/h
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",
        ]