Fix issues in xacml-pdp for new sonar rules
[policy/xacml-pdp.git] / applications / common / src / test / java / org / onap / policy / pdp / xacml / application / common / XacmlPolicyUtilsTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  * SPDX-License-Identifier: Apache-2.0
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.pdp.xacml.application.common;
24
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;
28
29 import com.att.research.xacml.api.XACML3;
30 import com.att.research.xacml.util.XACMLPolicyWriter;
31 import java.io.ByteArrayOutputStream;
32 import java.io.File;
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;
57
58 /**
59  * Utility methods for storing policies to disk and updating Properties objects
60  * that reference policies.
61  *
62  * @author pameladragosh
63  *
64  */
65 public class XacmlPolicyUtilsTest {
66     private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPolicyUtilsTest.class);
67
68     static Properties properties;
69
70     static PolicySetType rootPolicy = XacmlPolicyUtils.createEmptyPolicySet("root", XACML3.ID_POLICY_FIRST_APPLICABLE);
71
72     static Path rootPath;
73
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);
78
79     static PolicySetType policySet5 = XacmlPolicyUtils.createEmptyPolicySet(
80             "policyset1", XACML3.ID_POLICY_FIRST_APPLICABLE);
81
82     static Path path1;
83     static Path path2;
84     static Path path3;
85     static Path path4;
86
87     static Path policySetPath;
88
89     /**
90      * Temporary folder where we will store newly created policies.
91      */
92     @ClassRule
93     public static TemporaryFolder policyFolder = new TemporaryFolder();
94
95     /**
96      * Setup the JUnit tests by finishing creating the policies and
97      * writing them out to the temporary folder.
98      *
99      * @throws Exception thrown
100      */
101     @BeforeClass
102     public static void setUp() throws Exception {
103         assertThatCode(() -> {
104             //
105             // Load our test property object
106             //
107             try (InputStream is = new FileInputStream("src/test/resources/test.properties")) {
108                 properties = new Properties();
109                 properties.load(is);
110             }
111             //
112             // Change "/" to file separator in file names
113             //
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));
119                 }
120             }
121             //
122             // Save root policy
123             //
124             Path rootFile = XacmlPolicyUtils.constructUniquePolicyFilename(rootPolicy, policyFolder.getRoot().toPath());
125             LOGGER.info("Creating Root Policy {}", rootFile.toAbsolutePath());
126             rootPath = XacmlPolicyUtils.writePolicyFile(rootFile, rootPolicy);
127             //
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.
131             //
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)));
140             //
141             // Create our PolicySet
142             //
143             policySet5.setPolicySetId("policyset5");
144             policySet5.setTarget(new TargetType());
145             policySet5.setPolicyCombiningAlgId(XACML3.ID_POLICY_FIRST_APPLICABLE.stringValue());
146             ObjectFactory factory = new ObjectFactory();
147             //
148             // Add Policies 3 and 4 to the PolicySet
149             //
150             policySet5.getPolicySetOrPolicyOrPolicySetIdReference().add(factory.createPolicy(policy1));
151             policySet5.getPolicySetOrPolicyOrPolicySetIdReference().add(factory.createPolicy(policy2));
152             assertThat(policySet5.getPolicySetOrPolicyOrPolicySetIdReference()).hasSize(2);
153             //
154             // Save that to disk
155             //
156             File policySetFile = policyFolder.newFile("policySet5.xml");
157             LOGGER.info("Creating PolicySet {}", policySetFile.getAbsolutePath());
158             policySetPath = XACMLPolicyWriter.writePolicyFile(policySetFile.toPath(), policySet5);
159
160         }).doesNotThrowAnyException();
161     }
162
163     /**
164      * Helper method that creates a very simple Policy and Rule and saves it to disk.
165      *
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
170      */
171     private static Path createPolicyContents(PolicyType policy, String resource) throws IOException {
172         //
173         // Create The Match
174         //
175         MatchType matchPolicyId = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
176                 XACML3.ID_FUNCTION_STRING_EQUAL,
177                 resource,
178                 XACML3.ID_DATATYPE_STRING,
179                 XACML3.ID_RESOURCE_RESOURCE_ID,
180                 XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
181         //
182         // This is our outer AnyOf - which is an OR
183         //
184         AnyOfType anyOf = new AnyOfType();
185         //
186         // Create AllOf (AND) of just Policy Id
187         //
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());
196         //
197         // Add the rule to the policy
198         //
199         policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
200         //
201         // Save it to disk
202         //
203         Path policyFile = XacmlPolicyUtils.constructUniquePolicyFilename(policy, policyFolder.getRoot().toPath());
204         LOGGER.info("Creating Policy {}", policyFile.toAbsolutePath());
205         return XacmlPolicyUtils.writePolicyFile(policyFile, policy);
206     }
207
208     @Test
209     public void testUncommonConditions() throws IOException {
210         Path fileTemp = policyFolder.newFile().toPath();
211         assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() ->
212             XacmlPolicyUtils.writePolicyFile(fileTemp, "not a policy")
213         );
214         assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() ->
215             XacmlPolicyUtils.constructUniquePolicyFilename("not a policy",
216                     policyFolder.getRoot().toPath())
217         );
218     }
219
220     @Test
221     public void testUpdatingPolicies() {
222         assertThatCode(() -> {
223             //
224             // Just update root and policies
225             //
226             XacmlPolicyUtils.addPoliciesToXacmlRootPolicy(rootPolicy, policy1, policy2);
227             //
228             // Make sure it is correct
229             //
230             assertThat(rootPolicy.getPolicySetOrPolicyOrPolicySetIdReference()).hasSize(2);
231             //
232             // Save to disk
233             //
234             try (OutputStream os = new ByteArrayOutputStream()) {
235                 XACMLPolicyWriter.writePolicyFile(os, rootPolicy);
236                 LOGGER.debug("New Root Policy:{}{}", XacmlPolicyUtils.LINE_SEPARATOR, os);
237             }
238             //
239             // Just update root and PolicySet
240             //
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);
245             }
246         }).doesNotThrowAnyException();
247     }
248
249     @Test
250     public void testRemovingReferencedProperties() {
251         //
252         // Dump what we are starting with
253         //
254         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
255         //
256         // Remove referenced policies
257         //
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();
262
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();
267
268         //
269         // Test one that isn't in there
270         //
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();
275
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();
280
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();
285     }
286
287     @Test
288     public void testRemovingRootProperties() {
289         //
290         // Dump what we are starting with
291         //
292         XacmlPolicyUtils.debugDumpPolicyProperties(properties, LOGGER);
293         //
294         // Remove root policies
295         //
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();
300
301         //
302         // Test one that isn't in there
303         //
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();
308     }
309
310     @Test
311     public void testCopyingProperties() throws Exception {
312         //
313         // Copy to this folder
314         //
315         File copyFolder = policyFolder.newFolder("copy");
316         assertThat(copyFolder).exists();
317         //
318         // Mock up a properties object
319         //
320         Properties mockProperties = new Properties();
321         XacmlPolicyUtils.addRootPolicy(mockProperties, rootPath);
322         XacmlPolicyUtils.addReferencedPolicy(mockProperties, path1);
323         //
324         // Write the properties out to a file
325         //
326         Path fileProperties = XacmlPolicyUtils.getPropertiesPath(policyFolder.getRoot().toPath());
327         XacmlPolicyUtils.storeXacmlProperties(mockProperties, fileProperties);
328         //
329         // Now we can test the copy method
330         //
331         XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile("copy/" + filename);
332         File propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents(
333                 fileProperties.toAbsolutePath().toString(), mockProperties, myCreator);
334
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();
340     }
341 }