Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.util.ServiceDefUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

Expand All @@ -38,24 +41,25 @@ public class RangerAccessResult {
private static final String KEY_ALLOWED_BY_DATASETS = "allowedByDatasets";
private static final String KEY_ALLOWED_BY_PROJECTS = "allowedByProjects";

private final String serviceName;
private final RangerServiceDef serviceDef;
private final RangerAccessRequest request;

private final int policyType; // Really, policy-type for audit purpose
private boolean isAccessDetermined;
private boolean isAllowed;
private boolean isAuditedDetermined;
private boolean isAudited;
private long auditPolicyId = -1;
private String auditLogId;
private long policyId = -1;
private int policyPriority;
private String zoneName;
private Long policyVersion;
private long evaluatedPoliciesCount;
private String reason;
private Map<String, Object> additionalInfo;
private final String serviceName;
private final RangerServiceDef serviceDef;
private final RangerAccessRequest request;

private final int policyType; // Really, policy-type for audit purpose
private boolean isAccessDetermined;
private boolean isAllowed;
private boolean isAuditedDetermined;
private boolean isAudited;
private long auditPolicyId = -1;
private String auditLogId;
private long policyId = -1;
private int policyPriority;
private String zoneName;
private Long policyVersion;
private long evaluatedPoliciesCount;
private String reason;
private Map<String, Object> additionalInfo;
private List<RangerConstraintResult> constraints;

public RangerAccessResult(final int policyType, final String serviceName, final RangerServiceDef serviceDef, final RangerAccessRequest request) {
this.serviceName = serviceName;
Expand Down Expand Up @@ -83,6 +87,7 @@ public void setAccessResultFrom(final RangerAccessResult other) {
this.evaluatedPoliciesCount = other.evaluatedPoliciesCount;
this.reason = other.getReason();
this.additionalInfo = other.additionalInfo == null ? new HashMap<>() : new HashMap<>(other.additionalInfo);
this.constraints = copyConstraints(other.constraints);
}

public void setAuditResultFrom(final RangerAccessResult other) {
Expand Down Expand Up @@ -138,6 +143,7 @@ public boolean getIsAllowed() {
public void setIsAllowed(boolean isAllowed) {
if (!isAllowed) {
setIsAccessDetermined(true);
this.constraints = null;
}

this.isAllowed = isAllowed;
Expand Down Expand Up @@ -408,6 +414,29 @@ public void setAllowedByProjects(Set<String> projects) {
}
}

/**
* Constraints that matched this request. Empty when access is denied or nothing matched.
*/
public List<RangerConstraintResult> getConstraints() {
return constraints == null ? Collections.emptyList() : constraints;
}

public void setConstraints(List<RangerConstraintResult> constraints) {
this.constraints = copyConstraints(constraints);
}

public void addConstraint(RangerConstraintResult constraint) {
if (constraint == null) {
return;
}

if (constraints == null) {
constraints = new ArrayList<>();
}

constraints.add(constraint);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Expand Down Expand Up @@ -439,10 +468,16 @@ public StringBuilder toString(StringBuilder sb) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append(", ");
}
}
sb.append("}");
sb.append("} ");

sb.append("constraints={").append(getConstraints()).append("}");

sb.append("}");

return sb;
}

private static List<RangerConstraintResult> copyConstraints(List<RangerConstraintResult> constraints) {
return constraints == null || constraints.isEmpty() ? null : new ArrayList<>(constraints);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ranger.plugin.policyengine;

import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher.MatchType;

import java.io.Serializable;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class RangerConstraintResult {
public static final Comparator<RangerConstraintResult> CONSTRAINT_RESULT_COMPARATOR = new ConstraintResultComparator();

private final Map<String, Object> parameters;
private String constraintName;
private long policyId;
private Long policyVersion;
private int policyPriority;
private MatchType matchType;

public RangerConstraintResult(String constraintName, Map<String, Object> parameters, long policyId, Long policyVersion, int policyPriority, MatchType matchType) {
this.constraintName = constraintName;
this.parameters = parameters == null ? new HashMap<>() : new HashMap<>(parameters);
this.policyId = policyId;
this.policyVersion = policyVersion;
this.policyPriority = policyPriority;
this.matchType = matchType;
}

public String getConstraintName() {
return constraintName;
}

public Map<String, Object> getParameters() {
return parameters;
}

public long getPolicyId() {
return policyId;
}

public Long getPolicyVersion() {
return policyVersion;
}

public int getPolicyPriority() {
return policyPriority;
}

public MatchType getMatchType() {
return matchType;
}

@Override
public int hashCode() {
return Objects.hash(constraintName, parameters, policyId, policyVersion, policyPriority, matchType);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}

if (obj == null || getClass() != obj.getClass()) {
return false;
}

RangerConstraintResult other = (RangerConstraintResult) obj;

return policyId == other.policyId &&
policyPriority == other.policyPriority &&
Objects.equals(policyVersion, other.policyVersion) &&
Objects.equals(constraintName, other.constraintName) &&
Objects.equals(matchType, other.matchType) &&
Objects.equals(parameters, other.parameters);
}

@Override
public String toString() {
return "RangerConstraintResult{constraintName=" + constraintName +
", parameters=" + parameters +
", policyId=" + policyId +
", policyVersion=" + policyVersion +
", policyPriority=" + policyPriority +
", matchType=" + matchType +
"}";
}

/**
* Orders by constraint name, policy priority (higher first), match type, then policy id.
*/
public static class ConstraintResultComparator implements Comparator<RangerConstraintResult>, Serializable {
@Override
public int compare(RangerConstraintResult me, RangerConstraintResult other) {
int ret = compareStrings(me.getConstraintName(), other.getConstraintName());

if (ret == 0) {
ret = Integer.compare(other.getPolicyPriority(), me.getPolicyPriority());
}

if (ret == 0) {
ret = RangerPolicyResourceMatcher.MATCH_TYPE_COMPARATOR.compare(me.getMatchType(), other.getMatchType());
}

if (ret == 0) {
ret = Long.compare(me.getPolicyId(), other.getPolicyId());
}

return ret;
}

private static int compareStrings(String me, String other) {
return me == null ? (other == null ? 0 : -1) : (other == null ? 1 : me.compareTo(other));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,10 @@ private void updateResultFromChainedResult(RangerAccessResult result, RangerAcce
} else if (policyType == RangerPolicy.POLICY_TYPE_ROWFILTER) {
result.setFilterExpr(chainedResult.getFilterExpr());
}

if (result.getIsAllowed()) {
result.setConstraints(chainedResult.getConstraints());
}
}

if (!result.getIsAuditedDetermined() && chainedResult.getIsAuditedDetermined()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ranger.plugin.policyengine;

import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher.MatchType;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class TestRangerAccessResult {
@Test
public void constraintsAreEmptyUntilOneIsAdded() {
RangerAccessResult result = newResult();

assertTrue(result.getConstraints().isEmpty());

result.addConstraint(null);
assertTrue(result.getConstraints().isEmpty());

RangerConstraintResult constraint = constraint(10L);

result.addConstraint(constraint);

assertEquals(Arrays.asList(constraint), result.getConstraints());
}

@Test
public void setConstraintsCopiesTheInputList() {
RangerAccessResult result = newResult();
List<RangerConstraintResult> constraints = new ArrayList<>();
RangerConstraintResult constraint = constraint(10L);

constraints.add(constraint);
result.setConstraints(constraints);
constraints.clear();

assertEquals(Arrays.asList(constraint), result.getConstraints());

result.setConstraints(new ArrayList<>());

assertTrue(result.getConstraints().isEmpty());
}

@Test
public void setAccessResultFromCopiesConstraints() {
RangerAccessResult source = newResult();
RangerAccessResult copied = newResult();
RangerConstraintResult constraint = constraint(10L);

source.addConstraint(constraint);
copied.setAccessResultFrom(source);

assertEquals(Arrays.asList(constraint), copied.getConstraints());
}

@Test
public void denyClearsConstraints() {
RangerAccessResult result = newResult();

result.addConstraint(constraint(10L));
result.setIsAllowed(false);

assertTrue(result.getConstraints().isEmpty());

result.addConstraint(constraint(11L));
result.setIsAllowed(true);

assertEquals(1, result.getConstraints().size());
}

private static RangerAccessResult newResult() {
return new RangerAccessResult(0, "agent-studio", null, null);
}

private static RangerConstraintResult constraint(long policyId) {
return new RangerConstraintResult("requireApproval", null, policyId, 1L, 0, MatchType.SELF);
}
}
Loading