Skip to content

Commit 6e4d997

Browse files
committed
testing
1 parent ee1efc7 commit 6e4d997

File tree

5 files changed

+148
-56
lines changed

5 files changed

+148
-56
lines changed

packages/postgres-database/src/simcore_postgres_database/utils_tags.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
""" Repository pattern, errors and data structures for models.tags
22
"""
3-
4-
from typing import TypedDict
5-
63
from common_library.errors_classes import OsparcErrorMixin
74
from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine
5+
from typing_extensions import TypedDict
86

97
from .utils_repos import pass_or_acquire_connection, transaction_context
108
from .utils_tags_sql import (
9+
TagAccessRightsDict,
1110
count_groups_with_given_access_rights_stmt,
1211
create_tag_stmt,
1312
delete_tag_access_rights_stmt,
@@ -20,12 +19,14 @@
2019
upsert_tags_access_rights_stmt,
2120
)
2221

22+
__all__: tuple[str, ...] = ("TagAccessRightsDict",)
23+
2324

2425
#
2526
# Errors
2627
#
27-
class _BaseTagError(ValueError, OsparcErrorMixin):
28-
pass
28+
class _BaseTagError(OsparcErrorMixin, Exception):
29+
msg_template = "Tag repo error on tag {tag_id}"
2930

3031

