22
33from aiohttp import web
44from common_library .json_serialization import json_dumps
5- from models_library .api_schemas_catalog .services import MyServiceGet
65from models_library .api_schemas_webserver .projects import (
76 EmptyModel ,
87 ProjectCopyOverride ,
4039from .. import _crud_api_create , _crud_api_read , _projects_service
4140from .._permalink_service import update_or_pop_permalink_in_project
4241from ..models import ProjectDict
42+ from ..utils import get_project_unavailable_services , project_uses_available_services
4343from . import _rest_utils
4444from ._rest_exceptions import handle_plugin_requests_exceptions
4545from ._rest_schemas import (
5555 ProjectsSearchQueryParams ,
5656)
5757
58+ # When the user requests a project with a repo, the working copy might differ from
59+ # the repo project. A middleware in the meta module (if active) will resolve
60+ # the working copy and redirect to the appropriate project entrypoint. Nonetheless, the
61+ # response needs to refer to the uuid of the request and this is passed through this request key
62+ RQ_REQUESTED_REPO_PROJECT_UUID_KEY = f"{ __name__ } .RQT_REQUESTED_REPO_PROJECT_UUID_KEY"
63+
5864_logger = logging .getLogger (__name__ )
5965
6066
@@ -271,34 +277,25 @@ async def get_project(request: web.Request):
271277 req_ctx = RequestContext .model_validate (request )
272278 path_params = parse_request_path_parameters_as (ProjectPathParams , request )
273279
274- # 1. Get project if user has access
280+ user_available_services : list [dict ] = (
281+ await catalog_service .get_services_for_user_in_product (
282+ request .app , req_ctx .user_id , req_ctx .product_name , only_key_versions = True
283+ )
284+ )
285+
275286 project = await _projects_service .get_project_for_user (
276287 request .app ,
277288 project_uuid = f"{ path_params .project_id } " ,
278289 user_id = req_ctx .user_id ,
279290 include_state = True ,
280291 include_trashed_by_primary_gid = True ,
281292 )
282-
283- # 2. Check if user has access to all services within the project
284- services_in_project = {
285- (srv ["key" ], srv ["version" ]) for _ , srv in project .get ("workbench" , {}).items ()
286- }
287-
288- my_services : list [MyServiceGet ] = await catalog_service .batch_get_my_services (
289- request .app ,
290- product_name = req_ctx .product_name ,
291- user_id = req_ctx .user_id ,
292- services_ids = list (services_in_project ),
293- )
294-
295- not_my_services = services_in_project .difference (
296- {(srv .key , srv .release .version ) for srv in my_services }
297- )
298-
299- if not_my_services :
293+ if not await project_uses_available_services (project , user_available_services ):
294+ unavilable_services = get_project_unavailable_services (
295+ project , user_available_services
296+ )
300297 formatted_services = ", " .join (
301- f"{ service } :{ version } " for service , version in not_my_services
298+ f"{ service } :{ version } " for service , version in unavilable_services
302299 )
303300 # TODO: lack of permissions should be notified with https://httpstatuses.com/403 web.HTTPForbidden
304301 raise web .HTTPNotFound (
@@ -308,7 +305,10 @@ async def get_project(request: web.Request):
308305 )
309306 )
310307
311- # 3. Adds permalink
308+ if new_uuid := request .get (RQ_REQUESTED_REPO_PROJECT_UUID_KEY ):
309+ project ["uuid" ] = new_uuid
310+
311+ # Adds permalink
312312 await update_or_pop_permalink_in_project (request , project )
313313
314314 data = ProjectGet .from_domain_model (project ).data (exclude_unset = True )
0 commit comments