Commit c8e372f5 authored by cdanger's avatar cdanger
Browse files

Improved license headers

parent acaf9d54
<?xml version="1.0" encoding="ISO-8859-1"?>
<additionalHeaders>
<javadoc_style>
<firstLine>/*</firstLine>
<beforeEachLine> * </beforeEachLine>
<endLine> */</endLine>
<!--<afterEachLine></afterEachLine>-->
<!--skipLine></skipLine-->
<firstLineDetectionPattern>(\s|\t)*/\*.*$</firstLineDetectionPattern>
<lastLineDetectionPattern>.*\*/(\s|\t)*$</lastLineDetectionPattern>
<allowBlankLines>false</allowBlankLines>
<isMultiline>true</isMultiline>
<padLines>false</padLines>
</javadoc_style>
</additionalHeaders>
......@@ -114,6 +114,9 @@
<artifactId>license-maven-plugin</artifactId>
<configuration>
<header>LICENSE_HEADER.txt</header>
<headerDefinitions>
<headerDefinition>LICENSE_HEADER_DEFS.xml</headerDefinition>
</headerDefinitions>
<includes>
<include>src/main/java/org/ow2/authzforce/**</include>
<!-- Include test files also -->
......
/**
/*
* Copyright 2012-2021 THALES.
*
* This file is part of AuthzForce CE.
......
/**
/*
* Copyright 2012-2021 THALES.
*
* This file is part of AuthzForce CE.
......
/**
/*
* Copyright 2012-2021 THALES.
*
* This file is part of AuthzForce CE.
......@@ -24,8 +24,8 @@ import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.util.*;
/**
* Instances of JSON schema as defined by JSON Profile of XACML 3.0
......@@ -34,7 +34,9 @@ import java.io.InputStream;
public final class XacmlJsonUtils
{
private static final SchemaClient CLASSPATH_AWARE_SCHEMA_CLIENT = SchemaClient.classPathAwareClient();
private static Schema loadSchema(String schemaFilenameRelativeToThisClass) {
private static Schema loadSchema(String schemaFilenameRelativeToThisClass)
{
try (InputStream inputStream = XacmlJsonUtils.class.getResourceAsStream(schemaFilenameRelativeToThisClass))
{
final JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream));
......@@ -67,17 +69,61 @@ public final class XacmlJsonUtils
POLICY_SCHEMA = loadSchema("Policy.schema.json");
}
/*
*/
private static void canonicalizeObligationsOrAdvice(JSONObject xacmlResult, String obligationsOrAdviceKey, boolean floatWithTrailingZeroToInt)
{
final JSONArray obligationsOrAdvice = xacmlResult.optJSONArray(obligationsOrAdviceKey);
if(obligationsOrAdvice != null) {
if (obligationsOrAdvice.length() == 0)
{
xacmlResult.remove(obligationsOrAdviceKey);
} else
{
for (final Object obligation : obligationsOrAdvice)
{
assert obligation instanceof JSONObject;
final JSONObject obligationJsonObj = (JSONObject) obligation;
final JSONArray jsonArrayOfAtts = obligationJsonObj.optJSONArray("AttributeAssignment");
if (jsonArrayOfAtts != null)
{
if (jsonArrayOfAtts.length() == 0)
{
obligationJsonObj.remove("AttributeAssignment");
} else
{
for (final Object attJson : jsonArrayOfAtts)
{
assert attJson instanceof JSONObject;
final JSONObject attJsonObj = (JSONObject) attJson;
if (floatWithTrailingZeroToInt)
{
floatWithTrailingZeroToInt(attJsonObj);
}
}
}
}
}
}
}
}
/**
* Canonicalize a XACML/JSON response, typically for comparison with another one. In particular, it removes every Result's status as we choose to ignore the Status. Indeed, a PDP implementation
* might return a perfectly XACML-compliant response but with extra StatusCode/Message/Detail that we would not expect.
*
* WARNING: this method modifies the content of {@code xacmlJsonResponse} directly
* FIXME: waiting for 'org.everity.json.schema' to upgrade dependency 'org.json:json' to v20210307 or later in order to fix https://github.com/stleary/JSON-java/issues/589
*
* @param xacmlJsonResponse
* input XACML Response
* @param floatWithTrailingZeroToInt true iff floats with trailing zero (after decimal point) in AttributeValues are converted to Integer, this is originally a workaround for <a href="https://github.com/stleary/JSON-java/issues/589">issue #589 on org.json:json library</a>, used by our dependency 'org.everity.json.schema', which has been fixed in v20210307 of org.json:json; but still waiting for 'org.everity.json.schema' to upgrade.
* @return canonicalized response
*/
public static JSONObject canonicalizeResponse(final JSONObject xacmlJsonResponse)
public static JSONObject canonicalizeResponse(final JSONObject xacmlJsonResponse, boolean floatWithTrailingZeroToInt)
{
/*
* We iterate over all results, because for each results, we don't compare everything. In particular, we choose to ignore the StatusMessage, StatusDetail and any nested StatusCode. Indeed, a
......@@ -125,23 +171,110 @@ public final class XacmlJsonUtils
final JSONArray jsonArrayOfAtts = attCatJsonObj.optJSONArray("Attribute");
if (jsonArrayOfAtts != null)
{
jsonArrayOfAtts.forEach(attJson ->
if (jsonArrayOfAtts.length() == 0)
{
assert attJson instanceof JSONObject;
final JSONObject attJsonObj = (JSONObject) attJson;
attJsonObj.remove("IncludeInResult");
});
attCatJsonObj.remove("Attribute");
} else
{
for (final Object attJson : jsonArrayOfAtts)
{
assert attJson instanceof JSONObject;
final JSONObject attJsonObj = (JSONObject) attJson;
attJsonObj.remove("IncludeInResult");
if (floatWithTrailingZeroToInt)
{
floatWithTrailingZeroToInt(attJsonObj);
}
}
}
}
}
}
}
// Handle attribute values in Obligations and AssociatedAdvice if floatWithTrailingZeroToInt
canonicalizeObligationsOrAdvice(resultJsonObj, "Obligations", floatWithTrailingZeroToInt);
canonicalizeObligationsOrAdvice(resultJsonObj, "AssociatedAdvice", floatWithTrailingZeroToInt);
}
return xacmlJsonResponse;
}
/*
Returns a number if input was a Double with zero fraction, therefore converted to an integer type (BigInteger, Integer, Long, Short); else null
FIXME: workaround for this issue: https://github.com/stleary/JSON-java/issues/589
*/
private static Number floatWithTrailingZeroToInt(Object input)
{
if (input instanceof JSONObject)
{
final JSONObject json = (JSONObject) input;
final Map<String, Number> modifiedProperties = new HashMap<>();
json.keySet().forEach(key ->
{
final Number convertedIfNonNull = floatWithTrailingZeroToInt(json.get(key));
if (convertedIfNonNull != null)
{
// Double value to be changed to an integer
modifiedProperties.put(key, convertedIfNonNull);
}
});
// apply modifications if any
modifiedProperties.forEach(json::put);
return null;
}
if (input instanceof JSONArray)
{
final JSONArray json = (JSONArray) input;
final Deque<Map.Entry<Integer, Number>> modifiedItems = new ArrayDeque<>(json.length());
int index = 0;
for (final Object item : json)
{
final Number convertedIfNonNull = floatWithTrailingZeroToInt(item);
if (convertedIfNonNull != null)
{
// Double value to be changed to an integer
modifiedItems.addLast(new AbstractMap.SimpleImmutableEntry<>(index, convertedIfNonNull));
}
index++;
}
// apply modifications if any
modifiedItems.forEach(e -> json.put(e.getKey(), e.getValue()));
return null;
}
if (input instanceof Double)
{
// FIXME: workaround for this issue: https://github.com/stleary/JSON-java/issues/589
// if there is some trailing zero, this Double is considered equivalent to an int
// The corresponding int is obtained after serializing/deserializing
final String serialized = JSONObject.valueToString(input);
final Object deserialized = JSONObject.stringToValue(serialized);
if (!(deserialized instanceof Double))
{
// value was converted to an int
assert deserialized instanceof Number;
return (Number) deserialized;
}
}
// nothing to change
return null;
}
private XacmlJsonUtils()
{
// hide constructor
}
/*
public static void main(String[] args) throws FileNotFoundException
{
final JSONObject jsonWithTrailing0 = XacmlJsonUtils.canonicalizeResponse(new JSONObject(new JSONTokener(new FileInputStream(new File("~/git/authzforce-ce-server/webapp/src/test/resources/xacml.samples/pdp/GeoJSON_good/response.json")))), true);
System.out.println(jsonWithTrailing0.toString());
}
*/
}
/**
/*
* Copyright 2012-2021 THALES.
*
* This file is part of AuthzForce CE.
......@@ -53,33 +53,30 @@ public class LimitsCheckingJSONObjectTest
/**
* Create test data. Various JSON files.
*
*
*
* @return iterator over test data
* @throws URISyntaxException
* @throws IOException
*/
@DataProvider(name = "jsonDataProvider")
public Iterator<Object[]> createData() throws URISyntaxException, IOException
public Iterator<Object[]> createData()
{
return TestDataProvider.createData(Arrays.stream(TEST_DATA_DIRECTORY_LOCATIONS).map(loc -> new AbstractMap.SimpleImmutableEntry<>(new File(loc), (File) null)).collect(Collectors.toList()));
}
@Test(dataProvider = "jsonDataProvider")
/**
*
* @param xacmlJsonFile
* @param xacmlJsonFile XACML/JSON file (Request or Response)
* @param expectedValid
* true iff validation against JSON schema should succeed
* @param srcXacmlXmlFile
* @param srcXacmlXmlFile original source XACML/XML file
* @param genXacmlXmlFileFromXslt
* Parameter not used by this test method but value returned anyway by the dataProvider (shared with other tests).
* @param testCtx
* @throws FileNotFoundException
* @throws IOException
* @param testCtx testng Test Context
* @throws JSONException error parsing JSON
* @throws IOException error reading input XACML files
*/
@Test(dataProvider = "jsonDataProvider")
public void test(final File xacmlJsonFile, final boolean expectedValid, final File srcXacmlXmlFile, final File genXacmlXmlFileFromXslt, final ITestContext testCtx)
throws FileNotFoundException, IOException, JSONException
throws IOException, JSONException
{
/*
* Read properly as UTF-8 to avoid character decoding issues with org.json API
......
/**
/*
* Copyright 2012-2021 THALES.
*
* This file is part of AuthzForce CE.
......@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Objects;
public final class TestDataProvider
{
......@@ -100,7 +101,7 @@ public final class TestDataProvider
}
}
for (final File jsonFile : validXacmlJsonFilesDir.listFiles(JSON_FILE_FILTER))
for (final File jsonFile : Objects.requireNonNull(validXacmlJsonFilesDir.listFiles(JSON_FILE_FILTER)))
{
/*
* Specific test's resources directory location, used as parameter to PdpTest(String). Check for a XML version of the file.
......@@ -127,7 +128,7 @@ public final class TestDataProvider
*/
final File invalidSrcXmlFilesDir = srcXmlFilesDirRelToMvnProj == null ? null : new File(srcXmlFilesDirRelToMvnProj, INVALID_TEST_DATA_DIRECTORY_NAME);
for (final File jsonFile : invalidXacmlJsonFilesDataDir.listFiles(JSON_FILE_FILTER))
for (final File jsonFile : Objects.requireNonNull(invalidXacmlJsonFilesDataDir.listFiles(JSON_FILE_FILTER)))
{
/*
* Specific test's resources directory location, used as parameter to PdpTest(String). Check for a XML version of the file.
......
/**
/*
* Copyright 2012-2021 THALES.
*
* This file is part of AuthzForce CE.
......@@ -17,13 +17,24 @@
*/
package org.ow2.authzforce.xacml.json.model.test;
import org.everit.json.schema.Schema;
import org.everit.json.schema.ValidationException;
import org.json.JSONObject;
import org.ow2.authzforce.xacml.Xacml3JaxbHelper;
import org.ow2.authzforce.xacml.json.model.LimitsCheckingJSONObject;
import org.ow2.authzforce.xacml.json.model.XacmlJsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import javax.xml.bind.JAXBException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
......@@ -34,21 +45,6 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import javax.xml.bind.JAXBException;
import org.everit.json.schema.Schema;
import org.everit.json.schema.ValidationException;
import org.json.JSONObject;
import org.ow2.authzforce.xacml.Xacml3JaxbHelper;
import org.ow2.authzforce.xacml.json.model.LimitsCheckingJSONObject;
import org.ow2.authzforce.xacml.json.model.XacmlJsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class XacmlJsonSchemaValidationTest
{
private static final Logger LOGGER = LoggerFactory.getLogger(XacmlJsonSchemaValidationTest.class);
......@@ -79,11 +75,9 @@ public class XacmlJsonSchemaValidationTest
*
*
* @return iterator over test data
* @throws URISyntaxException
* @throws IOException
*/
@DataProvider(name = "xacmlJsonDataProvider")
public Iterator<Object[]> createData() throws URISyntaxException, IOException
public Iterator<Object[]> createData()
{
final List<Entry<File, File>> testDataDirLocations = Arrays.stream(SRC_XACML_JSON_DATA_DIRECTORY_LOCATIONS).map(loc -> new AbstractMap.SimpleImmutableEntry<>(new File(loc), (File) null))
.collect(Collectors.toList());
......@@ -93,7 +87,7 @@ public class XacmlJsonSchemaValidationTest
try
{
final int testDataParentDirIndex = i;
Files.newDirectoryStream(Paths.get(loc)).forEach(testDataDirPath -> testDataDirLocations.add(new AbstractMap.SimpleImmutableEntry(testDataDirPath.toFile(),
Files.newDirectoryStream(Paths.get(loc)).forEach(testDataDirPath -> testDataDirLocations.add(new AbstractMap.SimpleImmutableEntry<>(testDataDirPath.toFile(),
new File(SRC_XACML_XML_CONFORMANCE_TEST_DATA_PARENT_DIRECTORY_LOCATIONS[testDataParentDirIndex], testDataDirPath.getFileName().toString()))));
i++;
}
......@@ -103,26 +97,25 @@ public class XacmlJsonSchemaValidationTest
}
}
final Iterator<Object[]> testData = TestDataProvider.createData(testDataDirLocations);
return testData;
return TestDataProvider.createData(testDataDirLocations);
}
@Test(dataProvider = "xacmlJsonDataProvider")
/**
*
* @param xacmlJsonFile
* @param expectedXacmlXmlFile
* @param xacmlJsonFile XACML/JSON file
* @param expectedXacmlXmlFile expected XACML/XML file from conversion of {@code xacmlJsonFile}
* @param expectedValid
* true iff validation against JSON schema should succeed
* @param xacmlXmlFile
* @param actualXacmlXmlFile
* XACML/XML file generated from {@code expectedXacmlXmlFile} by XSLT (during maven generate-test-resources phase) for XACML/XML->XACML/JSON conversion, then XSLT for XACML/JSON ->
* XACML/XML conversion back; may be null if no XACML/XML file exists (expected to have been converted from {@code xacmlJsonFile}, therefore should be equivalent)
* @param testCtx
* @throws FileNotFoundException
* @throws IOException
* @param testCtx testng Test Context
* @throws JAXBException error parsing XACML/XML
* @throws IOException error reading XACML file
*/
@Test(dataProvider = "xacmlJsonDataProvider")
public void validateXacmlJson(final File xacmlJsonFile, final boolean expectedValid, final File expectedXacmlXmlFile, final File actualXacmlXmlFile, final ITestContext testCtx)
throws FileNotFoundException, IOException, JAXBException
throws IOException, JAXBException
{
/*
* Read properly as UTF-8 to avoid character decoding issues with org.json API
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment