diff --git a/services/api-server/src/simcore_service_api_server/_service_function_jobs_task_client.py b/services/api-server/src/simcore_service_api_server/_service_function_jobs_task_client.py index 7b35041aeb6..e49f7855a1c 100644 --- a/services/api-server/src/simcore_service_api_server/_service_function_jobs_task_client.py +++ b/services/api-server/src/simcore_service_api_server/_service_function_jobs_task_client.py @@ -20,8 +20,6 @@ TaskID, ) from models_library.functions_errors import ( - FunctionExecuteAccessDeniedError, - FunctionsExecuteApiAccessDeniedError, UnsupportedFunctionClassError, UnsupportedFunctionFunctionJobClassCombinationError, ) @@ -245,36 +243,7 @@ async def get_cached_function_job( function: RegisteredFunction, job_inputs: JobInputs, ) -> RegisteredFunctionJob: - """ - N.B. this function checks access rights - - raises FunctionsExecuteApiAccessDeniedError if user cannot execute functions - raises FunctionJobCacheNotFoundError if no cached job is found - - """ - - user_api_access_rights = ( - await self._web_rpc_client.get_functions_user_api_access_rights( - user_id=self.user_id, product_name=self.product_name - ) - ) - if not user_api_access_rights.execute_functions: - raise FunctionsExecuteApiAccessDeniedError( - user_id=self.user_id, - function_id=function.uid, - ) - - user_permissions = await self._web_rpc_client.get_function_user_permissions( - function_id=function.uid, - user_id=self.user_id, - product_name=self.product_name, - ) - if not user_permissions.execute: - raise FunctionExecuteAccessDeniedError( - user_id=self.user_id, - function_id=function.uid, - ) - + """Raises FunctionJobCacheNotFoundError if no cached job is found""" if cached_function_jobs := await self._web_rpc_client.find_cached_function_jobs( function_id=function.uid, inputs=job_inputs.values, diff --git a/services/api-server/src/simcore_service_api_server/_service_functions.py b/services/api-server/src/simcore_service_api_server/_service_functions.py index 708ba0149be..55564e9e050 100644 --- a/services/api-server/src/simcore_service_api_server/_service_functions.py +++ b/services/api-server/src/simcore_service_api_server/_service_functions.py @@ -5,7 +5,11 @@ from common_library.exclude import as_dict_exclude_none from models_library.functions import FunctionClass, FunctionID, RegisteredFunction -from models_library.functions_errors import UnsupportedFunctionClassError +from models_library.functions_errors import ( + FunctionExecuteAccessDeniedError, + FunctionsExecuteApiAccessDeniedError, + UnsupportedFunctionClassError, +) from models_library.products import ProductName from models_library.rest_pagination import ( MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE, @@ -76,3 +80,37 @@ async def get_function(self, function_id: FunctionID) -> RegisteredFunction: product_name=self.product_name, function_id=function_id, ) + + async def check_execute_function_permission( + self, + *, + function: RegisteredFunction, + ) -> None: + """ + Check execute permissions for a user on a function + + raises FunctionsExecuteApiAccessDeniedError if user cannot execute functions via the functions API + raises FunctionExecuteAccessDeniedError if user cannot execute this functions + """ + + user_api_access_rights = ( + await self._web_rpc_client.get_functions_user_api_access_rights( + user_id=self.user_id, product_name=self.product_name + ) + ) + if not user_api_access_rights.execute_functions: + raise FunctionsExecuteApiAccessDeniedError( + user_id=self.user_id, + function_id=function.uid, + ) + + user_permissions = await self._web_rpc_client.get_function_user_permissions( + function_id=function.uid, + user_id=self.user_id, + product_name=self.product_name, + ) + if not user_permissions.execute: + raise FunctionExecuteAccessDeniedError( + user_id=self.user_id, + function_id=function.uid, + ) diff --git a/services/api-server/src/simcore_service_api_server/api/routes/functions_routes.py b/services/api-server/src/simcore_service_api_server/api/routes/functions_routes.py index 4cb2a58d87e..f009a0079f5 100644 --- a/services/api-server/src/simcore_service_api_server/api/routes/functions_routes.py +++ b/services/api-server/src/simcore_service_api_server/api/routes/functions_routes.py @@ -343,6 +343,10 @@ async def run_function( else None ) pricing_spec = JobPricingSpecification.create_from_headers(request.headers) + + await function_service.check_execute_function_permission( + function=to_run_function, + ) job_links = await function_service.get_function_job_links(to_run_function, url_for) return await function_job_task_client_service.create_function_job_creation_task( @@ -418,6 +422,10 @@ async def map_function( else None ) pricing_spec = JobPricingSpecification.create_from_headers(request.headers) + + await function_service.check_execute_function_permission( + function=to_run_function, + ) job_links = await function_service.get_function_job_links(to_run_function, url_for) async def _run_single_function(function_inputs: FunctionInputs) -> FunctionJobID: