Commit c12753b5 authored by cdanger's avatar cdanger
Browse files

Merge branch 'release/17.0.0'

parents 0f876367 c1baf561
/target/
/.CHANGELOG.md.html
/.README.md.html
/.settings/
**/.settings
/.classpath
/.pmd
/.pmdruleset.xml
/.project
/.checkstyle
/bin/
**/.idea
*.iml
**/.vscode
......@@ -6,6 +6,16 @@ All notable changes to this project are documented in this file following the [K
- Issues reported on [OW2's GitLab](https://gitlab.ow2.org/authzforce/core/issues) are referenced in the form of `[GL-N]`, where N is the issue number.
## 17.0.0
### Changed
- GH-40: Upgraded **supported JRE: JAVA 11** (LTS). Java 8 no longer supported.
- As part of Java 11 migration, upgraded JAXB (Jakarta XML Bining) to v2.3.3
- Upgraded authzforce-ce-core-pdp-api to v18.0.0
- Fixed CVE on jackson-databind -> v2.9.10.8
- Upgraded authzforce-ce-xacml-json-model: 3.0.0
- Upgraded Maven parent project to 8.0.0.
## 16.0.0
### Changed
- Upgraded parent project: 7.6.1
......
......@@ -75,31 +75,7 @@ See the [license file](LICENSE).
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fauthzforce%2Fcore.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fauthzforce%2Fcore?ref=badge_large)
## System requirements
Java (JRE) version: 8 or later.
### Java 8+ requirements
- System property `javax.xml.accessExternalSchema` must be set to include `http`, to work around Java 8+ external schema access restriction, e.g. with a JVM argument:
`-Djavax.xml.accessExternalSchema=http`
### Java 9+ requirements
In addition to Java 8+ ones, you need to add JAXB dependencies (no longer part of JDK), e.g. [in Maven](https://javaee.github.io/jaxb-v2/doc/user-guide/ch03.html#deployment-maven-coordinates):
```xml
<!-- API -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb.version}</version>
</dependency>
<!-- Runtime -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>${jaxb.version}</version>
</dependency>
```
Java (JRE) version: 11 or later. Java 8 is no longer supported.
## Usage
### Getting started
......@@ -140,7 +116,7 @@ Since this is a Maven artifact and it requires dependencies, you should build yo
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-engine</artifactId>
<version>14.0.0</version>
<version>${latest.version}</version>
</dependency>
...
......@@ -152,7 +128,7 @@ Then instantiate a PDP engine configuration with method [PdpEngineConfiguration#
```xml
<?xml version="1.0" encoding="UTF-8"?>
<pdp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://authzforce.github.io/core/xmlns/pdp/7">
<pdp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://authzforce.github.io/core/xmlns/pdp/7" version="7.1">
<policyProvider id="policyProvider" xsi:type="StaticPolicyProvider">
<policyLocation>${PARENT_DIR}/policy.xml</policyLocation>
</policyProvider>
......
......@@ -3,7 +3,7 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core</artifactId>
<version>16.0.0</version>
<version>17.0.0</version>
<relativePath>..</relativePath>
</parent>
<artifactId>authzforce-ce-core-pdp-cli</artifactId>
......@@ -30,12 +30,12 @@
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-engine</artifactId>
<version>16.0.0</version>
<version>17.0.0</version>
</dependency>
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-io-xacml-json</artifactId>
<version>16.0.0</version>
<version>17.0.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
......@@ -46,7 +46,7 @@
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-testutils</artifactId>
<version>16.0.0</version>
<version>17.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
......@@ -127,12 +127,8 @@
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<onlyAnalyze>org.ow2.authzforce.*</onlyAnalyze>
<excludeFilterFile>findbugs-exclude-filter.xml</excludeFilterFile>
</configuration>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<executions>
<execution>
<phase>verify</phase>
......
......@@ -11,4 +11,8 @@
-->
<Bug pattern="CRLF_INJECTION_LOGS" />
</Match>
<Match>
<Class name="org.ow2.authzforce.core.pdp.cli.PdpCommandLineCallable" />
<Bug pattern="UWF_NULL_FIELD" />
</Match>
</FindBugsFilter>
\ No newline at end of file
/**
* Copyright 2012-2020 THALES.
* Copyright 2012-2021 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -59,13 +59,13 @@ import picocli.CommandLine.Parameters;
@Command(name = "authzforce-ce-core-pdp-cli", description = "Evaluates a XACML Request against a XACML Policy(Set) using AuthzForce PDP engine")
public final class PdpCommandLineCallable implements Callable<Void>
{
private static enum RequestType
private enum RequestType
{
XACML_XML, XACML_JSON;
XACML_XML, XACML_JSON
}
/*
* WARNING: do not make picocli-annoated fields final here! Known issue: https://github.com/remkop/picocli/issues/68. Planned to be fixed in release 2.1.0.
* WARNING: do not make picocli-annotated fields final here! Known issue: https://github.com/remkop/picocli/issues/68. Planned to be fixed in release 2.1.0.
*/
@Option(names = { "-t",
"--type" }, description = "Type of XACML request/response: 'XACML_XML' for XACML 3.0/XML (XACML core specification), 'XACML_JSON' for XACML 3.0/JSON (JSON Profile of XACML 3.0)")
......@@ -130,7 +130,7 @@ public final class PdpCommandLineCallable implements Callable<Void>
final PdpEngineInoutAdapter<Request, Response> xmlPdpEngineAdapter = PdpEngineAdapters.newXacmlJaxbInoutAdapter(configuration);
final Response xmlResponse = xmlPdpEngineAdapter.evaluate((Request) request, parser.getNamespacePrefixUriMap());
final Marshaller marshaller = Xacml3JaxbHelper.createXacml3Marshaller();
final Boolean formatted = Boolean.valueOf(formattedOutput);
final Boolean formatted = formattedOutput;
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, formatted);
marshaller.marshal(xmlResponse, System.out);
break;
......
/**
* Copyright 2012-2020 THALES.
* Copyright 2012-2021 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -17,6 +17,7 @@
*/
package org.ow2.authzforce.core.pdp.cli.test;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader;
......@@ -53,7 +54,7 @@ public class CliTest
public void testXml() throws UnsupportedEncodingException, JAXBException
{
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintStream ps = new PrintStream(baos, true, "UTF-8"))
try (PrintStream ps = new PrintStream(baos, true, StandardCharsets.UTF_8))
{
/*
* Redirect system.out to the byte stream
......@@ -66,7 +67,7 @@ public class CliTest
System.setOut(System.out);
}
final String output = new String(baos.toByteArray(), StandardCharsets.UTF_8);
final String output = baos.toString(StandardCharsets.UTF_8);
System.out.println(output);
final Response expectedXacmlJaxbObj = (Response) Xacml3JaxbHelper.createXacml3Unmarshaller().unmarshal(new File(TEST_DATA_DIR + "/IIA001/Response.xml"));
......@@ -88,7 +89,7 @@ public class CliTest
{
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintStream ps = new PrintStream(baos, true, "UTF-8"))
try (PrintStream ps = new PrintStream(baos, true, StandardCharsets.UTF_8))
{
/*
* Redirect system.out to the byte stream
......@@ -101,7 +102,7 @@ public class CliTest
System.setOut(System.out);
}
final String output = new String(baos.toByteArray(), StandardCharsets.UTF_8);
final String output = baos.toString(StandardCharsets.UTF_8);
System.out.println(output);
final JSONObject normalizedExpectedResponse;
......@@ -128,7 +129,7 @@ public class CliTest
}
catch (final CommandLine.ExecutionException e)
{
assertTrue(e.getCause().getClass() == IllegalArgumentException.class);
assertSame(e.getCause().getClass(), IllegalArgumentException.class);
}
}
......
......@@ -3,7 +3,7 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core</artifactId>
<version>16.0.0</version>
<version>17.0.0</version>
<relativePath>..</relativePath>
</parent>
<artifactId>authzforce-ce-core-pdp-engine</artifactId>
......@@ -42,6 +42,18 @@
<groupId>xml-resolver</groupId>
<artifactId>xml-resolver</artifactId>
</dependency>
<!-- https://eclipse-ee4j.github.io/jaxb-ri/2.3.3/docs/ch03.html#deployment-maven-coordinates
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<scope>runtime</scope>
</dependency>
-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<scope>runtime</scope>
</dependency>
<!-- /Third-party dependencies -->
<!-- Authzforce dependencies -->
......@@ -49,7 +61,7 @@
<groupId>${project.groupId}</groupId>
<artifactId>${artifactId.prefix}-core-pdp-api</artifactId>
</dependency>
<!-- /Authzforce dependencies -->
<!-- /AuthzForce dependencies -->
<!-- Test dependencies -->
<dependency>
......@@ -105,12 +117,8 @@
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<onlyAnalyze>org.ow2.authzforce.*</onlyAnalyze>
<excludeFilterFile>findbugs-exclude-filter.xml</excludeFilterFile>
</configuration>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<executions>
<execution>
<phase>verify</phase>
......@@ -208,6 +216,29 @@
</execution>
</executions>
</plugin>
<!-- Note for the future migration to JAXB >= 3.0.0: since v3.0.0, package names have been changed to jakarta.xml.bind, so we'll need to change javax.xml.bind imports generated by maven-jaxb2-plugin-->
<!--
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>rename-old-jaxb-package-names-for-java-11</id>
<phase>process-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<replace token= "javax.xml.bind" value="jakarta.xml.bind" dir="${project.basedir}/target/generated-sources/xjc">
<include name="**/*.java" />
</replace>
</target>
</configuration>
</execution>
</executions>
</plugin>
-->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
......
......@@ -11,4 +11,25 @@
-->
<Bug pattern="CRLF_INJECTION_LOGS" />
</Match>
<Match>
<!-- spotbugs issue https://github.com/spotbugs/spotbugs/issues/811 -->
<!--
<Class name="org.ow2.authzforce.core.pdp.impl.SchemaHandler$OASISCatalogManager" />
-->
<Bug pattern="UPM_UNCALLED_PRIVATE_METHOD" />
</Match>
<Match>
<!-- Spotbugs issue with nested classes -->
<Bug pattern="PATH_TRAVERSAL_IN" />
</Match>
<Match>
<!-- Spotbugs issue: https://github.com/spotbugs/spotbugs/issues/756 -->
<Bug pattern="RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE" />
</Match>
<Match>
<!--
<Class name="org.ow2.authzforce.core.pdp.impl.SchemaHandler$OASISCatalogManager" />
-->
<Bug pattern="URLCONNECTION_SSRF_FD" />
</Match>
</FindBugsFilter>
\ No newline at end of file
/**
* Copyright 2012-2020 THALES.
* Copyright 2012-2021 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -36,138 +36,132 @@ import oasis.names.tc.xacml._3_0.core.schema.wd_17.Match;
*/
public final class AllOfEvaluator
{
private static final Logger LOGGER = LoggerFactory.getLogger(AllOfEvaluator.class);
private static final IllegalArgumentException NO_MATCH_EXCEPTION = new IllegalArgumentException(
"<AllOf> empty. Must contain at least one <Match>");
// Store the list of Matches as evaluatable Match types to avoid casting
// from JAXB MatchType
// during evaluation
private final transient List<MatchEvaluator> evaluatableMatchList;
/**
* Instantiates AllOf (evaluator) from XACML-Schema-derived
* <code>AllOf</code>.
*
* @param jaxbMatches
* XACML-schema-derived JAXB Match elements
* @param xPathCompiler
* XPath compiler corresponding to enclosing policy(set) default
* XPath version
* @param expFactory
* Expression factory
* @throws java.lang.IllegalArgumentException
* null {@code expFactory} or null/empty {@code jaxbMatches} or
* one of the child Match elements in {@code jaxbMatches} is
* invalid
*/
public AllOfEvaluator(final List<Match> jaxbMatches, final XPathCompiler xPathCompiler,
final ExpressionFactory expFactory) throws IllegalArgumentException
{
if (jaxbMatches == null || jaxbMatches.isEmpty())
{
throw NO_MATCH_EXCEPTION;
}
evaluatableMatchList = new ArrayList<>(jaxbMatches.size());
int matchIndex = 0;
for (final Match jaxbMatch : jaxbMatches)
{
final MatchEvaluator matchEvaluator;
try
{
matchEvaluator = new MatchEvaluator(jaxbMatch, xPathCompiler, expFactory);
}
catch (final IllegalArgumentException e)
{
throw new IllegalArgumentException("Invalid <AllOf>'s <Match>#" + matchIndex, e);
}
evaluatableMatchList.add(matchEvaluator);
matchIndex++;
}
}
/**
* Determines whether this <code>AllOf</code> matches the input request
* (whether it is applicable).Here is the table shown in the specification:
* <code>
* <Match> values <AllOf> value
* All True “Match�?
* No False and at least
* one "Indeterminate" “Indeterminate�?
* At least one False "No Match"
* </code>
*
* @param context
* the representation of the request
* @return true iff Match, else No match
* @throws org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException
* Indeterminate
*/
public boolean match(final EvaluationContext context) throws IndeterminateEvaluationException
{
// atLeastOneIndeterminate = true iff lastIndeterminate != null
IndeterminateEvaluationException lastIndeterminate = null;
// index of the current Match in this AllOf
int childIndex = 0;
// index of last Indeterminate for enhanced error message
int lastIndeterminateChildIndex = -1;
/*
* By construction, there must be at least one Match
*/
for (final MatchEvaluator matchEvaluator : evaluatableMatchList)
{
final boolean isMatched;
try
{
isMatched = matchEvaluator.match(context);
if (LOGGER.isDebugEnabled())
{
// Beware of autoboxing which causes call to
// Boolean.valueOf(...), Integer.valueOf(...)
LOGGER.debug("AllOf/Match#{} -> {}", childIndex, isMatched);
}
}
catch (final IndeterminateEvaluationException e)
{
if (LOGGER.isDebugEnabled())
{
// Beware of autoboxing which causes call to
// Integer.valueOf(...)
LOGGER.debug("AllOf/Match#{} -> Indeterminate", childIndex, e);
}
lastIndeterminate = e;
lastIndeterminateChildIndex = childIndex;
continue;
}
/*
* At least one False -> No match
*/
if (!isMatched)
{
return false;
}
// True (Match) -> continue, all must be true to match
childIndex += 1;
}
// No False (=NO_MATCH) occurred
// lastIndeterminate == null iff no Indeterminate occurred
if (lastIndeterminate == null)
{
// No False/Indeterminate, i.e. all True -> Match
return true;
}
// No False but at least one Indeterminate (lastIndeterminate != null)
throw new IndeterminateEvaluationException("Error evaluating <AllOf>'s <Match>#" + lastIndeterminateChildIndex,
lastIndeterminate.getStatusCode(), lastIndeterminate);
}
private static final Logger LOGGER = LoggerFactory.getLogger(AllOfEvaluator.class);
private static final IllegalArgumentException NO_MATCH_EXCEPTION = new IllegalArgumentException(
"<AllOf> empty. Must contain at least one <Match>");
/*
Store the list of Matches as evaluable Match types to avoid casting
from JAXB MatchType
during evaluation
*/
private final transient List<MatchEvaluator> evaluableMatchList;
/**
* Instantiates AllOf (evaluator) from XACML-Schema-derived
* <code>AllOf</code>.
*
* @param jaxbMatches XACML-schema-derived JAXB Match elements
* @param xPathCompiler XPath compiler corresponding to enclosing policy(set) default
* XPath version
* @param expFactory Expression factory
* @throws java.lang.IllegalArgumentException null {@code expFactory} or null/empty {@code jaxbMatches} or
* one of the child Match elements in {@code jaxbMatches} is
* invalid
*/
public AllOfEvaluator(final List<Match> jaxbMatches, final XPathCompiler xPathCompiler,
final ExpressionFactory expFactory) throws IllegalArgumentException
{
if (jaxbMatches == null || jaxbMatches.isEmpty())
{
throw NO_MATCH_EXCEPTION;
}
evaluableMatchList = new ArrayList<>(jaxbMatches.size());
int matchIndex = 0;
for (final Match jaxbMatch : jaxbMatches)
{
final MatchEvaluator matchEvaluator;
try
{
matchEvaluator = new MatchEvaluator(jaxbMatch, xPathCompiler, expFactory);
} catch (final IllegalArgumentException e)
{
throw new IllegalArgumentException("Invalid <AllOf>'s <Match>#" + matchIndex, e);
}
evaluableMatchList.add(matchEvaluator);
matchIndex++;
}
}
/**
* Determines whether this <code>AllOf</code> matches the input request
* (whether it is applicable).Here is the table shown in the specification:
* <code>
* <Match> values <AllOf> value
* All True “Match�?
* No False and at least
* one "Indeterminate" “Indeterminate�?
* At least one False "No Match"
* </code>
*
* @param context the representation of the request
* @return true iff Match, else No match
* @throws org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException Indeterminate
*/
public boolean match(final EvaluationContext context) throws IndeterminateEvaluationException
{
// atLeastOneIndeterminate = true iff lastIndeterminate != null
IndeterminateEvaluationException lastIndeterminate = null;
// index of the current Match in this AllOf
int childIndex = 0;
// index of last Indeterminate for enhanced error message
int lastIndeterminateChildIndex = -1;
/*
* By construction, there must be at least one Match
*/
for (final MatchEvaluator matchEvaluator : evaluableMatchList)
{
final boolean isMatched;
try
{
isMatched = matchEvaluator.match(context);
if (LOGGER.isDebugEnabled())
{
// Beware of autoboxing which causes call to
// Boolean.valueOf(...), Integer.valueOf(...)
LOGGER.debug("AllOf/Match#{} -> {}", childIndex, isMatched);
}
} catch (final IndeterminateEvaluationException e)
{
if (LOGGER.isDebugEnabled())
{
// Beware of autoboxing which causes call to
// Integer.valueOf(...)
LOGGER.debug("AllOf/Match#{} -> Indeterminate", childIndex, e);
}
lastIndeterminate = e;
lastIndeterminateChildIndex = childIndex;
continue;
}
/*
* At least one False -> No match
*/
if (!isMatched)
{
return false;
}
// True (Match) -> continue, all must be true to match
childIndex += 1;
}
// No False (=NO_MATCH) occurred
// lastIndeterminate == null iff no Indeterminate occurred
if (lastIndeterminate == null)
{
// No False/Indeterminate, i.e. all True -> Match
return true;
}
// No False but at least one Indeterminate (lastIndeterminate != null)
throw new Indeterm