Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Workspaces / Folders v2 🗃️🚨 #6248

Merged
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
941dfe3
daily work
matusdrobuliak66 Aug 23, 2024
686b4d6
Merge branch 'master' into sharing-folders
matusdrobuliak66 Aug 26, 2024
a873c57
daily work
matusdrobuliak66 Aug 27, 2024
3ece531
refactor has_permission
matusdrobuliak66 Aug 27, 2024
1c08686
remove has_permission function
matusdrobuliak66 Aug 28, 2024
2c1f6a3
merge master
matusdrobuliak66 Aug 28, 2024
bae77ee
refactoring check_project_permissions
matusdrobuliak66 Aug 28, 2024
582405d
refactoring get project
matusdrobuliak66 Aug 29, 2024
b8a617b
refactoring permissions + mypy folders
matusdrobuliak66 Aug 29, 2024
c2a22e8
open api specs
matusdrobuliak66 Aug 29, 2024
3274721
Merge branch 'master' into sharing-folders
matusdrobuliak66 Aug 29, 2024
82b1145
Merge branch 'master' into sharing-folders
matusdrobuliak66 Aug 29, 2024
e87a6e8
add user to projects_to_folders table
matusdrobuliak66 Aug 29, 2024
ebdb50a
projects to folders
matusdrobuliak66 Aug 29, 2024
1f6b115
unit tests workspaces
matusdrobuliak66 Aug 30, 2024
a153151
unit tests fix list projects with order_by_parameter
matusdrobuliak66 Aug 30, 2024
c61d23a
open api specs
matusdrobuliak66 Aug 30, 2024
a64f132
open api specs
matusdrobuliak66 Aug 30, 2024
8c314c0
open api specs
matusdrobuliak66 Aug 30, 2024
f36ed36
fix tags test
matusdrobuliak66 Aug 30, 2024
df1f0eb
fix workspace test
matusdrobuliak66 Aug 30, 2024
8c37ece
fix project listing
matusdrobuliak66 Aug 30, 2024
7b687af
cleaning
matusdrobuliak66 Aug 30, 2024
dab7a46
Merge branch 'master' into sharing-folders
matusdrobuliak66 Aug 30, 2024
33fa3ef
fix unit tests:
matusdrobuliak66 Aug 30, 2024
d57b2eb
Merge branch 'sharing-folders' of github.com:matusdrobuliak66/osparc-…
matusdrobuliak66 Aug 30, 2024
13da1d6
Merge branch 'master' into sharing-folders
matusdrobuliak66 Aug 30, 2024
06a4c57
fix listing projects with search
matusdrobuliak66 Aug 30, 2024
8fec8bf
Merge branch 'master' into sharing-folders
matusdrobuliak66 Aug 30, 2024
d8c1c47
fix project listing
matusdrobuliak66 Aug 30, 2024
6656e8e
fix project listing
matusdrobuliak66 Aug 30, 2024
eb0df9b
fix last tests
matusdrobuliak66 Aug 31, 2024
076aa99
adding improvements
matusdrobuliak66 Aug 31, 2024
f714498
adding improvements
matusdrobuliak66 Aug 31, 2024
ec24a9f
improvements to folder permission checking
matusdrobuliak66 Aug 31, 2024
b70321c
adding additional unit test
matusdrobuliak66 Sep 1, 2024
5364793
review @sanderegg
matusdrobuliak66 Sep 1, 2024
94336a2
review @sanderegg
matusdrobuliak66 Sep 2, 2024
7d722ac
review @sanderegg
matusdrobuliak66 Sep 2, 2024
fa3fc4f
review @sanderegg
matusdrobuliak66 Sep 2, 2024
2fafba8
remove comment:
matusdrobuliak66 Sep 2, 2024
b4fac4c
Merge branch 'master' into sharing-folders
matusdrobuliak66 Sep 2, 2024
2a5a983
open api specs
matusdrobuliak66 Sep 2, 2024
541cc3b
fix projects access
matusdrobuliak66 Sep 2, 2024
10af056
add tests user role permissions
matusdrobuliak66 Sep 2, 2024
0606090
review @prespo
matusdrobuliak66 Sep 2, 2024
7a1831d
Merge branch 'master' into sharing-folders
matusdrobuliak66 Sep 2, 2024
47eeed7
Merge branch 'master' into sharing-folders
matusdrobuliak66 Sep 2, 2024
353a17b
review @GitHK
matusdrobuliak66 Sep 3, 2024
518de28
Merge branch 'sharing-folders' of github.com:matusdrobuliak66/osparc-…
matusdrobuliak66 Sep 3, 2024
7082c04
review db
matusdrobuliak66 Sep 3, 2024
aa2a295
Merge branch 'master' into sharing-folders
matusdrobuliak66 Sep 3, 2024
aba1356
adding my_access_rights and access_rights to the workspaces resource …
matusdrobuliak66 Sep 3, 2024
77a1f57
Merge branch 'sharing-folders' of github.com:matusdrobuliak66/osparc-…
matusdrobuliak66 Sep 3, 2024
0cf4e0f
add workspace_id to project resource GET & override project access ri…
matusdrobuliak66 Sep 3, 2024
c2eefc6
improvements
matusdrobuliak66 Sep 3, 2024
c97ae29
Merge branch 'master' into sharing-folders
matusdrobuliak66 Sep 3, 2024
84d8f7b
revision migration id
matusdrobuliak66 Sep 3, 2024
6d2be35
default workspace id
matusdrobuliak66 Sep 3, 2024
a9de8e2
fix get project
matusdrobuliak66 Sep 3, 2024
56cce1d
add tests
matusdrobuliak66 Sep 3, 2024
163cf85
fix
matusdrobuliak66 Sep 4, 2024
0f23ae6
fix
matusdrobuliak66 Sep 4, 2024
0c73073
open api specs
matusdrobuliak66 Sep 4, 2024
aeed0b6
Merge branch 'master' into sharing-folders
matusdrobuliak66 Sep 4, 2024
5126448
Merge branch 'master' into sharing-folders
matusdrobuliak66 Sep 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 5 additions & 48 deletions api/specs/web-server/_folders.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,18 @@
from typing import Annotated

