Skip to content

Commit b116127

Browse files
authored
Merge branch 'master' into enh/ligth-theme
2 parents 3c1d1b2 + f7e6d5b commit b116127

File tree

13 files changed

+879
-420
lines changed

13 files changed

+879
-420
lines changed

api/specs/web-server/_folders.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,27 @@ async def list_folders(
6363
...
6464

6565

66+
@router.get(
67+
"/folders:search",
68+
response_model=Envelope[list[FolderGet]],
69+
)
70+
async def list_folders_full_search(
71+
params: Annotated[PageQueryParameters, Depends()],
72+
order_by: Annotated[
73+
Json,
74+
Query(
75+
description="Order by field (modified_at|name|description) and direction (asc|desc). The default sorting order is ascending.",
76+
example='{"field": "name", "direction": "desc"}',
77+
),
78+
] = '{"field": "modified_at", "direction": "desc"}',
79+
filters: Annotated[
80+
Json | None,
81+
Query(description=FolderFilters.schema_json(indent=1)),
82+
] = None,
83+
):
84+
...
85+
86+
6687
@router.get(
6788
"/folders/{folder_id}",
6889
response_model=Envelope[FolderGet],

packages/models-library/src/models_library/folders.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from pydantic import BaseModel, Field, PositiveInt, validator
66

7+
from .access_rights import AccessRights
78
from .users import GroupID, UserID
89
from .utils.enums import StrAutoEnum
910
from .workspaces import WorkspaceID
@@ -66,3 +67,10 @@ class FolderDB(BaseModel):
6667

6768
class Config:
6869
orm_mode = True
70+
71+
72+
class UserFolderAccessRightsDB(FolderDB):
73+
my_access_rights: AccessRights
74+
75+
class Config:
76+
orm_mode = True
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def assemble_array_groups(user_group_ids: list[int]) -> str:
2+
return (
3+
"array[]::text[]"
4+
if len(user_group_ids) == 0
5+
else f"""array[{', '.join(f"'{group_id}'" for group_id in user_group_ids)}]"""
6+
)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from simcore_postgres_database.models.groups import user_to_groups
2+
from simcore_postgres_database.models.workspaces_access_rights import (
3+
workspaces_access_rights,
4+
)
5+
from sqlalchemy import func
6+
from sqlalchemy.dialects.postgresql import BOOLEAN, INTEGER
7+
from sqlalchemy.sql import Subquery, select
8+
9+
10+
def create_my_workspace_access_rights_subquery(user_id: int) -> Subquery:
11+
return (
12+
select(
13+
workspaces_access_rights.c.workspace_id,
14+
func.json_build_object(
15+
"read",
16+
func.max(workspaces_access_rights.c.read.cast(INTEGER)).cast(BOOLEAN),
17+
"write",
18+
func.max(workspaces_access_rights.c.write.cast(INTEGER)).cast(BOOLEAN),
19+
"delete",
20+
func.max(workspaces_access_rights.c.delete.cast(INTEGER)).cast(BOOLEAN),
21+
).label("my_access_rights"),
22+
)
23+
.select_from(
24+
workspaces_access_rights.join(
25+
user_to_groups, user_to_groups.c.gid == workspaces_access_rights.c.gid
26+
)
27+
)
28+
.where(user_to_groups.c.uid == user_id)
29+
.group_by(workspaces_access_rights.c.workspace_id)
30+
).subquery("my_workspace_access_rights_subquery")

services/storage/src/simcore_service_storage/db_access_layer.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
workspaces_access_rights,
5252
)
5353
from simcore_postgres_database.storage_models import file_meta_data, user_to_groups
54+
from simcore_postgres_database.utils_sql import assemble_array_groups
5455

5556
logger = logging.getLogger(__name__)
5657

@@ -117,14 +118,6 @@ def _aggregate_access_rights(
117118
return AccessRights.none()
118119

119120

120-
def assemble_array_groups(user_group_ids: list[GroupID]) -> str:
121-
return (
122-
"array[]::text[]"
123-
if len(user_group_ids) == 0
124-
else f"""array[{', '.join(f"'{group_id}'" for group_id in user_group_ids)}]"""
125-
)
126-
127-
128121
access_rights_subquery = (
129122
sa.select(
130123
project_to_groups.c.project_uuid,

services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2690,6 +2690,70 @@ paths:
26902690
application/json:
26912691
schema:
26922692
$ref: '#/components/schemas/Envelope_FolderGet_'
2693+
/v0/folders:search:
2694+
get:
2695+
tags:
2696+
- folders
2697+
summary: List Folders Full Search
2698+
operationId: list_folders_full_search
2699+
parameters:
2700+
- description: Order by field (modified_at|name|description) and direction (asc|desc).
2701+
The default sorting order is ascending.
2702+
required: false
2703+
schema:
2704+
title: Order By
2705+
description: Order by field (modified_at|name|description) and direction
2706+
(asc|desc). The default sorting order is ascending.
2707+
default: '{"field": "modified_at", "direction": "desc"}'
2708+
example: '{"field": "name", "direction": "desc"}'
2709+
name: order_by
2710+
in: query
2711+
- description: "{\n \"title\": \"FolderFilters\",\n \"description\": \"Encoded\
2712+
\ as JSON. Each available filter can have its own logic (should be well\
2713+
\ documented)\\nInspired by Docker API https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerList.\"\
2714+
,\n \"type\": \"object\",\n \"properties\": {\n \"trashed\": {\n \"title\"\
2715+
: \"Trashed\",\n \"description\": \"Set to true to list trashed, false\
2716+
\ to list non-trashed (default), None to list all\",\n \"default\": false,\n\
2717+
\ \"type\": \"boolean\"\n }\n }\n}"
2718+
required: false
2719+
schema:
2720+
title: Filters
2721+
type: string
2722+
description: "{\n \"title\": \"FolderFilters\",\n \"description\": \"Encoded\
2723+
\ as JSON. Each available filter can have its own logic (should be well\
2724+
\ documented)\\nInspired by Docker API https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerList.\"\
2725+
,\n \"type\": \"object\",\n \"properties\": {\n \"trashed\": {\n \"\
2726+
title\": \"Trashed\",\n \"description\": \"Set to true to list trashed,\
2727+
\ false to list non-trashed (default), None to list all\",\n \"default\"\
2728+
: false,\n \"type\": \"boolean\"\n }\n }\n}"
2729+
format: json-string
2730+
name: filters
2731+
in: query
2732+
- required: false
2733+
schema:
2734+
title: Limit
2735+
exclusiveMaximum: true
2736+
minimum: 1
2737+
type: integer
2738+
default: 20
2739+
maximum: 50
2740+
name: limit
2741+
in: query
2742+
- required: false
2743+
schema:
2744+
title: Offset
2745+
minimum: 0
2746+
type: integer
2747+
default: 0
2748+
name: offset
2749+
in: query
2750+
responses:
2751+
'200':
2752+
description: Successful Response
2753+
content:
2754+
application/json:
2755+
schema:
2756+
$ref: '#/components/schemas/Envelope_list_models_library.api_schemas_webserver.folders_v2.FolderGet__'
26932757
/v0/folders/{folder_id}:
26942758
get:
26952759
tags:

0 commit comments

Comments
 (0)