Пример #1
0
def _app_oso():
    """Get the flask oso plugin for the current app instance."""
    try:
        return _app_context().oso_flask_oso
    except AttributeError:
        raise OsoError("No oso instance on current application. "
                       "Did you forget to call init_app?")
Пример #2
0
def _app_context():
    """Get the app context. Use this instead of direct access to raise an appropriate error"""
    top = _app_ctx_stack.top
    if top is None:
        raise OsoError(
            "Application context doesn't exist. Did you use oso outside the context of a request? "
            "See https://flask.palletsprojects.com/en/1.1.x/appcontext/#manually-push-a-context"
        )

    return top
Пример #3
0
    def middleware(request):
        response = get_response(request)
        if response.status_code in WHITELIST_STATUSES_DEFAULT:
            return response

        # Ensure authorization occurred.
        if not request_authorized(request):
            raise OsoError(
                "authorize was not called during processing request.")

        return response
Пример #4
0
    def _require_authorization(self, response):
        if not request.url_rule:
            # No rule matched this request
            # Skip requiring authorization.
            # NOTE: (dhatch) Confirm this is a safe behavior, think through edge
            # cases.
            return response

        if not getattr(_app_context(), "oso_flask_authorize_called", False):
            raise OsoError("Authorize not called.")

        return response
Пример #5
0
    def authorize(self, resource, *, actor=None, action=None):
        """Check whether the current request should be allowed.

        Calls :py:meth:`oso.Oso.is_allowed` to check authorization. If a request
        is unauthorized, raises a ``werkzeug.exceptions.Forbidden``
        exception.  This behavior can be controlled with
        :py:meth:`set_unauthorized_action`.

        :param actor: The actor to authorize. Defaults to ``flask.g.current_user``.
                      Use :py:meth:`set_get_actor` to override.
        :param action: The action to authorize. Defaults to
                       ``flask.request.method``.
        :param resource: The resource to authorize.  The flask request object
                         (``flask.request``) can be passed to authorize a
                         request based on route path or other request properties.

        See also: :py:func:`flask_oso.authorize` for a route decorator version.
        """
        if actor is None:
            try:
                actor = self.current_actor
            except AttributeError as e:
                raise OsoError(
                    "Getting the current actor failed. "
                    "You may need to override the current actor function with "
                    "FlaskOso#set_get_actor"
                ) from e

        if action is None:
            action = request.method

        # TODO (dhatch): Broader resource mapping functionality?
        # Special handling for flask request as a resource.
        # We use *is* here because == would actually need to get the request object.
        # We want to check that the resource is the proxy.
        if resource is request:
            resource = request._get_current_object()

        allowed = self.oso.is_allowed(actor, action, resource)
        _authorize_called()

        if not allowed:
            self._unauthorized_action()