from fastapi import APIRouter, Depends, Query, status
from models_library.api_schemas_webserver.folders import (
from models_library.api_schemas_webserver.folders_v2 import (
CreateFolderBodyParams,
FolderGet,
PutFolderBodyParams,
)
from models_library.folders import FolderID
from models_library.generics import Envelope
from models_library.rest_pagination import PageQueryParameters
from models_library.workspaces import WorkspaceID
from pydantic import Json
from simcore_service_webserver._meta import API_VTAG
from simcore_service_webserver.folders._folders_handlers import FoldersPathParams
from simcore_service_webserver.folders._groups_api import FolderGroupGet
from simcore_service_webserver.folders._groups_handlers import (
_FoldersGroupsBodyParams,
_FoldersGroupsPathParams,
)

router = APIRouter(
prefix=f"/{API_VTAG}",
Expand All @@ -51,6 +48,8 @@ async def create_folder(_body: CreateFolderBodyParams):
)
async def list_folders(
params: Annotated[PageQueryParameters, Depends()],
folder_id: FolderID | None = None,
workspace_id: WorkspaceID | None = None,
order_by: Annotated[
Json,
Query(
Expand Down Expand Up @@ -86,45 +85,3 @@ async def replace_folder(
)
async def delete_folder(_path: Annotated[FoldersPathParams, Depends()]):
...


### Folders groups


@router.post(
"/folders/{folder_id}/groups/{group_id}",
response_model=Envelope[FolderGroupGet],
status_code=status.HTTP_201_CREATED,
)
async def create_folder_group(
_path: Annotated[_FoldersGroupsPathParams, Depends()],
_body: _FoldersGroupsBodyParams,
):
...


@router.get(
"/folders/{folder_id}/groups",
response_model=Envelope[list[FolderGroupGet]],
)
async def list_folder_groups(_path: Annotated[FoldersPathParams, Depends()]):
...


@router.put(
"/folders/{folder_id}/groups/{group_id}",
response_model=Envelope[FolderGroupGet],
)
async def replace_folder_group(
_path: Annotated[_FoldersGroupsPathParams, Depends()],
_body: _FoldersGroupsBodyParams,
):
...


@router.delete(
"/folders/{folder_id}/groups/{group_id}",
status_code=status.HTTP_204_NO_CONTENT,
)
async def delete_folder_group(_path: Annotated[_FoldersGroupsPathParams, Depends()]):
...
113 changes: 113 additions & 0 deletions api/specs/web-server/_workspaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
""" Helper script to generate OAS automatically
"""

# pylint: disable=redefined-outer-name
# pylint: disable=unused-argument
# pylint: disable=unused-variable
# pylint: disable=too-many-arguments


from fastapi import APIRouter, status
from models_library.api_schemas_webserver.workspaces import (
CreateWorkspaceBodyParams,
PutWorkspaceBodyParams,
WorkspaceGet,
)
from models_library.generics import Envelope
from models_library.users import GroupID
from models_library.workspaces import WorkspaceID
from simcore_service_webserver._meta import API_VTAG
from simcore_service_webserver.workspaces._groups_api import WorkspaceGroupGet
from simcore_service_webserver.workspaces._groups_handlers import (
_WorkspacesGroupsBodyParams,
)

router = APIRouter(
prefix=f"/{API_VTAG}",
tags=[
"workspaces",
],
)

### Workspaces


@router.post(
"/workspaces",
response_model=Envelope[WorkspaceGet],
status_code=status.HTTP_201_CREATED,
)
async def create_workspace(body: CreateWorkspaceBodyParams):
...


@router.get(
"/workspaces",
response_model=Envelope[list[WorkspaceGet]],
)
async def list_workspaces():
...


@router.get(
"/workspaces/{workspace_id}",
response_model=Envelope[WorkspaceGet],
)
async def get_workspace(workspace_id: WorkspaceID):
...


@router.put(
"/workspaces/{workspace_id}",
response_model=Envelope[WorkspaceGet],
)
async def replace_workspace(workspace_id: WorkspaceID, body: PutWorkspaceBodyParams):
...


@router.delete(
"/workspaces/{workspace_id}",
status_code=status.HTTP_204_NO_CONTENT,
)
async def delete_workspace(workspace_id: WorkspaceID):
...


### Workspaces groups


@router.post(
"/workspaces/{workspace_id}/groups/{group_id}",
response_model=Envelope[WorkspaceGroupGet],
status_code=status.HTTP_201_CREATED,
)
async def create_workspace_group(
workspace_id: WorkspaceID, group_id: GroupID, body: _WorkspacesGroupsBodyParams
):
...


@router.get(
"/workspaces/{workspace_id}/groups",
response_model=Envelope[list[WorkspaceGroupGet]],
)
async def list_workspace_groups(workspace_id: WorkspaceID):
...


@router.put(
"/workspaces/{workspace_id}/groups/{group_id}",
response_model=Envelope[WorkspaceGroupGet],
)
async def replace_workspace_group(
workspace_id: WorkspaceID, group_id: GroupID, body: _WorkspacesGroupsBodyParams
):
...


@router.delete(
"/workspaces/{workspace_id}/groups/{group_id}",
status_code=status.HTTP_204_NO_CONTENT,
)
async def delete_workspace_group(workspace_id: WorkspaceID, group_id: GroupID):
...
1 change: 1 addition & 0 deletions api/specs/web-server/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"_users",
"_version_control",
"_wallets",
"_workspaces",
)
]

Expand Down
10 changes: 10 additions & 0 deletions packages/models-library/src/models_library/access_rights.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from pydantic import BaseModel, Extra, Field


class AccessRights(BaseModel):
read: bool = Field(..., description="has read access")
write: bool = Field(..., description="has write access")
delete: bool = Field(..., description="has deletion rights")

class Config:
extra = Extra.forbid
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from datetime import datetime
from typing import NamedTuple

from models_library.basic_types import IDStr
from models_library.folders import FolderID
from models_library.users import GroupID
from models_library.utils.common_validators import null_or_none_str_to_none_validator
from models_library.workspaces import WorkspaceID
from pydantic import Extra, PositiveInt, validator

from ._base import InputSchema, OutputSchema


class FolderGet(OutputSchema):
folder_id: FolderID
parent_folder_id: FolderID | None = None
name: str
created_at: datetime
modified_at: datetime
owner: GroupID


class FolderGetPage(NamedTuple):
items: list[FolderGet]
total: PositiveInt


class CreateFolderBodyParams(InputSchema):
name: IDStr
parent_folder_id: FolderID | None = None
workspace_id: WorkspaceID | None = None

class Config:
extra = Extra.forbid

_null_or_none_str_to_none_validator = validator(
"parent_folder_id", allow_reuse=True, pre=True
)(null_or_none_str_to_none_validator)

_null_or_none_str_to_none_validator2 = validator(
"workspace_id", allow_reuse=True, pre=True
)(null_or_none_str_to_none_validator)


class PutFolderBodyParams(InputSchema):
name: IDStr
parent_folder_id: FolderID | None

class Config:
extra = Extra.forbid

_null_or_none_str_to_none_validator = validator(
"parent_folder_id", allow_reuse=True, pre=True
)(null_or_none_str_to_none_validator)
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from datetime import datetime
from typing import NamedTuple

from models_library.basic_types import IDStr
from models_library.users import GroupID
from models_library.workspaces import WorkspaceID
from pydantic import Extra, PositiveInt

from ..access_rights import AccessRights
from ._base import InputSchema, OutputSchema


class WorkspaceGet(OutputSchema):
workspace_id: WorkspaceID
name: str
description: str | None
thumbnail: str | None
created_at: datetime
modified_at: datetime
owner_primary_gid: GroupID
my_access_rights: AccessRights


class WorkspaceGetPage(NamedTuple):
items: list[WorkspaceGet]
total: PositiveInt


class CreateWorkspaceBodyParams(InputSchema):
name: str
description: str | None = None
thumbnail: str | None = None

class Config:
extra = Extra.forbid


class PutWorkspaceBodyParams(InputSchema):
name: IDStr
description: str | None = None
thumbnail: str | None = None

class Config:
extra = Extra.forbid
30 changes: 29 additions & 1 deletion packages/models-library/src/models_library/folders.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
from datetime import datetime
from typing import TypeAlias

from pydantic import PositiveInt
from models_library.users import GroupID, UserID
from models_library.workspaces import WorkspaceID
from pydantic import BaseModel, Field, PositiveInt

FolderID: TypeAlias = PositiveInt


#
# DB
#


class FolderDB(BaseModel):
folder_id: FolderID
name: str
parent_folder_id: FolderID | None
created_by_gid: GroupID = Field(
...,
description="GID of the group that owns this wallet",
)
created: datetime = Field(
...,
description="Timestamp on creation",
)
modified: datetime = Field(
...,
description="Timestamp of last modification",
)
user_id: UserID | None
workspace_id: WorkspaceID | None
42 changes: 42 additions & 0 deletions packages/models-library/src/models_library/workspaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from datetime import datetime
from typing import TypeAlias

from pydantic import BaseModel, Field, PositiveInt

WorkspaceID: TypeAlias = PositiveInt


#
# DB
#


class WorkspaceDB(BaseModel):
workspace_id: WorkspaceID
name: str
description: str | None
owner_primary_gid: PositiveInt = Field(
...,
description="GID of the group that owns this wallet",
)
thumbnail: str | None
created: datetime = Field(
...,
description="Timestamp on creation",
)
modified: datetime = Field(
...,
description="Timestamp of last modification",
)

class Config:
orm_mode = True


class UserWorkspaceAccessRightsDB(WorkspaceDB):
read: bool
write: bool
delete: bool

class Config:
orm_mode = True
Loading
Loading