3132
class TagNotFoundError(_BaseTagError):
@@ -245,7 +246,7 @@ async def has_access_rights(
245246
delete: bool = False,
246247
) -> bool:
247248
async with pass_or_acquire_connection(self.engine, connection) as conn:
248-
result = await conn.execute(
249+
group_id_or_none = await conn.scalar(
249250
has_access_rights_stmt(
250251
tag_id=tag_id,
251252
caller_user_id=caller_id,
@@ -254,31 +255,39 @@ async def has_access_rights(
254255
delete=delete,
255256
)
256257
)
257-
return result.fetchone() is not None
258+
return bool(group_id_or_none)
258259

259260
async def list_access_rights(
260261
self,
261262
connection: AsyncConnection | None = None,
262263
*,
263-
# target
264264
tag_id: int,
265-
):
265+
) -> list[TagAccessRightsDict]:
266266
async with pass_or_acquire_connection(self.engine, connection) as conn:
267267
result = await conn.execute(list_tag_group_access_stmt(tag_id=tag_id))
268-
return [dict(row) for row in result.fetchall()]
268+
return [
269+
TagAccessRightsDict(
270+
tag_id=row.tag_id,
271+
group_id=row.group_id,
272+
read=row.read,
273+
write=row.write,
274+
delete=row.delete,
275+
)
276+
for row in result.fetchall()
277+
]
269278

270279
async def create_or_update_access_rights(
271280
self,
272281
connection: AsyncConnection | None = None,
273282
*,
274-
# target
275283
tag_id: int,
276284
group_id: int,
277285
# access-rights
278286
read: bool,
279287
write: bool,
280288
delete: bool,
281-
):
289+
) -> TagAccessRightsDict:
290+
282291
async with transaction_context(self.engine, connection) as conn:
283292
result = await conn.execute(
284293
upsert_tags_access_rights_stmt(
@@ -290,13 +299,20 @@ async def create_or_update_access_rights(
290299
)
291300
)
292301
row = result.first()
293-
return dict(row)
302+
assert row is not None
303+
304+
return TagAccessRightsDict(
305+
tag_id=row.tag_id,
306+
group_id=row.group_id,
307+
read=row.read,
308+
write=row.write,
309+
delete=row.delete,
310+
)
294311

295312
async def delete_access_rights(
296313
self,
297314
connection: AsyncConnection | None = None,
298315
*,
299-
# target
300316
tag_id: int,
301317
group_id: int,
302318
) -> bool:

packages/postgres-database/src/simcore_postgres_database/utils_tags_sql.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from simcore_postgres_database.models.tags_access_rights import tags_access_rights
1010
from simcore_postgres_database.models.users import users
1111
from sqlalchemy.dialects.postgresql import insert as pg_insert
12+
from typing_extensions import TypedDict
1213

1314
_TAG_COLUMNS = [
1415
tags.c.id,
@@ -167,6 +168,21 @@ def delete_tag_stmt(*, user_id: int, tag_id: int):
167168
# ACCESS RIGHTS
168169
#
169170

171+
_TAG_ACCESS_RIGHTS_COLS = [
172+
tags_access_rights.c.tag_id,
173+
tags_access_rights.c.group_id,
174+
*_ACCESS_RIGHTS_COLUMNS,
175+
]
176+
177+
178+
class TagAccessRightsDict(TypedDict):
179+
tag_id: int
180+
group_id: int
181+
# access rights
182+
read: bool
183+
write: bool
184+
delete: bool
185+
170186

171187
def has_access_rights_stmt(
172188
*,
@@ -194,14 +210,16 @@ def has_access_rights_stmt(
194210
raise ValueError(msg)
195211

196212
conditions.append(group_condition)
213+
214+
# access-right
197215
if read:
198216
conditions.append(tags_access_rights.c.read.is_(True))
199217
if write:
200218
conditions.append(tags_access_rights.c.write.is_(True))
201219
if delete:
202220
conditions.append(tags_access_rights.c.delete.is_(True))
203221

204-
return sa.select(tags_access_rights).where(
222+
return sa.select(tags_access_rights.c.group_id).where(
205223
sa.and_(
206224
tags_access_rights.c.tag_id == tag_id,
207225
*conditions,
@@ -210,11 +228,9 @@ def has_access_rights_stmt(
210228

211229

212230
def list_tag_group_access_stmt(*, tag_id: int):
213-
return sa.select(
214-
tags_access_rights.c.tag_id,
215-
tags_access_rights.c.group_id,
216-
*_ACCESS_RIGHTS_COLUMNS,
217-
).where(tags_access_rights.c.tag_id == tag_id)
231+
return sa.select(*_TAG_ACCESS_RIGHTS_COLS).where(
232+
tags_access_rights.c.tag_id == tag_id
233+
)
218234

219235

220236
def upsert_tags_access_rights_stmt(
@@ -226,7 +242,8 @@ def upsert_tags_access_rights_stmt(
226242
write: bool,
227243
delete: bool,
228244
):
229-
assert (user_id and group_id) or (not user_id and not group_id) # nosec
245+
assert not (user_id is None and group_id is None) # nosec
246+
assert not (user_id is not None and group_id is not None) # nosec
230247

231248
if user_id:
232249
assert not group_id # nosec
@@ -252,11 +269,7 @@ def upsert_tags_access_rights_stmt(
252269
index_elements=["tag_id", "group_id"],
253270
set_={"read": read, "write": write, "delete": delete},
254271
)
255-
.returning(
256-
tags_access_rights.c.tag_id,
257-
tags_access_rights.c.group_id,
258-
*_ACCESS_RIGHTS_COLUMNS,
259-
)
272+
.returning(*_TAG_ACCESS_RIGHTS_COLS)
260273
)
261274

262275

services/web/server/src/simcore_service_webserver/tags/_service.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
from models_library.groups import GroupID
88
from models_library.users import UserID
99
from servicelib.aiohttp.db_asyncpg_engine import get_async_engine
10-
from simcore_postgres_database.utils_tags import TagOperationNotAllowedError, TagsRepo
10+
from simcore_postgres_database.utils_tags import (
11+
TagAccessRightsDict,
12+
TagOperationNotAllowedError,
13+
TagsRepo,
14+
)
1115
from sqlalchemy.ext.asyncio import AsyncEngine
1216

1317
from .schemas import TagCreate, TagGet, TagUpdate
@@ -67,7 +71,7 @@ async def share_tag_with_group(
6771
tag_id: IdInt,
6872
group_id: GroupID,
6973
access_rights: AccessRightsDict,
70-
):
74+
) -> TagAccessRightsDict:
7175
"""
7276
Raises:
7377
TagOperationNotAllowedError
@@ -78,10 +82,10 @@ async def share_tag_with_group(
7882
caller_id=caller_user_id, tag_id=tag_id, write=True
7983
):
8084
raise TagOperationNotAllowedError(
81-
operation="share.write", user_id=caller_user_id, tag_id=tag_id
85+
operation="share or update", user_id=caller_user_id, tag_id=tag_id
8286
)
8387

84-
await repo.create_or_update_access_rights(
88+
return await repo.create_or_update_access_rights(
8589
tag_id=tag_id,
8690
group_id=group_id,
8791
**access_rights,
@@ -95,6 +99,13 @@ async def unshare_tag_with_group(
9599
tag_id: IdInt,
96100
group_id: GroupID,
97101
) -> bool:
102+
"""
103+
Raises:
104+
TagOperationNotAllowedError
105+
106+
Returns:
107+
True if unshared (NOTE: will not raise if not found)
108+
"""
98109
repo = TagsRepo(get_async_engine(app))
99110

100111
if not await repo.has_access_rights(
@@ -113,8 +124,8 @@ async def list_tag_groups(
113124
*,
114125
caller_user_id: UserID,
115126
tag_id: IdInt,
116-
):
117-
127+
) -> list[TagAccessRightsDict]:
128+
"""Returns list of groups sharing this tag"""
118129
repo = TagsRepo(get_async_engine(app))
119130

120131
if not await repo.has_access_rights(

services/web/server/src/simcore_service_webserver/tags/schemas.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import re
2-
from datetime import datetime
3-
from typing import Annotated, Any, Self
2+
from typing import Annotated, Self
43

54
from common_library.groups_dicts import AccessRightsDict
65
from models_library.api_schemas_webserver._base import InputSchema, OutputSchema
@@ -9,7 +8,7 @@
98
from models_library.users import UserID
109
from pydantic import Field, PositiveInt, StringConstraints
1110
from servicelib.request_keys import RQT_USERID_KEY
12-
from simcore_postgres_database.utils_tags import TagDict
11+
from simcore_postgres_database.utils_tags import TagAccessRightsDict, TagDict
1312

1413

1514
class TagRequestContext(RequestParameters):
@@ -95,10 +94,12 @@ class TagGroupGet(OutputSchema):
9594
read: bool
9695
write: bool
9796
delete: bool
98-
# timestamps
99-
created: datetime
100-
modified: datetime
10197

10298
@classmethod
103-
def from_model(cls, data: dict[str, Any]) -> Self:
104-
raise NotImplementedError
99+
def from_model(cls, data: TagAccessRightsDict) -> Self:
100+
return cls(
101+
gid=data["group_id"],
102+
read=data["read"],
103+
write=data["write"],
104+
delete=data["delete"],
105+
)

0 commit comments

Comments
 (0)