This is an automated email from the ASF dual-hosted git repository.
vyommani 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 986c5b610 RANGER-5838: Add constraintDefs to RangerServiceDef and
constraint po… (#1309)
986c5b610 is described below
commit 986c5b610f422620356185a3973852525acafc9a
Author: Vyom Mani Tiwari <[email protected]>
AuthorDate: Fri Oct 16 15:48:53 2026 +0530
RANGER-5838: Add constraintDefs to RangerServiceDef and constraint po…
(#1309)
* RANGER-5838: Add constraintDefs to RangerServiceDef and constraint policy
model to RangerPolicy
* Update RangerServiceDef.java: simplified new equals() methods
* added subtype to RangerConstraintParamDef
* fix checkstyle indentation
---------
Co-authored-by: Madhan Neethiraj <[email protected]>
---
.../apache/ranger/plugin/model/RangerPolicy.java | 242 +++++++++++
.../ranger/plugin/model/RangerServiceDef.java | 475 +++++++++++++++++++++
.../ranger/plugin/model/TestRangerPolicy.java | 110 +++++
.../ranger/plugin/model/TestRangerServiceDef.java | 165 +++++++
4 files changed, 992 insertions(+)
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
index 8b8f3d2ef..ff5604a53 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
@@ -31,8 +31,10 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@@ -44,6 +46,7 @@ public class RangerPolicy extends RangerBaseModelObject
implements java.io.Seria
public static final int POLICY_TYPE_DATAMASK = 1;
public static final int POLICY_TYPE_ROWFILTER = 2;
public static final int POLICY_TYPE_AUDIT = 3;
+ public static final int POLICY_TYPE_CONSTRAINTS = 4;
public static final int[] POLICY_TYPES = new int[] {
POLICY_TYPE_ACCESS,
@@ -79,6 +82,7 @@ public class RangerPolicy extends RangerBaseModelObject
implements java.io.Seria
private List<RangerPolicyItem> denyExceptions;
private List<RangerDataMaskPolicyItem> dataMaskPolicyItems;
private List<RangerRowFilterPolicyItem> rowFilterPolicyItems;
+ private List<RangerConstraintPolicyItem> constraintPolicyItems;
private String serviceType;
private Map<String, Object> options;
private List<RangerValiditySchedule> validitySchedules;
@@ -128,6 +132,7 @@ public RangerPolicy(String service, String name, Integer
policyType, Integer pol
setDenyExceptions(null);
setDataMaskPolicyItems(null);
setRowFilterPolicyItems(null);
+ setConstraintPolicyItems(null);
setOptions(options);
setValiditySchedules(validitySchedules);
setPolicyLabels(policyLables);
@@ -158,6 +163,7 @@ public void updateFrom(RangerPolicy other) {
setDenyExceptions(other.getDenyExceptions());
setDataMaskPolicyItems(other.getDataMaskPolicyItems());
setRowFilterPolicyItems(other.getRowFilterPolicyItems());
+ setConstraintPolicyItems(other.getConstraintPolicyItems());
setServiceType(other.getServiceType());
setOptions(other.getOptions());
setValiditySchedules(other.getValiditySchedules());
@@ -434,6 +440,20 @@ public boolean
addRowFilterPolicyItem(RangerRowFilterPolicyItem policyItem) {
return rowFilterPolicyItems.add(policyItem);
}
+ public List<RangerConstraintPolicyItem> getConstraintPolicyItems() {
+ return constraintPolicyItems;
+ }
+
+ public void setConstraintPolicyItems(List<RangerConstraintPolicyItem>
constraintPolicyItems) {
+ this.constraintPolicyItems = nullSafeList(constraintPolicyItems);
+ }
+
+ public boolean addConstraintPolicyItem(RangerConstraintPolicyItem
policyItem) {
+ constraintPolicyItems = getUpdatableList(constraintPolicyItems);
+
+ return constraintPolicyItems.add(policyItem);
+ }
+
public Map<String, Object> getOptions() {
return options;
}
@@ -555,6 +575,12 @@ public void dedupStrings(Map<String, String> strTbl) {
policyItem.dedupStrings(strTbl);
}
}
+
+ if (CollectionUtils.isNotEmpty(constraintPolicyItems)) {
+ for (RangerPolicyItem policyItem : constraintPolicyItems) {
+ policyItem.dedupStrings(strTbl);
+ }
+ }
}
@Override
@@ -682,6 +708,16 @@ public StringBuilder toString(StringBuilder sb) {
}
sb.append("} ");
+ sb.append("constraintPolicyItems={");
+ if (constraintPolicyItems != null) {
+ for (RangerConstraintPolicyItem constraintPolicyItem :
constraintPolicyItems) {
+ if (constraintPolicyItem != null) {
+ constraintPolicyItem.toString(sb);
+ }
+ }
+ }
+ sb.append("} ");
+
sb.append("options={");
if (options != null) {
for (Map.Entry<String, Object> e : options.entrySet()) {
@@ -1442,6 +1478,96 @@ public String toString() {
}
}
+ @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+ @JsonInclude(JsonInclude.Include.NON_EMPTY)
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class RangerConstraintPolicyItem extends RangerPolicyItem
implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private RangerPolicyItemConstraintInfo constraintInfo;
+
+ public RangerConstraintPolicyItem() {
+ this(null, null, null, null, null, null, null);
+ }
+
+ public RangerConstraintPolicyItem(RangerPolicyItemConstraintInfo
constraintInfo, List<RangerPolicyItemAccess> accesses, List<String> users,
List<String> groups, List<String> roles, List<RangerPolicyItemCondition>
conditions, Boolean delegateAdmin) {
+ super(accesses, users, groups, roles, conditions, delegateAdmin);
+
+ setConstraintInfo(constraintInfo);
+ }
+
+ public RangerPolicyItemConstraintInfo getConstraintInfo() {
+ return constraintInfo;
+ }
+
+ public void setConstraintInfo(RangerPolicyItemConstraintInfo
constraintInfo) {
+ this.constraintInfo = constraintInfo == null ? new
RangerPolicyItemConstraintInfo() : constraintInfo;
+ }
+
+ @Override
+ public void dedupStrings(Map<String, String> strTbl) {
+ super.dedupStrings(strTbl);
+
+ if (constraintInfo != null) {
+ constraintInfo.dedupStrings(strTbl);
+ }
+ }
+
+ @Override
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerConstraintPolicyItem={");
+
+ super.toString(sb);
+
+ sb.append("constraintInfo={");
+ if (constraintInfo != null) {
+ constraintInfo.toString(sb);
+ }
+ sb.append("} ");
+
+ sb.append("}");
+
+ return sb;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), constraintInfo);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!super.equals(obj)) {
+ return false;
+ }
+
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ RangerConstraintPolicyItem other = (RangerConstraintPolicyItem)
obj;
+
+ if (constraintInfo == null) {
+ return other.constraintInfo == null;
+ } else {
+ return constraintInfo.equals(other.constraintInfo);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ toString(sb);
+
+ return sb.toString();
+ }
+ }
+
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -1874,4 +2000,120 @@ public StringBuilder toString(StringBuilder sb) {
return sb;
}
}
+
+ @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+ @JsonInclude(JsonInclude.Include.NON_EMPTY)
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class RangerPolicyItemConstraintInfo implements
java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String constraintName;
+ private Map<String, Object> parameters;
+
+ public RangerPolicyItemConstraintInfo() {
+ this(null, null);
+ }
+
+ public RangerPolicyItemConstraintInfo(String constraintName,
Map<String, Object> parameters) {
+ setConstraintName(constraintName);
+ setParameters(parameters);
+ }
+
+ public RangerPolicyItemConstraintInfo(RangerPolicyItemConstraintInfo
that) {
+ setConstraintName(that.constraintName);
+ setParameters(that.parameters == null ? null : new
HashMap<>(that.parameters));
+ }
+
+ public String getConstraintName() {
+ return constraintName;
+ }
+
+ public void setConstraintName(String constraintName) {
+ this.constraintName = constraintName;
+ }
+
+ public Map<String, Object> getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(Map<String, Object> parameters) {
+ this.parameters = parameters == null ? new HashMap<>() :
parameters;
+ }
+
+ public void dedupStrings(Map<String, String> strTbl) {
+ constraintName = StringUtil.dedupString(constraintName, strTbl);
+
+ if (MapUtils.isNotEmpty(parameters)) {
+ Map<String, Object> updated = new HashMap<>(parameters.size());
+
+ for (Map.Entry<String, Object> entry : parameters.entrySet()) {
+ Object value = entry.getValue();
+
+ if (value instanceof String) {
+ value = StringUtil.dedupString((String) value, strTbl);
+ }
+
+ updated.put(StringUtil.dedupString(entry.getKey(),
strTbl), value);
+ }
+
+ parameters = updated;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(constraintName, parameters);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null) {
+ return false;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ RangerPolicyItemConstraintInfo other =
(RangerPolicyItemConstraintInfo) obj;
+
+ if (constraintName == null) {
+ if (other.constraintName != null) {
+ return false;
+ }
+ } else if (!constraintName.equals(other.constraintName)) {
+ return false;
+ }
+
+ if (parameters == null) {
+ return other.parameters == null;
+ } else {
+ return parameters.equals(other.parameters);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ toString(sb);
+
+ return sb.toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerPolicyItemConstraintInfo={");
+
+ sb.append("constraintName={").append(constraintName).append("} ");
+ sb.append("parameters={").append(parameters).append("} ");
+
+ sb.append("}");
+
+ return sb;
+ }
+ }
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
index 4cc01fb77..a7a90dc63 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
@@ -35,6 +35,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
@@ -66,6 +67,7 @@ public class RangerServiceDef extends RangerBaseModelObject
implements java.io.S
private List<RangerEnumDef> enums;
private RangerDataMaskDef dataMaskDef;
private RangerRowFilterDef rowFilterDef;
+ private List<RangerConstraintDef> constraintDefs;
private List<RangerAccessTypeDef> markerAccessTypes; // read-only
private transient volatile boolean normalized;
@@ -109,6 +111,7 @@ public RangerServiceDef(String name, String implClass,
String label, String desc
setEnums(enums);
setDataMaskDef(dataMaskDef);
setRowFilterDef(rowFilterDef);
+ setConstraintDefs(null);
setMarkerAccessTypes(null);
}
@@ -145,6 +148,7 @@ public void updateFrom(RangerServiceDef other) {
setEnums(other.getEnums());
setDataMaskDef(other.getDataMaskDef());
setRowFilterDef(other.getRowFilterDef());
+ setConstraintDefs(other.getConstraintDefs());
setMarkerAccessTypes(other.getMarkerAccessTypes());
}
@@ -465,6 +469,26 @@ public void setRowFilterDef(RangerRowFilterDef
rowFilterDef) {
clearNormalized();
}
+ public List<RangerConstraintDef> getConstraintDefs() {
+ return constraintDefs;
+ }
+
+ public void setConstraintDefs(List<RangerConstraintDef> constraintDefs) {
+ if (this.constraintDefs == null) {
+ this.constraintDefs = new ArrayList<>();
+ }
+
+ if (this.constraintDefs == constraintDefs) {
+ return;
+ }
+
+ this.constraintDefs.clear();
+
+ if (constraintDefs != null) {
+ this.constraintDefs.addAll(constraintDefs);
+ }
+ }
+
public List<RangerAccessTypeDef> getMarkerAccessTypes() {
return markerAccessTypes;
}
@@ -803,6 +827,12 @@ public void dedupStrings(Map<String, String> strTbl) {
rowFilterDef.dedupStrings(strTbl);
}
+ if (constraintDefs != null) {
+ for (RangerConstraintDef constraintDef : constraintDefs) {
+ constraintDef.dedupStrings(strTbl);
+ }
+ }
+
if (markerAccessTypes != null) {
for (RangerAccessTypeDef accessType : markerAccessTypes) {
accessType.dedupStrings(strTbl);
@@ -912,6 +942,16 @@ public StringBuilder toString(StringBuilder sb) {
}
sb.append("} ");
+ sb.append("constraintDefs={");
+ if (constraintDefs != null) {
+ for (RangerConstraintDef constraintDef : constraintDefs) {
+ if (constraintDef != null) {
+ constraintDef.toString(sb);
+ }
+ }
+ }
+ sb.append("} ");
+
sb.append("markerAccessTypes={");
if (markerAccessTypes != null) {
for (RangerAccessTypeDef accessType : markerAccessTypes) {
@@ -3742,4 +3782,439 @@ public String toString() {
return sb.toString();
}
}
+
+ @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+ @JsonInclude(JsonInclude.Include.NON_EMPTY)
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class RangerConstraintDef implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Long itemId;
+ private String name;
+ private String label;
+ private String description;
+ private String rbKeyLabel;
+ private String rbKeyDescription;
+ private List<String> resources;
+ private List<String> accessTypes;
+ private List<RangerConstraintParamDef> parameters;
+ private Map<String, String> options;
+
+ public RangerConstraintDef() {
+ setResources(null);
+ setAccessTypes(null);
+ setParameters(null);
+ setOptions(null);
+ }
+
+ public RangerConstraintDef(RangerConstraintDef other) {
+ setItemId(other.getItemId());
+ setName(other.getName());
+ setLabel(other.getLabel());
+ setDescription(other.getDescription());
+ setRbKeyLabel(other.getRbKeyLabel());
+ setRbKeyDescription(other.getRbKeyDescription());
+ setResources(other.getResources());
+ setAccessTypes(other.getAccessTypes());
+ setParameters(other.getParameters());
+ setOptions(other.getOptions() == null ? null : new
HashMap<>(other.getOptions()));
+ }
+
+ public Long getItemId() {
+ return itemId;
+ }
+
+ public void setItemId(Long itemId) {
+ this.itemId = itemId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getRbKeyLabel() {
+ return rbKeyLabel;
+ }
+
+ public void setRbKeyLabel(String rbKeyLabel) {
+ this.rbKeyLabel = rbKeyLabel;
+ }
+
+ public String getRbKeyDescription() {
+ return rbKeyDescription;
+ }
+
+ public void setRbKeyDescription(String rbKeyDescription) {
+ this.rbKeyDescription = rbKeyDescription;
+ }
+
+ public List<String> getResources() {
+ return resources;
+ }
+
+ public void setResources(List<String> resources) {
+ if (this.resources == null) {
+ this.resources = new ArrayList<>();
+ }
+
+ if (this.resources == resources) {
+ return;
+ }
+
+ this.resources.clear();
+
+ if (resources != null) {
+ this.resources.addAll(resources);
+ }
+ }
+
+ public List<String> getAccessTypes() {
+ return accessTypes;
+ }
+
+ public void setAccessTypes(List<String> accessTypes) {
+ if (this.accessTypes == null) {
+ this.accessTypes = new ArrayList<>();
+ }
+
+ if (this.accessTypes == accessTypes) {
+ return;
+ }
+
+ this.accessTypes.clear();
+
+ if (accessTypes != null) {
+ this.accessTypes.addAll(accessTypes);
+ }
+ }
+
+ public List<RangerConstraintParamDef> getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(List<RangerConstraintParamDef> parameters) {
+ if (this.parameters == null) {
+ this.parameters = new ArrayList<>();
+ }
+
+ if (this.parameters == parameters) {
+ return;
+ }
+
+ this.parameters.clear();
+
+ if (parameters != null) {
+ this.parameters.addAll(parameters);
+ }
+ }
+
+ public Map<String, String> getOptions() {
+ return options;
+ }
+
+ public void setOptions(Map<String, String> options) {
+ this.options = options == null ? new HashMap<>() : options;
+ }
+
+ public void dedupStrings(Map<String, String> strTbl) {
+ name = StringUtil.dedupString(name, strTbl);
+ label = StringUtil.dedupString(label, strTbl);
+ description = StringUtil.dedupString(description, strTbl);
+ rbKeyLabel = StringUtil.dedupString(rbKeyLabel, strTbl);
+ rbKeyDescription = StringUtil.dedupString(rbKeyDescription,
strTbl);
+ resources = StringUtil.dedupStringsList(resources, strTbl);
+ accessTypes = StringUtil.dedupStringsList(accessTypes,
strTbl);
+ options = StringUtil.dedupStringsMap(options, strTbl);
+
+ if (parameters != null) {
+ for (RangerConstraintParamDef parameter : parameters) {
+ parameter.dedupStrings(strTbl);
+ }
+ }
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerConstraintDef={");
+ sb.append("itemId={").append(itemId).append("} ");
+ sb.append("name={").append(name).append("} ");
+ sb.append("label={").append(label).append("} ");
+ sb.append("description={").append(description).append("} ");
+ sb.append("rbKeyLabel={").append(rbKeyLabel).append("} ");
+ sb.append("rbKeyDescription={").append(rbKeyDescription).append("}
");
+
+ sb.append("resources={");
+ if (resources != null) {
+ for (String resource : resources) {
+ if (resource != null) {
+ sb.append(resource).append(" ");
+ }
+ }
+ }
+ sb.append("} ");
+
+ sb.append("accessTypes={");
+ if (accessTypes != null) {
+ for (String accessType : accessTypes) {
+ if (accessType != null) {
+ sb.append(accessType).append(" ");
+ }
+ }
+ }
+ sb.append("} ");
+
+ sb.append("parameters={");
+ if (parameters != null) {
+ for (RangerConstraintParamDef parameter : parameters) {
+ if (parameter != null) {
+ parameter.toString(sb);
+ }
+ }
+ }
+ sb.append("} ");
+
+ sb.append("options={").append(options).append("} ");
+ sb.append("}");
+
+ return sb;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(itemId, name, label, description, rbKeyLabel,
rbKeyDescription, resources, accessTypes, parameters, options);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ } else if (obj == null) {
+ return false;
+ } else if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ RangerConstraintDef other = (RangerConstraintDef) obj;
+
+ return Objects.equals(itemId, other.itemId) &&
+ Objects.equals(name, other.name) &&
+ Objects.equals(label, other.label) &&
+ Objects.equals(description, other.description) &&
+ Objects.equals(rbKeyLabel, other.rbKeyLabel) &&
+ Objects.equals(rbKeyDescription, other.rbKeyDescription) &&
+ Objects.equals(resources, other.resources) &&
+ Objects.equals(accessTypes, other.accessTypes) &&
+ Objects.equals(parameters, other.parameters) &&
+ Objects.equals(options, other.options);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ toString(sb);
+
+ return sb.toString();
+ }
+ }
+
+ @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+ @JsonInclude(JsonInclude.Include.NON_EMPTY)
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class RangerConstraintParamDef implements
java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Long itemId;
+ private String name;
+ private String label;
+ private String description;
+ private String type;
+ private String subType;
+ private Boolean mandatory;
+ private String defaultValue;
+ private String rbKeyLabel;
+ private String rbKeyDescription;
+
+ public RangerConstraintParamDef() {
+ setMandatory(null);
+ }
+
+ public RangerConstraintParamDef(RangerConstraintParamDef other) {
+ setItemId(other.getItemId());
+ setName(other.getName());
+ setLabel(other.getLabel());
+ setDescription(other.getDescription());
+ setType(other.getType());
+ setSubType(other.getSubType());
+ setMandatory(other.getMandatory());
+ setDefaultValue(other.getDefaultValue());
+ setRbKeyLabel(other.getRbKeyLabel());
+ setRbKeyDescription(other.getRbKeyDescription());
+ }
+
+ public Long getItemId() {
+ return itemId;
+ }
+
+ public void setItemId(Long itemId) {
+ this.itemId = itemId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getSubType() {
+ return subType;
+ }
+
+ public void setSubType(String subType) {
+ this.subType = subType;
+ }
+
+ public Boolean getMandatory() {
+ return mandatory;
+ }
+
+ public void setMandatory(Boolean mandatory) {
+ this.mandatory = mandatory == null ? Boolean.FALSE : mandatory;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ public String getRbKeyLabel() {
+ return rbKeyLabel;
+ }
+
+ public void setRbKeyLabel(String rbKeyLabel) {
+ this.rbKeyLabel = rbKeyLabel;
+ }
+
+ public String getRbKeyDescription() {
+ return rbKeyDescription;
+ }
+
+ public void setRbKeyDescription(String rbKeyDescription) {
+ this.rbKeyDescription = rbKeyDescription;
+ }
+
+ public void dedupStrings(Map<String, String> strTbl) {
+ name = StringUtil.dedupString(name, strTbl);
+ label = StringUtil.dedupString(label, strTbl);
+ description = StringUtil.dedupString(description, strTbl);
+ type = StringUtil.dedupString(type, strTbl);
+ subType = StringUtil.dedupString(subType, strTbl);
+ defaultValue = StringUtil.dedupString(defaultValue, strTbl);
+ rbKeyLabel = StringUtil.dedupString(rbKeyLabel, strTbl);
+ rbKeyDescription = StringUtil.dedupString(rbKeyDescription,
strTbl);
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerConstraintParamDef={");
+ sb.append("itemId={").append(itemId).append("} ");
+ sb.append("name={").append(name).append("} ");
+ sb.append("label={").append(label).append("} ");
+ sb.append("description={").append(description).append("} ");
+ sb.append("type={").append(type).append("} ");
+ sb.append("subType={").append(subType).append("} ");
+ sb.append("mandatory={").append(mandatory).append("} ");
+ sb.append("defaultValue={").append(defaultValue).append("} ");
+ sb.append("rbKeyLabel={").append(rbKeyLabel).append("} ");
+ sb.append("rbKeyDescription={").append(rbKeyDescription).append("}
");
+ sb.append("}");
+
+ return sb;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(itemId, name, label, description, type,
subType, mandatory, defaultValue, rbKeyLabel, rbKeyDescription);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ } else if (obj == null) {
+ return false;
+ } else if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ RangerConstraintParamDef other = (RangerConstraintParamDef) obj;
+
+ return Objects.equals(itemId, other.itemId) &&
+ Objects.equals(name, other.name) &&
+ Objects.equals(label, other.label) &&
+ Objects.equals(description, other.description) &&
+ Objects.equals(type, other.type) &&
+ Objects.equals(subType, other.subType) &&
+ Objects.equals(mandatory, other.mandatory) &&
+ Objects.equals(defaultValue, other.defaultValue) &&
+ Objects.equals(rbKeyLabel, other.rbKeyLabel) &&
+ Objects.equals(rbKeyDescription, other.rbKeyDescription);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ toString(sb);
+
+ return sb.toString();
+ }
+ }
}
diff --git
a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicy.java
b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicy.java
index 467fc0f34..36e44a0dd 100644
---
a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicy.java
+++
b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicy.java
@@ -19,10 +19,15 @@
package org.apache.ranger.plugin.model;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.ranger.authorization.utils.JsonUtils;
+import org.apache.ranger.authorization.utils.StringUtil;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerConstraintPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
+import
org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemConstraintInfo;
import
org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
import
org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
@@ -234,7 +239,9 @@ public void test09_PolicySettersAndNullSafeSupplierV2() {
// switch supplier to V2 and verify empty collections are immutable
empty
RangerBaseModelObject.setNullSafeSupplier(RangerBaseModelObject.NULL_SAFE_SUPPLIER_V2);
p.setPolicyItems(null);
+ p.setConstraintPolicyItems(null);
Assertions.assertEquals(0, p.getPolicyItems().size());
+ Assertions.assertEquals(0, p.getConstraintPolicyItems().size());
// revert to default
RangerBaseModelObject.setNullSafeSupplier((RangerBaseModelObject.NullSafeSupplier)
null);
}
@@ -282,6 +289,109 @@ public void test12_NestedEqualsNullPaths() {
Assertions.assertEquals(rf1, rf2);
}
+ @Test
+ public void test13_ConstraintPolicyItemsAndJson() throws Exception {
+ Assertions.assertEquals(4, RangerPolicy.POLICY_TYPE_CONSTRAINTS);
+ Assertions.assertEquals(3, RangerPolicy.POLICY_TYPES.length);
+ for (int policyType : RangerPolicy.POLICY_TYPES) {
+ Assertions.assertNotEquals(RangerPolicy.POLICY_TYPE_CONSTRAINTS,
policyType);
+ }
+
+ Map<String, Object> parameters = new LinkedHashMap<>();
+ parameters.put("approver", "alice");
+ parameters.put("rowCount", 100);
+
+ RangerPolicyItemConstraintInfo info = new
RangerPolicyItemConstraintInfo("requireApproval", parameters);
+ RangerConstraintPolicyItem item = new RangerConstraintPolicyItem(info,
Collections.emptyList(), Collections.singletonList("bob"),
Collections.emptyList(), Collections.emptyList(), Collections.emptyList(),
Boolean.FALSE);
+
+ Assertions.assertEquals("requireApproval",
item.getConstraintInfo().getConstraintName());
+ Assertions.assertEquals("alice",
item.getConstraintInfo().getParameters().get("approver"));
+ Assertions.assertEquals(Boolean.FALSE, item.getDelegateAdmin());
+ Assertions.assertTrue(item.toString().contains("constraintInfo={"));
+ Assertions.assertTrue(item.toString().contains("requireApproval"));
+
+ item.setConstraintInfo(null);
+ Assertions.assertNotNull(item.getConstraintInfo());
+
Assertions.assertTrue(item.getConstraintInfo().getParameters().isEmpty());
+ item.setConstraintInfo(info);
+
+ RangerConstraintPolicyItem copy = new RangerConstraintPolicyItem(new
RangerPolicyItemConstraintInfo(item.getConstraintInfo()), item.getAccesses(),
item.getUsers(), item.getGroups(), item.getRoles(), item.getConditions(),
item.getDelegateAdmin());
+ Assertions.assertEquals(item, copy);
+ Assertions.assertEquals(item.hashCode(), copy.hashCode());
+
+ RangerPolicyItemConstraintInfo otherInfo = new
RangerPolicyItemConstraintInfo("maxRows", parameters);
+ RangerConstraintPolicyItem otherItem = new
RangerConstraintPolicyItem(otherInfo, item.getAccesses(), item.getUsers(),
item.getGroups(), item.getRoles(), item.getConditions(),
item.getDelegateAdmin());
+ Assertions.assertNotEquals(item, otherItem);
+
+ RangerPolicy policy = new RangerPolicy();
+ policy.setName("approve-transfer");
+ policy.setPolicyType(RangerPolicy.POLICY_TYPE_CONSTRAINTS);
+ policy.setConstraintPolicyItems(null);
+ Assertions.assertEquals(0, policy.getConstraintPolicyItems().size());
+ Assertions.assertTrue(policy.addConstraintPolicyItem(item));
+ Assertions.assertEquals(1, policy.getConstraintPolicyItems().size());
+
+ RangerPolicy updated = new RangerPolicy();
+ updated.updateFrom(policy);
+ Assertions.assertEquals(policy.getConstraintPolicyItems(),
updated.getConstraintPolicyItems());
+
Assertions.assertTrue(updated.toString().contains("constraintPolicyItems={"));
+
+ ObjectMapper mapper = JsonUtils.getMapper();
+ RangerPolicy accessPolicy = new RangerPolicy();
+ accessPolicy.setName("plain-access");
+ accessPolicy.setPolicyType(RangerPolicy.POLICY_TYPE_ACCESS);
+
Assertions.assertFalse(mapper.writeValueAsString(accessPolicy).contains("constraintPolicyItems"));
+
+ String json = "{"
+ + "\"name\":\"approve-transfer\","
+ + "\"policyType\":4,"
+ + "\"unknownField\":\"ignore-me\","
+ + "\"constraintPolicyItems\":[{"
+ + "\"users\":[\"bob\"],"
+ + "\"delegateAdmin\":false,"
+ + "\"constraintInfo\":{"
+ + "\"constraintName\":\"requireApproval\","
+ + "\"parameters\":{\"approver\":\"alice\",\"rowCount\":100},"
+ + "\"unknownInfo\":\"ignore\""
+ + "}}]"
+ + "}";
+ RangerPolicy parsed = mapper.readValue(json, RangerPolicy.class);
+ Assertions.assertEquals(RangerPolicy.POLICY_TYPE_CONSTRAINTS,
parsed.getPolicyType().intValue());
+ Assertions.assertEquals(1, parsed.getConstraintPolicyItems().size());
+
+ RangerPolicyItemConstraintInfo parsedInfo =
parsed.getConstraintPolicyItems().get(0).getConstraintInfo();
+ Assertions.assertEquals("requireApproval",
parsedInfo.getConstraintName());
+ Assertions.assertEquals("alice",
parsedInfo.getParameters().get("approver"));
+ Assertions.assertEquals(Integer.valueOf(100),
parsedInfo.getParameters().get("rowCount"));
+ Assertions.assertEquals(Collections.singletonList("bob"),
parsed.getConstraintPolicyItems().get(0).getUsers());
+
+ RangerPolicy roundTrip =
mapper.readValue(mapper.writeValueAsString(parsed), RangerPolicy.class);
+ Assertions.assertEquals(parsed.getConstraintPolicyItems(),
roundTrip.getConstraintPolicyItems());
+
+ Map<String, String> strTbl = new HashMap<>();
+ String canonicalName = StringUtil.dedupString(new
String("requireApproval"), strTbl);
+ String canonicalKey = StringUtil.dedupString(new String("approver"),
strTbl);
+ String canonicalValue = StringUtil.dedupString(new String("alice"),
strTbl);
+ parsedInfo.setConstraintName(new String("requireApproval"));
+ Map<String, Object> fresh = new HashMap<>();
+ fresh.put(new String("approver"), new String("alice"));
+ fresh.put("rowCount", 100);
+ parsedInfo.setParameters(fresh);
+ parsed.getConstraintPolicyItems().get(0).dedupStrings(strTbl);
+ Assertions.assertSame(canonicalName, parsedInfo.getConstraintName());
+ Assertions.assertEquals(Integer.valueOf(100),
parsedInfo.getParameters().get("rowCount"));
+
+ boolean foundApprover = false;
+ for (Map.Entry<String, Object> entry :
parsedInfo.getParameters().entrySet()) {
+ if ("approver".equals(entry.getKey())) {
+ Assertions.assertSame(canonicalKey, entry.getKey());
+ Assertions.assertSame(canonicalValue, entry.getValue());
+ foundApprover = true;
+ }
+ }
+ Assertions.assertTrue(foundApprover);
+ }
+
private <T> List<T> getList(T value) {
List<T> ret = new ArrayList<>();
diff --git
a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceDef.java
b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceDef.java
index 408b18b01..c36eb6232 100644
---
a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceDef.java
+++
b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerServiceDef.java
@@ -19,7 +19,11 @@
package org.apache.ranger.plugin.model;
+import org.apache.ranger.authorization.utils.JsonUtils;
+import org.apache.ranger.authorization.utils.StringUtil;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerConstraintDef;
+import
org.apache.ranger.plugin.model.RangerServiceDef.RangerConstraintParamDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumElementDef;
import
org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
@@ -345,4 +349,165 @@ public void test13_EnumDefSetElementsSameRefAndDedup() {
String s = enumDef.toString();
Assertions.assertTrue(s.contains("RangerEnumDef={"));
}
+
+ @Test
+ public void test14_ConstraintDefsJsonRoundTrip() throws Exception {
+ RangerServiceDef empty =
JsonUtils.getMapper().readValue("{\"name\":\"hive\"}", RangerServiceDef.class);
+ Assertions.assertEquals("hive", empty.getName());
+ Assertions.assertNotNull(empty.getDataMaskDef());
+ Assertions.assertNotNull(empty.getRowFilterDef());
+ Assertions.assertNotNull(empty.getConstraintDefs());
+ Assertions.assertTrue(empty.getConstraintDefs().isEmpty());
+
Assertions.assertFalse(JsonUtils.getMapper().writeValueAsString(empty).contains("constraintDefs"));
+
+ RangerConstraintParamDef param = new RangerConstraintParamDef();
+ param.setItemId(1L);
+ param.setName("approver");
+ param.setLabel("Approver");
+ param.setDescription("User who must approve");
+ param.setType("user");
+ param.setSubType(null);
+ Assertions.assertNull(param.getSubType());
+ param.setMandatory(null);
+ Assertions.assertEquals(Boolean.FALSE, param.getMandatory());
+ param.setMandatory(Boolean.TRUE);
+ param.setDefaultValue("alice");
+ param.setRbKeyLabel("rb.approver");
+ param.setRbKeyDescription("rb.approver.desc");
+
+ RangerConstraintParamDef paramCopy = new
RangerConstraintParamDef(param);
+ Assertions.assertEquals(param, paramCopy);
+ Assertions.assertEquals(param.hashCode(), paramCopy.hashCode());
+ Assertions.assertNull(paramCopy.getSubType());
+
+ RangerConstraintParamDef enumParam = new
RangerConstraintParamDef(param);
+ enumParam.setName("maskExpression");
+ enumParam.setType("enum");
+ enumParam.setSubType("MaskTypes");
+ RangerConstraintParamDef enumCopy = new
RangerConstraintParamDef(enumParam);
+ Assertions.assertEquals(enumParam, enumCopy);
+ Assertions.assertEquals(enumParam.hashCode(), enumCopy.hashCode());
+ Assertions.assertEquals("MaskTypes", enumCopy.getSubType());
+ Assertions.assertNotEquals(param, enumParam);
+ RangerConstraintParamDef parsedEnum =
JsonUtils.getMapper().readValue("{\"type\":\"enum\",\"subType\":\"MaskTypes\"}",
RangerConstraintParamDef.class);
+ Assertions.assertEquals("enum", parsedEnum.getType());
+ Assertions.assertEquals("MaskTypes", parsedEnum.getSubType());
+
Assertions.assertTrue(JsonUtils.getMapper().writeValueAsString(enumParam).contains("\"subType\":\"MaskTypes\""));
+
+ RangerConstraintDef constraintDef = new RangerConstraintDef();
+ constraintDef.setItemId(1L);
+ constraintDef.setName("requireApproval");
+ constraintDef.setLabel("Require approval");
+ constraintDef.setDescription("Pause until approved");
+ constraintDef.setRbKeyLabel("rb.requireApproval");
+ constraintDef.setRbKeyDescription("rb.requireApproval.desc");
+ constraintDef.setResources(null);
+ Assertions.assertNotNull(constraintDef.getResources());
+ Assertions.assertTrue(constraintDef.getResources().isEmpty());
+ constraintDef.setResources(Arrays.asList("tool"));
+ constraintDef.setAccessTypes(Arrays.asList("execute"));
+ List<RangerConstraintParamDef> params = new ArrayList<>();
+ params.add(param);
+ constraintDef.setParameters(params);
+ constraintDef.setOptions(null);
+ Assertions.assertNotNull(constraintDef.getOptions());
+ Map<String, String> options = new HashMap<>();
+ options.put("scope", "tool");
+ constraintDef.setOptions(options);
+
+
Assertions.assertTrue(constraintDef.toString().contains("RangerConstraintDef={"));
+
Assertions.assertTrue(param.toString().contains("RangerConstraintParamDef={"));
+
+ RangerConstraintDef defCopy = new RangerConstraintDef(constraintDef);
+ Assertions.assertEquals(constraintDef, defCopy);
+ Assertions.assertEquals(constraintDef.hashCode(), defCopy.hashCode());
+
+ RangerConstraintDef different = new RangerConstraintDef(constraintDef);
+ different.setName("maxRows");
+ Assertions.assertNotEquals(constraintDef, different);
+
+ RangerServiceDef def = new RangerServiceDef();
+ def.setName("agent-studio");
+ def.setConstraintDefs(null);
+ Assertions.assertTrue(def.getConstraintDefs().isEmpty());
+ List<RangerConstraintDef> defs = new ArrayList<>();
+ defs.add(constraintDef);
+ def.setConstraintDefs(defs);
+ Assertions.assertEquals(1, def.getConstraintDefs().size());
+
+ List<RangerConstraintDef> sameRef = def.getConstraintDefs();
+ sameRef.add(new RangerConstraintDef());
+ def.setConstraintDefs(sameRef);
+ Assertions.assertEquals(2, def.getConstraintDefs().size());
+ List<RangerConstraintDef> reset = new ArrayList<>();
+ reset.add(constraintDef);
+ def.setConstraintDefs(reset);
+
+ RangerServiceDef copied = new RangerServiceDef();
+ copied.updateFrom(def);
+ Assertions.assertEquals(def.getName(), copied.getName());
+ Assertions.assertEquals(def.getConstraintDefs(),
copied.getConstraintDefs());
+ Assertions.assertEquals(def.getDataMaskDef(), copied.getDataMaskDef());
+ Assertions.assertEquals(def.getRowFilterDef(),
copied.getRowFilterDef());
+
+ def.normalize();
+ Assertions.assertEquals("requireApproval",
def.getConstraintDefs().get(0).getName());
+ Assertions.assertEquals(Arrays.asList("tool"),
def.getConstraintDefs().get(0).getResources());
+
+ String json = "{"
+ + "\"name\":\"agent-studio\","
+ + "\"unknownTop\":\"x\","
+ + "\"constraintDefs\":[{"
+ + "\"itemId\":1,"
+ + "\"name\":\"requireApproval\","
+ + "\"label\":\"Require approval\","
+ + "\"description\":\"Pause until approved\","
+ + "\"rbKeyLabel\":\"rb.requireApproval\","
+ + "\"rbKeyDescription\":\"rb.requireApproval.desc\","
+ + "\"resources\":[\"tool\"],"
+ + "\"accessTypes\":[\"execute\"],"
+ + "\"unknownDef\":\"x\","
+ + "\"parameters\":[{"
+ + "\"itemId\":1,"
+ + "\"name\":\"approver\","
+ + "\"label\":\"Approver\","
+ + "\"description\":\"User who must approve\","
+ + "\"type\":\"user\","
+ + "\"mandatory\":true,"
+ + "\"defaultValue\":\"alice\","
+ + "\"rbKeyLabel\":\"rb.approver\","
+ + "\"rbKeyDescription\":\"rb.approver.desc\","
+ + "\"unknownParam\":\"x\""
+ + "}],"
+ + "\"options\":{\"scope\":\"tool\"}"
+ + "}]"
+ + "}";
+ RangerServiceDef parsed = JsonUtils.getMapper().readValue(json,
RangerServiceDef.class);
+ Assertions.assertEquals("agent-studio", parsed.getName());
+ Assertions.assertEquals(1, parsed.getConstraintDefs().size());
+ RangerConstraintDef parsedDef = parsed.getConstraintDefs().get(0);
+ Assertions.assertEquals(constraintDef, parsedDef);
+ Assertions.assertEquals(Boolean.TRUE,
parsedDef.getParameters().get(0).getMandatory());
+ Assertions.assertEquals("alice",
parsedDef.getParameters().get(0).getDefaultValue());
+ Assertions.assertNull(parsedDef.getParameters().get(0).getSubType());
+ Assertions.assertNotNull(parsed.getDataMaskDef());
+ Assertions.assertNotNull(parsed.getRowFilterDef());
+
+ Map<String, String> tbl = new HashMap<>();
+ String canonicalResource = StringUtil.dedupString(new String("tool"),
tbl);
+ String canonicalName = StringUtil.dedupString(new
String("requireApproval"), tbl);
+ String canonicalType = StringUtil.dedupString(new String("user"),
tbl);
+ String canonicalSubType = StringUtil.dedupString(new
String("MaskTypes"), tbl);
+ parsedDef.setName(new String("requireApproval"));
+ List<String> resources = new ArrayList<>();
+ resources.add(new String("tool"));
+ parsedDef.setResources(resources);
+ parsedDef.getParameters().get(0).setType(new String("user"));
+ parsedDef.getParameters().get(0).setSubType(new String("MaskTypes"));
+ parsedDef.dedupStrings(tbl);
+ Assertions.assertSame(canonicalName, parsedDef.getName());
+ Assertions.assertSame(canonicalResource,
parsedDef.getResources().get(0));
+ Assertions.assertSame(canonicalType,
parsedDef.getParameters().get(0).getType());
+ Assertions.assertSame(canonicalSubType,
parsedDef.getParameters().get(0).getSubType());
+ }
}