org.apache.ranger.plugin.policyevaluator.RangerDefaultPolicyItemEvaluator.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ranger.plugin.policyevaluator.RangerDefaultPolicyItemEvaluator.java

Source

/*
 * 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.policyevaluator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ranger.plugin.conditionevaluator.RangerAbstractConditionEvaluator;
import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef;
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.RangerServiceDef.RangerPolicyConditionDef;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
import org.apache.ranger.plugin.util.RangerPerfTracer;

public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEvaluator {
    private static final Log LOG = LogFactory.getLog(RangerDefaultPolicyItemEvaluator.class);

    private static final Log PERF_POLICYITEM_INIT_LOG = RangerPerfTracer.getPerfLogger("policyitem.init");
    private static final Log PERF_POLICYITEM_REQUEST_LOG = RangerPerfTracer.getPerfLogger("policyitem.request");
    private static final Log PERF_POLICYCONDITION_INIT_LOG = RangerPerfTracer.getPerfLogger("policycondition.init");
    private static final Log PERF_POLICYCONDITION_REQUEST_LOG = RangerPerfTracer
            .getPerfLogger("policycondition.request");

    private boolean hasCurrentUser = false;
    private boolean hasResourceOwner = false;
    private boolean hasAllPerms = false;

    public RangerDefaultPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy,
            RangerPolicyItem policyItem, int policyItemType, int policyItemIndex,
            RangerPolicyEngineOptions options) {
        super(serviceDef, policy, policyItem, policyItemType, policyItemIndex, options);
    }

    public void init() {
        if (LOG.isDebugEnabled()) {
            LOG.debug("==> RangerDefaultPolicyItemEvaluator(policyId=" + policyId + ", policyItem=" + policyItem
                    + ", serviceType=" + getServiceType() + ", conditionsDisabled=" + getConditionsDisabledOption()
                    + ")");
        }

        Set<String> accessPerms = new HashSet<String>();

        List<RangerPolicy.RangerPolicyItemAccess> policyItemAccesses = policyItem.getAccesses();
        for (RangerPolicy.RangerPolicyItemAccess policyItemAccess : policyItemAccesses) {

            if (policyItemAccess.getIsAllowed()) {
                accessPerms.add(policyItemAccess.getType());
            }
        }

        hasAllPerms = true;
        List<RangerServiceDef.RangerAccessTypeDef> serviceAccessTypes = serviceDef.getAccessTypes();
        for (RangerServiceDef.RangerAccessTypeDef serviceAccessType : serviceAccessTypes) {
            String serviceAccessTypeName = serviceAccessType.getName();
            if (!accessPerms.contains(serviceAccessTypeName)) {
                hasAllPerms = false;
                break;
            }
        }

        if (!getConditionsDisabledOption() && CollectionUtils.isNotEmpty(policyItem.getConditions())) {
            conditionEvaluators = new ArrayList<RangerConditionEvaluator>();

            RangerPerfTracer perf = null;

            if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYITEM_INIT_LOG)) {
                perf = RangerPerfTracer.getPerfTracer(PERF_POLICYITEM_INIT_LOG,
                        "RangerPolicyItemEvaluator.init(policyId=" + policyId + ",policyItemIndex="
                                + getPolicyItemIndex() + ")");
            }

            for (RangerPolicyItemCondition condition : policyItem.getConditions()) {
                RangerPolicyConditionDef conditionDef = getConditionDef(condition.getType());

                if (conditionDef == null) {
                    LOG.error("RangerDefaultPolicyItemEvaluator(policyId=" + policyId + "): conditionDef '"
                            + condition.getType() + "' not found. Ignoring the condition");

                    continue;
                }

                RangerConditionEvaluator conditionEvaluator = newConditionEvaluator(conditionDef.getEvaluator());

                if (conditionEvaluator != null) {
                    conditionEvaluator.setServiceDef(serviceDef);
                    conditionEvaluator.setConditionDef(conditionDef);
                    conditionEvaluator.setPolicyItemCondition(condition);

                    RangerPerfTracer perfConditionInit = null;

                    if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_INIT_LOG)) {
                        perfConditionInit = RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_INIT_LOG,
                                "RangerConditionEvaluator.init(policyId=" + policyId + ",policyItemIndex="
                                        + getPolicyItemIndex() + ",policyConditionType=" + condition.getType()
                                        + ")");
                    }

                    conditionEvaluator.init();

                    RangerPerfTracer.log(perfConditionInit);

                    conditionEvaluators.add(conditionEvaluator);
                } else {
                    LOG.error("RangerDefaultPolicyItemEvaluator(policyId=" + policyId
                            + "): failed to instantiate condition evaluator '" + condition.getType()
                            + "'; evaluatorClassName='" + conditionDef.getEvaluator() + "'");
                }
            }
            RangerPerfTracer.log(perf);
        }

        List<String> users = policyItem.getUsers();
        this.hasCurrentUser = CollectionUtils.isNotEmpty(users) && users.contains(RangerPolicyEngine.USER_CURRENT);
        this.hasResourceOwner = CollectionUtils.isNotEmpty(users)
                && users.contains(RangerPolicyEngine.RESOURCE_OWNER);

        if (LOG.isDebugEnabled()) {
            LOG.debug("<== RangerDefaultPolicyItemEvaluator(policyId=" + policyId + ", conditionsCount="
                    + getConditionEvaluators().size() + ")");
        }
    }

    @Override
    public boolean isMatch(RangerAccessRequest request) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("==> RangerDefaultPolicyItemEvaluator.isMatch(" + request + ")");
        }

        boolean ret = false;

        RangerPerfTracer perf = null;

        if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYITEM_REQUEST_LOG)) {
            perf = RangerPerfTracer.getPerfTracer(PERF_POLICYITEM_REQUEST_LOG,
                    "RangerPolicyItemEvaluator.isMatch(resource=" + request.getResource().getAsString() + ")");
        }

        if (policyItem != null) {
            if (matchUserGroupAndOwner(request)) {
                if (request.isAccessTypeDelegatedAdmin()) { // used only in grant/revoke scenario
                    if (policyItem.getDelegateAdmin()) {
                        ret = true;
                    }
                } else if (CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
                    boolean isAccessTypeMatched = false;

                    if (request.isAccessTypeAny()) {
                        if (getPolicyItemType() == POLICY_ITEM_TYPE_DENY
                                || getPolicyItemType() == POLICY_ITEM_TYPE_DENY_EXCEPTIONS) {
                            if (hasAllPerms) {
                                isAccessTypeMatched = true;
                            }
                        } else {
                            for (RangerPolicy.RangerPolicyItemAccess access : policyItem.getAccesses()) {
                                if (access.getIsAllowed()) {
                                    isAccessTypeMatched = true;
                                    break;
                                }
                            }
                        }
                    } else {
                        for (RangerPolicy.RangerPolicyItemAccess access : policyItem.getAccesses()) {
                            if (access.getIsAllowed()
                                    && StringUtils.equalsIgnoreCase(access.getType(), request.getAccessType())) {
                                isAccessTypeMatched = true;
                                break;
                            }
                        }
                    }

                    if (isAccessTypeMatched) {
                        if (matchCustomConditions(request)) {
                            ret = true;
                        }
                    }
                }
            }
        }

        RangerPerfTracer.log(perf);

        if (LOG.isDebugEnabled()) {
            LOG.debug("<== RangerDefaultPolicyItemEvaluator.isMatch(" + request + "): " + ret);
        }

        return ret;
    }

    @Override
    public boolean matchUserGroup(String user, Set<String> userGroups) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("==> RangerDefaultPolicyItemEvaluator.matchUserGroup(" + policyItem + ", " + user + ", "
                    + userGroups + ")");
        }

        boolean ret = false;

        if (policyItem != null) {
            if (!ret && user != null && policyItem.getUsers() != null) {
                ret = hasCurrentUser || policyItem.getUsers().contains(user);
            }

            if (!ret && userGroups != null && policyItem.getGroups() != null) {
                ret = policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC)
                        || !Collections.disjoint(policyItem.getGroups(), userGroups);
            }
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("<== RangerDefaultPolicyItemEvaluator.matchUserGroup(" + policyItem + ", " + user + ", "
                    + userGroups + "): " + ret);
        }

        return ret;
    }

    private boolean matchUserGroupAndOwner(RangerAccessRequest request) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("==> RangerDefaultPolicyItemEvaluator.matchUserGroupAndOwner(" + request + ")");
        }

        boolean ret = false;

        String user = request.getUser();
        Set<String> userGroups = request.getUserGroups();

        if (hasResourceOwner) {
            RangerAccessResource accessedResource = request.getResource();
            String resourceOwner = accessedResource != null ? accessedResource.getOwnerUser() : null;

            if (user != null && resourceOwner != null && user.equals(resourceOwner)) {
                ret = true;
            }
        }
        if (!ret) {
            ret = matchUserGroup(user, userGroups);
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("<== RangerDefaultPolicyItemEvaluator.matchUserGroupAndOwner(" + request + "): " + ret);
        }

        return ret;
    }

    @Override
    public boolean matchAccessType(String accessType) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("==> RangerDefaultPolicyItemEvaluator.matchAccessType(" + accessType + ")");
        }

        boolean ret = false;

        if (policyItem != null) {
            boolean isAdminAccess = StringUtils.equals(accessType, RangerPolicyEngine.ADMIN_ACCESS);

            if (isAdminAccess) {
                ret = policyItem.getDelegateAdmin();
            } else {
                if (CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
                    boolean isAnyAccess = StringUtils.equals(accessType, RangerPolicyEngine.ANY_ACCESS);

                    for (RangerPolicyItemAccess itemAccess : policyItem.getAccesses()) {
                        if (!itemAccess.getIsAllowed()) {
                            continue;
                        }

                        if (isAnyAccess) {
                            ret = true;

                            break;
                        } else if (StringUtils.equalsIgnoreCase(itemAccess.getType(), accessType)) {
                            ret = true;

                            break;
                        }
                    }
                }
            }
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("<== RangerDefaultPolicyItemEvaluator.matchAccessType(" + accessType + "): " + ret);
        }

        return ret;
    }

    @Override
    public boolean matchCustomConditions(RangerAccessRequest request) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("==> RangerDefaultPolicyItemEvaluator.matchCustomConditions(" + request + ")");
        }

        boolean ret = true;

        if (CollectionUtils.isNotEmpty(conditionEvaluators)) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("RangerDefaultPolicyItemEvaluator.matchCustomConditions(): conditionCount="
                        + conditionEvaluators.size());
            }
            for (RangerConditionEvaluator conditionEvaluator : conditionEvaluators) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("evaluating condition: " + conditionEvaluator);
                }
                RangerPerfTracer perf = null;

                if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_REQUEST_LOG)) {

                    String conditionType = null;
                    if (conditionEvaluator instanceof RangerAbstractConditionEvaluator) {
                        conditionType = ((RangerAbstractConditionEvaluator) conditionEvaluator)
                                .getPolicyItemCondition().getType();
                    }

                    perf = RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_REQUEST_LOG,
                            "RangerConditionEvaluator.matchCondition(policyId=" + policyId + ",policyItemIndex="
                                    + getPolicyItemIndex() + ",policyConditionType=" + conditionType + ")");
                }

                boolean conditionEvalResult = conditionEvaluator.isMatched(request);

                RangerPerfTracer.log(perf);

                if (!conditionEvalResult) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug(conditionEvaluator + " returned false");
                    }

                    ret = false;

                    break;
                }
            }
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("<== RangerDefaultPolicyItemEvaluator.matchCustomConditions(" + request + "): " + ret);
        }

        return ret;
    }

    RangerPolicyConditionDef getConditionDef(String conditionName) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("==> RangerDefaultPolicyItemEvaluator.getConditionDef(" + conditionName + ")");
        }

        RangerPolicyConditionDef ret = null;

        if (serviceDef != null && CollectionUtils.isNotEmpty(serviceDef.getPolicyConditions())) {
            for (RangerPolicyConditionDef conditionDef : serviceDef.getPolicyConditions()) {
                if (StringUtils.equals(conditionName, conditionDef.getName())) {
                    ret = conditionDef;

                    break;
                }
            }
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("<== RangerDefaultPolicyItemEvaluator.getConditionDef(" + conditionName + "): " + ret);
        }

        return ret;
    }

    RangerConditionEvaluator newConditionEvaluator(String className) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("==> RangerDefaultPolicyItemEvaluator.newConditionEvaluator(" + className + ")");
        }

        RangerConditionEvaluator evaluator = null;

        try {
            @SuppressWarnings("unchecked")
            Class<RangerConditionEvaluator> matcherClass = (Class<RangerConditionEvaluator>) Class
                    .forName(className);

            evaluator = matcherClass.newInstance();
        } catch (Throwable t) {
            LOG.error("RangerDefaultPolicyItemEvaluator.newConditionEvaluator(" + className
                    + "): error instantiating evaluator");
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug(
                    "<== RangerDefaultPolicyItemEvaluator.newConditionEvaluator(" + className + "): " + evaluator);
        }

        return evaluator;
    }
}