From 805588b7bb1bf42656e6a0c43fc1d729911f2460 Mon Sep 17 00:00:00 2001 From: Dhaval Rajpara Date: Tue, 30 Dec 2025 00:59:55 +0530 Subject: [PATCH] RANGER-5303 : Implement White-space Input Validation Across Ranger UI Forms --- .../src/components/CommonComponents.jsx | 9 +++ .../src/components/CreatableField.jsx | 4 +- .../react-webapp/src/components/Editable.jsx | 35 +++++++++-- .../webapp/react-webapp/src/utils/XAEnums.js | 4 +- .../react-webapp/src/utils/XAMessages.js | 6 +- .../src/views/Encryption/KeyCreate.jsx | 47 +++++++++----- .../PolicyListing/AddUpdatePolicyForm.jsx | 27 ++++---- .../PolicyListing/PolicyConditionsComp.jsx | 32 +++++++++- .../src/views/Resources/ResourceComp.jsx | 6 +- .../views/Resources/ResourceSelectComp.jsx | 2 +- .../views/SecurityZone/SecurityZoneForm.jsx | 47 +++++++------- .../src/views/ServiceManager/ServiceForm.jsx | 62 ++++++++++++------- .../groups_details/GroupForm.jsx | 9 ++- .../role_details/RoleForm.jsx | 17 ++--- .../users_details/UserForm.jsx | 39 ++++++------ .../react-webapp/src/views/UserProfile.jsx | 16 +++-- 16 files changed, 239 insertions(+), 123 deletions(-) diff --git a/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx b/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx index 15b8569f83..053ced0e21 100644 --- a/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx @@ -568,3 +568,12 @@ export const ModalLoader = () => { ); }; + +export const trimInputValue = (e, input) => { + const value = e.target.value; + const trimmed = value.trim(); + if (value !== trimmed) { + input.onChange(trimmed); + } + input.onBlur(e); // Always call onBlur to trigger validation +}; diff --git a/security-admin/src/main/webapp/react-webapp/src/components/CreatableField.jsx b/security-admin/src/main/webapp/react-webapp/src/components/CreatableField.jsx index 4433044303..f9974ae882 100644 --- a/security-admin/src/main/webapp/react-webapp/src/components/CreatableField.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/components/CreatableField.jsx @@ -52,8 +52,8 @@ const CreatableField = (props) => { }; const createOption = (label) => ({ - value: label, - label: label + value: label.trim(), + label: label.trim() }); const handleInputChange = (value) => { diff --git a/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx b/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx index 9d1234d2b0..c5754ac958 100644 --- a/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx @@ -231,7 +231,7 @@ const CustomCondition = (props) => { const expressionVal = (val) => { let value = null; if (val != "" && typeof val != "object") { - valRef.current[m.name] = val; + valRef.current[m.name] = val.trim(); return (value = val); } return value !== null ? value : ""; @@ -264,6 +264,12 @@ const CustomCondition = (props) => { key={m.name} value={expressionVal(selectedJSCondVal)} onChange={(e) => textAreaHandleChange(e, m.name)} + onBlur={(e) => { + textAreaHandleChange( + { target: { value: e.target.value.trim() } }, + m.name + ); + }} isInvalid={validExpression.state} /> {validExpression.state && ( @@ -295,14 +301,33 @@ const CustomCondition = (props) => { {m.label}: handleChange(e, m.name)} + value={selectedInputVal || null} + onChange={(e) => { + setSelectVal(e); + handleChange(e, m.name); + }} placeholder="" width="500px" isClearable={false} styles={selectInputCustomStyles} + formatCreateLabel={(inputValue) => + `Create "${inputValue.trim()}"` + } + onCreateOption={(inputValue) => { + const trimmedValue = inputValue.trim(); + if (trimmedValue) { + const newOption = { + label: trimmedValue, + value: trimmedValue + }; + const currentValues = selectedInputVal || []; + const newValues = Array.isArray(currentValues) + ? [...currentValues, newOption] + : [newOption]; + setSelectVal(newValues); + tagAccessData(newValues, m.name); + } + }} /> diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js b/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js index ac9bdfb30a..4e08f3a061 100755 --- a/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js +++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js @@ -586,7 +586,7 @@ export const RegexValidation = { /^([A-Za-z0-9_]|[\u00C0-\u017F])([a-z0-9,._\-+/@= ]|[\u00C0-\u017F])+$/i, regexExpressionForFirstAndLastName: /^([A-Za-z0-9_]|[\u00C0-\u017F])([a-zA-Z0-9\s_. -@]|[\u00C0-\u017F])+$/i, - regexforNameValidation: /^[a-zA-Z0-9_-][a-zA-Z0-9\s_-]{0,254}$/, + regexForNameValidation: /^[a-zA-Z0-9_-][a-zA-Z0-9\s_-]{0,254}$/, regexExpressionForSecondaryName: /^([A-Za-z0-9_]|[\u00C0-\u017F])([a-zA-Z0-9\s_. -@]|[\u00C0-\u017F])+$/i, regexforServiceNameValidation: /^[a-zA-Z0-9_-][a-zA-Z0-9_-]{0,254}$/, @@ -601,7 +601,7 @@ export const RegexValidation = { 3. Name length should be greater than one." ), - regexforNameValidationMessage: + regexForNameValidationMessage: "Name should not start with space, it should be less than 256 characters and special characters are not allowed(except _ - and space).", secondaryNameValidationMessage: ( <> diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js b/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js index ee7b010ea4..75b0647580 100644 --- a/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js +++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js @@ -36,9 +36,9 @@ export const RegexMessage = {

), - passwordvalidationinfomessage: - "Password should be minimum 8 characters ,atleast one uppercase letter, one lowercase letter and one numeric. For FIPS environment password should be minimum 14 characters with atleast one uppercase letter, one special characters, one lowercase letter and one numeric.", - emailvalidationinfomessage: ( + passwordValidationInfoMessage: + "Password should be minimum 8 characters ,at least one uppercase letter, one lowercase letter and one numeric. For FIPS environment password should be minimum 14 characters with atleast one uppercase letter, one special characters, one lowercase letter and one numeric.", + emailValidationInfoMessage: ( <>

1. Email address should be start with alphabet / numeric / underscore diff --git a/security-admin/src/main/webapp/react-webapp/src/views/Encryption/KeyCreate.jsx b/security-admin/src/main/webapp/react-webapp/src/views/Encryption/KeyCreate.jsx index fcb8a95524..6ad5343656 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/Encryption/KeyCreate.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/Encryption/KeyCreate.jsx @@ -24,7 +24,12 @@ import { toast } from "react-toastify"; import { FieldArray } from "react-final-form-arrays"; import arrayMutators from "final-form-arrays"; import { fetchApi } from "Utils/fetchAPI"; -import { BlockUi, Loader, scrollToError } from "Components/CommonComponents"; +import { + BlockUi, + Loader, + scrollToError, + trimInputValue +} from "Components/CommonComponents"; import { commonBreadcrumb, serverError } from "Utils/XAUtils"; import { cloneDeep, find, isEmpty, values } from "lodash"; import withRouter from "Hooks/withRouter"; @@ -69,7 +74,7 @@ const reducer = (state, action) => { } }; -const PromtDialog = (props) => { +const PromptDialog = (props) => { const { isDirtyField, isUnblock } = props; usePrompt("Are you sure you want to leave", isDirtyField && !isUnblock); return null; @@ -120,7 +125,7 @@ function KeyCreate(props) { serviceJson.name = values.name; serviceJson.cipher = values.cipher; serviceJson.length = values.length; - serviceJson.description = values.description; + serviceJson.description = values?.description?.trim(); serviceJson.attributes = {}; for (let key of Object.keys(values.attributes)) { @@ -128,8 +133,8 @@ function KeyCreate(props) { !isEmpty(values?.attributes[key]?.name) && !isEmpty(values?.attributes[key]?.value) ) { - serviceJson.attributes[values.attributes[key].name] = - values.attributes[key].value; + serviceJson.attributes[values.attributes[key].name.trim()] = + values.attributes[key].value.trim(); } } @@ -251,7 +256,7 @@ function KeyCreate(props) { } }) => (

- +
{ handleSubmit(event); @@ -268,6 +273,7 @@ function KeyCreate(props) { {...input} name="name" type="text" + onBlur={(e) => trimInputValue(e, input)} id={meta.error && meta.touched ? "isError" : "name"} className={ meta.error && meta.touched @@ -335,6 +341,7 @@ function KeyCreate(props) { {...input} className="form-control" data-cy="description" + onBlur={(e) => trimInputValue(e, input)} /> @@ -361,18 +368,26 @@ function KeyCreate(props) { fields.map((name, index) => ( - + + {({ input }) => ( + trimInputValue(e, input)} + /> + )} + - + + {({ input }) => ( + trimInputValue(e, input)} + /> + )} +