Skip to content

Commit

Permalink
Merge pull request #224 from bento-platform/feat/auth/build-authz-fro…
Browse files Browse the repository at this point in the history
…m-fastapi-config

feat(auth): build authz middlware from FastAPI config
  • Loading branch information
davidlougheed authored Aug 20, 2024
2 parents 240d923 + ba70ef1 commit b4b4adf
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
20 changes: 20 additions & 0 deletions bento_lib/auth/middleware/fastapi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import re

from fastapi import Depends, FastAPI, Request, Response, status
from fastapi.responses import JSONResponse
Expand All @@ -8,6 +9,7 @@
from bento_lib.auth.middleware.base import BaseAuthMiddleware
from bento_lib.auth.permissions import Permission
from bento_lib.auth.resources import RESOURCE_EVERYTHING
from bento_lib.config.pydantic import BentoFastAPIBaseConfig
from bento_lib.responses.errors import http_error

__all__ = [
Expand All @@ -16,6 +18,24 @@


class FastApiAuthMiddleware(BaseAuthMiddleware):
@classmethod
def build_from_fastapi_pydantic_config(cls, config: BentoFastAPIBaseConfig, logger: logging.Logger, **kwargs):
"""
Build a FastAPI authorization middlware instance from a Bento Pydantic FastAPI config instance and a logger
instance. This automatically exempts the FastAPI-generated docs OpenAPI schema paths from requiring
authorization.
:param config: instance of the FastAPI subclass of the Bento Pydantic config class.
:param logger: A Python logger to instantiate the FastAPI authorization middlware with.
:param kwargs: Keyword arguments to pass to the FastAPI authorization middleware constructor.
:return: An instance of the authorization middleware.
"""
exempt_request_patterns = (
(r"GET", re.escape(config.service_docs_path)),
(r"GET", re.escape(config.service_openapi_path)),
*kwargs.pop("exempt_request_patterns", ()),
)
return cls.build_from_pydantic_config(config, logger, exempt_request_patterns=exempt_request_patterns, **kwargs)

def attach(self, app: FastAPI):
"""
Attach the middleware to an application. Must be called in order for requests to be checked.
Expand Down
14 changes: 13 additions & 1 deletion tests/test_platform_fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def get_403():
bento_authz_service_url="https://bento-auth.local",
cors_origins=("*",),
)
auth_middleware = FastApiAuthMiddleware.build_from_pydantic_config(
auth_middleware = FastApiAuthMiddleware.build_from_fastapi_pydantic_config(
app_test_auth_config,
logger,
include_request_patterns=authz_test_include_patterns,
Expand Down Expand Up @@ -327,6 +327,18 @@ def test_fastapi_auth_public(fastapi_client_auth: TestClient):
rd2 = r.json()
assert rd == rd2

# can get the FastAPI docs
r = fastapi_client_auth.get("/docs")
assert r.status_code == 200

# can get the OpenAPI schema
r = fastapi_client_auth.get("/openapi.json")
assert r.status_code == 200

# can post to the exempted post endpoint
r = fastapi_client_auth.post("/post-exempted", json=TEST_AUTHZ_VALID_POST_BODY)
assert r.status_code == 200

# can post to the public post endpoint
r = fastapi_client_auth.post("/post-public", json=TEST_AUTHZ_VALID_POST_BODY)
assert r.status_code == 200
Expand Down

0 comments on commit b4b4adf

Please sign in to comment.