Skip to content

Commit

Permalink
Merge pull request #146 from bento-platform/chore/auth/dedup-resource…
Browse files Browse the repository at this point in the history
…-everything

chore(auth)!: rm dup. everything resource const, use Permission types
  • Loading branch information
davidlougheed authored Nov 20, 2023
2 parents c5d35c7 + 22d1d2f commit fe3dca1
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 39 deletions.
24 changes: 14 additions & 10 deletions bento_lib/auth/middleware/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing import Any, Callable, Iterable

from ..exceptions import BentoAuthException
from ..permissions import Permission
from ..types import EvaluationResultMatrix, EvaluationResultDict
from .mark_authz_done_mixin import MarkAuthzDoneMixin

Expand Down Expand Up @@ -94,22 +95,25 @@ def authz_post(
return res.json()

@staticmethod
def _evaluate_body(resources: Iterable[dict], permissions: Iterable[str]) -> dict:
def _evaluate_body(resources: Iterable[dict], permissions: Iterable[Permission]) -> dict:
return {"resources": tuple(resources), "permissions": tuple(permissions)}

@staticmethod
def _matrix_tuple_cast(authz_result: list[list[bool]]) -> EvaluationResultMatrix:
return tuple(tuple(x) for x in authz_result)

@staticmethod
def _permissions_matrix_to_dict(m: EvaluationResultMatrix, permissions: Iterable[str]) -> EvaluationResultDict:
def _permissions_matrix_to_dict(
m: EvaluationResultMatrix,
permissions: Iterable[Permission],
) -> EvaluationResultDict:
return tuple({p: pv for p, pv in zip(permissions, r)} for r in m)

def evaluate(
self,
request: Any,
resources: Iterable[dict],
permissions: Iterable[str],
permissions: Iterable[Permission],
require_token: bool = False,
headers_getter: Callable[[Any], dict[str, str]] | None = None,
mark_authz_done: bool = False,
Expand All @@ -130,7 +134,7 @@ def evaluate_to_dict(
self,
request: Any,
resources: Iterable[dict],
permissions: Iterable[str],
permissions: Iterable[Permission],
require_token: bool = False,
headers_getter: Callable[[Any], dict[str, str]] | None = None,
mark_authz_done: bool = False,
Expand All @@ -144,7 +148,7 @@ def evaluate_one(
self,
request: Any,
resource: dict,
permission: str,
permission: Permission,
require_token: bool = False,
headers_getter: Callable[[Any], dict[str, str]] | None = None,
mark_authz_done: bool = False,
Expand Down Expand Up @@ -175,7 +179,7 @@ async def async_evaluate(
self,
request: Any,
resources: Iterable[dict],
permissions: Iterable[str],
permissions: Iterable[Permission],
require_token: bool = False,
headers_getter: Callable[[Any], dict[str, str]] | None = None,
mark_authz_done: bool = False,
Expand All @@ -198,7 +202,7 @@ async def async_evaluate_to_dict(
self,
request: Any,
resources: Iterable[dict],
permissions: Iterable[str],
permissions: Iterable[Permission],
require_token: bool = False,
headers_getter: Callable[[Any], dict[str, str]] | None = None,
mark_authz_done: bool = False,
Expand All @@ -213,7 +217,7 @@ async def async_evaluate_one(
self,
request: Any,
resource: dict,
permission: str,
permission: Permission,
require_token: bool = False,
headers_getter: Callable[[Any], dict[str, str]] | None = None,
mark_authz_done: bool = False,
Expand All @@ -227,7 +231,7 @@ async def async_evaluate_one(
def check_authz_evaluate(
self,
request: Any,
permissions: frozenset[str],
permissions: frozenset[Permission],
resource: dict,
require_token: bool = True,
set_authz_flag: bool = False,
Expand All @@ -253,7 +257,7 @@ def check_authz_evaluate(
async def async_check_authz_evaluate(
self,
request: Any,
permissions: frozenset[str],
permissions: frozenset[Permission],
resource: dict,
require_token: bool = True,
set_authz_flag: bool = False,
Expand Down
1 change: 0 additions & 1 deletion bento_lib/auth/middleware/constants.py

This file was deleted.

5 changes: 3 additions & 2 deletions bento_lib/auth/middleware/fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from bento_lib.responses.errors import http_error
from bento_lib.auth.exceptions import BentoAuthException
from bento_lib.auth.middleware.base import BaseAuthMiddleware
from bento_lib.auth.middleware.constants import RESOURCE_EVERYTHING
from bento_lib.auth.permissions import Permission
from bento_lib.auth.resources import RESOURCE_EVERYTHING

__all__ = [
"FastApiAuthMiddleware",
Expand Down Expand Up @@ -74,7 +75,7 @@ def _inner(request: Request):

def dep_require_permissions_on_resource(
self,
permissions: frozenset[str],
permissions: frozenset[Permission],
resource: dict | None = None,
require_token: bool = True,
set_authz_flag: bool = True,
Expand Down
5 changes: 3 additions & 2 deletions bento_lib/auth/middleware/flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

from bento_lib.auth.exceptions import BentoAuthException
from bento_lib.auth.middleware.base import BaseAuthMiddleware
from bento_lib.auth.middleware.constants import RESOURCE_EVERYTHING
from bento_lib.auth.permissions import Permission
from bento_lib.auth.resources import RESOURCE_EVERYTHING
from bento_lib.responses.errors import http_error

__all__ = [
Expand Down Expand Up @@ -75,7 +76,7 @@ def get_authz_header_value(self, r: Request) -> str | None:

def deco_require_permissions_on_resource(
self,
permissions: frozenset[str],
permissions: frozenset[Permission],
resource: dict | None = None,
require_token: bool = True,
set_authz_flag: bool = True,
Expand Down
4 changes: 0 additions & 4 deletions tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from bento_lib import workflows

__all__ = [
"PERMISSION_INGEST_DATA",
"authz_test_case_params",
"authz_test_cases",
"TEST_AUTHZ_VALID_POST_BODY",
Expand All @@ -12,9 +11,6 @@
"WORKFLOW_DEF",
]


PERMISSION_INGEST_DATA = "ingest:data"

# cases: (authz response code, authz response result, test client URL, auth header included, assert final response)
authz_test_case_params = "authz_code, authz_res, test_url, inc_headers, test_code"
authz_test_cases = (
Expand Down
11 changes: 5 additions & 6 deletions tests/django_test_project/test_app/views.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import json
from bento_lib.auth.middleware.constants import RESOURCE_EVERYTHING
from bento_lib.auth.resources import RESOURCE_EVERYTHING
from bento_lib.auth.permissions import P_INGEST_DATA
from django.http import HttpRequest, JsonResponse

from ..django_test_project.authz import authz

PERMISSION_INGEST_DATA = "ingest:data"


def auth_post_public(request: HttpRequest):
authz.mark_authz_done(request)
Expand All @@ -15,7 +14,7 @@ def auth_post_public(request: HttpRequest):
def auth_post_private(request: HttpRequest):
authz.check_authz_evaluate(
request,
frozenset({PERMISSION_INGEST_DATA}),
frozenset({P_INGEST_DATA}),
RESOURCE_EVERYTHING,
require_token=True,
set_authz_flag=True,
Expand All @@ -26,7 +25,7 @@ def auth_post_private(request: HttpRequest):
def auth_post_private_no_flag(request: HttpRequest):
authz.check_authz_evaluate(
request,
frozenset({PERMISSION_INGEST_DATA}),
frozenset({P_INGEST_DATA}),
RESOURCE_EVERYTHING,
require_token=True,
set_authz_flag=False,
Expand All @@ -38,7 +37,7 @@ def auth_post_private_no_flag(request: HttpRequest):
def auth_post_private_no_token(request: HttpRequest):
authz.check_authz_evaluate(
request,
frozenset({PERMISSION_INGEST_DATA}),
frozenset({P_INGEST_DATA}),
RESOURCE_EVERYTHING,
require_token=False,
set_authz_flag=True,
Expand Down
7 changes: 3 additions & 4 deletions tests/test_platform_fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
from pydantic import BaseModel

from bento_lib.auth.exceptions import BentoAuthException
from bento_lib.auth.middleware.constants import RESOURCE_EVERYTHING
from bento_lib.auth.middleware.fastapi import FastApiAuthMiddleware
from bento_lib.auth.permissions import P_INGEST_DATA
from bento_lib.auth.resources import RESOURCE_EVERYTHING
from bento_lib.responses.fastapi_errors import (
http_exception_handler_factory,
bento_auth_exception_handler_factory,
Expand All @@ -24,7 +24,6 @@
from bento_lib.workflows.fastapi import build_workflow_router

from .common import (
PERMISSION_INGEST_DATA,
authz_test_case_params,
authz_test_cases,
TEST_AUTHZ_VALID_POST_BODY,
Expand Down Expand Up @@ -157,7 +156,7 @@ async def auth_post_with_token_in_body(request: Request, body: TestTokenPayloadB
token = body.token
await auth_middleware.async_check_authz_evaluate(
request,
frozenset({PERMISSION_INGEST_DATA}),
frozenset({P_INGEST_DATA}),
RESOURCE_EVERYTHING,
require_token=True,
set_authz_flag=True,
Expand Down Expand Up @@ -365,7 +364,7 @@ async def test_fastapi_auth_disabled(aioresponse: aioresponses, fastapi_client_a

assert await auth_middleware_disabled.async_check_authz_evaluate(
Request({"type": "http"}),
frozenset({PERMISSION_INGEST_DATA}),
frozenset({P_INGEST_DATA}),
{"everything": True},
) is None

Expand Down
20 changes: 10 additions & 10 deletions tests/test_platform_flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
from flask.testing import FlaskClient
from werkzeug.exceptions import BadRequest, NotFound, InternalServerError

from bento_lib.auth.middleware.constants import RESOURCE_EVERYTHING
from bento_lib.auth.middleware.flask import FlaskAuthMiddleware
from bento_lib.auth.permissions import P_INGEST_DATA
from bento_lib.auth.resources import RESOURCE_EVERYTHING

from .common import (
PERMISSION_INGEST_DATA,
authz_test_case_params,
authz_test_cases,
TEST_AUTHZ_VALID_POST_BODY,
Expand Down Expand Up @@ -73,18 +73,18 @@ def auth_post_public():
return jsonify(request.json)

@test_app_auth.route("/post-private", methods=["POST"])
@auth_middleware.deco_require_permissions_on_resource(frozenset({PERMISSION_INGEST_DATA}))
@auth_middleware.deco_require_permissions_on_resource(frozenset({P_INGEST_DATA}))
def auth_post_private():
return jsonify(request.json)

@test_app_auth.route("/post-private-no-flag", methods=["POST"])
@auth_middleware.deco_require_permissions_on_resource(frozenset({PERMISSION_INGEST_DATA}), set_authz_flag=False)
@auth_middleware.deco_require_permissions_on_resource(frozenset({P_INGEST_DATA}), set_authz_flag=False)
def auth_post_private_no_flag():
auth_middleware.mark_authz_done(request)
return jsonify(request.json)

@test_app_auth.route("/post-private-no-token", methods=["POST"])
@auth_middleware.deco_require_permissions_on_resource(frozenset({PERMISSION_INGEST_DATA}), require_token=False)
@auth_middleware.deco_require_permissions_on_resource(frozenset({P_INGEST_DATA}), require_token=False)
def auth_post_private_no_token():
return jsonify(request.json)

Expand All @@ -106,7 +106,7 @@ def auth_post_with_token_in_body():
payload = request.json["payload"]
auth_middleware.check_authz_evaluate(
request,
frozenset({PERMISSION_INGEST_DATA}),
frozenset({P_INGEST_DATA}),
RESOURCE_EVERYTHING,
require_token=True,
set_authz_flag=True,
Expand All @@ -122,7 +122,7 @@ def auth_post_with_token_evaluate_one():
return jsonify({"payload": auth_middleware.evaluate_one(
request,
RESOURCE_EVERYTHING,
PERMISSION_INGEST_DATA,
P_INGEST_DATA,
require_token=True,
headers_getter=(lambda _r: {"Authorization": f"Bearer {token}"}),
)})
Expand All @@ -135,7 +135,7 @@ def auth_post_with_token_evaluate__to_dict():
return jsonify({"payload": auth_middleware.evaluate_to_dict(
request,
(RESOURCE_EVERYTHING,),
(PERMISSION_INGEST_DATA,),
(P_INGEST_DATA,),
require_token=True,
headers_getter=(lambda _r: {"Authorization": f"Bearer {token}"}),
)})
Expand Down Expand Up @@ -163,7 +163,7 @@ def auth_disabled_post_public():
return jsonify(request.json)

@test_app_auth_disabled.route("/post-private", methods=["POST"])
@auth_middleware_disabled.deco_require_permissions_on_resource(frozenset({PERMISSION_INGEST_DATA}))
@auth_middleware_disabled.deco_require_permissions_on_resource(frozenset({P_INGEST_DATA}))
def auth_disabled_post_private():
return jsonify(request.json)

Expand Down Expand Up @@ -293,6 +293,6 @@ def test_flask_auth_disabled(flask_client_auth_disabled_with_middleware: tuple[F

assert auth_middleware_disabled.check_authz_evaluate(
Request({}),
frozenset({PERMISSION_INGEST_DATA}),
frozenset({P_INGEST_DATA}),
{"everything": True},
) is None

0 comments on commit fe3dca1

Please sign in to comment.