/* Copyright 2012-2015 SAP SE * * Licensed 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 eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; import java.io.PrintStream; import java.net.URI; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AttributeHelper; import com.sun.xacml.PolicyTreeElement; import com.sun.xacml.Rule; import com.sun.xacml.Target; import com.sun.xacml.TargetMatch; import com.sun.xacml.TargetMatchGroup; import com.sun.xacml.TargetSection; import com.sun.xacml.attr.AttributeDesignator; import com.sun.xacml.attr.AttributeValue; import com.sun.xacml.cond.Apply; import com.sun.xacml.cond.Condition; import com.sun.xacml.cond.Evaluatable; import com.sun.xacml.cond.Expression; import com.sun.xacml.cond.Function; public class PraefixEncoder implements ExtToolEncoder { private ExtToolTypeEncoder typeEnc; private KnownAttrStore attrResolver; private static Logger logger = Logger.getLogger(PraefixEncoder.class); public PraefixEncoder(ExtToolTypeEncoder typeEnc, KnownAttrStore attrResolver) { this.typeEnc = typeEnc; this.attrResolver = attrResolver; } public void printApply(Apply apply, PrintStream out) { typeEnc.printApply(apply, out); } public void printRule(Rule rule, PrintStream out, boolean printTarget) { boolean enclosingAnd = printTarget && rule.getCondition() != null; if (enclosingAnd ) { out.print(typeEnc.getAND() + "("); } if ( printTarget ) { printTarget(rule.getTarget(), out); } if ( rule.getCondition() != null ) { if ( printTarget ) { out.print(typeEnc.getAND() + "("); } printCondition(rule.getCondition(), out); if ( printTarget ) { out.print(")"); } } if (enclosingAnd ) { out.print(")"); } } public void printCondition(Condition cond, PrintStream out) { Expression expr = cond.getExpression(); if ( ! ( expr instanceof Apply )) { throw new RuntimeException("Currently expression for Conditions not being an Apply are not support"); } printApply( (Apply) expr, out); } public void printTarget(Target target, PrintStream out) { if ( target.getTargetSections().size() > 0 ) { if ( target.getTargetSections().size() > 1 ) { out.print(typeEnc.getAND() + "("); } for ( TargetSection section : target.getTargetSections() ) { printTargetSection(section, out); } if ( target.getTargetSections().size() > 1 ) { out.print(") "); } } } private void printTargetSection(TargetSection section, PrintStream out) { if ( section.getMatchGroups().size() > 0 ) { if ( section.getMatchGroups().size() > 1 ) { out.print(typeEnc.getOR() + "("); } for ( TargetMatchGroup group : section.getMatchGroups()) { printTargetGroup(group, out); } if ( section.getMatchGroups().size() > 1 ) { out.print(") "); } } } private void printTargetGroup(TargetMatchGroup group, PrintStream out) { if ( group.getMatches().size() > 0 ) { if ( group.getMatches().size() > 1 ) { out.print(typeEnc.getAND() + "("); } for ( TargetMatch match : group.getMatches()) { printTargetMatch(match, out); } if ( group.getMatches().size() > 1 ) { out.print(") "); } } } /** * recursively print AND combined target matches of all enclosing PolicyTreeElements * @param treeElement * @param out */ public void printTargetMatches(Map<PolicyTreeElement, Map<URI, List<TargetMatch>>> policyMatches, XACMLTree<PolicyTreeElement> treeElement, PrintStream out) { printTargetMatches(policyMatches, treeElement, out, true); } private boolean printTargetMatches(Map<PolicyTreeElement, Map<URI, List<TargetMatch>>> policyMatches, XACMLTree<PolicyTreeElement> treeElement, PrintStream out, boolean isFirst) { // print in format // AND (treeElement.category1.match OR rule.category1.match) AND (treeElement.category2.match OR ...) if (treeElement.getFather() != null && treeElement.getFather().getElement() != null) { isFirst = printTargetMatches(policyMatches, treeElement.getFather(), out, isFirst); } PolicyTreeElement element = treeElement.getElement(); Map<URI, List<TargetMatch>> matches = policyMatches.get(element); for ( URI category : matches.keySet()) { if ( isFirst ) { isFirst = false; } else { out.print(typeEnc.getAND()); } out.print(" ( "); List<TargetMatch> matches2 = matches.get(category); for ( int i = 0; i < matches2.size(); ++i ) { if ( i > 0 ) { out.print(" "+ typeEnc.getOR() + " "); } printTargetMatch(matches2.get(i), out); } out.print(" ) "); } return isFirst; } /** * print target match * @param match * @param out */ public void printTargetMatch(TargetMatch match, PrintStream out) { AttributeValue attrVal = match.getMatchValue(); Function func = match.getMatchFunction(); Evaluatable eval = match.getMatchEvaluatable(); AttributeDesignator attr = null; if ( ! (eval instanceof AttributeDesignator) ) { logger.error("Currently, only AttributeDesignators are supported for TargetMatches"); throw new RuntimeException("Currently, only AttributeDesignators are supported for TargetMatches"); } else { attr = (AttributeDesignator) eval; } AttributeIdentifier attrId = AttributeHelper.getAttributeIdentifier(attr); AttributeValue attrValRes = attrResolver.getAttributeValue(attrId); out.print(typeEnc.getFunctionEnc(func) + "(" + typeEnc.getAttrValueEnc(attrVal) + " " + typeEnc.getAttrDesignatorEnc(attr, attrValRes) + ") "); } public void printConditionAndMatches(Condition cond, Map<PolicyTreeElement, Map<URI, List<TargetMatch>>> policyMatches, XACMLTree<PolicyTreeElement> treeElement, PrintStream out) { boolean isFirst = printTargetMatches(policyMatches, treeElement, out, true); if ( ! isFirst ) { out.print(typeEnc.getAND() + "( "); } printCondition(cond, out); if ( ! isFirst ) { out.print(")"); } } }