33from aiohttp import web
44from aiopg .sa .engine import Engine
55from models_library .groups import GroupID
6- from models_library .projects import ProjectID
6+ from models_library .projects import ProjectID , ProjectIDStr
77from models_library .users import UserID
88from models_library .workspaces import WorkspaceID
99from simcore_postgres_database .models .project_to_groups import project_to_groups
1010from simcore_postgres_database .models .projects import projects
11- from simcore_postgres_database .models .workspace_access_rights import (
12- workspace_access_rights ,
11+ from simcore_postgres_database .models .workspaces_access_rights import (
12+ workspaces_access_rights ,
1313)
1414from simcore_postgres_database .utils_repos import (
1515 pass_or_acquire_connection ,
@@ -33,22 +33,30 @@ async def get_project_owner(engine: Engine, project_uuid: ProjectID) -> UserID:
3333 return owner_id
3434
3535
36+ def _split_private_and_shared_projects (
37+ projects_uuids_with_workspace_id : list [tuple [ProjectID , WorkspaceID | None ]],
38+ ) -> tuple [list [ProjectID ], dict [WorkspaceID , list [ProjectID ]]]:
39+ """Splits project tuples into private project IDs and a mapping of workspace_id to project IDs."""
40+ private_project_ids = []
41+ workspace_to_project_ids : dict [WorkspaceID , list [ProjectID ]] = {}
42+ for pid , wid in projects_uuids_with_workspace_id :
43+ if wid is None :
44+ private_project_ids .append (pid )
45+ else :
46+ workspace_to_project_ids .setdefault (wid , []).append (pid )
47+ return private_project_ids , workspace_to_project_ids
48+
49+
3650async def batch_get_project_access_rights (
3751 app : web .Application ,
3852 connection : AsyncConnection | None = None ,
3953 * ,
40- projects_uuids_with_workspace_id : list [
41- tuple [ProjectID , WorkspaceID | None ]
42- ], # list of tuples (project_uuid, workspace_id)
43- ) -> dict [ProjectID , dict [GroupID , dict [str , bool ]]]:
44- # Split into private and shared workspace project IDs
45- private_project_ids = [
46- pid for pid , wid in projects_uuids_with_workspace_id if wid is None
47- ]
48- shared_project_ids = [
49- pid for pid , wid in projects_uuids_with_workspace_id if wid is not None
50- ]
51-
54+ projects_uuids_with_workspace_id : list [tuple [ProjectID , WorkspaceID | None ]],
55+ ) -> dict [ProjectIDStr , dict [GroupID , dict [str , bool ]]]:
56+ private_project_ids , workspace_to_project_ids = _split_private_and_shared_projects (
57+ projects_uuids_with_workspace_id
58+ )
59+ shared_workspace_ids = set (workspace_to_project_ids .keys ())
5260 results = {}
5361
5462 async with pass_or_acquire_connection (get_asyncpg_engine (app ), connection ) as conn :
@@ -80,32 +88,37 @@ async def batch_get_project_access_rights(
8088 async for row in private_result :
8189 results [row .project_uuid ] = row .access_rights
8290
83- # Query shared workspace projects
84- if shared_project_ids :
91+ # Query shared workspace projects by workspace_id
92+ if shared_workspace_ids :
8593 shared_query = (
8694 sa .select (
87- workspace_access_rights .c .project_uuid ,
95+ workspaces_access_rights .c .workspace_id ,
8896 sa .func .jsonb_object_agg (
89- workspace_access_rights .c .gid ,
97+ workspaces_access_rights .c .gid ,
9098 sa .func .jsonb_build_object (
9199 "read" ,
92- workspace_access_rights .c .read ,
100+ workspaces_access_rights .c .read ,
93101 "write" ,
94- workspace_access_rights .c .write ,
102+ workspaces_access_rights .c .write ,
95103 "delete" ,
96- workspace_access_rights .c .delete ,
104+ workspaces_access_rights .c .delete ,
97105 ),
98106 ).label ("access_rights" ),
99107 )
100108 .where (
101- workspace_access_rights .c .project_uuid .in_ (
102- [f"{ uuid } " for uuid in shared_project_ids ]
103- )
109+ workspaces_access_rights .c .workspace_id .in_ (shared_workspace_ids )
104110 )
105- .group_by (workspace_access_rights .c .project_uuid )
111+ .group_by (workspaces_access_rights .c .workspace_id )
106112 )
107113 shared_result = await conn .stream (shared_query )
114+ workspace_access_rights_map = {}
108115 async for row in shared_result :
109- results [row .project_uuid ] = row .access_rights
116+ workspace_access_rights_map [row .workspace_id ] = row .access_rights
117+ # Assign access rights to each project in the workspace
118+ for wid , project_ids in workspace_to_project_ids .items ():
119+ access_rights = workspace_access_rights_map .get (wid )
120+ if access_rights is not None :
121+ for pid in project_ids :
122+ results [f"{ pid } " ] = access_rights
110123
111124 return results
0 commit comments