feat: service permissions endpoint

Endpoint to allow services to register their own permissions into the hub.
This commit is contained in:
Chris Milne 2026-06-16 16:11:21 +01:00
parent 327f857190
commit 4b384db98a
2 changed files with 77 additions and 0 deletions

View file

@ -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}

View file

@ -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]]