This is an automated email from the ASF dual-hosted git repository.

fimugdha pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 747d6dd46 RANGER-5686 : Follow-on UI side fix to refresh policy 
condition actions when resources change at Final Review (#1113)
747d6dd46 is described below

commit 747d6dd46ba82ecd75bd78797e20ed6c35e39da7
Author: Dhaval Rajpara <[email protected]>
AuthorDate: Tue Aug 4 18:53:19 2026 +0530

    RANGER-5686 : Follow-on UI side fix to refresh policy condition actions 
when resources change at Final Review (#1113)
---
 .../react-webapp/src/utils/policyConditionUtils.js | 105 +++++++++++++++++++++
 .../NewPolicyForm/CreateNewPolicyForm.jsx          |  28 +++++-
 2 files changed, 132 insertions(+), 1 deletion(-)

diff --git 
a/security-admin/src/main/webapp/react-webapp/src/utils/policyConditionUtils.js 
b/security-admin/src/main/webapp/react-webapp/src/utils/policyConditionUtils.js
index aef63af18..3397769c3 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/utils/policyConditionUtils.js
+++ 
b/security-admin/src/main/webapp/react-webapp/src/utils/policyConditionUtils.js
@@ -39,6 +39,7 @@
  * (ozone.json keyed by volume | bucket | key) and the row's selected access 
types.
  */
 
+import { find, isEqual, isArray } from "lodash";
 import { actionRequirementsRegistry } from "./actionRequirements/registry";
 
 /**
@@ -754,3 +755,107 @@ export const buildActionReqsMapFromConditionDef = 
(conditionDefVal) => {
 
   return map;
 };
+
+export const pruneStaleActionMatcherInPolicyItemCondition = ({
+  form,
+  attrNames,
+  serviceCompDetails,
+  conditionDefVal,
+  actionReqsMap
+}) => {
+  if (!Array.isArray(attrNames) || attrNames.length === 0) {
+    return;
+  }
+
+  // Read form state AFTER accesses have already been pruned by the caller.
+  const formValues = form.getState().values;
+  const leafResourceTypes = getSelectedLeafResourceTypes(
+    serviceCompDetails,
+    formValues
+  );
+
+  for (const attrName of attrNames) {
+    const items = formValues?.[attrName];
+    if (!isArray(items)) {
+      continue;
+    }
+
+    let hasChanges = false;
+    const newItems = [...items];
+
+    items.forEach((item, index) => {
+      if (!item?.conditions) {
+        return;
+      }
+
+      const accesses = getSelectedAccessTypesForRow(
+        formValues,
+        attrName,
+        index
+      );
+
+      let itemChanged = false;
+      const newConditions = { ...item.conditions };
+
+      for (const conditionName in newConditions) {
+        if (!isPerRowCondition(conditionName)) {
+          continue;
+        }
+
+        if (accesses.length === 0) {
+          // No valid accesses left → unconditionally drop per-row conditions.
+          delete newConditions[conditionName];
+          itemChanged = true;
+          hasChanges = true;
+          continue;
+        }
+        //This is needed for when we update resources
+        const conditionDef = find(conditionDefVal, { name: conditionName });
+        if (!conditionDef) {
+          continue;
+        }
+
+        const uiHintVal = parseConditionUiHint(conditionDef.uiHint);
+
+        if (
+          uiHintVal?.isMultiValue &&
+          Array.isArray(newConditions[conditionName])
+        ) {
+          const current = newConditions[conditionName];
+          const actionFilterContext = {
+            selectedAccessTypes: accesses,
+            leafResourceTypes,
+            accessTypeDefs: serviceCompDetails?.accessTypes
+          };
+
+          const { prunedSelection } = getAllowedActionMatchesForCondition({
+            conditionName,
+            actionFilterContext,
+            actionReqsMap,
+            servicedefName: serviceCompDetails?.name,
+            uiHintAttb: uiHintVal,
+            currentSelection: current
+          });
+
+          if (!isEqual(current, prunedSelection)) {
+            if (prunedSelection && prunedSelection.length > 0) {
+              newConditions[conditionName] = prunedSelection;
+            } else {
+              delete newConditions[conditionName];
+            }
+            itemChanged = true;
+            hasChanges = true;
+          }
+        }
+      }
+
+      if (itemChanged) {
+        newItems[index] = { ...item, conditions: newConditions };
+      }
+    });
+
+    if (hasChanges) {
+      form.change(attrName, newItems);
+    }
+  }
+};
diff --git 
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/NewPolicyForm/CreateNewPolicyForm.jsx
 
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/NewPolicyForm/CreateNewPolicyForm.jsx
index 44abb6324..46273abd7 100644
--- 
a/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/NewPolicyForm/CreateNewPolicyForm.jsx
+++ 
b/security-admin/src/main/webapp/react-webapp/src/views/PolicyListing/NewPolicyForm/CreateNewPolicyForm.jsx
@@ -24,8 +24,13 @@ import { getServiceDef } from "Utils/appState";
 import { fetchApi } from "Utils/fetchAPI";
 import {
   getResourcesDefVal,
-  prunePolicyItemAccessesToAllowedTypes
+  prunePolicyItemAccessesToAllowedTypes,
+  policyConditionUpdatedJSON
 } from "Utils/XAUtils";
+import {
+  buildActionReqsMapFromConditionDef,
+  pruneStaleActionMatcherInPolicyItemCondition
+} from "Utils/policyConditionUtils";
 import { isEmpty, isArray, map, reject, groupBy } from "lodash";
 import moment from "moment";
 import StepperForm from "../../../components/StepperFormComponents";
@@ -629,6 +634,27 @@ const CreateNewPolicyForm = () => {
                         form,
                         selectedServiceComponentDef
                       );
+
+                      const conditionDefVal = policyConditionUpdatedJSON(
+                        selectedServiceComponentDef?.policyConditions
+                      );
+                      const actionReqsMap =
+                        buildActionReqsMapFromConditionDef(conditionDefVal);
+                      const isDenyAllElse =
+                        form.getState().values?.isDenyAllElse;
+                      pruneStaleActionMatcherInPolicyItemCondition({
+                        form,
+                        attrNames: [
+                          "policyItems",
+                          "allowExceptions",
+                          ...(isDenyAllElse
+                            ? []
+                            : ["denyPolicyItems", "denyExceptions"])
+                        ],
+                        serviceCompDetails: selectedServiceComponentDef,
+                        conditionDefVal,
+                        actionReqsMap
+                      });
                     }
                   }}
                   initialValues={{

Reply via email to