Skip to content

Commit 081098c

Browse files
authored
🐛 fixes unhandled access-rights exception in projects (#7012)
1 parent 81eb245 commit 081098c

File tree

12 files changed

+44
-38
lines changed

12 files changed

+44
-38
lines changed

packages/service-library/src/servicelib/aiohttp/rest_middlewares.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
DEFAULT_API_VERSION = "v0"
3333
_FMSG_INTERNAL_ERROR_USER_FRIENDLY_WITH_OEC = (
3434
"We apologize for the inconvenience."
35-
" Our team has recorded the issue [{error_code}] and is working to resolve it as quickly as possible."
35+
" Our team has recorded the issue [SupportID={error_code}] and is working to resolve it as quickly as possible."
3636
" Thank you for your patience"
3737
)
3838

services/web/server/src/simcore_service_webserver/_constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929

3030

3131
__all__: tuple[str, ...] = (
32-
"APP_CONFIG_KEY",
3332
"APP_AIOPG_ENGINE_KEY",
33+
"APP_CONFIG_KEY",
3434
"APP_FIRE_AND_FORGET_TASKS_KEY",
3535
"APP_SETTINGS_KEY",
3636
"RQT_USERID_KEY",

services/web/server/src/simcore_service_webserver/projects/_crud_handlers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ async def _wrapper(request: web.Request) -> web.StreamResponse:
113113
@login_required
114114
@permission_required("project.create")
115115
@permission_required("services.pipeline.*") # due to update_pipeline_db
116+
@_handle_projects_exceptions
116117
async def create_project(request: web.Request):
117118
#
118119
# - Create https://google.aip.dev/133
@@ -267,6 +268,7 @@ async def list_projects_full_search(request: web.Request):
267268
@routes.get(f"/{VTAG}/projects/active", name="get_active_project")
268269
@login_required
269270
@permission_required("project.read")
271+
@_handle_projects_exceptions
270272
async def get_active_project(request: web.Request) -> web.Response:
271273
#
272274
# - Get https://google.aip.dev/131
@@ -314,6 +316,7 @@ async def get_active_project(request: web.Request) -> web.Response:
314316
@routes.get(f"/{VTAG}/projects/{{project_id}}", name="get_project")
315317
@login_required
316318
@permission_required("project.read")
319+
@_handle_projects_exceptions
317320
async def get_project(request: web.Request):
318321
"""
319322
@@ -377,6 +380,7 @@ async def get_project(request: web.Request):
377380
)
378381
@login_required
379382
@permission_required("project.read")
383+
@_handle_projects_exceptions
380384
async def get_project_inactivity(request: web.Request):
381385
path_params = parse_request_path_parameters_as(ProjectPathParams, request)
382386

@@ -413,6 +417,7 @@ async def patch_project(request: web.Request):
413417
@routes.delete(f"/{VTAG}/projects/{{project_id}}", name="delete_project")
414418
@login_required
415419
@permission_required("project.delete")
420+
@_handle_projects_exceptions
416421
async def delete_project(request: web.Request):
417422
# Delete https://google.aip.dev/135
418423
"""
@@ -502,6 +507,7 @@ async def delete_project(request: web.Request):
502507
@login_required
503508
@permission_required("project.create")
504509
@permission_required("services.pipeline.*") # due to update_pipeline_db
510+
@_handle_projects_exceptions
505511
async def clone_project(request: web.Request):
506512
req_ctx = RequestContext.model_validate(request)
507513
path_params = parse_request_path_parameters_as(ProjectPathParams, request)

services/web/server/src/simcore_service_webserver/studies_dispatcher/_catalog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
2+
from collections.abc import AsyncIterator
23
from contextlib import suppress
34
from dataclasses import dataclass
4-
from typing import AsyncIterator
55

66
import sqlalchemy as sa
77
from aiohttp import web

services/web/server/src/simcore_service_webserver/studies_dispatcher/_constants.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
"Please try later or login with a registered account."
2828
)
2929

30-
MSG_UNEXPECTED_ERROR: Final[
31-
str
32-
] = "Opps this is embarrasing! Something went really wrong {hint}"
30+
MSG_UNEXPECTED_DISPATCH_ERROR: Final[str] = (
31+
"Sorry, but looks like something unexpected went wrong!"
32+
"We track these errors automatically, but if the problem persists feel free to contact us."
33+
"In the meantime, try refreshing."
34+
)

services/web/server/src/simcore_service_webserver/studies_dispatcher/_core.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
@lru_cache
2929
def compose_uuid_from(*values) -> uuid.UUID:
3030
composition: str = "/".join(map(str, values))
31-
new_uuid = uuid.uuid5(_BASE_UUID, composition)
32-
return new_uuid
31+
return uuid.uuid5(_BASE_UUID, composition)
3332

3433

3534
async def list_viewers_info(
@@ -58,9 +57,8 @@ async def list_viewers_info(
5857
async for row in await conn.execute(query):
5958
try:
6059
# TODO: filter in database (see test_list_default_compatible_services )
61-
if only_default:
62-
if row["filetype"] in listed_filetype:
63-
continue
60+
if only_default and row["filetype"] in listed_filetype:
61+
continue
6462
listed_filetype.add(row["filetype"])
6563
consumer = ViewerInfo.create_from_db(row)
6664
consumers.append(consumer)

services/web/server/src/simcore_service_webserver/studies_dispatcher/_projects.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def _create_project(
9292
access_rights.write = access_rights.delete = False
9393

9494
# Assambles project instance
95-
project = Project(
95+
return Project(
9696
uuid=project_id,
9797
name=name,
9898
description=description,
@@ -105,8 +105,6 @@ def _create_project(
105105
ui=StudyUI(workbench=workbench_ui), # type: ignore[arg-type]
106106
)
107107

108-
return project
109-
110108

111109
def _create_project_with_service(
112110
project_id: ProjectID,
@@ -275,7 +273,7 @@ async def get_or_create_project_with_file_and_service(
275273
download_link,
276274
)
277275
# FIXME: CANNOT GUARANTEE!!, DELETE?? ERROR?? and cannot be viewed until verified?
278-
raise web.HTTPInternalServerError()
276+
raise web.HTTPInternalServerError
279277

280278
except (ProjectNotFoundError, ProjectInvalidRightsError):
281279
exists = False

services/web/server/src/simcore_service_webserver/studies_dispatcher/_projects_permalinks.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class _GroupAccessRightsDict(TypedDict):
3131

3232
def create_permalink_for_study(
3333
request: web.Request,
34+
*,
3435
project_uuid: ProjectID | ProjectIDStr,
3536
project_type: ProjectType,
3637
project_access_rights: dict[_GroupID, _GroupAccessRightsDict],
@@ -44,19 +45,21 @@ def create_permalink_for_study(
4445

4546
# check: criterias/conditions on a project to have a permalink
4647
if project_type != ProjectType.TEMPLATE:
47-
raise PermalinkNotAllowedError(
48+
msg = (
4849
"Can only create permalink from a template project. "
4950
f"Got {project_uuid=} with {project_type=}"
5051
)
52+
raise PermalinkNotAllowedError(msg)
5153

5254
project_access_rights_group_1_or_empty: _GroupAccessRightsDict | dict = (
5355
project_access_rights.get("1", {})
5456
)
5557
if not project_access_rights_group_1_or_empty.get("read", False):
56-
raise PermalinkNotAllowedError(
58+
msg = (
5759
"Cannot create permalink if not shared with everyone. "
5860
f"Got {project_uuid=} with {project_access_rights=}"
5961
)
62+
raise PermalinkNotAllowedError(msg)
6063

6164
# create
6265
url_for = create_url_for_function(request)
@@ -114,14 +117,13 @@ async def permalink_factory(
114117
if not row:
115118
raise ProjectNotFoundError(project_uuid=project_uuid)
116119

117-
permalink_info = create_permalink_for_study(
120+
return create_permalink_for_study(
118121
request,
119122
project_uuid=row.uuid,
120123
project_type=row.type,
121124
project_access_rights=row.access_rights,
122125
project_is_public=row.published,
123126
)
124-
return permalink_info
125127

126128

127129
def setup_projects_permalinks(

services/web/server/src/simcore_service_webserver/studies_dispatcher/_redirects_handlers.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from ..utils import compose_support_error_msg
2424
from ..utils_aiohttp import create_redirect_to_page_response
2525
from ._catalog import ValidService, validate_requested_service
26-
from ._constants import MSG_UNEXPECTED_ERROR
26+
from ._constants import MSG_UNEXPECTED_DISPATCH_ERROR
2727
from ._core import validate_requested_file, validate_requested_viewer
2828
from ._errors import InvalidRedirectionParams, StudyDispatcherError
2929
from ._models import FileParams, ServiceInfo, ServiceParams, ViewerInfo
@@ -73,12 +73,12 @@ def _create_redirect_response_to_error_page(
7373

7474

7575
def _create_service_info_from(service: ValidService) -> ServiceInfo:
76-
values_map = dict(
77-
key=service.key,
78-
version=service.version,
79-
label=service.title,
80-
is_guest_allowed=service.is_public,
81-
)
76+
values_map = {
77+
"key": service.key,
78+
"version": service.version,
79+
"label": service.title,
80+
"is_guest_allowed": service.is_public,
81+
}
8282
if service.thumbnail:
8383
values_map["thumbnail"] = service.thumbnail
8484
return ServiceInfo.model_construct(_fields_set=set(values_map.keys()), **values_map)
@@ -127,7 +127,7 @@ async def wrapper(request: web.Request) -> web.StreamResponse:
127127
error_code = create_error_code(err)
128128

129129
user_error_msg = compose_support_error_msg(
130-
msg=MSG_UNEXPECTED_ERROR.format(hint=""), error_code=error_code
130+
msg=MSG_UNEXPECTED_DISPATCH_ERROR, error_code=error_code
131131
)
132132
_logger.exception(
133133
**create_troubleshotting_log_kwargs(
@@ -335,7 +335,7 @@ async def get_redirection_to_viewer(request: web.Request):
335335

336336
else:
337337
# NOTE: if query is done right, this should never happen
338-
raise InvalidRedirectionParams()
338+
raise InvalidRedirectionParams
339339

340340
# Adds auth cookies (login)
341341
await ensure_authentication(user, request, response)

services/web/server/src/simcore_service_webserver/studies_dispatcher/_studies_access.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
MSG_PROJECT_NOT_PUBLISHED,
4949
MSG_PUBLIC_PROJECT_NOT_PUBLISHED,
5050
MSG_TOO_MANY_GUESTS,
51-
MSG_UNEXPECTED_ERROR,
51+
MSG_UNEXPECTED_DISPATCH_ERROR,
5252
)
5353
from ._errors import GuestUsersLimitError
5454
from ._users import create_temporary_guest_user, get_authorized_user
@@ -260,7 +260,7 @@ async def wrapper(request: web.Request) -> web.StreamResponse:
260260
except Exception as err:
261261
error_code = create_error_code(err)
262262
user_error_msg = compose_support_error_msg(
263-
msg=MSG_UNEXPECTED_ERROR.format(hint=""), error_code=error_code
263+
msg=MSG_UNEXPECTED_DISPATCH_ERROR, error_code=error_code
264264
)
265265
_logger.exception(
266266
**create_troubleshotting_log_kwargs(
@@ -366,7 +366,7 @@ async def get_redirection_to_study_page(request: web.Request) -> web.Response:
366366
except Exception as exc: # pylint: disable=broad-except
367367
error_code = create_error_code(exc)
368368

369-
user_error_msg = MSG_UNEXPECTED_ERROR.format(hint="while copying your study")
369+
user_error_msg = MSG_UNEXPECTED_DISPATCH_ERROR
370370
_logger.exception(
371371
**create_troubleshotting_log_kwargs(
372372
user_error_msg,

0 commit comments

Comments
 (0)