diff --git a/src/service/router.py b/src/service/router.py index d4954fd..22e8594 100644 --- a/src/service/router.py +++ b/src/service/router.py @@ -18,6 +18,9 @@ from src.auth.dependencies import ( super_admin_dependency, org_model_root_claim_query_dependency, ) +from src.iam.service import service_key_dependency +from src.iam.models import Permission as Perm +from src.service.exceptions import ServiceNotFoundException from src.service.models import Service from src.service.utils import generate_api_key @@ -32,6 +35,8 @@ from src.service.schemas import ( ServiceWithKeySchema, ServicePatchKeyResponse, ServicePatchKeyRequest, + ServicePostPermissionsResponse, + ServicePostPermissionsRequest, ) router = APIRouter( @@ -170,3 +175,66 @@ async def remove_service( """ db.delete(service_model) db.commit() + + +@router.post( + path="/permissions", + summary="Service endpoint for creating its own permissions.", + status_code=status.HTTP_200_OK, + response_model=ServicePostPermissionsResponse, + responses={ + status.HTTP_401_UNAUTHORIZED: { + "description": "API Key missing or invalid | Issue verifying user OIDC claims" + }, + }, +) +async def service_create_new_permissions( + db: db_dependency, + request_model: ServicePostPermissionsRequest, + valid_key: service_key_dependency, +): + """ + Allows a service to register its own set of permissions. + """ + service_model = ( + db.query(Service).filter(Service.name == request_model.rn.service).first() + ) + if service_model is None: + raise ServiceNotFoundException() + else: + service_id = service_model.id + response_list = [] + for new_permission in request_model.permissions: + perm_model = ( + db.query(Perm) + .filter(Perm.service_id == service_id) + .filter(Perm.resource == new_permission.resource) + .filter(Perm.action == new_permission.action) + .first() + ) + if perm_model is not None: + response_code = 409 + response = { + "id": perm_model.id, + "service_name": perm_model.service_name, + "resource": perm_model.resource, + "action": perm_model.action, + } + response_list.append((response, response_code)) + continue + + new_perm_model = Perm(**new_permission.__dict__) + new_perm_model.service_id = service_id + db.add(new_perm_model) + db.flush() + response_code = 201 + response = { + "id": new_perm_model.id, + "service_name": new_perm_model.service_name, + "resource": new_perm_model.resource, + "action": new_perm_model.action, + } + response_list.append((response, response_code)) + + db.commit() + return {"permissions": response_list} diff --git a/src/service/schemas.py b/src/service/schemas.py index 27d0483..544dac3 100644 --- a/src/service/schemas.py +++ b/src/service/schemas.py @@ -60,3 +60,12 @@ class ServicePatchKeyRequest(ServiceIDMixin): class ServicePatchKeyResponse(CustomBaseModel): service: ServiceWithKeySchema + + +class ServicePostPermissionsRequest(CustomBaseModel): + rn: ServiceNameMixin + permissions: list[PermissionRequestSchema] + + +class ServicePostPermissionsResponse(CustomBaseModel): + permissions: list[tuple[PermissionResponseSchema, int]]