Skip to content

Commit 6f80ef8

Browse files
feat: return updated access rights
1 parent b389b90 commit 6f80ef8

File tree

7 files changed

+86
-36
lines changed

7 files changed

+86
-36
lines changed

api/specs/web-server/_functions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from _common import as_query
1111
from fastapi import APIRouter, Depends, status
1212
from models_library.api_schemas_webserver.functions import (
13-
FunctionGroupGet,
14-
FunctionGroupUpdate,
13+
FunctionGroupAccessRightsGet,
14+
FunctionGroupAccessRightsUpdate,
1515
FunctionToRegister,
1616
RegisteredFunctionGet,
1717
RegisteredFunctionUpdate,
@@ -84,11 +84,11 @@ async def delete_function(
8484

8585
@router.put(
8686
"/functions/{function_id}/groups/{group_id}",
87-
response_model=Envelope[FunctionGroupGet],
87+
response_model=Envelope[FunctionGroupAccessRightsGet],
8888
)
8989
async def update_function_group(
9090
_path: Annotated[FunctionGroupPathParams, Depends()],
91-
_body: FunctionGroupUpdate,
91+
_body: FunctionGroupAccessRightsUpdate,
9292
): ...
9393

9494

packages/models-library/src/models_library/api_schemas_webserver/functions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,13 @@ class ProjectFunctionToRegister(ProjectFunction, InputSchema): ...
151151
class RegisteredFunctionUpdate(FunctionUpdate, InputSchema): ...
152152

153153

154-
class FunctionGroupGet(OutputSchema):
154+
class FunctionGroupAccessRightsGet(OutputSchema):
155155
read: bool
156156
write: bool
157157
execute: bool
158158

159159

160-
class FunctionGroupUpdate(InputSchema):
160+
class FunctionGroupAccessRightsUpdate(InputSchema):
161161
read: bool
162162
write: bool
163163
execute: bool

services/web/server/src/simcore_service_webserver/functions/_controller/_functions_rest.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from aiohttp import web
44
from models_library.api_schemas_webserver.functions import (
55
Function,
6-
FunctionGroupUpdate,
6+
FunctionGroupAccessRightsGet,
7+
FunctionGroupAccessRightsUpdate,
78
FunctionToRegister,
89
RegisteredFunction,
910
RegisteredFunctionGet,
@@ -378,24 +379,32 @@ async def update_function_group(request: web.Request) -> web.Response:
378379

379380
req_ctx = AuthenticatedRequestContext.model_validate(request)
380381

381-
function_group_update = FunctionGroupUpdate.model_validate(await request.json())
382-
383-
await _functions_service.set_function_group_permissions(
384-
request.app,
385-
user_id=req_ctx.user_id,
386-
product_name=req_ctx.product_name,
387-
function_id=function_id,
388-
permissions=FunctionGroupAccessRights(
389-
group_id=group_id,
390-
read=function_group_update.read,
391-
write=function_group_update.write,
392-
execute=function_group_update.execute,
393-
),
382+
function_group_update = FunctionGroupAccessRightsUpdate.model_validate(
383+
await request.json()
394384
)
395385

396-
# TODO: return updated permissions
386+
updated_function_access_rights = (
387+
await _functions_service.set_function_group_permissions(
388+
request.app,
389+
user_id=req_ctx.user_id,
390+
product_name=req_ctx.product_name,
391+
function_id=function_id,
392+
permissions=FunctionGroupAccessRights(
393+
group_id=group_id,
394+
read=function_group_update.read,
395+
write=function_group_update.write,
396+
execute=function_group_update.execute,
397+
),
398+
)
399+
)
397400

398-
return web.json_response(status=status.HTTP_202_ACCEPTED)
401+
return envelope_json_response(
402+
FunctionGroupAccessRightsGet(
403+
read=updated_function_access_rights.read,
404+
write=updated_function_access_rights.write,
405+
execute=updated_function_access_rights.execute,
406+
)
407+
)
399408

400409

401410
@routes.delete(
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from common_library.errors_classes import OsparcErrorMixin
2+
3+
4+
class FunctionGroupAccessRightsNotFoundError(OsparcErrorMixin, Exception):
5+
msg_template = "Group '{group_id}' does not have access rights to {object_type} '{object_id}' in product '{product_name}'"

services/web/server/src/simcore_service_webserver/functions/_functions_repository.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from models_library.functions import (
1111
FunctionAccessRightsDB,
1212
FunctionClass,
13+
FunctionGroupAccessRights,
1314
FunctionID,
1415
FunctionInputs,
1516
FunctionInputSchema,
@@ -1075,7 +1076,7 @@ async def set_group_permissions(
10751076
read: bool | None = None,
10761077
write: bool | None = None,
10771078
execute: bool | None = None,
1078-
) -> None:
1079+
) -> list[tuple[UUID, FunctionGroupAccessRights]]:
10791080
async with pass_or_acquire_connection(get_asyncpg_engine(app), connection) as conn:
10801081
for object_id in object_ids:
10811082
await check_user_permissions(
@@ -1088,7 +1089,7 @@ async def set_group_permissions(
10881089
permissions=["write"],
10891090
)
10901091

1091-
await _internal_set_group_permissions(
1092+
return await _internal_set_group_permissions(
10921093
app,
10931094
connection=connection,
10941095
permission_group_id=permission_group_id,
@@ -1180,7 +1181,7 @@ async def _internal_set_group_permissions(
11801181
read: bool | None = None,
11811182
write: bool | None = None,
11821183
execute: bool | None = None,
1183-
) -> None:
1184+
) -> list[tuple[UUID, FunctionGroupAccessRights]]:
11841185
access_rights_table = None
11851186
field_name = None
11861187
if object_type == "function":
@@ -1196,6 +1197,7 @@ async def _internal_set_group_permissions(
11961197
assert access_rights_table is not None # nosec
11971198
assert field_name is not None # nosec
11981199

1200+
access_rights_list: list[tuple[UUID, FunctionGroupAccessRights]] = []
11991201
async with transaction_context(get_asyncpg_engine(app), connection) as transaction:
12001202
for object_id in object_ids:
12011203
# Check if the group already has access rights for the function
@@ -1209,16 +1211,25 @@ async def _internal_set_group_permissions(
12091211

12101212
if row is None:
12111213
# Insert new access rights if the group does not have any
1212-
await transaction.execute(
1213-
access_rights_table.insert().values(
1214+
result = await transaction.execute(
1215+
access_rights_table.insert()
1216+
.values(
12141217
**{field_name: object_id},
12151218
group_id=permission_group_id,
12161219
product_name=product_name,
12171220
read=read if read is not None else False,
12181221
write=write if write is not None else False,
12191222
execute=execute if execute is not None else False,
12201223
)
1224+
.returning(
1225+
access_rights_table.c.group_id,
1226+
access_rights_table.c.read,
1227+
access_rights_table.c.write,
1228+
access_rights_table.c.execute,
1229+
)
12211230
)
1231+
row = result.one()
1232+
access_rights_list.append((object_id, FunctionGroupAccessRights(**row)))
12221233
else:
12231234
# Update existing access rights only for non-None values
12241235
update_values = {
@@ -1234,7 +1245,17 @@ async def _internal_set_group_permissions(
12341245
access_rights_table.c.group_id == permission_group_id,
12351246
)
12361247
.values(**update_values)
1248+
.returning(
1249+
access_rights_table.c.group_id,
1250+
access_rights_table.c.read,
1251+
access_rights_table.c.write,
1252+
access_rights_table.c.execute,
1253+
)
12371254
)
1255+
row = result.one()
1256+
access_rights_list.append((object_id, FunctionGroupAccessRights(**row)))
1257+
1258+
return access_rights_list
12381259

12391260

12401261
async def get_user_api_access_rights(

services/web/server/src/simcore_service_webserver/functions/_functions_service.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
from servicelib.rabbitmq import RPCRouter
4545

4646
from . import _functions_repository
47+
from ._functions_exceptions import FunctionGroupAccessRightsNotFoundError
4748

4849
router = RPCRouter()
4950

@@ -464,8 +465,8 @@ async def set_function_group_permissions(
464465
product_name: ProductName,
465466
function_id: FunctionID,
466467
permissions: FunctionGroupAccessRights,
467-
) -> None:
468-
await _functions_repository.set_group_permissions(
468+
) -> FunctionGroupAccessRights:
469+
access_rights_list = await _functions_repository.set_group_permissions(
469470
app=app,
470471
user_id=user_id,
471472
product_name=product_name,
@@ -476,6 +477,16 @@ async def set_function_group_permissions(
476477
write=permissions.write,
477478
execute=permissions.execute,
478479
)
480+
for object_id, access_rights in access_rights_list:
481+
if object_id == function_id:
482+
return access_rights
483+
484+
raise FunctionGroupAccessRightsNotFoundError(
485+
group_id=permissions.group_id,
486+
product_name=product_name,
487+
object_id=function_id,
488+
object_type="function",
489+
)
479490

480491

481492
async def remove_function_group_permissions(

services/web/server/tests/unit/with_dbs/04/functions/test_functions_service.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,24 @@ async def test_set_and_remove_group_permissions(
5353
function_id=registered_function.uid,
5454
)
5555

56+
group_permissions = FunctionGroupAccessRights(
57+
group_id=int(other_logged_user["primary_gid"]),
58+
read=True,
59+
write=True,
60+
execute=False,
61+
)
62+
5663
# Give non-registering user group access
57-
await _functions_service.set_function_group_permissions(
64+
updated_group_permissions = await _functions_service.set_function_group_permissions(
5865
app=client.app,
5966
user_id=logged_user["id"],
6067
product_name=osparc_product_name,
6168
function_id=registered_function.uid,
62-
permissions=FunctionGroupAccessRights(
63-
group_id=int(other_logged_user["primary_gid"]),
64-
read=True,
65-
write=True,
66-
execute=False,
67-
),
69+
permissions=group_permissions,
6870
)
6971

72+
assert updated_group_permissions == group_permissions
73+
7074
# Test if non-registering user can access the function
7175
returned_function = await _functions_service.get_function(
7276
app=client.app,

0 commit comments

Comments
 (0)