feat: root user verification

New root users must already be members of the organisation.
This commit is contained in:
Chris Milne 2026-05-29 09:52:34 +01:00
parent da5099e172
commit 8e8c00c34c

View file

@ -15,21 +15,21 @@ Endpoints:
- [GET](/org/contact): [root user]: Gets the (contact_type) contact for an org(id)
- [PATCH](/org/contact): [root user]: Updates the (contact_type) contact for an org(id). Any number of details can be changed.
"""
from typing import Annotated, Optional
from typing import Annotated
from fastapi import APIRouter, status
from fastapi.params import Query
from psycopg.errors import UniqueViolation
from sqlalchemy.exc import IntegrityError
from contact.schemas import ContactModel
from src.exceptions import UnprocessableContent, Conflict
from src.auth.exceptions import UnauthorizedException
from src.contact.schemas import ContactModel
from src.exceptions import UnprocessableContentException, ConflictException
from src.contact.models import Contact
from src.contact.schemas import ContactAddress
from src.contact.exceptions import ContactNotFoundException
from src.database import db_dependency
from src.user.models import User
from user.dependencies import user_model_body_dependency, user_model_claims_dependency
from src.user.dependencies import user_model_body_dependency, user_model_claims_dependency
from src.auth.dependencies import super_admin_dependency, org_model_root_claim_query_dependency, org_model_root_claim_body_dependency
from src.organisation.dependencies import org_model_body_dependency
@ -94,7 +94,7 @@ async def create_org(db: db_dependency, user_model: user_model_claims_dependency
db.flush()
except IntegrityError as e:
if isinstance(e.orig, UniqueViolation):
raise Conflict(message="Organisation with this name already exists")
raise ConflictException(message="Organisation with this name already exists")
# Adds currently logged-in user to org users list and sets them as root_user
org_model.user_rel.append(user_model)
org_model.root_user_rel = user_model
@ -177,7 +177,7 @@ async def get_users(org_model: org_model_root_claim_query_dependency):
})
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):
if user_model in org_model.user_rel:
raise Conflict(message="User already a part of this organisation")
raise ConflictException(message="User already a part of this organisation")
org_model.user_rel.append(user_model)
db.flush()
response = {"users": [user.email for user in org_model.user_rel]}
@ -208,7 +208,8 @@ async def delete_organisation_by_id(db: db_dependency, org_model: org_model_body
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):
# TODO: verify new user is already an org member
if user_model not in org_model.user_rel:
raise UnauthorizedException(message="This user does not belong to your organisation.")
org_model.root_user_rel = user_model
db.flush()
response = OrgPatchRootResponse(**org_model.__dict__)
@ -263,7 +264,7 @@ async def get_contact(org_model: org_model_root_claim_query_dependency, contact_
case "owner":
contact_model = org_model.owner_contact_rel
case _:
raise UnprocessableContent("Invalid contact type")
raise UnprocessableContentException("Invalid contact type")
if contact_model is None:
raise ContactNotFoundException()
@ -292,7 +293,7 @@ async def update_contact(db: db_dependency, org_model: org_model_root_claim_body
case "owner":
contact_model = org_model.owner_contact_rel
case _:
raise UnprocessableContent("Invalid contact type")
raise UnprocessableContentException("Invalid contact type")
if contact_model is None:
raise ContactNotFoundException()
@ -302,7 +303,7 @@ async def update_contact(db: db_dependency, org_model: org_model_root_claim_body
if hasattr(contact_model, key):
setattr(contact_model, key, value)
else:
raise UnprocessableContent("Invalid keys in update request")
raise UnprocessableContentException("Invalid keys in update request")
db.flush()
address = ContactAddress.model_validate(contact_model)