Skip to content
Snippets Groups Projects
Commit dad72bb1 authored by Tim Repke's avatar Tim Repke
Browse files

update project list endpoint

parent b50f5ef5
No related branches found
No related tags found
1 merge request!49Master
......@@ -2,11 +2,11 @@ import uuid
from typing import TYPE_CHECKING
from fastapi import APIRouter, Depends
from nacsos_data.db.schemas import Project
from nacsos_data.db.schemas import Project, ProjectPermissions, User
from nacsos_data.models.users import UserModel
from nacsos_data.models.users import UserModel, UserBaseModel
from nacsos_data.models.projects import ProjectModel
from nacsos_data.db.crud.projects import read_all_projects, read_all_projects_for_user
from sqlalchemy import select, func, text
from server.api.errors import MissingInformationError
from server.data import db_engine
......@@ -22,8 +22,12 @@ router = APIRouter()
logger.info('Setting up projects route')
@router.get('/list', response_model=list[ProjectModel])
async def get_all_projects(current_user: UserModel = Depends(get_current_active_user)) -> list[ProjectModel]:
class ProjectInfo(ProjectModel):
owners: list[UserBaseModel] # list of users with ProjectPermissions.owner==True
@router.get('/list', response_model=list[ProjectInfo])
async def get_all_projects(current_user: UserModel = Depends(get_current_active_user)) -> list[ProjectInfo]:
"""
This endpoint returns all projects the currently logged-in user can see.
For regular users, this includes all projects for which an entry in ProjectPermissions exists.
......@@ -31,13 +35,41 @@ async def get_all_projects(current_user: UserModel = Depends(get_current_active_
:return: List of projects
"""
stmt_owners = select(ProjectPermissions.project_id,
func.array_agg(
func.row_to_json(text('"user".*'))
).label('owners')) \
.join(User, ProjectPermissions.user_id == User.user_id) \
.group_by(ProjectPermissions.project_id) \
.cte()
stmt_projects = select(Project, stmt_owners.c.owners) \
.join(stmt_owners, Project.project_id == stmt_owners.c.project_id)
if current_user.is_superuser:
return await read_all_projects(engine=db_engine)
# superuser needs no filtering, sees all projects
pass
else:
if current_user.user_id is not None:
# regular users only see their own projects
stmt_projects = stmt_projects \
.join(ProjectPermissions, Project.project_id == ProjectPermissions.project_id) \
.where(ProjectPermissions.user_id == current_user.user_id)
else:
raise MissingInformationError(
'`current_user` has no `user_id`, which points to a serious issue in the system!')
if current_user.user_id is None:
raise MissingInformationError('`current_user` has no `user_id`, which points to a serious issue in the system!')
async with db_engine.session() as session: # type: AsyncSession
result = await session.execute(stmt_projects)
return await read_all_projects_for_user(current_user.user_id, engine=db_engine)
return [
ProjectInfo(owners=[
UserBaseModel.parse_obj(owner)
for owner in row['owners']
],
**row['Project'].__dict__)
for row in result.mappings().all()
]
@router.put('/create', response_model=str)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment