diff --git a/src/iam/service.py b/src/iam/service.py index 4f23969..e3c8740 100644 --- a/src/iam/service.py +++ b/src/iam/service.py @@ -8,15 +8,11 @@ Exports: from typing import Annotated from datetime import datetime, timedelta, timezone from fastapi import Request, Depends -from sqlalchemy.orm import Session from src.database import db_dependency from src.exceptions import UnauthorizedException from src.utils import send_email, generate_jwt from src.iam.models import Group -from src.organisation.models import Organisation as Org -from src.user.models import User -from src.iam.models import Permission as Perm from src.service.models import Service from src.service.schemas import HasServiceName @@ -70,43 +66,47 @@ async def send_user_group_invitation( ) -async def create_group_and_assign_perms( - db: Session, org_model: Org, group_name: str, perm_list: list[int] -): - new_group = Group(name=group_name, org_id=org_model.id) +async def create_default_user_group(db: db_dependency, org_model): + new_group = Group(name="Default Users", org_id=org_model.id) db.add(new_group) db.flush() - - for permission in perm_list: - perm_model = db.get(Perm, permission) - - if perm_model is None: - continue - - new_group.permission_rel.append(perm_model) - db.flush() - + # Grant default permissions here + db.flush() return new_group -async def assign_default_group( - db: db_dependency, - org_model: Org, - user_model: User, - group_name: str, - perm_list: list[int], -): - group_model = ( - db.query(Group) - .filter(Group.org_id == org_model.id) - .filter(Group.name == group_name) - .first() - ) +async def assign_default_user_group(db: db_dependency, org_model, user_model): + group_model = None + for group in org_model.group_rel: + if group.name == "Default Users": + group_model = group + break if group_model is None: - group_model = await create_group_and_assign_perms( - db=db, group_name=group_name, org_model=org_model, perm_list=perm_list - ) + group_model = await create_default_user_group(db=db, org_model=org_model) + + user_model.group_rel.append(group_model) + db.flush() + + +async def create_default_root_group(db: db_dependency, org_model): + new_group = Group(name="Root User", org_id=org_model.id) + db.add(new_group) + db.flush() + # Grant default permissions here + db.flush() + return new_group + + +async def assign_default_root_group(db: db_dependency, org_model, user_model): + group_model = None + for group in org_model.group_rel: + if group.name == "Root User": + group_model = group + break + + if group_model is None: + group_model = await create_default_root_group(db=db, org_model=org_model) user_model.group_rel.append(group_model) db.flush() diff --git a/src/organisation/router.py b/src/organisation/router.py index 129e48c..a7114c3 100644 --- a/src/organisation/router.py +++ b/src/organisation/router.py @@ -21,7 +21,7 @@ from typing import Annotated from sqlalchemy.exc import IntegrityError from psycopg.errors import UniqueViolation -from fastapi import APIRouter, status, BackgroundTasks +from fastapi import APIRouter, status from fastapi.params import Query from src.contact.schemas import ContactModel @@ -34,8 +34,8 @@ 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.iam.service import assign_default_user_group, assign_default_root_group from src.organisation.schemas_questionnaires import QuestionnaireQuestionsVersion0 -from src.organisation.service import assign_defaults from src.user.dependencies import ( user_model_body_dependency, user_model_claims_dependency, @@ -46,7 +46,6 @@ from src.auth.dependencies import ( org_model_root_claim_query_dependency, org_model_root_claim_body_dependency, ) -from src.iam.models import Group from src.organisation.dependencies import ( org_model_body_dependency, @@ -148,7 +147,6 @@ async def create_org( db: db_dependency, user_model: user_model_claims_dependency, request_model: OrgPostOrgRequest, - background_tasks: BackgroundTasks, ): """ Creates a new organisation with optional questionnaire (to be completed or submitted). @@ -189,10 +187,9 @@ async def create_org( org_model.user_rel.append(user_model) org_model.root_user_rel = user_model - background_tasks.add_task( - assign_defaults, db, org_id=org_model.id, user_id=user_model.id - ) - + # Creates default user and default root IAM groups and assigns them + await assign_default_user_group(db, org_model, user_model) + await assign_default_root_group(db, org_model, user_model) for contact_type in [ "billing_contact_id", "security_contact_id", @@ -357,14 +354,7 @@ async def add_user_to_org( raise ConflictException(message="User already a part of this organisation") org_model.user_rel.append(user_model) db.flush() - group_model = ( - db.query(Group) - .filter(Group.org_id == org_model.id) - .filter(Group.name == "Default Users") - .first() - ) - if group_model is not None: - user_model.group_rel.append(group_model) + await assign_default_user_group(db=db, org_model=org_model, user_model=user_model) response = { "organisation": org_model, "users": [{"id": user.id, "email": user.email} for user in org_model.user_rel], diff --git a/src/organisation/service.py b/src/organisation/service.py index 4fc2f03..cfe3925 100644 --- a/src/organisation/service.py +++ b/src/organisation/service.py @@ -1,71 +1,3 @@ """ Reusable business logic functions for the organisation module """ - -from sqlalchemy.orm import Session -from typing import cast - -from src.iam.service import assign_default_group -from src.organisation.models import Organisation as Org -from src.iam.models import Permission as Perm -from src.user.models import User - - -async def add_default_org_permissions( - db: Session, - org_model: Org, - perm_list: list[int], -): - for permission in perm_list: - perm_model = db.get(Perm, permission) - - if perm_model is None: - continue - - if perm_model in org_model.permission_rel: - continue - - org_model.permission_rel.append(perm_model) - db.flush() - - db.commit() - - -async def assign_defaults( - db: Session, - org_id: int, - user_id: int, -): - default_org_permissions = [] - - default_user_permissions = [] - - org_model = db.get(Org, org_id) - if org_model is None: - print("Org not found while adding defaults") - return - - user_model = db.get(User, user_id) - if user_model is None: - print("User not found while adding defaults") - return - - org_model = cast(Org, org_model) - user_model = cast(User, user_model) - - await add_default_org_permissions(db, org_model, default_org_permissions) - await assign_default_group( - db=db, - org_model=org_model, - user_model=user_model, - group_name="Default Users", - perm_list=default_user_permissions, - ) - await assign_default_group( - db=db, - org_model=org_model, - user_model=user_model, - group_name="Root User", - perm_list=default_org_permissions, - ) - db.commit() diff --git a/src/user/router.py b/src/user/router.py index 7aecc12..c4b5379 100644 --- a/src/user/router.py +++ b/src/user/router.py @@ -10,7 +10,7 @@ Endpoints: from fastapi import APIRouter, status, BackgroundTasks -from src.iam.models import Group +from src.iam.service import assign_default_user_group from src.organisation.exceptions import OrgNotFoundException from src.user.schemas import ( UserResponse, @@ -200,14 +200,7 @@ async def accept_invitation( org_model.user_rel.append(user_model) db.flush() - group_model = ( - db.query(Group) - .filter(Group.org_id == org_model.id) - .filter(Group.name == "Default Users") - .first() - ) - if group_model is not None: - user_model.group_rel.append(group_model) + await assign_default_user_group(db=db, org_model=org_model, user_model=user_model) response = { "organisation": org_model,