Compare commits
No commits in common. "6a90e03d4056c1b1b2a1531e91b9209b178f5625" and "f7efbfcfc58dce8695475b3533e03f5ab32c5ec1" have entirely different histories.
6a90e03d40
...
f7efbfcfc5
3 changed files with 29 additions and 147 deletions
|
|
@ -36,10 +36,6 @@ tags_metadata = [
|
||||||
"name": "Service",
|
"name": "Service",
|
||||||
"description": "Services related operations, includes registering services and reissuing API keys",
|
"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",
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,20 +43,11 @@ from src.organisation.schemas import OrgPostOrgRequest, OrgPatchQuestionnaireReq
|
||||||
|
|
||||||
router = APIRouter(
|
router = APIRouter(
|
||||||
prefix="/org",
|
prefix="/org",
|
||||||
tags=["Organisation"],
|
tags=["org"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/id",
|
@router.get("/id", response_model=OrgGetOrgResponse)
|
||||||
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."},
|
|
||||||
})
|
|
||||||
async def get_org_by_id(org_model: org_model_root_claim_query_dependency):
|
async def get_org_by_id(org_model: org_model_root_claim_query_dependency):
|
||||||
response = {
|
response = {
|
||||||
"name": org_model.name,
|
"name": org_model.name,
|
||||||
|
|
@ -70,17 +61,8 @@ async def get_org_by_id(org_model: org_model_root_claim_query_dependency):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@router.post("/",
|
@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."},
|
|
||||||
})
|
|
||||||
async def create_org(db: db_dependency, user_model: user_model_claims_dependency, request_model: OrgPostOrgRequest):
|
async def create_org(db: db_dependency, user_model: user_model_claims_dependency, request_model: OrgPostOrgRequest):
|
||||||
# TODO: Response model
|
|
||||||
if request_model.intake_questionnaire:
|
if request_model.intake_questionnaire:
|
||||||
intake_questionnaire = request_model.intake_questionnaire.model_dump()
|
intake_questionnaire = request_model.intake_questionnaire.model_dump()
|
||||||
else:
|
else:
|
||||||
|
|
@ -106,21 +88,13 @@ async def create_org(db: db_dependency, user_model: user_model_claims_dependency
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
@router.patch("/questionnaire",
|
@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."},
|
|
||||||
})
|
|
||||||
async def update_questionnaire(db: db_dependency, org_model: org_model_root_claim_query_dependency, request_model: OrgPatchQuestionnaireRequest):
|
async def update_questionnaire(db: db_dependency, org_model: org_model_root_claim_query_dependency, request_model: OrgPatchQuestionnaireRequest):
|
||||||
"""
|
"""
|
||||||
Route for updating questionnaire.
|
Route for updating questionnaire.
|
||||||
The partial bool allows for submission of partially completed questionnaire and/or
|
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.
|
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()
|
org_model.intake_questionnaire = request_model.intake_questionnaire.model_dump()
|
||||||
|
|
||||||
# Allows for partially completed questionnaires to be saved without being submitted for review
|
# 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()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
@router.patch("/status",
|
@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."},
|
|
||||||
})
|
|
||||||
async def update_status(db: db_dependency, org_model: org_model_body_dependency, su: super_admin_dependency, request_model: OrgPatchStatusRequest):
|
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
|
org_model.status = request_model.status
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/users",
|
@router.get("/users", response_model=OrgGetUserResponse)
|
||||||
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."},
|
|
||||||
})
|
|
||||||
async def get_users(org_model: org_model_root_claim_query_dependency):
|
async def get_users(org_model: org_model_root_claim_query_dependency):
|
||||||
return {"users": [user.email for user in org_model.user_rel]}
|
return {"users": [user.email for user in org_model.user_rel]}
|
||||||
|
|
||||||
|
|
||||||
@router.post("/users",
|
@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."},
|
|
||||||
})
|
|
||||||
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):
|
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:
|
if user_model in org_model.user_rel:
|
||||||
raise Conflict(message="User already a part of this organisation")
|
raise Conflict(message="User already a part of this organisation")
|
||||||
org_model.user_rel.append(user_model)
|
org_model.user_rel.append(user_model)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/",
|
@router.delete("/", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
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."},
|
|
||||||
})
|
|
||||||
async def delete_organisation_by_id(db: db_dependency, org_model: org_model_body_dependency, su: super_admin_dependency, request_model: OrgDeleteOrgRequest):
|
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.delete(org_model)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
@router.patch("/root_user",
|
@router.patch("/root_user", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
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."},
|
|
||||||
})
|
|
||||||
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):
|
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
|
org_model.root_user_rel = user_model
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/groups",
|
@router.get("/groups", response_model=OrgGetGroupResponse)
|
||||||
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."},
|
|
||||||
})
|
|
||||||
async def get_org_groups(org_model: org_model_root_claim_query_dependency):
|
async def get_org_groups(org_model: org_model_root_claim_query_dependency):
|
||||||
return {"groups": [group.name for group in org_model.group_rel]}
|
return {"groups": [group.name for group in org_model.group_rel]}
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/user",
|
@router.delete("/user", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
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."},
|
|
||||||
})
|
|
||||||
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):
|
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:
|
if user_model not in org_model.user_rel:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -232,15 +150,7 @@ async def remove_user_from_org(db: db_dependency, org_model: org_model_root_clai
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/contact",
|
@router.get("/contact", response_model=OrgGetContactResponse)
|
||||||
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."},
|
|
||||||
})
|
|
||||||
async def get_contact(org_model: org_model_root_claim_query_dependency, contact_type: Annotated[ContactType, Query()]):
|
async def get_contact(org_model: org_model_root_claim_query_dependency, contact_type: Annotated[ContactType, Query()]):
|
||||||
match contact_type:
|
match contact_type:
|
||||||
case "billing":
|
case "billing":
|
||||||
|
|
@ -261,15 +171,7 @@ async def get_contact(org_model: org_model_root_claim_query_dependency, contact_
|
||||||
return {"contact": contact_response}
|
return {"contact": contact_response}
|
||||||
|
|
||||||
|
|
||||||
@router.patch("/contact",
|
@router.patch("/contact", response_model=OrgGetContactResponse)
|
||||||
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."},
|
|
||||||
})
|
|
||||||
async def update_contact(db: db_dependency, org_model: org_model_root_claim_body_dependency, request_model: OrgPatchContactRequest):
|
async def update_contact(db: db_dependency, org_model: org_model_root_claim_body_dependency, request_model: OrgPatchContactRequest):
|
||||||
match request_model.contact_type:
|
match request_model.contact_type:
|
||||||
case "billing":
|
case "billing":
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,9 @@ router = APIRouter(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/self/claims",
|
@router.get("/self/claims", response_model=OIDCClaims, status_code=status.HTTP_200_OK, responses={
|
||||||
summary="Get current user OIDC claims.",
|
status.HTTP_200_OK: {"description": "Successful retrieval from database"},
|
||||||
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):
|
async def current_user_claims(user: claims_dependency):
|
||||||
"""
|
"""
|
||||||
Returns the full OIDC claims associated with the currently logged-in user.
|
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
|
return user
|
||||||
|
|
||||||
|
|
||||||
@router.get("/self/db",
|
@router.get("/self/db", response_model=UserResponse, status_code=status.HTTP_200_OK, responses={
|
||||||
summary="Get current user hub details.",
|
status.HTTP_404_NOT_FOUND: {"description": "User not found"},
|
||||||
response_model=UserResponse,
|
status.HTTP_200_OK: {"description": "Successful retrieval from database"},
|
||||||
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):
|
async def current_user(user_model: user_model_claims_dependency):
|
||||||
"""
|
"""
|
||||||
Returns the database details associated with the currently logged-in user.
|
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
|
return user_model
|
||||||
|
|
||||||
|
|
||||||
@router.get("/",
|
@router.get("/", response_model=UserResponse, status_code=status.HTTP_200_OK, responses={
|
||||||
summary="Get user hub details by ID.",
|
status.HTTP_404_NOT_FOUND: {"description": "User not found"},
|
||||||
response_model=UserResponse,
|
status.HTTP_200_OK: {"description": "Successful retrieval from database"},
|
||||||
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):
|
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.
|
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
|
return user_model
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/",
|
@router.delete("/", status_code=status.HTTP_204_NO_CONTENT, responses={
|
||||||
summary="Delete user from hub by ID.",
|
status.HTTP_204_NO_CONTENT: {"description": "User deleted"},
|
||||||
status_code=status.HTTP_204_NO_CONTENT,
|
status.HTTP_404_NOT_FOUND: {"description": "User not found"},
|
||||||
responses={
|
})
|
||||||
status.HTTP_204_NO_CONTENT: {"description": "User deleted"},
|
async def delete_user_by_id(db: db_dependency, user_model: user_model_body_dependency, su: super_admin_dependency, request_model: UserDeleteUserRequest):
|
||||||
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.
|
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.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue