5757 ProjectNodesRepo ,
5858)
5959from simcore_postgres_database .webserver_models import ProjectType , projects , users
60- from sqlalchemy import func , literal_column
60+ from sqlalchemy import func , literal_column , sql
6161from sqlalchemy .dialects .postgresql import BOOLEAN , INTEGER
6262from sqlalchemy .dialects .postgresql import insert as pg_insert
6363from sqlalchemy .sql import ColumnElement , CompoundSelect , Select , and_
@@ -370,6 +370,159 @@ async def upsert_project_linked_product(
370370 ).group_by (project_to_groups .c .project_uuid )
371371 ).subquery ("access_rights_subquery" )
372372
373+ def _create_private_workspace_query (
374+ self ,
375+ * ,
376+ product_name : ProductName ,
377+ user_id : UserID ,
378+ workspace_query : WorkspaceQuery ,
379+ project_tags_subquery : sql .Subquery ,
380+ is_search_by_multi_columns : bool ,
381+ user_groups : list [RowProxy ],
382+ ) -> sql .Select | None :
383+ private_workspace_query = None
384+ if workspace_query .workspace_scope is not WorkspaceScope .SHARED :
385+ assert workspace_query .workspace_scope in ( # nosec
386+ WorkspaceScope .PRIVATE ,
387+ WorkspaceScope .ALL ,
388+ )
389+
390+ private_workspace_query = (
391+ sa .select (
392+ * PROJECT_DB_COLS ,
393+ projects .c .workbench ,
394+ self ._access_rights_subquery .c .access_rights ,
395+ projects_to_products .c .product_name ,
396+ projects_to_folders .c .folder_id ,
397+ sa .func .coalesce (
398+ project_tags_subquery .c .tags ,
399+ sa .cast (sa .text ("'{}'" ), sa .ARRAY (sa .Integer )),
400+ ).label ("tags" ),
401+ )
402+ .select_from (
403+ projects .join (self ._access_rights_subquery , isouter = True )
404+ .join (projects_to_products )
405+ .join (
406+ projects_to_folders ,
407+ (
408+ (projects_to_folders .c .project_uuid == projects .c .uuid )
409+ & (projects_to_folders .c .user_id == user_id )
410+ ),
411+ isouter = True ,
412+ )
413+ .join (project_tags_subquery , isouter = True )
414+ )
415+ .where (
416+ (
417+ (projects .c .prj_owner == user_id )
418+ | sa .text (
419+ f"jsonb_exists_any(access_rights_subquery.access_rights, { assemble_array_groups (user_groups )} )"
420+ )
421+ )
422+ & (projects .c .workspace_id .is_ (None )) # <-- Private workspace
423+ & (projects_to_products .c .product_name == product_name )
424+ )
425+ )
426+ if is_search_by_multi_columns :
427+ private_workspace_query = private_workspace_query .join (
428+ users , users .c .id == projects .c .prj_owner , isouter = True
429+ )
430+
431+ return private_workspace_query
432+
433+ def _create_shared_workspace_query (
434+ self ,
435+ * ,
436+ product_name : ProductName ,
437+ workspace_query : WorkspaceQuery ,
438+ project_tags_subquery : sql .Subquery ,
439+ user_groups : list [RowProxy ],
440+ is_search_by_multi_columns : bool ,
441+ ) -> sql .Select | None :
442+
443+ if workspace_query .workspace_scope is not WorkspaceScope .PRIVATE :
444+ assert workspace_query .workspace_scope in (
445+ WorkspaceScope .SHARED ,
446+ WorkspaceScope .ALL ,
447+ )
448+ workspace_access_rights_subquery = (
449+ sa .select (
450+ workspaces_access_rights .c .workspace_id ,
451+ sa .func .jsonb_object_agg (
452+ workspaces_access_rights .c .gid ,
453+ sa .func .jsonb_build_object (
454+ "read" ,
455+ workspaces_access_rights .c .read ,
456+ "write" ,
457+ workspaces_access_rights .c .write ,
458+ "delete" ,
459+ workspaces_access_rights .c .delete ,
460+ ),
461+ )
462+ .filter (workspaces_access_rights .c .read )
463+ .label ("access_rights" ),
464+ ).group_by (workspaces_access_rights .c .workspace_id )
465+ ).subquery ("workspace_access_rights_subquery" )
466+
467+ shared_workspace_query = (
468+ sa .select (
469+ * PROJECT_DB_COLS ,
470+ projects .c .workbench ,
471+ workspace_access_rights_subquery .c .access_rights ,
472+ projects_to_products .c .product_name ,
473+ projects_to_folders .c .folder_id ,
474+ sa .func .coalesce (
475+ project_tags_subquery .c .tags ,
476+ sa .cast (sa .text ("'{}'" ), sa .ARRAY (sa .Integer )),
477+ ).label ("tags" ),
478+ )
479+ .select_from (
480+ projects .join (
481+ workspace_access_rights_subquery ,
482+ projects .c .workspace_id
483+ == workspace_access_rights_subquery .c .workspace_id ,
484+ )
485+ .join (projects_to_products )
486+ .join (
487+ projects_to_folders ,
488+ (
489+ (projects_to_folders .c .project_uuid == projects .c .uuid )
490+ & (projects_to_folders .c .user_id .is_ (None ))
491+ ),
492+ isouter = True ,
493+ )
494+ .join (project_tags_subquery , isouter = True )
495+ )
496+ .where (
497+ (
498+ sa .text (
499+ f"jsonb_exists_any(workspace_access_rights_subquery.access_rights, { assemble_array_groups (user_groups )} )"
500+ )
501+ )
502+ & (projects_to_products .c .product_name == product_name )
503+ )
504+ )
505+ if workspace_query .workspace_scope == WorkspaceScope .ALL :
506+ shared_workspace_query = shared_workspace_query .where (
507+ projects .c .workspace_id .is_not (None ) # <-- All shared workspaces
508+ )
509+ else :
510+ assert workspace_query .workspace_scope == WorkspaceScope .SHARED
511+ shared_workspace_query = shared_workspace_query .where (
512+ projects .c .workspace_id
513+ == workspace_query .workspace_id # <-- Specific shared workspace
514+ )
515+
516+ if is_search_by_multi_columns :
517+ # NOTE: fields searched with text include user's email
518+ shared_workspace_query = shared_workspace_query .join (
519+ users , users .c .id == projects .c .prj_owner , isouter = True
520+ )
521+
522+ return shared_workspace_query
523+
524+ return None
525+
373526 async def list_projects_dicts ( # pylint: disable=too-many-arguments,too-many-statements,too-many-branches
374527 self ,
375528 * ,
@@ -400,26 +553,6 @@ async def list_projects_dicts( # pylint: disable=too-many-arguments,too-many-st
400553
401554 async with self .engine .acquire () as conn :
402555 user_groups : list [RowProxy ] = await self ._list_user_groups (conn , user_id )
403-
404- workspace_access_rights_subquery = (
405- sa .select (
406- workspaces_access_rights .c .workspace_id ,
407- sa .func .jsonb_object_agg (
408- workspaces_access_rights .c .gid ,
409- sa .func .jsonb_build_object (
410- "read" ,
411- workspaces_access_rights .c .read ,
412- "write" ,
413- workspaces_access_rights .c .write ,
414- "delete" ,
415- workspaces_access_rights .c .delete ,
416- ),
417- )
418- .filter (workspaces_access_rights .c .read )
419- .label ("access_rights" ),
420- ).group_by (workspaces_access_rights .c .workspace_id )
421- ).subquery ("workspace_access_rights_subquery" )
422-
423556 project_tags_subquery = (
424557 sa .select (
425558 projects_tags .c .project_id ,
@@ -433,127 +566,25 @@ async def list_projects_dicts( # pylint: disable=too-many-arguments,too-many-st
433566 # Private workspace query
434567 ###
435568
436- if workspace_query .workspace_scope is not WorkspaceScope .SHARED :
437- assert workspace_query .workspace_scope in ( # nosec
438- WorkspaceScope .PRIVATE ,
439- WorkspaceScope .ALL ,
440- )
441-
442- private_workspace_query = (
443- sa .select (
444- * PROJECT_DB_COLS ,
445- projects .c .workbench ,
446- self ._access_rights_subquery .c .access_rights ,
447- projects_to_products .c .product_name ,
448- projects_to_folders .c .folder_id ,
449- sa .func .coalesce (
450- project_tags_subquery .c .tags ,
451- sa .cast (sa .text ("'{}'" ), sa .ARRAY (sa .Integer )),
452- ).label ("tags" ),
453- )
454- .select_from (
455- projects .join (self ._access_rights_subquery , isouter = True )
456- .join (projects_to_products )
457- .join (
458- projects_to_folders ,
459- (
460- (projects_to_folders .c .project_uuid == projects .c .uuid )
461- & (projects_to_folders .c .user_id == user_id )
462- ),
463- isouter = True ,
464- )
465- .join (project_tags_subquery , isouter = True )
466- )
467- .where (
468- (
469- (projects .c .prj_owner == user_id )
470- | sa .text (
471- f"jsonb_exists_any(access_rights_subquery.access_rights, { assemble_array_groups (user_groups )} )"
472- )
473- )
474- & (projects .c .workspace_id .is_ (None )) # <-- Private workspace
475- & (projects_to_products .c .product_name == product_name )
476- )
477- )
478- if search_by_multi_columns is not None :
479- private_workspace_query = private_workspace_query .join (
480- users , users .c .id == projects .c .prj_owner , isouter = True
481- )
482- else :
483- private_workspace_query = None
569+ private_workspace_query = self ._create_private_workspace_query (
570+ product_name = product_name ,
571+ user_id = user_id ,
572+ workspace_query = workspace_query ,
573+ project_tags_subquery = project_tags_subquery ,
574+ is_search_by_multi_columns = search_by_multi_columns is not None ,
575+ user_groups = user_groups ,
576+ )
484577
485578 ###
486579 # Shared workspace query
487580 ###
488-
489- if workspace_query .workspace_scope is not WorkspaceScope .PRIVATE :
490-
491- assert workspace_query .workspace_scope in ( # nosec
492- WorkspaceScope .SHARED ,
493- WorkspaceScope .ALL ,
494- )
495-
496- shared_workspace_query = (
497- sa .select (
498- * PROJECT_DB_COLS ,
499- projects .c .workbench ,
500- workspace_access_rights_subquery .c .access_rights ,
501- projects_to_products .c .product_name ,
502- projects_to_folders .c .folder_id ,
503- sa .func .coalesce (
504- project_tags_subquery .c .tags ,
505- sa .cast (sa .text ("'{}'" ), sa .ARRAY (sa .Integer )),
506- ).label ("tags" ),
507- )
508- .select_from (
509- projects .join (
510- workspace_access_rights_subquery ,
511- projects .c .workspace_id
512- == workspace_access_rights_subquery .c .workspace_id ,
513- )
514- .join (projects_to_products )
515- .join (
516- projects_to_folders ,
517- (
518- (projects_to_folders .c .project_uuid == projects .c .uuid )
519- & (projects_to_folders .c .user_id .is_ (None ))
520- ),
521- isouter = True ,
522- )
523- .join (project_tags_subquery , isouter = True )
524- )
525- .where (
526- (
527- sa .text (
528- f"jsonb_exists_any(workspace_access_rights_subquery.access_rights, { assemble_array_groups (user_groups )} )"
529- )
530- )
531- & (projects_to_products .c .product_name == product_name )
532- )
533- )
534- if workspace_query .workspace_scope == WorkspaceScope .ALL :
535- shared_workspace_query = shared_workspace_query .where (
536- projects .c .workspace_id .is_not (
537- None
538- ) # <-- All shared workspaces
539- )
540- else :
541- assert ( # nosec
542- workspace_query .workspace_scope == WorkspaceScope .SHARED
543- )
544- shared_workspace_query = shared_workspace_query .where (
545- projects .c .workspace_id
546- == workspace_query .workspace_id # <-- Specific shared workspace
547- )
548-
549- if search_by_multi_columns is not None :
550- # NOTE: fields searched with text include user's email
551- shared_workspace_query = shared_workspace_query .join (
552- users , users .c .id == projects .c .prj_owner , isouter = True
553- )
554-
555- else :
556- shared_workspace_query = None
581+ shared_workspace_query = self ._create_shared_workspace_query (
582+ product_name = product_name ,
583+ workspace_query = workspace_query ,
584+ project_tags_subquery = project_tags_subquery ,
585+ user_groups = user_groups ,
586+ is_search_by_multi_columns = search_by_multi_columns is not None ,
587+ )
557588
558589 ###
559590 # Attributes Filters
0 commit comments