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?")
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
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
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
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()