This is an automated email from the ASF dual-hosted git repository.
rmani 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 8adbf7f470 RANGER-5130: DatSet policies fail to authorize when
condition expression is present
8adbf7f470 is described below
commit 8adbf7f4709bb8bea14b457b85dac6671b7997a6
Author: Ramesh Mani <[email protected]>
AuthorDate: Tue Feb 11 09:58:39 2025 -0800
RANGER-5130: DatSet policies fail to authorize when condition expression is
present
Signed-off-by: Ramesh Mani <[email protected]>
---
.../apache/ranger/plugin/model/RangerGrant.java | 115 +++++++++++++++++++--
.../main/java/org/apache/ranger/rest/GdsREST.java | 41 +++++---
.../java/org/apache/ranger/rest/TestGdsREST.java | 14 ++-
3 files changed, 147 insertions(+), 23 deletions(-)
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerGrant.java
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerGrant.java
index d6c358fd7f..51c41b103a 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerGrant.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerGrant.java
@@ -23,6 +23,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -34,16 +35,16 @@ public class RangerGrant implements java.io.Serializable {
private RangerPrincipal principal;
private List<String> accessTypes;
- private List<String> conditions;
+ private List<Condition> conditions;
public RangerGrant() {
this(null, null, null);
}
- public RangerGrant(RangerPrincipal principal, List<String> accessTypes,
List<String> conditions) {
- this.principal = principal;
- this.accessTypes = accessTypes;
- this.conditions = conditions;
+ public RangerGrant(RangerPrincipal principal, List<String> accessTypes,
List<Condition> conditions) {
+ setPrincipal(principal);
+ setAccessTypes(accessTypes);
+ setConditions(conditions);
}
public RangerPrincipal getPrincipal() {
@@ -59,15 +60,39 @@ public List<String> getAccessTypes() {
}
public void setAccessTypes(List<String> accessTypes) {
- this.accessTypes = 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<String> getConditions() {
+ public List<Condition> getConditions() {
return conditions;
}
- public void setConditions(List<String> conditions) {
- this.conditions = conditions;
+ public void setConditions(List<Condition> conditions) {
+ if (this.conditions == null) {
+ this.conditions = new ArrayList<>();
+ }
+
+ if (this.conditions == conditions) {
+ return;
+ }
+
+ this.conditions.clear();
+
+ if (conditions != null) {
+ this.conditions.addAll(conditions);
+ }
}
@Override
@@ -100,4 +125,76 @@ public String toString() {
", conditions=" + conditions +
'}';
}
+
+ @JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE,
setterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility =
JsonAutoDetect.Visibility.ANY)
+ @JsonInclude(JsonInclude.Include.NON_EMPTY)
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class Condition implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String type;
+ private List<String> values;
+
+ public Condition() {
+ this(null, null);
+ }
+
+ public Condition(String type, List<String> values) {
+ setType(type);
+ setValues(values);
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public List<String> getValues() {
+ return values;
+ }
+
+ public void setValues(List<String> values) {
+ if (this.values == null) {
+ this.values = new ArrayList<>();
+ }
+
+ if (this.values == values) {
+ return;
+ }
+
+ this.values.clear();
+
+ if (values != null) {
+ this.values.addAll(values);
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Condition that = (Condition) o;
+ return Objects.equals(type, that.type) && Objects.equals(values,
that.values);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, values);
+ }
+
+ @Override
+ public String toString() {
+ return "Conditions{" +
+ "type='" + type + '\'' +
+ ", values=" + values +
+ '}';
+ }
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java
b/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java
index 05bc4fd17b..e44bb18c4b 100755
--- a/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java
@@ -1931,29 +1931,29 @@ List<RangerGrant>
transformPolicyItemsToGrants(List<RangerPolicyItem> policyItem
return null;
}
- List<RangerGrant> ret = new ArrayList<>();
+ List<RangerGrant> ret = new ArrayList<>();
for (RangerPolicyItem policyItem : policyItems) {
List<String> policyItemUsers = policyItem.getUsers();
List<String> policyItemGroups = policyItem.getGroups();
List<String> policyItemRoles = policyItem.getRoles();
- List<RangerPolicyItemAccess> policyItemAccesses =
policyItem.getAccesses();
- List<RangerPolicyItemCondition> policyItemConditions =
policyItem.getConditions();
+ List<RangerPolicyItemAccess> policyItemAccesses =
policyItem.getAccesses();
+ List<RangerPolicyItemCondition> policyItemConditions =
policyItem.getConditions();
+ List<String> policyItemAccessTypes =
policyItemAccesses.stream().map(RangerPolicyItemAccess::getType).collect(Collectors.toList());
- List<String> policyItemAccessTypes =
policyItemAccesses.stream().map(RangerPolicyItemAccess::getType).collect(Collectors.toList());
- List<String> policyItemConditionValues =
policyItemConditions.stream().flatMap(x ->
x.getValues().stream()).collect(Collectors.toList());
+ List<RangerGrant.Condition> conditions =
getGrantConditions(policyItemConditions);
if (CollectionUtils.isNotEmpty(policyItemUsers)) {
- policyItemUsers.forEach(x -> ret.add(new RangerGrant(new
RangerPrincipal(RangerPrincipal.PrincipalType.USER, x), policyItemAccessTypes,
policyItemConditionValues)));
+ policyItemUsers.forEach(x -> ret.add(new RangerGrant(new
RangerPrincipal(PrincipalType.USER, x), policyItemAccessTypes, conditions)));
}
if (CollectionUtils.isNotEmpty(policyItemGroups)) {
- policyItemGroups.forEach(x -> ret.add(new RangerGrant(new
RangerPrincipal(RangerPrincipal.PrincipalType.GROUP, x), policyItemAccessTypes,
policyItemConditionValues)));
+ policyItemGroups.forEach(x -> ret.add(new RangerGrant(new
RangerPrincipal(PrincipalType.GROUP, x), policyItemAccessTypes, conditions)));
}
if (CollectionUtils.isNotEmpty(policyItemRoles)) {
- policyItemRoles.forEach(x -> ret.add(new RangerGrant(new
RangerPrincipal(RangerPrincipal.PrincipalType.ROLE, x), policyItemAccessTypes,
policyItemConditionValues)));
+ policyItemRoles.forEach(x -> ret.add(new RangerGrant(new
RangerPrincipal(PrincipalType.ROLE, x), policyItemAccessTypes, conditions)));
}
}
@@ -2005,6 +2005,16 @@ RangerPolicy updatePolicyWithModifiedGrants(RangerPolicy
policy, List<RangerGran
return policy;
}
+ private List<RangerGrant.Condition>
getGrantConditions(List<RangerPolicy.RangerPolicyItemCondition>
policyItemConditions) {
+ List<RangerGrant.Condition> ret = new ArrayList<>();
+
+ if (CollectionUtils.isNotEmpty(policyItemConditions)) {
+ policyItemConditions.stream().map(condition -> new
RangerGrant.Condition(condition.getType(),
condition.getValues())).forEach(ret::add);
+ }
+
+ return ret;
+ }
+
private Long getOrCreateDataShare(Long datasetId, Long serviceId, Long
zoneId, String serviceName) throws Exception {
LOG.debug("==> GdsREST.getOrCreateDataShare(dataSetId={} serviceId={}
zoneId={} serviceName={})", datasetId, serviceId, zoneId, serviceName);
@@ -2156,18 +2166,23 @@ private RangerPolicyItem
transformGrantToPolicyItem(RangerGrant grant) {
return null;
}
- RangerPolicyItem policyItem = new RangerPolicyItem();
- List<String> permissions = grant.getAccessTypes();
- List<String> conditions = grant.getConditions();
+ RangerPolicyItem policyItem = new RangerPolicyItem();
+ List<String> permissions = grant.getAccessTypes();
+ List<RangerGrant.Condition> conditions = grant.getConditions();
if (CollectionUtils.isNotEmpty(permissions)) {
- policyItem.setAccesses(permissions.stream().map(accessType -> new
RangerPolicyItemAccess(accessType, true)).collect(Collectors.toList()));
+ policyItem.setAccesses(permissions.stream()
+ .map(accessType -> new RangerPolicyItemAccess(accessType,
true))
+ .collect(Collectors.toList()));
}
+ List<RangerPolicyItemCondition> policyItemConditions = new
ArrayList<>();
if (CollectionUtils.isNotEmpty(conditions)) {
- policyItem.setConditions(conditions.stream().map(condition -> new
RangerPolicyItemCondition(GDS_POLICY_EXPR_CONDITION,
Collections.singletonList(condition))).collect(Collectors.toList()));
+ conditions.stream().map(condition -> new
RangerPolicyItemCondition(condition.getType(),
condition.getValues())).forEach(policyItemConditions::add);
}
+ policyItem.setConditions(policyItemConditions);
+
switch (grant.getPrincipal().getType()) {
case USER:
policyItem.setUsers(Collections.singletonList(grant.getPrincipal().getName()));
diff --git
a/security-admin/src/test/java/org/apache/ranger/rest/TestGdsREST.java
b/security-admin/src/test/java/org/apache/ranger/rest/TestGdsREST.java
index 68d62fc31a..11df009a46 100644
--- a/security-admin/src/test/java/org/apache/ranger/rest/TestGdsREST.java
+++ b/security-admin/src/test/java/org/apache/ranger/rest/TestGdsREST.java
@@ -238,7 +238,19 @@ private RangerPolicy
createPolicyForDataSet(RangerGds.RangerDataset dataset) {
}
private List<RangerGrant> createAndGetSampleGrantData() {
- RangerGrant grant1 = new RangerGrant(new
RangerPrincipal(RangerPrincipal.PrincipalType.USER, "hive"),
Collections.singletonList("_READ"),
Collections.singletonList("IS_ACCESSED_BEFORE('2024/12/12')"));
+ List<RangerGrant.Condition> conditions = new ArrayList<>();
+
+ RangerGrant.Condition condition1 = new RangerGrant.Condition(null,
null);
+ condition1.setType("expression");
+ condition1.setValues(Arrays.asList("IS_ACCESSED_BEFORE('2024/12/12')",
"_STATE == 'CA'"));
+ conditions.add(condition1);
+
+ RangerGrant.Condition condition2 = new RangerGrant.Condition(null,
null);
+ condition2.setType("validitySchedule");
+ condition2.setValues(Arrays.asList("{\"startTime\":\"1970/01/01
00:00:00\",\"endTime\":\"2025/03/08 00:35:28\",\"timeZone\":\"UTC\"}"));
+ conditions.add(condition2);
+
+ RangerGrant grant1 = new RangerGrant(new
RangerPrincipal(RangerPrincipal.PrincipalType.USER, "hive"),
Collections.singletonList("_READ"), conditions);
RangerGrant grant2 = new RangerGrant(new
RangerPrincipal(RangerPrincipal.PrincipalType.GROUP, "hdfs"),
Collections.singletonList("_MANAGE"), Collections.emptyList());
return Arrays.asList(grant1, grant2);