Skip to content

Commit

Permalink
fix: use raw sql for organisation crud (#1253)
Browse files Browse the repository at this point in the history
  • Loading branch information
spwoodcock authored Feb 23, 2024
1 parent a370631 commit 51ae6a2
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 21 deletions.
60 changes: 43 additions & 17 deletions src/backend/app/organisations/organisation_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@
from app.auth.osm import AuthUser
from app.config import encrypt_value, settings
from app.db import db_models
from app.models.enums import HTTPStatus, UserRole
from app.models.enums import HTTPStatus
from app.organisations.organisation_deps import (
check_org_exists,
get_organisation_by_name,
)
from app.organisations.organisation_schemas import OrganisationEdit, OrganisationIn
from app.s3 import add_obj_to_bucket
from app.users.user_crud import get_user


async def init_admin_org(db: Session):
Expand Down Expand Up @@ -128,35 +127,62 @@ async def init_admin_org(db: Session):
async def get_organisations(
db: Session,
current_user: AuthUser,
) -> list[db_models.DbOrganisation]:
"""Get all orgs."""
db_user = await get_user(db, current_user.id)
):
"""Get all orgs.
# If admin, show all orgs
if db_user.role == UserRole.ADMIN:
return db.query(db_models.DbOrganisation).all()
Also returns unapproved orgs if admin user.
"""
user_id = current_user.id

# If not admin, only show approved orgs
return db.query(db_models.DbOrganisation).filter_by(approved=True).all()
sql = text(
"""
SELECT *
FROM organisations
WHERE
CASE
WHEN (SELECT role FROM users WHERE id = :user_id) = 'ADMIN' THEN TRUE
ELSE approved
END = TRUE;
"""
)
return db.execute(sql, {"user_id": user_id}).all()


async def get_my_organisations(
db: Session,
current_user: AuthUser,
) -> list[db_models.DbOrganisation]:
):
"""Get organisations filtered by the current user.
TODO add extra UNION for all associated projects to user.
Args:
db (Session): The database session.
current_user (AuthUser): The current user.
db (Session): The database session.
current_user (AuthUser): The current user.
Returns:
list[db_models.DbOrganisation]: A list of organisations
filtered by the current user.
list[dict]: A list of organisation objects to be serialised.
"""
db_user = await get_user(db, current_user.id)
user_id = current_user.id

return db_user.organisations
sql = text(
"""
SELECT DISTINCT org.*
FROM organisations org
JOIN organisation_managers managers
ON managers.organisation_id = org.id
WHERE managers.user_id = :user_id
UNION
SELECT DISTINCT org.*
FROM organisations org
JOIN projects project
ON project.organisation_id = org.id
WHERE project.author_id = :user_id;
"""
)
return db.execute(sql, {"user_id": user_id}).all()


async def get_unapproved_organisations(
Expand Down
16 changes: 14 additions & 2 deletions src/backend/app/organisations/organisation_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,24 @@ async def update_organisation(


@router.delete("/{org_id}")
async def delete_organisations(
org_id: int,
async def delete_org(
db: Session = Depends(database.get_db),
org_user_dict: DbUser = Depends(org_admin),
):
"""Delete an organisation."""
return await organisation_crud.delete_organisation(db, org_user_dict["org"])


@router.delete("/unapproved/{org_id}")
async def delete_unapproved_org(
org_id: int,
db: Session = Depends(database.get_db),
current_user: DbUser = Depends(super_admin),
):
"""Delete an unapproved organisation.
ADMIN ONLY ENDPOINT.
"""
organisation = db.query(DbOrganisation).filter(DbOrganisation.id == org_id).first()
return await organisation_crud.delete_organisation(db, organisation)

Expand Down
13 changes: 11 additions & 2 deletions src/backend/app/organisations/organisation_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
"""Pydantic models for Organisations."""

from re import sub
from typing import Optional
from typing import Optional, Union

from fastapi import Form
from pydantic import BaseModel, Field, computed_field
from pydantic.functional_validators import field_validator

from app.config import HttpUrlStr
from app.models.enums import CommunityType, OrganisationType
Expand Down Expand Up @@ -93,9 +94,17 @@ class OrganisationOut(BaseModel):
id: int
name: str
approved: bool
type: OrganisationType
type: Union[OrganisationType, str]
logo: Optional[str]
description: Optional[str]
slug: Optional[str]
url: Optional[str]
odk_central_url: Optional[str]

@field_validator("type", mode="before")
@classmethod
def parse_enum_string(cls, value: Union[str, OrganisationType]) -> OrganisationType:
"""If a string value is used, parsed as Enum."""
if isinstance(value, OrganisationType):
return value
return OrganisationType[value]

0 comments on commit 51ae6a2

Please sign in to comment.