diff --git a/services/web/server/src/simcore_service_webserver/groups/_db.py b/services/web/server/src/simcore_service_webserver/groups/_db.py index d2c6f4d2db5..e3ad2f824c7 100644 --- a/services/web/server/src/simcore_service_webserver/groups/_db.py +++ b/services/web/server/src/simcore_service_webserver/groups/_db.py @@ -7,6 +7,7 @@ from models_library.groups import GroupAtDB from models_library.users import GroupID, UserID from pydantic import parse_obj_as +from simcore_postgres_database.errors import UniqueViolation from simcore_postgres_database.utils_products import get_or_create_product_group from sqlalchemy import and_, literal_column from sqlalchemy.dialects.postgresql import insert @@ -20,7 +21,11 @@ convert_groups_db_to_schema, convert_groups_schema_to_db, ) -from .exceptions import GroupNotFoundError, UserInGroupNotFoundError +from .exceptions import ( + GroupNotFoundError, + UserAlreadyInGroupError, + UserInGroupNotFoundError, +) _DEFAULT_PRODUCT_GROUP_ACCESS_RIGHTS = AccessRightsDict( read=False, @@ -305,6 +310,7 @@ async def add_new_user_in_group( # first check if the group exists group: RowProxy = await _get_user_group(conn, user_id, gid) check_group_permissions(group, user_id, gid, "write") + # now check the new user exists users_count = await conn.scalar( sa.select(sa.func.count()).where(users.c.id == new_user_id) @@ -317,12 +323,18 @@ async def add_new_user_in_group( user_access_rights = _DEFAULT_GROUP_READ_ACCESS_RIGHTS if access_rights: user_access_rights.update(access_rights) - await conn.execute( - # pylint: disable=no-value-for-parameter - user_to_groups.insert().values( - uid=new_user_id, gid=group.gid, access_rights=user_access_rights + + try: + await conn.execute( + # pylint: disable=no-value-for-parameter + user_to_groups.insert().values( + uid=new_user_id, gid=group.gid, access_rights=user_access_rights + ) ) - ) + except UniqueViolation as exc: + raise UserAlreadyInGroupError( + uid=new_user_id, gid=gid, user_id=user_id, access_rights=access_rights + ) from exc async def _get_user_in_group_permissions( diff --git a/services/web/server/src/simcore_service_webserver/groups/_handlers.py b/services/web/server/src/simcore_service_webserver/groups/_handlers.py index 13d9acf71b5..1fa398e84f2 100644 --- a/services/web/server/src/simcore_service_webserver/groups/_handlers.py +++ b/services/web/server/src/simcore_service_webserver/groups/_handlers.py @@ -38,6 +38,7 @@ from ._classifiers import GroupClassifierRepository, build_rrids_tree_view from .exceptions import ( GroupNotFoundError, + UserAlreadyInGroupError, UserInGroupNotFoundError, UserInsufficientRightsError, ) @@ -67,6 +68,11 @@ async def wrapper(request: web.Request) -> web.StreamResponse: except UserInGroupNotFoundError as exc: raise web.HTTPNotFound(reason=f"User not found in group {exc.gid}") from exc + except UserAlreadyInGroupError as exc: + raise web.HTTPConflict( + reason=f"User is already in group {exc.gid}" + ) from exc + except UserInsufficientRightsError as exc: raise web.HTTPForbidden from exc diff --git a/services/web/server/src/simcore_service_webserver/groups/exceptions.py b/services/web/server/src/simcore_service_webserver/groups/exceptions.py index 7556a8cae85..545c73a7727 100644 --- a/services/web/server/src/simcore_service_webserver/groups/exceptions.py +++ b/services/web/server/src/simcore_service_webserver/groups/exceptions.py @@ -4,19 +4,12 @@ class GroupsError(WebServerBaseError): - msg_template = "{msg}" - - def __init__(self, msg: str | None = None): - super().__init__(msg=msg or "Unexpected error occured in projects subpackage") + msg_template = "Groups plugin errored {msg}" class GroupNotFoundError(GroupsError): msg_template = "Group with id {gid} not found" - def __init__(self, gid, **extras): - super().__init__(**extras) - self.gid = gid - class UserInsufficientRightsError(GroupsError): ... @@ -25,7 +18,6 @@ class UserInsufficientRightsError(GroupsError): class UserInGroupNotFoundError(GroupsError): msg_template = "User id {uid} in Group {gid} not found" - def __init__(self, uid, gid, **extras): - super().__init__(**extras) - self.uid = uid - self.gid = gid + +class UserAlreadyInGroupError(GroupsError): + msg_template = "User `{uid}` is already in Group `{gid}`"