2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.policy.pdp.test;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
28 import java.io.BufferedWriter;
30 import java.io.FileWriter;
31 import java.util.ArrayList;
32 import java.util.Iterator;
33 import java.util.List;
35 import javax.xml.namespace.NamespaceContext;
37 import org.junit.Ignore;
39 import com.att.research.xacml.api.Request;
40 import com.att.research.xacml.api.XACML3;
41 import com.att.research.xacml.std.StdMutableRequest;
42 import com.att.research.xacml.std.datatypes.DataTypes;
43 import com.att.research.xacml.std.dom.DOMRequest;
44 import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
45 import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
46 import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;
47 import com.att.research.xacmlatt.pdp.std.StdEvaluationContext;
48 import com.att.research.xacmlatt.pdp.std.StdFunctions;
49 import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionAccessPermitted;
52 * Test of PDP Functions (See XACML core spec section A.3)
55 * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
57 * NOT IMPLEMENTED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
58 * This function is not yet implemented so these tests intentionally fail.
62 public class FunctionDefinitionAccessPermittedTest {
65 // Strings for the Request contents
68 String reqStrMainStart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
69 + "<Request xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
70 + " http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\""
71 + " ReturnPolicyIdList=\"false\""
72 + " CombinedDecision=\"false\""
73 + " xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\""
74 + " xmlns:md=\"http://www.medico.com/schemas/record\""
75 + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
76 + " <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">"
77 + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\">"
78 + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Julius Hibbert</AttributeValue>"
80 + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"
81 + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>"
83 + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"
84 + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>"
88 String reqStrResourceStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">";
90 String reqStrMdRecordSimpson =
92 "<md:hospital_info>" +
93 "<md:name>ABC Hospital</md:name>" +
94 "<md:department>Surgery</md:department>" +
95 "</md:hospital_info>" +
97 "<md:name>Bart Simpson</md:name>" +
98 "<md:age>60</md:age>" +
99 "<md:sex>male</md:sex>" +
100 "<md:health_insurance>123456</md:health_insurance>" +
101 "</md:patient_info>" +
102 "<md:diagnosis_info>" +
104 "<md:item type=\"primary\">Gastric Cancer</md:item>" +
105 "<md:item type=\"secondary\">Hyper tension</md:item>" +
107 "<md:pathological_diagnosis>" +
109 "<md:item type=\"primary\">Well differentiated adeno carcinoma</md:item>" +
111 "<md:date>2000-10-05</md:date>" +
112 "<md:malignancy type=\"yes\"/>" +
113 "</md:pathological_diagnosis>" +
114 "</md:diagnosis_info>" +
116 String reqStrContentMdRecordSimpson = "<Content>" + reqStrMdRecordSimpson + "</Content>";
117 String reqStrMalformedContent =
120 "<md:hospital_info>" +
121 "<md:name>ABC Hospital</md:name>" +
122 "<md:malignancy type=\"yes\"/>" +
124 String reqStrMdRecordSpringer =
126 "<md:hospital_info>" +
127 "<md:name>XYZ Hospital</md:name>" +
128 "<md:department>Surgery</md:department>" +
129 "</md:hospital_info>" +
130 "<md:patient_info>" +
131 "<md:name>Jerry Springer</md:name>" +
132 "<md:age>65</md:age>" +
133 "<md:sex>male</md:sex>" +
134 "<md:health_insurance>765432</md:health_insurance>" +
135 "</md:patient_info>" +
136 "<md:diagnosis_info>" +
138 "<md:item type=\"primary\">Hyatal Hernia</md:item>" +
139 "<md:item type=\"secondary\">Diabetes</md:item>" +
140 "<md:item type=\"tertiary\">Neuronal Collapse</md:item>" +
142 "<md:pathological_diagnosis>" +
144 "<md:item type=\"primary\">We have no idea</md:item>" +
146 "<md:date>2012-07-22</md:date>" +
147 "<md:malignancy type=\"no\"/>" +
148 "</md:pathological_diagnosis>" +
149 "</md:diagnosis_info>" +
151 String reqStrContentMdRecordSpringer =
152 "<Content>" + reqStrMdRecordSpringer + "</Content>";
154 String reqStrResourceEnd = " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\">"
155 + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#anyURI\">http://medico.com/record/patient/BartSimpson</AttributeValue>"
158 String reqStrActionStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">";
160 String reqStrActionEnd = "<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\">"
161 + "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">read</AttributeValue>"
164 String reqStrEnvironmentStartEnd = " <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />";
165 String reqStrMainEnd = " </Request>";
168 // combined strings for convenience
169 String reqStrMainResourceStart = reqStrMainStart + reqStrResourceStart;
170 String reqStrResourceAllEnd = reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrEnvironmentStartEnd + reqStrMainEnd;
174 * variables useful in the following tests
176 List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
180 // Name Spaces used in the XML as part of these examples - needed for compiling XPaths
181 NamespaceContext nameSpaceContext = new NamespaceContext() {
183 public Iterator<?> getPrefixes(String arg0) { return null;}
186 public String getPrefix(String arg0) {return null;}
189 public String getNamespaceURI(String arg0) {
190 if("md".equals(arg0)) {
191 return "http://www.medico.com/schemas/record";
192 } else if ("xacml-context".equals(arg0)) {
193 return "urn:oasis:names:tc:xacml:3.0:context:schema:os";
194 } else if ("xsi".equals(arg0)) {
195 return "http://www.w3.org/2001/XMLSchema-instance";
204 // URIs for attribute categroies
207 FunctionArgumentAttributeValue attrUriNull = null;
208 FunctionArgumentAttributeValue attrUriEmpty = null;
209 FunctionArgumentAttributeValue attrUriResources = null;
210 FunctionArgumentAttributeValue attrUriAction = null;
211 FunctionArgumentAttributeValue attrUriNotInRequest = null;
212 FunctionArgumentAttributeValue attrUriNotCategory = null;
220 FunctionArgumentAttributeValue attrXnull = null;
221 FunctionArgumentAttributeValue attrXEmpty = null;
222 FunctionArgumentAttributeValue attrXSimpson = null;
223 FunctionArgumentAttributeValue attrXSpringer = null;
224 FunctionArgumentAttributeValue attrXContentSimpson = null;
225 FunctionArgumentAttributeValue attrXContentSpringer = null;
226 FunctionArgumentAttributeValue attrXBadXML = null;
234 // REQUEST objects available for use in tests
236 Request requestEmpty = new StdMutableRequest();
237 Request requestMdRecord = null;
238 Request requestDoubleResources = null;
239 Request requestDoubleContent = null;
240 Request requestResourceActionContent = null;
241 Request requestContentInAction = null;
247 * Set up all variables in one place because it is complicated (lots of steps needed for each attribute)
249 public FunctionDefinitionAccessPermittedTest() {
253 // create Function Attributes for URIs
255 attrUriEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));
256 attrUriResources = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:resource"));
257 attrUriAction = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:action"));
258 attrUriNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("NoSuchURI"));
259 attrUriNotCategory = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:1.0:resource:resource-id"));
261 // create Function Attributes for XML Strings
262 attrXnull = new FunctionArgumentAttributeValue(null);
263 attrXEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
264 attrXSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSimpson));
265 attrXSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSpringer));
266 attrXContentSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSimpson));
267 attrXContentSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSpringer));
268 attrXBadXML = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMalformedContent));
273 // to create a Request object the easiest way is to put the xml into a file and use the DOMRequest to load it.
275 // single Content in the Resources section (normal valid request)
276 String reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceAllEnd;
277 File tFile = File.createTempFile("functionJunit", "request");
278 BufferedWriter bw = new BufferedWriter(new FileWriter(tFile));
279 bw.append(reqString);
282 requestMdRecord = DOMRequest.load(tFile);
285 // Resources included twice
286 reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrResourceStart + reqStrContentMdRecordSimpson +reqStrResourceAllEnd;
287 tFile = File.createTempFile("functionJunit", "request");
288 bw = new BufferedWriter(new FileWriter(tFile));
289 bw.append(reqString);
292 requestDoubleResources = DOMRequest.load(tFile);
295 // Content included twice - error
296 reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrContentMdRecordSimpson +reqStrResourceAllEnd;
297 tFile = File.createTempFile("functionJunit", "request");
298 bw = new BufferedWriter(new FileWriter(tFile));
299 bw.append(reqString);
303 requestDoubleContent = DOMRequest.load(tFile);
305 } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
306 // this is what it should do, so just continue
307 } catch (Exception e) {
308 fail("Unexpected exception for bad XML, e="+e);
311 // content included in both Resource and Action - ok
312 reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd;
313 tFile = File.createTempFile("functionJunit", "request");
314 bw = new BufferedWriter(new FileWriter(tFile));
315 bw.append(reqString);
318 requestResourceActionContent = DOMRequest.load(tFile);
321 // Content included only in Action - missing content produces non-error result according to spec
322 reqString = reqStrMainResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd;
323 tFile = File.createTempFile("functionJunit", "request");
324 bw = new BufferedWriter(new FileWriter(tFile));
325 bw.append(reqString);
328 requestContentInAction = DOMRequest.load(tFile);
333 // Test that Bad XML is caught
334 @SuppressWarnings("unused")
335 Request requestContentMisplaced = null;
336 @SuppressWarnings("unused")
337 Request requestMalformedContent = null;
340 // Bad XML - Content not under a Category
341 reqString = reqStrMainStart + reqStrContentMdRecordSimpson + reqStrResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrMainEnd;
342 tFile = File.createTempFile("functionJunit", "request");
343 bw = new BufferedWriter(new FileWriter(tFile));
344 bw.append(reqString);
348 requestContentMisplaced = DOMRequest.load(tFile);
350 } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
351 // this is what it should do, so just continue
352 } catch (Exception e) {
353 fail("Unexpected exception for bad XML, e="+e);
356 // Bad XML - Content is not valid XML
357 reqString = reqStrMainResourceStart + reqStrMalformedContent + reqStrResourceAllEnd;
358 tFile = File.createTempFile("functionJunit", "request");
359 bw = new BufferedWriter(new FileWriter(tFile));
360 bw.append(reqString);
364 requestMalformedContent = DOMRequest.load(tFile);
366 } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
367 // this is what it should do, so just continue
368 } catch (Exception e) {
369 fail("Unexpected exception for bad XML, e="+e);
372 } catch (Exception e) {
373 fail("Constructor initializing variables, e="+ e + " cause="+e.getCause());
386 public void testAccess_permitted() {
388 ExpressionResult res = null;
389 Boolean resValue = null;
391 FunctionDefinitionAccessPermitted fd = (FunctionDefinitionAccessPermitted) StdFunctions.FD_ACCESS_PERMITTED;
393 // check identity and type of the thing created
394 assertEquals(XACML3.ID_FUNCTION_ACCESS_PERMITTED, fd.getId());
395 assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
397 // just to be safe... If tests take too long these can probably be eliminated
398 assertFalse(fd.returnsBag());
402 // successful invoke returns true
404 arguments.add(attrUriResources);
405 arguments.add(attrXEmpty);
406 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
407 assertTrue(res.isOk());
408 resValue = (Boolean)res.getValue().getValue();
409 assertTrue(resValue);
413 // successful invoke returns false
416 // URI not in Request (ok - evaluate anyway)
418 // test for infinite loop
420 // second arg ok both with and without <Content> tag
422 arguments.add(attrUriResources);
423 arguments.add(attrXContentSpringer);
424 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
425 assertTrue(res.isOk());
426 resValue = (Boolean)res.getValue().getValue();
427 assertTrue(resValue);
430 arguments.add(attrUriResources);
431 arguments.add(attrXSpringer);
432 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
433 assertTrue(res.isOk());
434 resValue = (Boolean)res.getValue().getValue();
435 assertTrue(resValue);
437 // second arg not valid XML
439 arguments.add(attrUriResources);
440 arguments.add(attrXBadXML);
441 res = fd.evaluate(null, arguments);
442 assertFalse(res.getStatus().isOk());
443 assertEquals( "function:access-permitted Parsing of XML string failed. Cause='The element type \"md:hospital_info\" must be terminated by the matching end-tag \"</md:hospital_info>\".'", res.getStatus().getStatusMessage());
444 assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
446 // null Evaluation Context
448 arguments.add(attrUriNotCategory);
449 arguments.add(attrXContentSimpson);
450 res = fd.evaluate(null, arguments);
451 assertFalse(res.getStatus().isOk());
452 assertEquals( "function:access-permitted First argument must be a urn for an attribute-category, not 'urn:oasis:names:tc:xacml:1.0:resource:resource-id", res.getStatus().getStatusMessage());
453 assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
457 arguments.add(attrUriAction);
458 arguments.add(attrXContentSimpson);
459 res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments);
460 assertFalse(res.getStatus().isOk());
461 assertEquals( "function:access-permitted Got null Request in EvaluationContext", res.getStatus().getStatusMessage());
462 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
467 arguments.add(attrUriNotCategory);
468 arguments.add(attrXContentSimpson);
469 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
470 assertFalse(res.getStatus().isOk());
471 assertEquals( "function:access-permitted First argument must be a urn for an attribute-category, not 'urn:oasis:names:tc:xacml:1.0:resource:resource-id", res.getStatus().getStatusMessage());
472 assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
474 // first arg not attribute-category urn
476 arguments.add(attrXContentSimpson);
477 arguments.add(attrXContentSimpson);
478 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
479 assertFalse(res.getStatus().isOk());
480 assertEquals( "function:access-permitted Expected data type 'anyURI' saw 'string'", res.getStatus().getStatusMessage());
481 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
483 // second arg not string
485 arguments.add(attrUriAction);
486 arguments.add(attrUriAction);
487 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
488 assertFalse(res.getStatus().isOk());
489 assertEquals( "function:access-permitted Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage());
490 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
495 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
496 assertFalse(res.getStatus().isOk());
497 assertEquals( "function:access-permitted Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
498 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
501 arguments.add(attrXContentSimpson);
502 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
503 assertFalse(res.getStatus().isOk());
504 assertEquals( "function:access-permitted Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
505 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
510 arguments.add(attrUriEmpty);
511 arguments.add(attrXContentSimpson);
512 arguments.add(attrXContentSimpson);
513 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
514 assertFalse(res.getStatus().isOk());
515 assertEquals( "function:access-permitted Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
516 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());