feat: improved caor request model
All checks were successful
ci / lint_and_test (push) Successful in 14s
All checks were successful
ci / lint_and_test (push) Successful in 14s
Issue: #23
This commit is contained in:
parent
768a3881ef
commit
939abaefe9
4 changed files with 44 additions and 17 deletions
|
|
@ -24,7 +24,6 @@ from src.organisation.exceptions import OrgNotFoundException
|
||||||
from src.service.exceptions import ServiceNotFoundException
|
from src.service.exceptions import ServiceNotFoundException
|
||||||
from src.exceptions import ConflictException
|
from src.exceptions import ConflictException
|
||||||
from src.database import db_dependency
|
from src.database import db_dependency
|
||||||
from src.schemas import ResourceName
|
|
||||||
from src.auth.exceptions import UnauthorizedException
|
from src.auth.exceptions import UnauthorizedException
|
||||||
from src.auth.service import claims_dependency
|
from src.auth.service import claims_dependency
|
||||||
from src.auth.dependencies import (
|
from src.auth.dependencies import (
|
||||||
|
|
@ -55,10 +54,11 @@ from src.iam.dependencies import (
|
||||||
perm_model_query_dependency,
|
perm_model_query_dependency,
|
||||||
)
|
)
|
||||||
from src.iam.schemas import (
|
from src.iam.schemas import (
|
||||||
|
GroupSchema,
|
||||||
|
IAMCAoRRequest,
|
||||||
IAMGetGroupPermissionsResponse,
|
IAMGetGroupPermissionsResponse,
|
||||||
IAMGetGroupUsersResponse,
|
IAMGetGroupUsersResponse,
|
||||||
IAMPostGroupRequest,
|
IAMPostGroupRequest,
|
||||||
GroupSchema,
|
|
||||||
IAMPostGroupResponse,
|
IAMPostGroupResponse,
|
||||||
IAMPutGroupPermissionRequest,
|
IAMPutGroupPermissionRequest,
|
||||||
IAMPutGroupPermissionResponse,
|
IAMPutGroupPermissionResponse,
|
||||||
|
|
@ -87,10 +87,11 @@ async def can_act_on_resource(
|
||||||
valid_key: service_key_dependency,
|
valid_key: service_key_dependency,
|
||||||
db: db_dependency,
|
db: db_dependency,
|
||||||
user_claims: claims_dependency,
|
user_claims: claims_dependency,
|
||||||
rn: ResourceName,
|
request_model: IAMCAoRRequest,
|
||||||
action: str,
|
|
||||||
) -> bool:
|
) -> bool:
|
||||||
try:
|
try:
|
||||||
|
rn = request_model.rn
|
||||||
|
action = request_model.action
|
||||||
user_id = user_claims["db_id"]
|
user_id = user_claims["db_id"]
|
||||||
rn_org = rn.organisation
|
rn_org = rn.organisation
|
||||||
rn_service = rn.service
|
rn_service = rn.service
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ from pydantic import EmailStr, ConfigDict, Field
|
||||||
|
|
||||||
from src.schemas import (
|
from src.schemas import (
|
||||||
CustomBaseModel,
|
CustomBaseModel,
|
||||||
|
ResourceName,
|
||||||
ServiceIDMixin,
|
ServiceIDMixin,
|
||||||
OrgIDMixin,
|
OrgIDMixin,
|
||||||
UserIDMixin,
|
UserIDMixin,
|
||||||
|
|
@ -43,6 +44,11 @@ class GroupSchema(CustomBaseModel):
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
|
class IAMCAoRRequest(CustomBaseModel):
|
||||||
|
action: str
|
||||||
|
rn: ResourceName
|
||||||
|
|
||||||
|
|
||||||
class IAMGetGroupPermissionsResponse(CustomBaseModel):
|
class IAMGetGroupPermissionsResponse(CustomBaseModel):
|
||||||
permissions: list[PermissionSchema]
|
permissions: list[PermissionSchema]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ Exports:
|
||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
|
|
||||||
|
from src.iam.schemas import IAMCAoRRequest
|
||||||
from src.service.models import Service
|
from src.service.models import Service
|
||||||
from src.database import db_dependency
|
from src.database import db_dependency
|
||||||
from src.schemas import ResourceName
|
|
||||||
from src.auth.exceptions import UnauthorizedException
|
from src.auth.exceptions import UnauthorizedException
|
||||||
from src.utils import send_email, generate_jwt
|
from src.utils import send_email, generate_jwt
|
||||||
|
|
||||||
|
|
@ -18,7 +18,10 @@ from src.utils import send_email, generate_jwt
|
||||||
from fastapi import Request, Depends
|
from fastapi import Request, Depends
|
||||||
|
|
||||||
|
|
||||||
def valid_service_key(db: db_dependency, request: Request, rn: ResourceName) -> bool:
|
def valid_service_key(
|
||||||
|
db: db_dependency, request: Request, request_model: IAMCAoRRequest
|
||||||
|
) -> bool:
|
||||||
|
rn = request_model.rn
|
||||||
api_key = request.headers.get("X-API-Key", None)
|
api_key = request.headers.get("X-API-Key", None)
|
||||||
if not api_key:
|
if not api_key:
|
||||||
raise UnauthorizedException("Missing API key")
|
raise UnauthorizedException("Missing API key")
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,20 @@ pytestmark = [
|
||||||
@pytest.mark.anyio
|
@pytest.mark.anyio
|
||||||
async def test_post_act_on_resource_endpoint_success(default_client: AsyncClient):
|
async def test_post_act_on_resource_endpoint_success(default_client: AsyncClient):
|
||||||
body = {
|
body = {
|
||||||
"service": "Test Service",
|
"rn": {
|
||||||
"organisation": "Test Org",
|
"service": "Test Service",
|
||||||
"resource": "test_resource",
|
"organisation": "Test Org",
|
||||||
|
"resource": "test_resource",
|
||||||
|
"instance": None,
|
||||||
|
},
|
||||||
|
"action": "read",
|
||||||
}
|
}
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": "Bearer not_checked_when_auth_is_disabled",
|
"Authorization": "Bearer not_checked_when_auth_is_disabled",
|
||||||
"X-API-Key": "123456789",
|
"X-API-Key": "123456789",
|
||||||
}
|
}
|
||||||
resp = await default_client.post(
|
resp = await default_client.post(
|
||||||
"/iam/can_act_on_resource?action=read", json=body, headers=headers
|
"/iam/can_act_on_resource", json=body, headers=headers
|
||||||
)
|
)
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
|
|
||||||
|
|
@ -43,13 +47,20 @@ async def test_post_act_on_resource_endpoint_success(default_client: AsyncClient
|
||||||
async def test_act_on_resource_wrong_key(
|
async def test_act_on_resource_wrong_key(
|
||||||
default_client: AsyncClient, db_session, service: str, api_key: str
|
default_client: AsyncClient, db_session, service: str, api_key: str
|
||||||
):
|
):
|
||||||
body = {"service": service, "organisation": "Test Org", "resource": "test_resource"}
|
body = {
|
||||||
|
"rn": {
|
||||||
|
"service": service,
|
||||||
|
"organisation": "Test Org",
|
||||||
|
"resource": "test_resource",
|
||||||
|
},
|
||||||
|
"action": "read",
|
||||||
|
}
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": "Bearer not_checked_when_auth_is_disabled",
|
"Authorization": "Bearer not_checked_when_auth_is_disabled",
|
||||||
"X-API-Key": api_key,
|
"X-API-Key": api_key,
|
||||||
}
|
}
|
||||||
resp = await default_client.post(
|
resp = await default_client.post(
|
||||||
"/iam/can_act_on_resource?action=read", json=body, headers=headers
|
"/iam/can_act_on_resource", json=body, headers=headers
|
||||||
)
|
)
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
|
|
||||||
|
|
@ -60,9 +71,12 @@ async def test_act_on_resource_wrong_key(
|
||||||
@pytest.mark.anyio
|
@pytest.mark.anyio
|
||||||
async def test_act_on_resource_missing_key(default_client: AsyncClient):
|
async def test_act_on_resource_missing_key(default_client: AsyncClient):
|
||||||
body = {
|
body = {
|
||||||
"service": "Test Service",
|
"rn": {
|
||||||
"organisation": "Test Org",
|
"service": "Test Service",
|
||||||
"resource": "test_resource",
|
"organisation": "Test Org",
|
||||||
|
"resource": "test_resource",
|
||||||
|
},
|
||||||
|
"action": "read",
|
||||||
}
|
}
|
||||||
headers = {"Authorization": "Bearer not_checked_when_auth_is_disabled"}
|
headers = {"Authorization": "Bearer not_checked_when_auth_is_disabled"}
|
||||||
resp = await default_client.post(
|
resp = await default_client.post(
|
||||||
|
|
@ -120,13 +134,16 @@ async def test_act_on_resource_logic(
|
||||||
action,
|
action,
|
||||||
expected_response: bool,
|
expected_response: bool,
|
||||||
):
|
):
|
||||||
body = {"service": service, "organisation": org, "resource": resource}
|
body = {
|
||||||
|
"rn": {"service": service, "organisation": org, "resource": resource},
|
||||||
|
"action": action,
|
||||||
|
}
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": "Bearer not_checked_when_auth_is_disabled",
|
"Authorization": "Bearer not_checked_when_auth_is_disabled",
|
||||||
"X-API-Key": "123456789",
|
"X-API-Key": "123456789",
|
||||||
}
|
}
|
||||||
resp = await default_client.post(
|
resp = await default_client.post(
|
||||||
f"/iam/can_act_on_resource?action={action}", json=body, headers=headers
|
"/iam/can_act_on_resource", json=body, headers=headers
|
||||||
)
|
)
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue