diff --git a/src/main.py b/src/main.py index a5ed717..0092af0 100644 --- a/src/main.py +++ b/src/main.py @@ -36,10 +36,6 @@ tags_metadata = [ "name": "Service", "description": "Services related operations, includes registering services and reissuing API keys", }, - { - "name": "Organisation", - "description": "Organisation related operations, includes getting lists of users etc associated with orgs", - }, ] diff --git a/src/organisation/router.py b/src/organisation/router.py index 97f3e85..2e71fba 100644 --- a/src/organisation/router.py +++ b/src/organisation/router.py @@ -43,20 +43,11 @@ from src.organisation.schemas import OrgPostOrgRequest, OrgPatchQuestionnaireReq router = APIRouter( prefix="/org", - tags=["Organisation"], + tags=["org"], ) -@router.get("/id", - summary="Get org details by ID.", - response_model=OrgGetOrgResponse, - status_code=status.HTTP_200_OK, - responses={ - status.HTTP_200_OK: {"description": "Successful retrieval from database"}, - status.HTTP_404_NOT_FOUND: {"description": "Organisation not found"}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Missing or invalid org_id query parameter"}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be org root user."}, - }) +@router.get("/id", response_model=OrgGetOrgResponse) async def get_org_by_id(org_model: org_model_root_claim_query_dependency): response = { "name": org_model.name, @@ -70,17 +61,8 @@ async def get_org_by_id(org_model: org_model_root_claim_query_dependency): return response -@router.post("/", - summary="Create new organisation.", - status_code=status.HTTP_201_CREATED, - responses={ - status.HTTP_201_CREATED: {"description": "Successfully created organisation."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, - status.HTTP_401_UNAUTHORIZED: {"description": "User must be logged in with OIDC to create organisation."}, - status.HTTP_409_CONFLICT: {"description": "Organisation with this name already exists."}, - }) +@router.post("/") async def create_org(db: db_dependency, user_model: user_model_claims_dependency, request_model: OrgPostOrgRequest): - # TODO: Response model if request_model.intake_questionnaire: intake_questionnaire = request_model.intake_questionnaire.model_dump() else: @@ -106,21 +88,13 @@ async def create_org(db: db_dependency, user_model: user_model_claims_dependency db.commit() -@router.patch("/questionnaire", - summary="Update questionnaire.", - status_code=status.HTTP_200_OK, - responses={ - status.HTTP_200_OK: {"description": "Successfully updated questionnaire."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be org root user."}, - }) +@router.patch("/questionnaire") async def update_questionnaire(db: db_dependency, org_model: org_model_root_claim_query_dependency, request_model: OrgPatchQuestionnaireRequest): """ Route for updating questionnaire. The partial bool allows for submission of partially completed questionnaire and/or final "are you sure" check before setting the org to be in "submitted" status, awaiting admin approval. """ - # TODO: Response model org_model.intake_questionnaire = request_model.intake_questionnaire.model_dump() # Allows for partially completed questionnaires to be saved without being submitted for review @@ -130,101 +104,45 @@ async def update_questionnaire(db: db_dependency, org_model: org_model_root_clai db.commit() -@router.patch("/status", - summary="Update status of organisation.", - status_code=status.HTTP_200_OK, - responses={ - status.HTTP_200_OK: {"description": "Successfully updated organisation status."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be super admin."}, - }) +@router.patch("/status") async def update_status(db: db_dependency, org_model: org_model_body_dependency, su: super_admin_dependency, request_model: OrgPatchStatusRequest): - # TODO: Response model org_model.status = request_model.status db.commit() -@router.get("/users", - summary="Get email addresses of users of the organisation.", - status_code=status.HTTP_200_OK, - response_model=OrgGetUserResponse, - responses={ - status.HTTP_200_OK: {"description": "Successful retrieval of users."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Org ID missing or invalid."}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be org root user."}, - }) +@router.get("/users", response_model=OrgGetUserResponse) async def get_users(org_model: org_model_root_claim_query_dependency): return {"users": [user.email for user in org_model.user_rel]} -@router.post("/users", - summary="All user to the organisation.", - status_code=status.HTTP_200_OK, - responses={ - status.HTTP_200_OK: {"description": "Successfully added user to the organisation."}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be org root user."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, - status.HTTP_409_CONFLICT: {"description": "User is already a member of the organisation."}, - }) +@router.post("/users") async def add_user_to_org(db: db_dependency, org_model: org_model_root_claim_body_dependency, user_model: user_model_body_dependency, request_model: OrgPostUserRequest): - # TODO: response model if user_model in org_model.user_rel: raise Conflict(message="User already a part of this organisation") org_model.user_rel.append(user_model) db.commit() -@router.delete("/", - summary="Delete organisation from the hub.", - status_code=status.HTTP_204_NO_CONTENT, - responses={ - status.HTTP_204_NO_CONTENT: {"description": "Successfully deleted organisation."}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be super admin."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Org ID missing or invalid."}, - }) +@router.delete("/", status_code=status.HTTP_204_NO_CONTENT) async def delete_organisation_by_id(db: db_dependency, org_model: org_model_body_dependency, su: super_admin_dependency, request_model: OrgDeleteOrgRequest): db.delete(org_model) db.commit() -@router.patch("/root_user", - summary="Update the root user of the organisation.", - status_code=status.HTTP_200_OK, - responses={ - status.HTTP_200_OK: {"description": "Successfully updated root user."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be super admin."}, - }) +@router.patch("/root_user", status_code=status.HTTP_204_NO_CONTENT) async def update_root_user(db: db_dependency, org_model: org_model_body_dependency, user_model: user_model_body_dependency, su: super_admin_dependency, request_model: OrgPatchRootRequest): - # TODO: response model org_model.root_user_rel = user_model db.commit() -@router.get("/groups", - summary="Get all organisation IAM groups.", - status_code=status.HTTP_200_OK, - response_model=OrgGetGroupResponse, - responses={ - status.HTTP_200_OK: {"description": "Successful retrieval of IAM groups."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Org ID missing or invalid."}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be org root user."}, - }) +@router.get("/groups", response_model=OrgGetGroupResponse) async def get_org_groups(org_model: org_model_root_claim_query_dependency): return {"groups": [group.name for group in org_model.group_rel]} -@router.delete("/user", - summary="Remove user from organisation.", - status_code=status.HTTP_204_NO_CONTENT, - responses={ - status.HTTP_204_NO_CONTENT: {"description": "Successfully removed user."}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be org root user."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, - }) +@router.delete("/user", status_code=status.HTTP_204_NO_CONTENT) async def remove_user_from_org(db: db_dependency, org_model: org_model_root_claim_body_dependency, user_model: user_model_body_dependency, request_model: OrgDeleteUserRequest): - # TODO: response model if user_model not in org_model.user_rel: return @@ -232,15 +150,7 @@ async def remove_user_from_org(db: db_dependency, org_model: org_model_root_clai db.commit() -@router.get("/contact", - summary="Get contact for organisation.", - status_code=status.HTTP_200_OK, - response_model=OrgGetContactResponse, - responses={ - status.HTTP_200_OK: {"description": "Successful retrieval of contact."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be org root user."}, - }) +@router.get("/contact", response_model=OrgGetContactResponse) async def get_contact(org_model: org_model_root_claim_query_dependency, contact_type: Annotated[ContactType, Query()]): match contact_type: case "billing": @@ -261,15 +171,7 @@ async def get_contact(org_model: org_model_root_claim_query_dependency, contact_ return {"contact": contact_response} -@router.patch("/contact", - summary="Update contact for organisation.", - status_code=status.HTTP_200_OK, - response_model=OrgGetContactResponse, - responses={ - status.HTTP_200_OK: {"description": "Successfully updated contact."}, - status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, - status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be org root user."}, - }) +@router.patch("/contact", response_model=OrgGetContactResponse) async def update_contact(db: db_dependency, org_model: org_model_root_claim_body_dependency, request_model: OrgPatchContactRequest): match request_model.contact_type: case "billing": diff --git a/src/user/router.py b/src/user/router.py index 0966850..90c133f 100644 --- a/src/user/router.py +++ b/src/user/router.py @@ -23,13 +23,9 @@ router = APIRouter( ) -@router.get("/self/claims", - summary="Get current user OIDC claims.", - response_model=OIDCClaims, - status_code=status.HTTP_200_OK, - responses={ - status.HTTP_200_OK: {"description": "Successful retrieval from database"}, - }) +@router.get("/self/claims", response_model=OIDCClaims, status_code=status.HTTP_200_OK, responses={ + status.HTTP_200_OK: {"description": "Successful retrieval from database"}, +}) async def current_user_claims(user: claims_dependency): """ Returns the full OIDC claims associated with the currently logged-in user. @@ -38,14 +34,10 @@ async def current_user_claims(user: claims_dependency): return user -@router.get("/self/db", - summary="Get current user hub details.", - response_model=UserResponse, - status_code=status.HTTP_200_OK, - responses={ - status.HTTP_404_NOT_FOUND: {"description": "User not found"}, - status.HTTP_200_OK: {"description": "Successful retrieval from database"}, - }) +@router.get("/self/db", response_model=UserResponse, status_code=status.HTTP_200_OK, responses={ + status.HTTP_404_NOT_FOUND: {"description": "User not found"}, + status.HTTP_200_OK: {"description": "Successful retrieval from database"}, +}) async def current_user(user_model: user_model_claims_dependency): """ Returns the database details associated with the currently logged-in user. @@ -53,14 +45,10 @@ async def current_user(user_model: user_model_claims_dependency): return user_model -@router.get("/", - summary="Get user hub details by ID.", - response_model=UserResponse, - status_code=status.HTTP_200_OK, - responses={ - status.HTTP_404_NOT_FOUND: {"description": "User not found"}, - status.HTTP_200_OK: {"description": "Successful retrieval from database"}, - }) +@router.get("/", response_model=UserResponse, status_code=status.HTTP_200_OK, responses={ + status.HTTP_404_NOT_FOUND: {"description": "User not found"}, + status.HTTP_200_OK: {"description": "Successful retrieval from database"}, +}) async def get_user_by_id(user_model: user_model_query_dependency, su: super_admin_dependency): """ Returns the database details associated with the provided user ID. @@ -68,15 +56,11 @@ async def get_user_by_id(user_model: user_model_query_dependency, su: super_admi return user_model -@router.delete("/", - summary="Delete user from hub by ID.", - status_code=status.HTTP_204_NO_CONTENT, - responses={ - status.HTTP_204_NO_CONTENT: {"description": "User deleted"}, - status.HTTP_404_NOT_FOUND: {"description": "User not found"}, - }) -async def delete_user_by_id(db: db_dependency, user_model: user_model_body_dependency, su: super_admin_dependency, - request_model: UserDeleteUserRequest): +@router.delete("/", status_code=status.HTTP_204_NO_CONTENT, responses={ + status.HTTP_204_NO_CONTENT: {"description": "User deleted"}, + status.HTTP_404_NOT_FOUND: {"description": "User not found"}, + }) +async def delete_user_by_id(db: db_dependency, user_model: user_model_body_dependency, su: super_admin_dependency, request_model: UserDeleteUserRequest): """ Deletes the user with the provided ID from the database. This will not remove them from OIDC, and they will be automatically readded on next login. """