Commit 26023e5a authored by cdanger's avatar cdanger

REFACTORING & SIMPLIFICATION

- Removed XACML AttributeValueType as superclass of AttributeValue
(datatype ID no longer part of AttributeValue)
- AttributeValue class becomes an interface
- Removed XACML CombinerParameter as superclass of
CombinerParameterEvaluator
- Renamed CombinerParameterEvaluator class to ParameterAssignment
- Renamed AbstractDecisionResult class to BaseDecisionResult
- Added AttributeValueFactoryRegistry#getCompatibleFactory() (used in
unit tests)
- PepAction replaces XACML Obligation/Advice in API, and
(Immutable)PepActions removed/replaced with (Immutable)List<PepAction>,
and UpdatablePepActions removed/replaced with UpdatableList<PepAction>
- Added PrimitiveDatatype#getInstanceClass) to give Java class
associated to xacml datatype
- Added PepActionAttributeAssignment as equivalent to XACML
AttributeAssignment in API
- Added XacmlJaxbParingUtils#parseXacmlJaxbResult(Result) to parse
XACML/XML Result into API's DecisionResult
parent 2242a0a5
......@@ -19,19 +19,21 @@ package org.ow2.authzforce.core.pdp.api;
import java.util.Objects;
import com.google.common.collect.ImmutableList;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Status;
/**
* This class provides a skeletal implementation of the {@link DecisionResult} interface to minimize the effort required to implement this interface. Note that this class only overrides/implements
* {@link #equals(Object)}, {@link #hashCode()} and {@link #getStatus()}.
*/
public abstract class AbstractDecisionResult implements DecisionResult
public abstract class BaseDecisionResult implements DecisionResult
{
private final Status status;
private transient volatile int hashCode = 0;
protected AbstractDecisionResult(final Status status)
protected BaseDecisionResult(final Status status)
{
this.status = status;
}
......@@ -80,12 +82,9 @@ public abstract class AbstractDecisionResult implements DecisionResult
return false;
}
final PepActions otherPepActions = other.getPepActions();
final PepActions thisPepActions = other.getPepActions();
if (thisPepActions == null)
{
return otherPepActions == null || otherPepActions.isEmpty();
}
final ImmutableList<PepAction> otherPepActions = other.getPepActions();
assert otherPepActions != null;
final ImmutableList<PepAction> thisPepActions = this.getPepActions();
return thisPepActions.equals(otherPepActions);
}
......
......@@ -32,11 +32,11 @@ public interface DecisionResult extends ExtendedDecision
{
/**
* Get PEP actions (Obligations/Advices), may be null if the decision is neither Permit or Deny
* Get PEP actions (Obligations/Advices), may be empty - but <b>not null</b> - if the decision is neither Permit or Deny
*
* @return PEP actions
*/
ImmutablePepActions getPepActions();
ImmutableList<PepAction> getPepActions();
/**
* Get the list of the "applicable" policy elements (XACML Policy/PolicySet elements) that contributed to this decision.
......@@ -52,7 +52,7 @@ public interface DecisionResult extends ExtendedDecision
* More formally: {@code isApplicable(policy) iff evaluate(policy) != NotApplicable && (policy.parent == null || isApplicable(policy.parent)) }
*
* @return identifiers of policies found applicable for the decision request. Must be null if and only if the decision is NotApplicable. In particular, if the decision is different from
* NotApplicable but no applicable policy is returned (e.g. it was not requested to return such a list in the request), the returned list must be an empty list, not null.
* NotApplicable but no applicable policy is returned (e.g. it was not requested to return such a list in the request), the returned list must be an empty list, <b>not null</b>.
*/
ImmutableList<PrimaryPolicyMetadata> getApplicablePolicies();
......
......@@ -19,21 +19,21 @@ package org.ow2.authzforce.core.pdp.api;
import java.util.Optional;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.DecisionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Status;
import org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.DecisionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Status;
/**
* Factory for creating immutable {@link DecisionResult}s
*
*/
public final class DecisionResults
{
private static final class ImmutableNotApplicableResult extends AbstractDecisionResult
private static final class ImmutableNotApplicableResult extends BaseDecisionResult
{
private transient volatile String toString = null;
......@@ -55,15 +55,15 @@ public final class DecisionResults
}
@Override
public ImmutablePepActions getPepActions()
public ImmutableList<PepAction> getPepActions()
{
return null;
return ImmutableList.of();
}
@Override
public ImmutableList<PrimaryPolicyMetadata> getApplicablePolicies()
{
return null;
return ImmutableList.of();
}
@Override
......@@ -85,7 +85,7 @@ public final class DecisionResults
}
}
private static abstract class ApplicableResult extends AbstractDecisionResult
private static abstract class ApplicableResult extends BaseDecisionResult
{
protected final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList;
......@@ -94,7 +94,7 @@ public final class DecisionResults
{
super(status);
this.applicablePolicyIdList = applicablePolicyIdList == null ? ImmutableList.<PrimaryPolicyMetadata> of() : applicablePolicyIdList;
this.applicablePolicyIdList = applicablePolicyIdList == null ? ImmutableList.<PrimaryPolicyMetadata>of() : applicablePolicyIdList;
}
@Override
......@@ -148,9 +148,9 @@ public final class DecisionResults
}
@Override
public ImmutablePepActions getPepActions()
public ImmutableList<PepAction> getPepActions()
{
return null;
return ImmutableList.of();
}
@Override
......@@ -179,20 +179,20 @@ public final class DecisionResults
private final DecisionType decision;
private final ImmutablePepActions pepActions;
private final ImmutableList<PepAction> pepActions;
private transient volatile String toString = null;
/*
* For permit/deny result
*/
private ImmutableDPResult(final DecisionType decision, final Status status, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
private ImmutableDPResult(final DecisionType decision, final Status status, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
{
super(status, applicablePolicyIdList);
assert decision == DecisionType.PERMIT || decision == DecisionType.DENY;
this.decision = decision;
this.pepActions = pepActions == null ? ImmutablePepActions.EMPTY : pepActions;
this.pepActions = pepActions == null ? ImmutableList.of() : pepActions;
}
/** {@inheritDoc} */
......@@ -219,7 +219,7 @@ public final class DecisionResults
}
@Override
public ImmutablePepActions getPepActions()
public ImmutableList<PepAction> getPepActions()
{
return this.pepActions;
}
......@@ -259,7 +259,7 @@ public final class DecisionResults
* list of identifiers of applicable policies that contributed to this result. If not null, the created instance uses only an immutable copy of this list.
* @return permit result, more particularly {@link #SIMPLE_PERMIT} iff {@code status == null && pepActions == null}.
*/
public static DecisionResult getPermit(final Status status, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
public static DecisionResult getPermit(final Status status, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
{
if (status == null && (pepActions == null || pepActions.isEmpty()) && (applicablePolicyIdList == null || applicablePolicyIdList.isEmpty()))
{
......@@ -282,7 +282,7 @@ public final class DecisionResults
* list of identifiers of applicable policies that contributed to this result. If not null, the created instance uses only an immutable copy of this list.
* @return deny result, more particularly {@link #SIMPLE_DENY} iff {@code status == null && pepActions == null}.
*/
public static DecisionResult getDeny(final Status status, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
public static DecisionResult getDeny(final Status status, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
{
if (status == null && (pepActions == null || pepActions.isEmpty()) && (applicablePolicyIdList == null || applicablePolicyIdList.isEmpty()))
{
......@@ -331,7 +331,7 @@ public final class DecisionResults
* if {@code cause == null}
*/
public static DecisionResult newIndeterminate(final DecisionType extendedIndeterminate, final IndeterminateEvaluationException cause,
final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList) throws IllegalArgumentException
final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList) throws IllegalArgumentException
{
Preconditions.checkNotNull(cause, "No cause defined for Indeterminate result");
return new ImmutableIndeterminateResult(extendedIndeterminate == null ? DecisionType.INDETERMINATE : extendedIndeterminate, cause, applicablePolicyIdList);
......@@ -351,8 +351,8 @@ public final class DecisionResults
* if
* {@code extendedDecision == null || extendedDecision.getDecision() ==null || (extendedDecision.getDecision() == INDETERMINATE && !extendedDecision.getCauseForIndeterminate().isPresent())}
*/
public static DecisionResult getInstance(final ExtendedDecision extendedDecision, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
throws IllegalArgumentException
public static DecisionResult getInstance(final ExtendedDecision extendedDecision, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
throws IllegalArgumentException
{
Preconditions.checkNotNull(extendedDecision, "Undefined extendedDecision");
final DecisionType decision = extendedDecision.getDecision();
......
/**
* Copyright 2012-2018 Thales Services SAS.
*
* This file is part of AuthzForce CE.
*
* 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 org.ow2.authzforce.core.pdp.api;
import java.util.Objects;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Advice;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Obligation;
import com.google.common.collect.ImmutableList;
/**
* Static immutable {@link PepActions}, e.g. empty actions, or static methods returning immutable {@link PepActions} or
*
*/
public final class ImmutablePepActions implements PepActions
{
// always non-null fields, immutable
private final ImmutableList<Obligation> obligationList;
private final ImmutableList<Advice> adviceList;
private transient volatile int hashCode;
private transient volatile String toString;
private ImmutablePepActions()
{
this.obligationList = ImmutableList.of();
this.adviceList = ImmutableList.of();
this.hashCode = 1;
this.toString = "( obligation_list= null, advice_list= null )";
}
/**
* Instantiates PEP action set from obligations/advice. Not used if there is neither any obligation and nor any advice, in which case the {@link ImmutablePepActions#EMPTY} must be used.
*
* @param obligationList
* obligation list; null if no obligation
* @param adviceList
* advice list; null if no advice
*/
public ImmutablePepActions(final ImmutableList<Obligation> obligationList, final ImmutableList<Advice> adviceList)
{
assert obligationList != null && !obligationList.isEmpty() || adviceList != null && !adviceList.isEmpty();
this.obligationList = obligationList == null ? ImmutableList.<Obligation> of() : obligationList;
this.adviceList = adviceList == null ? ImmutableList.<Advice> of() : adviceList;
this.hashCode = 0;
this.toString = null;
}
/**
* {@inheritDoc}
*
* Get the internal obligation list
*/
@Override
public ImmutableList<Obligation> getObligatory()
{
return obligationList;
}
/**
* {@inheritDoc}
*
* Get the internal advice list
*/
@Override
public ImmutableList<Advice> getAdvisory()
{
return adviceList;
}
/** {@inheritDoc} */
@Override
public int hashCode()
{
if (hashCode == 0)
{
hashCode = Objects.hash(this.obligationList, this.adviceList);
}
return hashCode;
}
/** {@inheritDoc} */
@Override
public boolean equals(final Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof PepActions))
{
return false;
}
final PepActions other = (PepActions) obj;
return this.obligationList.equals(other.getObligatory()) && this.adviceList.equals(other.getAdvisory());
}
/** {@inheritDoc} */
@Override
public String toString()
{
if (toString == null)
{
toString = "[obligation_list=" + obligationList + ", advice_list=" + adviceList + "]";
}
return toString;
}
/**
* Get immutable {@link PepActions} from obligations/advice elements.
*
* @param obligationList
* obligations; null if no obligation
* @param adviceList
* advice elements; null if no advice
* @return immutable instance; {@link ImmutablePepActions#EMPTY} is returned if {@code obligationList == null || obligationList.isEmpty()) && (adviceList == null || adviceList.isEmpty()}
*/
public static ImmutablePepActions getInstance(final ImmutableList<Obligation> obligationList, final ImmutableList<Advice> adviceList)
{
if ((obligationList == null || obligationList.isEmpty()) && (adviceList == null || adviceList.isEmpty()))
{
return EMPTY;
}
return new ImmutablePepActions(obligationList, adviceList);
}
/**
* Get immutable view (copy) of other PEP actions.
*
* @param pepActions
* obligations; null if no obligation
*
* @return immutable instance; {@link ImmutablePepActions#EMPTY} is returned if {@code pepActions == null || (obligationList == null || obligationList.isEmpty()) && (adviceList == null ||
adviceList.isEmpty())}
*/
public static ImmutablePepActions getInstance(final PepActions pepActions)
{
if (pepActions == null)
{
return EMPTY;
}
return getInstance(pepActions.getObligatory(), pepActions.getAdvisory());
}
/**
* Empty PEP actions (no obligation/advice)
*/
public static final ImmutablePepActions EMPTY = new ImmutablePepActions();
@Override
public boolean isEmpty()
{
return this.obligationList.isEmpty() && this.adviceList.isEmpty();
}
}
\ No newline at end of file
......@@ -49,7 +49,7 @@ public final class MutableAttributeBag<AV extends AttributeValue> implements Ite
private static final IllegalArgumentException NULL_DATATYPE_FACTORY_EXCEPTION = new IllegalArgumentException("Undefined attribute datatype");
private static final UnsupportedOperationException UNSUPPORTED_ADD_OPERATION_EXCEPTION = new UnsupportedOperationException(
"Operation forbidden: immutable bag (toImmutable() method already called)");
"Operation forbidden: immutable bag (toImmutable() method already called)");
private static final IllegalArgumentException ILLEGAL_ATTRIBUTE_VALUE_ARGUMENT_EXCEPTION = new IllegalArgumentException("Undefined attribute value");
......@@ -138,11 +138,10 @@ public final class MutableAttributeBag<AV extends AttributeValue> implements Ite
try
{
av = this.elementType.cast(value);
}
catch (final ClassCastException e)
} catch (final ClassCastException e)
{
throw new IllegalArgumentException("Invalid datatype of AttributeValue in Attribute element: " + value.getDataType() + ". Expected: " + elementType
+ " (datatype of other value(s) already found in the same attribute bag)");
throw new IllegalArgumentException(
"Invalid datatype of AttributeValue in Attribute element. Expected: " + elementType + " (datatype of other value(s) already found in the same attribute bag)");
}
vals.add(av);
......
/**
* Copyright 2012-2018 Thales Services SAS.
*
* This file is part of AuthzForce CE.
*
* 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 org.ow2.authzforce.core.pdp.api;
import java.util.List;
import com.google.common.collect.ImmutableList;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Advice;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignment;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Obligation;
/**
* PEP actions (obligations/advice)
*
*/
public interface PepActions
{
/**
* PEP action (obligation/advice) factory
*
* @param <JAXB_T>
* JAXB-annotated PEP action type
* @version $Id: $
*/
interface Factory<JAXB_T>
{
/**
* Creates instance of PEP action (obligation/advice)
*
* @param attributeAssignments
* XML/JAXB AttributeAssignments in the PEP action
* @param actionId
* action ID (ObligationId, AdviceId)
* @return PEP action
*/
JAXB_T getInstance(List<AttributeAssignment> attributeAssignments, String actionId);
/**
* Get name of PEP Action element in XACML model, e.g. 'Obligation'
*
* @return action element name
*/
String getActionXmlElementName();
}
/**
* Get an immutable list of the obligations
*
* @return obligations; empty if no obligation (always non-null)
*/
ImmutableList<Obligation> getObligatory();
/**
* Get an immutable list of the advice elements
*
* @return advice; empty if no obligation (always non-null)
*/
ImmutableList<Advice> getAdvisory();
/**
* Is there any obligation/advice?
*
* @return true iff there is none
*/
boolean isEmpty();
}
/**
* Copyright 2012-2018 Thales Services SAS.
*
* This file is part of AuthzForce CE.
*
* 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 org.ow2.authzforce.core.pdp.api;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
/**
* PEP Action, i.e. XACML Obligation/Advice
*
*/
public final class PepAction
{
private final String actionId;
private final boolean isMandatory;
private final ImmutableList<PepActionAttributeAssignment<?>> attAssignments;
/**
* Constructor
*
* @param actionId
* action ID (XACML ObligationId/AdviceId)
* @param isMandatory
* true iff the action is mandatory (XACML Obligation, else Advice)
* @param attributeAssignments
* action arguments (parameter assignments)
*/
public PepAction(String actionId, boolean isMandatory, ImmutableList<PepActionAttributeAssignment<?>> attributeAssignments)
{
Preconditions.checkArgument(actionId != null, "PEP action (obligation/advice) ID == null (undefined)");
Preconditions.checkArgument(attributeAssignments != null, "PEP action (obligation/advice) attribute assignments == null (undefined)");
this.actionId = actionId;
this.isMandatory = isMandatory;
this.attAssignments = attributeAssignments;
}
/**
* @return the action ID (XACML ObligationId / AdviceId)
*/
public String getId()
{
return actionId;
}
/**
* True iff it is an obligation (mandatory action), else an advice
*
* @return the isMandatory
*/
public boolean isMandatory()
{
return isMandatory;
}
/**
* @return the action's arguments (attribute assignments)
*/
public ImmutableList<PepActionAttributeAssignment<?>> getAttributeAssignments()
{
return attAssignments;
}
}
/**
* Copyright 2012-2018 Thales Services SAS.
*
* This file is part of AuthzForce CE.
*
* 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 org.ow2.authzforce.core.pdp.api;
import java.util.Optional;
import org.ow2.authzforce.core.pdp.api.value.AttributeValue;
import org.ow2.authzforce.core.pdp.api.value.Datatype;
/**
* (XACML-like) AttributeAssignment to be passed to a PEP action (obligation, advice).
*
* @param <AV>
* type assigned attribute value
*/
public final class PepActionAttributeAssignment<AV extends AttributeValue>
{
private final String attId;
private final Optional<String> category;
private final Optional<String> issuer;
private final Datatype<AV> datatype;
private final AV value;
/**
* Default constructor
*
* @param attributeId
* attribute ID
* @param category
* attribute category
* @param issuer
* attribute Issuer
* @param datatype
* attribute datatype
* @param value
* attribute value
*/
public PepActionAttributeAssignment(String attributeId, Optional<String> category, Optional<String> issuer, Datatype<AV> datatype, AV value)
{
this.attId = attributeId;
this.datatype = datatype;
this.value = value;
this.category = category;
this.issuer = issuer;
}
/**
* @return the attribute Id
*/
public String getAttributeId()
{
return attId;
}
/**
* @return the category
*/
public Optional<String> getCategory()
{
return category;
}
/**
* @return the issuer
*/
public Optional<String> getIssuer()
{
return issuer;
}
/**
* @return the attribute datatype
*/
public Datatype<AV> getDatatype()
{
return datatype;
}
/**
* @return the attribute value
*/
public AV getValue()
{