2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  19  * SPDX-License-Identifier: Apache-2.0
 
  20  * ============LICENSE_END=========================================================
 
  23 package org.onap.policy.pdp.xacml.application.common;
 
  25 import static org.assertj.core.api.Assertions.assertThat;
 
  26 import static org.assertj.core.api.Assertions.assertThatCode;
 
  27 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 
  29 import com.att.research.xacml.api.XACML3;
 
  30 import com.att.research.xacml.util.XACMLPolicyWriter;
 
  31 import java.io.ByteArrayOutputStream;
 
  33 import java.io.FileInputStream;
 
  34 import java.io.IOException;
 
  35 import java.io.InputStream;
 
  36 import java.io.OutputStream;
 
  37 import java.nio.file.Files;
 
  38 import java.nio.file.Path;
 
  39 import java.nio.file.Paths;
 
  40 import java.util.List;
 
  41 import java.util.Properties;
 
  42 import java.util.stream.Collectors;
 
  43 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
 
  44 import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
 
  45 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
 
  46 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
 
  47 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
 
  48 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
 
  49 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
 
  50 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
 
  51 import org.junit.BeforeClass;
 
  52 import org.junit.ClassRule;
 
  53 import org.junit.Test;
 
  54 import org.junit.rules.TemporaryFolder;
 
  55 import org.slf4j.Logger;
 
  56 import org.slf4j.LoggerFactory;
 
  59  * Utility methods for storing policies to disk and updating Properties objects
 
  60  * that reference policies.
 
  62  * @author pameladragosh
 
  65 public class XacmlPolicyUtilsTest {
 
  66     private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPolicyUtilsTest.class);
 
  68     static Properties properties;
 
  70     static PolicySetType rootPolicy = XacmlPolicyUtils.createEmptyPolicySet("root", XACML3.ID_POLICY_FIRST_APPLICABLE);
 
  74     static PolicyType policy1 = XacmlPolicyUtils.createEmptyPolicy("policy1", XACML3.ID_RULE_DENY_UNLESS_PERMIT);
 
  75     static PolicyType policy2 = XacmlPolicyUtils.createEmptyPolicy("policy2", XACML3.ID_RULE_DENY_UNLESS_PERMIT);
 
  76     static PolicyType policy3 = XacmlPolicyUtils.createEmptyPolicy("policy3", XACML3.ID_RULE_DENY_UNLESS_PERMIT);
 
  77     static PolicyType policy4 = XacmlPolicyUtils.createEmptyPolicy("policy4", XACML3.ID_RULE_DENY_UNLESS_PERMIT);
 
  79     static PolicySetType policySet5 = XacmlPolicyUtils.createEmptyPolicySet(
 
  80             "policyset1", XACML3.ID_POLICY_FIRST_APPLICABLE);
 
  87     static Path policySetPath;
 
  90      * Temporary folder where we will store newly created policies.
 
  93     public static TemporaryFolder policyFolder = new TemporaryFolder();
 
  96      * Setup the JUnit tests by finishing creating the policies and
 
  97      * writing them out to the temporary folder.
 
  99      * @throws Exception thrown
 
 102     public static void setUp() throws Exception {
 
 103         assertThatCode(() -> {
 
 105             // Load our test property object
 
 107             try (InputStream is = new FileInputStream("src/test/resources/test.properties")) {
 
 108                 properties = new Properties();
 
 112             // Change "/" to file separator in file names
 
 114             if (!"/".equals(File.separator)) {
 
 115                 List<String> fileProps = properties.keySet().stream().map(Object::toString)
 
 116                                 .filter(key -> key.endsWith(".file")).collect(Collectors.toList());
 
 117                 for (String fileProp : fileProps) {
 
 118                     properties.setProperty(fileProp, properties.getProperty(fileProp).replace("/", File.separator));
 
 124             Path rootFile = XacmlPolicyUtils.constructUniquePolicyFilename(rootPolicy, policyFolder.getRoot().toPath());
 
 125             LOGGER.info("Creating Root Policy {}", rootFile.toAbsolutePath());
 
 126             rootPath = XacmlPolicyUtils.writePolicyFile(rootFile, rootPolicy);
 
 128             // Create policies - Policies 1 and 2 will become references in the
 
 129             // root policy. While Policies 3 and 4 will become references in the
 
 130             // soon to be created PolicySet 5 below.
 
 132             path1 = createPolicyContents(policy1, "resource1");
 
 133             LOGGER.info(new String(Files.readAllBytes(path1)));
 
 134             path2 = createPolicyContents(policy2, "resource2");
 
 135             LOGGER.info(new String(Files.readAllBytes(path2)));
 
 136             path3 = createPolicyContents(policy3, "resourc31");
 
 137             LOGGER.info(new String(Files.readAllBytes(path3)));
 
 138             path4 = createPolicyContents(policy4, "resource4");
 
 139             LOGGER.info(new String(Files.readAllBytes(path4)));
 
 141             // Create our PolicySet
 
 143             policySet5.setPolicySetId("policyset5");
 
 144             policySet5.setTarget(new TargetType());
 
 145             policySet5.setPolicyCombiningAlgId(XACML3.ID_POLICY_FIRST_APPLICABLE.stringValue());
 
 146             ObjectFactory factory = new ObjectFactory();
 
 148             // Add Policies 3 and 4 to the PolicySet
 
 150             policySet5.getPolicySetOrPolicyOrPolicySetIdReference().add(factory.createPolicy(policy1));
 
 151             policySet5.getPolicySetOrPolicyOrPolicySetIdReference().add(factory.createPolicy(policy2));
 
 152             assertThat(policySet5.getPolicySetOrPolicyOrPolicySetIdReference()).hasSize(2);
 
 156             File policySetFile = policyFolder.newFile("policySet5.xml");
 
 157             LOGGER.info("Creating PolicySet {}", policySetFile.getAbsolutePath());
 
 158             policySetPath = XACMLPolicyWriter.writePolicyFile(policySetFile.toPath(), policySet5);
 
 160         }).doesNotThrowAnyException();
 
 164      * Helper method that creates a very simple Policy and Rule and saves it to disk.
 
 166      * @param policy Policy to store contents in
 
 167      * @param resource A simple resource id for the Target
 
 168      * @return Path object of the policy
 
 169      * @throws IOException If unable to write to disk
 
 171     private static Path createPolicyContents(PolicyType policy, String resource) throws IOException {
 
 175         MatchType matchPolicyId = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
 
 176                 XACML3.ID_FUNCTION_STRING_EQUAL,
 
 178                 XACML3.ID_DATATYPE_STRING,
 
 179                 XACML3.ID_RESOURCE_RESOURCE_ID,
 
 180                 XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
 
 182         // This is our outer AnyOf - which is an OR
 
 184         AnyOfType anyOf = new AnyOfType();
 
 186         // Create AllOf (AND) of just Policy Id
 
 188         anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(matchPolicyId));
 
 189         TargetType target = new TargetType();
 
 190         target.getAnyOf().add(anyOf);
 
 191         policy.setTarget(target);
 
 192         RuleType rule = new RuleType();
 
 193         rule.setRuleId(policy.getPolicyId() + ":rule");
 
 194         rule.setEffect(EffectType.PERMIT);
 
 195         rule.setTarget(new TargetType());
 
 197         // Add the rule to the policy
 
 199         policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
 
 203         Path policyFile = XacmlPolicyUtils.constructUniquePolicyFilename(policy, policyFolder.getRoot().toPath());
 
 204         LOGGER.info("Creating Policy {}", policyFile.toAbsolutePath());
 
 205         return XacmlPolicyUtils.writePolicyFile(policyFile, policy);
 
 209     public void testUncommonConditions() throws IOException {
 
 210         Path fileTemp = policyFolder.newFile().toPath();
 
 211         assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() ->
 
 212             XacmlPolicyUtils.writePolicyFile(fileTemp, "not a policy")
 
 214         assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() ->
 
 215             XacmlPolicyUtils.constructUniquePolicyFilename("not a policy",
 
 216                     policyFolder.getRoot().toPath())
 
 221     public void testUpdatingPolicies() {
 
 222         assertThatCode(() -> {
 
 224             // Just update root and policies
 
 226             XacmlPolicyUtils.addPoliciesToXacmlRootPolicy(rootPolicy, policy1, policy2);
 
 228             // Make sure it is correct
 
 230             assertThat(rootPolicy.getPolicySetOrPolicyOrPolicySetIdReference()).hasSize(2);
 
 234             try (OutputStream os = new ByteArrayOutputStream()) {
 
 235                 XACMLPolicyWriter.writePolicyFile(os, rootPolicy);
 
 236                 LOGGER.debug("New Root Policy:{}{}", XacmlPolicyUtils.LINE_SEPARATOR, os);
 
 239             // Just update root and PolicySet
 
 241             XacmlPolicyUtils.addPolicySetsToXacmlRootPolicy(rootPolicy, policySet5);
 
 242             try (OutputStream os = new ByteArrayOutputStream()) {
 
 243                 XACMLPolicyWriter.writePolicyFile(os, rootPolicy);
 
 244                 LOGGER.debug("New Root Policy:{}{}", XacmlPolicyUtils.LINE_SEPARATOR, os);
 
 246         }).doesNotThrowAnyException();
 
 250     public void testRemovingReferencedProperties() {
 
 252         // Dump what we are starting with
 
 254         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
 
 256         // Remove referenced policies
 
 258         Path ref = Paths.get("src/test/resources/ref1.xml");
 
 259         XacmlPolicyUtils.removeReferencedPolicy(properties, ref);
 
 260         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
 
 261         assertThat(properties.getProperty("refstart1.file")).isNullOrEmpty();
 
 263         ref = Paths.get("src/test/resources/ref2.xml");
 
 264         XacmlPolicyUtils.removeReferencedPolicy(properties, ref);
 
 265         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
 
 266         assertThat(properties.getProperty("refstart2.file")).isNullOrEmpty();
 
 269         // Test one that isn't in there
 
 271         ref = Paths.get("src/test/resources/NotThere.xml");
 
 272         XacmlPolicyUtils.removeReferencedPolicy(properties, ref);
 
 273         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
 
 274         assertThat(properties.getProperty("refstart3.file")).isNotBlank();
 
 276         ref = Paths.get("src/test/resources/ref3.xml");
 
 277         XacmlPolicyUtils.removeReferencedPolicy(properties, ref);
 
 278         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
 
 279         assertThat(properties.getProperty("refstart3.file")).isNullOrEmpty();
 
 281         ref = Paths.get("src/test/resources/ref4.xml");
 
 282         XacmlPolicyUtils.removeReferencedPolicy(properties, ref);
 
 283         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
 
 284         assertThat(properties.getProperty("refstart4.file")).isNullOrEmpty();
 
 288     public void testRemovingRootProperties() {
 
 290         // Dump what we are starting with
 
 292         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
 
 294         // Remove root policies
 
 296         Path ref = Paths.get("src/test/resources/root.xml");
 
 297         XacmlPolicyUtils.removeRootPolicy(properties, ref);
 
 298         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
 
 299         assertThat(properties.getProperty("root.file")).isNullOrEmpty();
 
 302         // Test one that isn't in there
 
 304         ref = Paths.get("src/test/resources/NotThere.xml");
 
 305         XacmlPolicyUtils.removeRootPolicy(properties, ref);
 
 306         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
 
 307         assertThat(properties.getProperty("refstart3.file")).isNotBlank();
 
 311     public void testCopyingProperties() throws Exception {
 
 313         // Copy to this folder
 
 315         File copyFolder = policyFolder.newFolder("copy");
 
 316         assertThat(copyFolder).exists();
 
 318         // Mock up a properties object
 
 320         Properties mockProperties = new Properties();
 
 321         XacmlPolicyUtils.addRootPolicy(mockProperties, rootPath);
 
 322         XacmlPolicyUtils.addReferencedPolicy(mockProperties, path1);
 
 324         // Write the properties out to a file
 
 326         Path fileProperties = XacmlPolicyUtils.getPropertiesPath(policyFolder.getRoot().toPath());
 
 327         XacmlPolicyUtils.storeXacmlProperties(mockProperties, fileProperties);
 
 329         // Now we can test the copy method
 
 331         XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile("copy/" + filename);
 
 332         File propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents(
 
 333                 fileProperties.toAbsolutePath().toString(), mockProperties, myCreator);
 
 335         assertThat(propertiesFile).canRead();
 
 336         assertThat(Path.of(copyFolder.getAbsolutePath(),
 
 337                 rootPath.getFileName().toString()).toFile()).canRead();
 
 338         assertThat(Path.of(copyFolder.getAbsolutePath(),
 
 339                 path1.getFileName().toString()).toFile()).canRead();