feat: caor docs and response model
All checks were successful
ci / lint_and_test (push) Successful in 13s
All checks were successful
ci / lint_and_test (push) Successful in 13s
This commit is contained in:
parent
0b521414b3
commit
ec41d1ed05
4 changed files with 45 additions and 9 deletions
|
|
@ -28,7 +28,7 @@ oidc_dependency = Annotated[str, Depends(oidc)]
|
|||
|
||||
|
||||
def get_dev_user():
|
||||
return {"db_id": 1}
|
||||
return {"db_id": 1, "email": "chris@sr2.uk"}
|
||||
|
||||
|
||||
async def get_current_user(
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ from sqlalchemy.exc import IntegrityError
|
|||
|
||||
from src.iam.exceptions import GroupNotFoundException
|
||||
from src.organisation.exceptions import OrgNotFoundException
|
||||
from src.schemas import GroupSummary, OrgSummary
|
||||
from src.schemas import GroupSummary, OrgSummary, ResourceName
|
||||
from src.service.exceptions import ServiceNotFoundException
|
||||
from src.exceptions import ConflictException, ForbiddenException
|
||||
from src.database import db_dependency
|
||||
|
|
@ -74,6 +74,7 @@ from src.iam.schemas import (
|
|||
IAMGetPermissionsSearchResponse,
|
||||
IAMPutGroupInvitationRequest,
|
||||
IAMPutGroupInvitationAcceptRequest,
|
||||
IAMCAoRResponse,
|
||||
)
|
||||
from src.utils import verify_email_token
|
||||
|
||||
|
|
@ -83,13 +84,35 @@ router = APIRouter(
|
|||
)
|
||||
|
||||
|
||||
@router.post("/can_act_on_resource")
|
||||
@router.post(
|
||||
path="/can_act_on_resource",
|
||||
summary="Used for services to check user access permission",
|
||||
status_code=status.HTTP_200_OK,
|
||||
response_model=IAMCAoRResponse,
|
||||
responses={
|
||||
status.HTTP_401_UNAUTHORIZED: {
|
||||
"description": "API Key missing or invalid | Issue verifying user OIDC claims"
|
||||
},
|
||||
},
|
||||
)
|
||||
async def can_act_on_resource(
|
||||
valid_key: service_key_dependency,
|
||||
db: db_dependency,
|
||||
user_claims: claims_dependency,
|
||||
request_model: IAMCAoRRequest,
|
||||
) -> bool:
|
||||
):
|
||||
"""
|
||||
This endpoint is not meant for the Hub frontend to interact with.
|
||||
Services accessing this endpoint must be already registered within the Hub and been issued an API key.
|
||||
Resource Names have an instance property but permissions do not presently have that level of granularity.
|
||||
"""
|
||||
response = {
|
||||
"allowed": False,
|
||||
"rn": ResourceName(organisation="", service="", resource=""),
|
||||
"action": "",
|
||||
"user": {"id": 0, "email": ""},
|
||||
}
|
||||
|
||||
try:
|
||||
rn = request_model.rn
|
||||
action = request_model.action
|
||||
|
|
@ -98,6 +121,10 @@ async def can_act_on_resource(
|
|||
rn_service = rn.service
|
||||
rn_resource = rn.resource
|
||||
|
||||
response["user"] = {"id": user_id, "email": user_claims["email"]}
|
||||
response["action"] = action
|
||||
response["rn"] = rn
|
||||
|
||||
result = (
|
||||
db.query(Perm)
|
||||
.join(Service, Service.id == Perm.service_id)
|
||||
|
|
@ -114,11 +141,13 @@ async def can_act_on_resource(
|
|||
).first()
|
||||
|
||||
if result:
|
||||
return True
|
||||
response["allowed"] = True
|
||||
else:
|
||||
return False
|
||||
response["allowed"] = False
|
||||
except Exception:
|
||||
return False
|
||||
response["allowed"] = False
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@router.get("/group/permissions", response_model=IAMGetGroupPermissionsResponse)
|
||||
|
|
|
|||
|
|
@ -52,6 +52,13 @@ class IAMCAoRRequest(CustomBaseModel):
|
|||
rn: ResourceName
|
||||
|
||||
|
||||
class IAMCAoRResponse(CustomBaseModel):
|
||||
allowed: bool
|
||||
user: UserSummary
|
||||
action: str
|
||||
rn: ResourceName
|
||||
|
||||
|
||||
class IAMGetGroupPermissionsResponse(CustomBaseModel):
|
||||
organisation: OrgSummary
|
||||
group: GroupSummary
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ async def test_post_act_on_resource_endpoint_success(default_client: AsyncClient
|
|||
data = resp.json()
|
||||
|
||||
assert resp.status_code == 200
|
||||
assert data is True
|
||||
assert data["allowed"] is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
@ -148,7 +148,7 @@ async def test_act_on_resource_logic(
|
|||
data = resp.json()
|
||||
|
||||
assert resp.status_code == 200
|
||||
assert data == expected_response
|
||||
assert data["allowed"] == expected_response
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue