fix: create permission endpoint

Verifies service exists before attaching permission.

Response built manually because calculated properties are not handled by .__dict()__

Request model uses Service ID mixin.

Service ID mixin verifies ID > 0
This commit is contained in:
Chris Milne 2026-06-02 15:36:05 +01:00
parent 5d1606aa9d
commit ae0181c3ff
3 changed files with 13 additions and 9 deletions

View file

@ -19,6 +19,7 @@ from fastapi import APIRouter, status
from sqlalchemy.exc import IntegrityError
from psycopg import errors
from service.exceptions import ServiceNotFoundException
from src.exceptions import ConflictException
from src.database import db_dependency
from src.schemas import ResourceName
@ -170,18 +171,21 @@ async def get_permissions(db: db_dependency, org_model: org_model_root_claim_que
return {"permissions": permission_models}
@router.post("/permission")
async def create_new_permission(db: db_dependency, su: super_admin_dependency, request_mode: IAMPostPermissionRequest):
perm_model = Perm(**request_mode.__dict__)
@router.post("/permission", response_model=IAMPostPermissionResponse)
async def create_new_permission(db: db_dependency, su: super_admin_dependency, request_model: IAMPostPermissionRequest):
service_model = db.get(Service, request_model.service_id)
if service_model is None:
raise ServiceNotFoundException(service_id=request_model.service_id)
perm_model = Perm(**request_model.__dict__)
try:
db.add(perm_model)
except IntegrityError as e:
if isinstance(e.orig, errors.UniqueViolation):
raise ConflictException(message="Permission already exists")
db.flush()
response = IAMPostPermissionResponse(permission=PermissionSchema(**perm_model.__dict__))
response = {"service_name": perm_model.service_name, "resource": perm_model.resource, "action": perm_model.action}
db.commit()
return response
return {"permission": response}
@router.delete("/permission", status_code=status.HTTP_204_NO_CONTENT)

View file

@ -10,6 +10,7 @@ from typing import Optional
from pydantic import EmailStr, ConfigDict, Field
from src.service.schemas import ServiceIDMixin
from src.organisation.schemas import OrgIDMixin
from src.schemas import CustomBaseModel
from user.schemas import UserIDMixin
@ -83,8 +84,7 @@ class IAMDeleteGroupUserResponse(CustomBaseModel):
class IAMGetPermissionsResponse(CustomBaseModel):
permissions: list[PermissionSchema]
class IAMPostPermissionRequest(CustomBaseModel):
service_id: int
class IAMPostPermissionRequest(ServiceIDMixin):
resource: str
action: str

View file

@ -6,12 +6,12 @@ Models follow the nomenclature of:
- Mixins: "<Attribute>Mixin"
- Models: "<Module><Method><Resource><Opt:Resource><Direction>" ie "ServiceGetServiceResponse"
"""
from pydantic import ConfigDict
from pydantic import ConfigDict, Field
from src.schemas import CustomBaseModel
class ServiceIDMixin(CustomBaseModel):
service_id: int
service_id: int = Field(gt=0)
class ServiceSchema(CustomBaseModel):
model_config = ConfigDict(from_attributes=True, extra="ignore")