/* * Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. 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.wso2.carbon.identity.entitlement.pap.store; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.balana.AbstractPolicy; import org.wso2.balana.MatchResult; import org.wso2.balana.Policy; import org.wso2.balana.PolicyMetaData; import org.wso2.balana.PolicyReference; import org.wso2.balana.PolicySet; import org.wso2.balana.VersionConstraints; import org.wso2.balana.combine.PolicyCombiningAlgorithm; import org.wso2.balana.combine.xacml2.OnlyOneApplicablePolicyAlg; import org.wso2.balana.ctx.EvaluationCtx; import org.wso2.balana.ctx.Status; import org.wso2.balana.finder.PolicyFinder; import org.wso2.balana.finder.PolicyFinderModule; import org.wso2.balana.finder.PolicyFinderResult; import org.wso2.carbon.identity.entitlement.EntitlementException; import org.wso2.carbon.identity.entitlement.dto.PolicyDTO; import org.wso2.carbon.identity.entitlement.policy.collection.DefaultPolicyCollection; import java.net.URI; import java.util.ArrayList; import java.util.List; public class PAPPolicyFinder extends PolicyFinderModule { // the logger we'll use for all messages private static Log log = LogFactory.getLog(PAPPolicyFinder.class); // the list of policy URLs passed to the constructor private PAPPolicyStoreReader policyReader; // the map of policies private DefaultPolicyCollection policies; //keeps policy ids according to the order private List<String> policyIds; private PolicyFinder policyFinder; // only five policies are allowed private int maxInMemoryPolicies = 5; /** * Creates a PAPPolicyFinder that provides access to the given collection of policies. * Any policy that cannot be loaded will be noted in the log, but will not cause an error. The * schema file used to validate policies is defined by the property * PolicyRepository.POLICY_SCHEMA_PROPERTY. If the retrieved property is null, then no schema * validation will occur. * * @param policyReader Policy store repository for Registry */ public PAPPolicyFinder(PAPPolicyStoreReader policyReader) { this.policyReader = policyReader; } /** * Always returns <code>true</code> since this module does support finding policies based on * reference. * * @return true */ public boolean isIdReferenceSupported() { return true; } /* * (non-Javadoc) * * @see org.wso2.balana.finder.PolicyFinderModule#isRequestSupported() */ public boolean isRequestSupported() { return true; } /* * (non-Javadoc) * * @see org.wso2.balana.finder.PolicyFinderModule#init(org.wso2.balana.finder.CarbonPolicyFinder) */ public void init(PolicyFinder finder) { PolicyCombiningAlgorithm algorithm; this.policyFinder = finder; try { // for PAP policy store, Global policy combining algorithm is not needed. As we are // only evaluating one policy therefore using default algorithm. algorithm = new OnlyOneApplicablePolicyAlg(); initPolicyIds(); this.policies = new DefaultPolicyCollection(algorithm, 0); } catch (EntitlementException e) { log.error("Error while initializing PAPPolicyFinder", e); } } /* * (non-Javadoc) * * @see org.wso2.balana.finder.PolicyFinderModule#findPolicy(java.net.URI, int, * org.wso2.balana.VersionConstraints, org.wso2.balana.PolicyMetaData) */ public PolicyFinderResult findPolicy(URI idReference, int type, VersionConstraints constraints, PolicyMetaData parentMetaData) { // clear all current policies policies.getPolicies().clear(); AbstractPolicy policy = null; try { AbstractPolicy policyFromStore = policyReader.readPolicy(idReference.toString(), this.policyFinder); if (policyFromStore != null) { if (type == PolicyReference.POLICY_REFERENCE) { if (policyFromStore instanceof Policy) { policy = policyFromStore; policies.addPolicy(policy); } } else { if (policyFromStore instanceof PolicySet) { policy = policyFromStore; policies.addPolicy(policy); } } } } catch (EntitlementException e) { // ignore and just log the error. log.error(e); } if (policy == null) { return new PolicyFinderResult(); } else { return new PolicyFinderResult(policy); } } /* * (non-Javadoc) * * @see org.wso2.balana.finder.PolicyFinderModule#findPolicy(org.wso2.balana.EvaluationCtx) */ public PolicyFinderResult findPolicy(EvaluationCtx context) { // clear all current policies policies.getPolicies().clear(); ArrayList<AbstractPolicy> list = new ArrayList<AbstractPolicy>(); try { for (String policyId : policyIds) { if (list.size() == maxInMemoryPolicies) { break; } AbstractPolicy policy = null; try { policy = policyReader.readPolicy(policyId, this.policyFinder); } catch (EntitlementException e) { //log and ignore log.error(e); } if (policy == null) { continue; } else { policies.addPolicy(policy); } // see if we match MatchResult match = policy.match(context); int result = match.getResult(); // if there was an error, we stop right away if (result == MatchResult.INDETERMINATE) { log.error(match.getStatus().getMessage()); throw new EntitlementException(match.getStatus().getMessage()); } // if we matched, we keep track of the matching policy... if (result == MatchResult.MATCH) { if (log.isDebugEnabled()) { log.debug("Matching XACML policy found " + policy.getId().toString()); } list.add(policy); } } AbstractPolicy policy = policies.getEffectivePolicy(list); if (policy == null) { return new PolicyFinderResult(); } else { return new PolicyFinderResult(policy); } } catch (EntitlementException e) { ArrayList<String> code = new ArrayList<String>(); code.add(Status.STATUS_PROCESSING_ERROR); Status status = new Status(code, e.getMessage()); return new PolicyFinderResult(status); } } /** * Sets polices ids that is evaluated * * @param policyIds */ public void setPolicyIds(List<String> policyIds) { this.policyIds = policyIds; } public void initPolicyIds() throws EntitlementException { this.policyIds = new ArrayList<String>(); PolicyDTO[] policyDTOs = policyReader.readAllLightPolicyDTOs(); for (PolicyDTO dto : policyDTOs) { if (dto.isActive()) { policyIds.add(dto.getPolicyId()); } } } }