diff --git a/xacml-core/src/main/java/org/xacml4j/v30/marshal/jaxb/ExpressionTypeBuilder.java b/xacml-core/src/main/java/org/xacml4j/v30/marshal/jaxb/ExpressionTypeBuilder.java index a8054a6a5..fea554649 100644 --- a/xacml-core/src/main/java/org/xacml4j/v30/marshal/jaxb/ExpressionTypeBuilder.java +++ b/xacml-core/src/main/java/org/xacml4j/v30/marshal/jaxb/ExpressionTypeBuilder.java @@ -24,6 +24,7 @@ import javax.xml.bind.JAXBElement; +import com.google.common.base.Optional; import org.oasis.xacml.v30.jaxb.ApplyType; import org.oasis.xacml.v30.jaxb.AttributeDesignatorType; import org.oasis.xacml.v30.jaxb.AttributeSelectorType; @@ -92,10 +93,9 @@ public JAXBElement from(Expression e){ public JAXBElement from(Expression e){ Preconditions.checkArgument(e instanceof AttributeExp); AttributeExp v = (AttributeExp)e; - AttributeValueType exp = factory.createAttributeValueType(); - exp.setDataType(v.getType().getDataTypeId()); - exp.getContent().add(v.getValue()); - return factory.createAttributeValue(exp); + Optional toXacml30 = TypeToXacml30.Types.getIndex().get(v.getType()); + Preconditions.checkState(toXacml30.isPresent()); + return factory.createAttributeValue(toXacml30.get().toXacml30(v)); } }, ATTRIBUTE_DESIGNATOR(AttributeDesignator.class){ diff --git a/xacml-core/src/main/java/org/xacml4j/v30/pdp/Condition.java b/xacml-core/src/main/java/org/xacml4j/v30/pdp/Condition.java index f35132a57..fcaef75bb 100644 --- a/xacml-core/src/main/java/org/xacml4j/v30/pdp/Condition.java +++ b/xacml-core/src/main/java/org/xacml4j/v30/pdp/Condition.java @@ -22,6 +22,8 @@ * #L% */ +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.xacml4j.v30.EvaluationContext; import org.xacml4j.v30.EvaluationException; import org.xacml4j.v30.Expression; @@ -42,6 +44,8 @@ */ public class Condition implements PolicyElement { + private final static Logger log = LoggerFactory.getLogger(Condition.class); + private final Expression predicate; /** @@ -88,9 +92,11 @@ public ConditionResult evaluate(EvaluationContext context) return result.getValue()?ConditionResult.TRUE:ConditionResult.FALSE; }catch(EvaluationException e){ context.setEvaluationStatus(e.getStatus()); + log.debug("Evaluation FAILED.", e); return ConditionResult.INDETERMINATE; }catch(Exception e){ context.setEvaluationStatus(Status.processingError().build()); + log.debug("Evaluation FAILED", e); return ConditionResult.INDETERMINATE; } } diff --git a/xacml-core/src/test/java/org/xacml4j/v30/marshal/jaxb/Xacml30AttributeValueMarshalingTest.java b/xacml-core/src/test/java/org/xacml4j/v30/marshal/jaxb/Xacml30AttributeValueMarshalingTest.java new file mode 100644 index 000000000..a0b04e8a3 --- /dev/null +++ b/xacml-core/src/test/java/org/xacml4j/v30/marshal/jaxb/Xacml30AttributeValueMarshalingTest.java @@ -0,0 +1,103 @@ +package org.xacml4j.v30.marshal.jaxb; + +/* + * #%L + * Xacml4J Core Engine Implementation + * %% + * Copyright (C) 2009 - 2015 Xacml4J.org + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + + +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.xacml4j.v30.Effect; +import org.xacml4j.v30.Expression; +import org.xacml4j.v30.pdp.Apply; +import org.xacml4j.v30.pdp.Policy; +import org.xacml4j.v30.pdp.Rule; +import org.xacml4j.v30.policy.combine.DenyOverridesRuleCombiningAlgorithm; +import org.xacml4j.v30.spi.function.FunctionProvider; +import org.xacml4j.v30.spi.function.FunctionProviderBuilder; +import org.xacml4j.v30.types.AnyURIExp; +import org.xacml4j.v30.types.IntegerExp; +import org.xacml4j.v30.types.StringExp; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.Collection; + +@RunWith(Parameterized.class) +public class Xacml30AttributeValueMarshalingTest { + private final static FunctionProvider Funcs = + FunctionProviderBuilder.builder() + .defaultFunctions() + .build(); + + @Parameterized.Parameters(name = "#{0}") + public static Collection data() { + return Arrays.asList(new Object[][]{ + {"integer", "urn:oasis:names:tc:xacml:1.0:function:integer-equal", IntegerExp.of(0)}, + {"string", "urn:oasis:names:tc:xacml:1.0:function:string-equal", StringExp.of("a")}, + {"anyURI", "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", AnyURIExp.of("about:blank")}, + }); + } + + private String name; + private String functionId; + private Expression expression; + + public Xacml30AttributeValueMarshalingTest(String name, String functionId, Expression expression) { + this.name = name; + this.functionId = functionId; + this.expression = expression; + } + + @org.junit.Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void testAttributeValueMarshaling() throws IOException { + // arrange + Policy policy = createPolicy(); + + // act + new Xacml30PolicyMarshaller().marshal(policy, new StringWriter()); + + // assert + // should not throw + } + + private Policy createPolicy() { + Rule rule = Rule.builder("rule", Effect.DENY) + .condition( + Apply.builder(Funcs.getFunction(functionId)) + .param(expression) + .param(expression) + .build() + ) + .build(); + + return Policy.builder("policy") + .combiningAlgorithm(new DenyOverridesRuleCombiningAlgorithm()) + .rule(rule) + .build(); + } +} diff --git a/xacml-test/src/main/java/org/xacml4j/v30/XacmlPolicyTestSupport.java b/xacml-test/src/main/java/org/xacml4j/v30/XacmlPolicyTestSupport.java index 0d25cc8c9..287d85790 100644 --- a/xacml-test/src/main/java/org/xacml4j/v30/XacmlPolicyTestSupport.java +++ b/xacml-test/src/main/java/org/xacml4j/v30/XacmlPolicyTestSupport.java @@ -79,16 +79,22 @@ protected Builder builder(String rootPolicyId, String rootPolicyVersion) } protected void verifyXacml30Response(PolicyDecisionPoint pdp, - String xacmlRequestResource, - String expectedXacmlResponseResource) throws Exception { - RequestContext req = getXacml30Request(xacmlRequestResource); - ResponseContext expectedResponse = getXacml30Response(expectedXacmlResponseResource); - ResponseContext resp = pdp.decide(req); + RequestContext request, + ResponseContext expectedResponse) throws Exception { + ResponseContext resp = pdp.decide(request); log.debug("Expected XACML 3.0 response=\"{}\"", expectedResponse); log.debug("Received XACML 3.0 response=\"{}\"", resp); assertResponse(expectedResponse, resp); } + protected void verifyXacml30Response(PolicyDecisionPoint pdp, + String xacmlRequestResource, + String expectedXacmlResponseResource) throws Exception { + RequestContext req = getXacml30Request(xacmlRequestResource); + ResponseContext expectedResponse = getXacml30Response(expectedXacmlResponseResource); + verifyXacml30Response(pdp, req, expectedResponse); + } + protected void verifyXacml20Response( PolicyDecisionPoint pdp, String xacmlRequestResource, @@ -265,7 +271,7 @@ public class Builder private FunctionProviderBuilder functionProviderBuilder; private PolicyInformationPointBuilder pipBuilder; private DecisionCombiningAlgorithmProviderBuilder decisionAlgoProviderBuilder; - private Collection> policies; + private Collection policies; // might be either Supplier or CompositeDecisionRule public Builder(String pdpId, String pipId, String repositoryId){ Preconditions.checkNotNull(pdpId); @@ -274,7 +280,7 @@ public Builder(String pdpId, String pipId, String repositoryId){ this.functionProviderBuilder = FunctionProviderBuilder.builder(); this.decisionAlgoProviderBuilder = DecisionCombiningAlgorithmProviderBuilder.builder(); this.pipBuilder = PolicyInformationPointBuilder.builder(pipId); - this.policies = new ArrayList>(); + this.policies = new ArrayList(); this.repositoryId = repositoryId; this.pdpId = pdpId; } @@ -325,6 +331,16 @@ public Builder policies(Supplier ... policies){ return this; } + public Builder policy(CompositeDecisionRule policy){ + this.policies.add(policy); + return this; + } + + public Builder policies(CompositeDecisionRule... policies){ + Collections.addAll(this.policies, policies); + return this; + } + public Builder policyFromClasspath(String path){ this.policies.add(getPolicy(path)); return this; @@ -340,14 +356,25 @@ public Builder resolver(String policyId, Object resolver){ return this; } + @SuppressWarnings("unchecked") public PolicyDecisionPoint build() throws Exception { PolicyRepository repository = new InMemoryPolicyRepository( repositoryId, functionProviderBuilder.build(), decisionAlgoProviderBuilder.create()); - for (Supplier in : policies) { - repository.importPolicy(in); + for (Object policy : policies) { + if (policy instanceof Supplier) { + repository.importPolicy((Supplier) policy); + } else if (policy instanceof CompositeDecisionRule) { + repository.add((CompositeDecisionRule) policy); + } else { + throw new UnsupportedOperationException( + String.format( + "Unable to interpret policy represented by '%s'. " + + "There are 'Supplier' or 'CompositeDecisionRule' supported only.", + policy.getClass())); + } } return PolicyDecisionPointBuilder .builder(pdpId)