From 654a5b41803e1594d9e2a81fd9bd1d298b1edc1b Mon Sep 17 00:00:00 2001 From: auslin-aot <99173163+auslin-aot@users.noreply.github.com> Date: Wed, 27 Nov 2024 16:55:18 +0530 Subject: [PATCH] FWF-3972: [Bugfix] Multitenant form validation fix --- .../services/form_process_mapper.py | 32 +++++++++++++++-- .../formsflow_api/services/import_support.py | 34 ++++++------------- .../src/formsflow_api/services/process.py | 2 +- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/forms-flow-api/src/formsflow_api/services/form_process_mapper.py b/forms-flow-api/src/formsflow_api/services/form_process_mapper.py index 63b73effc..9769acc77 100644 --- a/forms-flow-api/src/formsflow_api/services/form_process_mapper.py +++ b/forms-flow-api/src/formsflow_api/services/form_process_mapper.py @@ -742,8 +742,22 @@ def validate_title_name_path(cls, title: str, path: str, name: str): include_details=True, ) + @classmethod + def validate_form_title(cls, title, exclude_id=None): + """Validate form tile in the form_process_mapper table.""" + # Exclude the current mapper from the query + current_app.logger.info( + f"Validation for form title...{title}..with exclude id-{exclude_id}" + ) + mappers = FormProcessMapper.find_forms_by_title(title, exclude_id=exclude_id) + if mappers: + current_app.logger.debug(f"Other mappers matching the title- {mappers}") + raise BusinessException(BusinessErrorCode.FORM_EXISTS) + return True + @staticmethod - def validate_form_name_path_title(request): + @user_context + def validate_form_name_path_title(request, **kwargs): """Validate a form name by calling the external validation API.""" # Retrieve the parameters from the query string title = request.args.get("title") @@ -757,8 +771,20 @@ def validate_form_name_path_title(request): FormProcessMapperService.validate_title_name_path(title, path, name) - # Combine them into query parameters dictionary - query_params = f"title={title}&name={name}&path={path}&select=title,path,name" + if current_app.config.get("MULTI_TENANCY_ENABLED"): + # In multitenant environment, validate title exists validation on mapper & path, name in formio. + if title: + FormProcessMapperService.validate_form_title(title) + user: UserContext = kwargs["user"] + tenant_key = user.tenant_key + name = f"{tenant_key}-{name}" + path = f"{tenant_key}-{path}" + query_params = f"name={name}&path={path}&select=title,path,name" + else: + # In non-multitenant environment, validate title, path, name in formio. + query_params = ( + f"title={title}&name={name}&path={path}&select=title,path,name" + ) # Initialize the FormioService and get the access token formio_service = FormioService() diff --git a/forms-flow-api/src/formsflow_api/services/import_support.py b/forms-flow-api/src/formsflow_api/services/import_support.py index 3a132bc13..ad7ae8740 100644 --- a/forms-flow-api/src/formsflow_api/services/import_support.py +++ b/forms-flow-api/src/formsflow_api/services/import_support.py @@ -12,13 +12,7 @@ from lxml import etree from formsflow_api.constants import BusinessErrorCode -from formsflow_api.models import ( - AuthType, - FormHistory, - FormProcessMapper, - Process, - ProcessType, -) +from formsflow_api.models import AuthType, FormHistory, Process, ProcessType from formsflow_api.schemas import ( ImportEditRequestSchema, ImportRequestSchema, @@ -170,9 +164,13 @@ def validate_form( # Build query params based on validation type if validate_path_only and mapper: - # In case of edit import validate title in mapper table & path in mapper table. - self.validate_form_title(title, mapper) + # In case of edit import validate title in mapper table & path in formio. + FormProcessMapperService.validate_form_title(title, mapper.parent_form_id) query_params = f"path={path}&select=title,path,name,_id" + elif not validate_path_only and current_app.config.get("MULTI_TENANCY_ENABLED"): + # In case of new import in multitenant env, validate title in mapper table & path,name in formio. + FormProcessMapperService.validate_form_title(title, exclude_id=None) + query_params = f"path={path}&name={name}&select=title,path,name,_id" else: query_params = ( f"title={title}&name={name}&path={path}&select=title,path,name" @@ -181,18 +179,6 @@ def validate_form( response = self.get_form_by_query(query_params) return response - def validate_form_title(self, title, mapper): - """Validate form tile in the form_process_mapper table.""" - # Exclude the current mapper from the query - current_app.logger.info(f"Validation for form title...{title}") - mappers = FormProcessMapper.find_forms_by_title( - title, exclude_id=mapper.parent_form_id - ) - if mappers: - current_app.logger.debug(f"Other mappers matching the title- {mappers}") - raise BusinessException(BusinessErrorCode.FORM_EXISTS) - return True - def validate_edit_form_exists(self, form_json, mapper, tenant_key): """Validate form exists on edit import.""" current_app.logger.info("Validating form exists in import edit...") @@ -572,8 +558,10 @@ def import_form_workflow( workflow_minor=minor, ) if action == "import": - skip_form = edit_request.get("form", {}).get("skip") - skip_workflow = edit_request.get("workflow", {}).get("skip") + skip_form = edit_request.get("form", {}).get("skip", True) + skip_workflow = edit_request.get("workflow", {}).get( + "skip", True + ) # selected version of form and workflow: major/minor selected_form_version = edit_request.get("form", {}).get( "selectedVersion" diff --git a/forms-flow-api/src/formsflow_api/services/process.py b/forms-flow-api/src/formsflow_api/services/process.py index 926b9f9f0..554c9403c 100644 --- a/forms-flow-api/src/formsflow_api/services/process.py +++ b/forms-flow-api/src/formsflow_api/services/process.py @@ -203,7 +203,7 @@ def list_process(): # If process empty consider it as subflows not migrated, so fetch from camunda if not process: # Check subflows exists without search before fetching from camunda. - check_subflows_exists = Process.find_all_process( + check_subflows_exists, count = Process.find_all_process( is_subflow=True, process_type=process_type, )