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.std.functions;
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;
38 import org.junit.Test;
40 import com.att.research.xacml.api.Request;
41 import com.att.research.xacml.api.XACML3;
42 import com.att.research.xacml.std.StdMutableRequest;
43 import com.att.research.xacml.std.datatypes.DataTypes;
44 import com.att.research.xacml.std.dom.DOMRequest;
45 import com.att.research.xacmlatt.pdp.policy.ExpressionResult;
46 import com.att.research.xacmlatt.pdp.policy.FunctionArgument;
47 import com.att.research.xacmlatt.pdp.policy.FunctionArgumentAttributeValue;
48 import com.att.research.xacmlatt.pdp.std.StdEvaluationContext;
49 import com.att.research.xacmlatt.pdp.std.StdFunctions;
50 import com.att.research.xacmlatt.pdp.std.functions.FunctionDefinitionAccessPermitted;
53 * Test of PDP Functions (See XACML core spec section A.3)
56 * In Eclipse select this file or the enclosing directory, right-click and select Run As/JUnit Test
58 * NOT IMPLEMENTED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
59 * This function is not yet implemented so these tests intentionally fail.
63 public class FunctionDefinitionAccessPermittedTest {
66 // Strings for the Request contents
69 String reqStrMainStart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
70 + "<Request xsi:schemaLocation=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
71 + " http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd\""
72 + " ReturnPolicyIdList=\"false\""
73 + " CombinedDecision=\"false\""
74 + " xmlns=\"urn:oasis:names:tc:xacml:3.0:core:schema:wd-17\""
75 + " xmlns:md=\"http://www.medico.com/schemas/record\""
76 + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
77 + " <Attributes Category=\"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject\">"
78 + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:subject:subject-id\">"
79 + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">Julius Hibbert</AttributeValue>"
81 + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"
82 + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>"
84 + " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:2.0:conformance-test:test-attr\">"
85 + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\"> This is IT! </AttributeValue>"
89 String reqStrResourceStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:resource\">";
91 String reqStrMdRecordSimpson =
93 "<md:hospital_info>" +
94 "<md:name>ABC Hospital</md:name>" +
95 "<md:department>Surgery</md:department>" +
96 "</md:hospital_info>" +
98 "<md:name>Bart Simpson</md:name>" +
99 "<md:age>60</md:age>" +
100 "<md:sex>male</md:sex>" +
101 "<md:health_insurance>123456</md:health_insurance>" +
102 "</md:patient_info>" +
103 "<md:diagnosis_info>" +
105 "<md:item type=\"primary\">Gastric Cancer</md:item>" +
106 "<md:item type=\"secondary\">Hyper tension</md:item>" +
108 "<md:pathological_diagnosis>" +
110 "<md:item type=\"primary\">Well differentiated adeno carcinoma</md:item>" +
112 "<md:date>2000-10-05</md:date>" +
113 "<md:malignancy type=\"yes\"/>" +
114 "</md:pathological_diagnosis>" +
115 "</md:diagnosis_info>" +
117 String reqStrContentMdRecordSimpson = "<Content>" + reqStrMdRecordSimpson + "</Content>";
118 String reqStrMalformedContent =
121 "<md:hospital_info>" +
122 "<md:name>ABC Hospital</md:name>" +
123 "<md:malignancy type=\"yes\"/>" +
125 String reqStrMdRecordSpringer =
127 "<md:hospital_info>" +
128 "<md:name>XYZ Hospital</md:name>" +
129 "<md:department>Surgery</md:department>" +
130 "</md:hospital_info>" +
131 "<md:patient_info>" +
132 "<md:name>Jerry Springer</md:name>" +
133 "<md:age>65</md:age>" +
134 "<md:sex>male</md:sex>" +
135 "<md:health_insurance>765432</md:health_insurance>" +
136 "</md:patient_info>" +
137 "<md:diagnosis_info>" +
139 "<md:item type=\"primary\">Hyatal Hernia</md:item>" +
140 "<md:item type=\"secondary\">Diabetes</md:item>" +
141 "<md:item type=\"tertiary\">Neuronal Collapse</md:item>" +
143 "<md:pathological_diagnosis>" +
145 "<md:item type=\"primary\">We have no idea</md:item>" +
147 "<md:date>2012-07-22</md:date>" +
148 "<md:malignancy type=\"no\"/>" +
149 "</md:pathological_diagnosis>" +
150 "</md:diagnosis_info>" +
152 String reqStrContentMdRecordSpringer =
153 "<Content>" + reqStrMdRecordSpringer + "</Content>";
155 String reqStrResourceEnd = " <Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\">"
156 + " <AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#anyURI\">http://medico.com/record/patient/BartSimpson</AttributeValue>"
159 String reqStrActionStart = "<Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:action\">";
161 String reqStrActionEnd = "<Attribute IncludeInResult=\"false\" AttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\">"
162 + "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">read</AttributeValue>"
165 String reqStrEnvironmentStartEnd = " <Attributes Category=\"urn:oasis:names:tc:xacml:3.0:attribute-category:environment\" />";
166 String reqStrMainEnd = " </Request>";
169 // combined strings for convenience
170 String reqStrMainResourceStart = reqStrMainStart + reqStrResourceStart;
171 String reqStrResourceAllEnd = reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrEnvironmentStartEnd + reqStrMainEnd;
175 * variables useful in the following tests
177 List<FunctionArgument> arguments = new ArrayList<FunctionArgument>();
181 // Name Spaces used in the XML as part of these examples - needed for compiling XPaths
182 NamespaceContext nameSpaceContext = new NamespaceContext() {
184 public Iterator<?> getPrefixes(String arg0) { return null;}
187 public String getPrefix(String arg0) {return null;}
190 public String getNamespaceURI(String arg0) {
191 if("md".equals(arg0)) {
192 return "http://www.medico.com/schemas/record";
193 } else if ("xacml-context".equals(arg0)) {
194 return "urn:oasis:names:tc:xacml:3.0:context:schema:os";
195 } else if ("xsi".equals(arg0)) {
196 return "http://www.w3.org/2001/XMLSchema-instance";
205 // URIs for attribute categroies
208 FunctionArgumentAttributeValue attrUriNull = null;
209 FunctionArgumentAttributeValue attrUriEmpty = null;
210 FunctionArgumentAttributeValue attrUriResources = null;
211 FunctionArgumentAttributeValue attrUriAction = null;
212 FunctionArgumentAttributeValue attrUriNotInRequest = null;
213 FunctionArgumentAttributeValue attrUriNotCategory = null;
221 FunctionArgumentAttributeValue attrXnull = null;
222 FunctionArgumentAttributeValue attrXEmpty = null;
223 FunctionArgumentAttributeValue attrXSimpson = null;
224 FunctionArgumentAttributeValue attrXSpringer = null;
225 FunctionArgumentAttributeValue attrXContentSimpson = null;
226 FunctionArgumentAttributeValue attrXContentSpringer = null;
227 FunctionArgumentAttributeValue attrXBadXML = null;
235 // REQUEST objects available for use in tests
237 Request requestEmpty = new StdMutableRequest();
238 Request requestMdRecord = null;
239 Request requestDoubleResources = null;
240 Request requestDoubleContent = null;
241 Request requestResourceActionContent = null;
242 Request requestContentInAction = null;
248 * Set up all variables in one place because it is complicated (lots of steps needed for each attribute)
250 public FunctionDefinitionAccessPermittedTest() {
254 // create Function Attributes for URIs
256 attrUriEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(""));
257 attrUriResources = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:resource"));
258 attrUriAction = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:3.0:attribute-category:action"));
259 attrUriNotInRequest = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("NoSuchURI"));
260 attrUriNotCategory = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue("urn:oasis:names:tc:xacml:1.0:resource:resource-id"));
262 // create Function Attributes for XML Strings
263 attrXnull = new FunctionArgumentAttributeValue(null);
264 attrXEmpty = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(""));
265 attrXSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSimpson));
266 attrXSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMdRecordSpringer));
267 attrXContentSimpson = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSimpson));
268 attrXContentSpringer = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrContentMdRecordSpringer));
269 attrXBadXML = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(reqStrMalformedContent));
274 // to create a Request object the easiest way is to put the xml into a file and use the DOMRequest to load it.
276 // single Content in the Resources section (normal valid request)
277 String reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceAllEnd;
278 File tFile = File.createTempFile("functionJunit", "request");
279 BufferedWriter bw = new BufferedWriter(new FileWriter(tFile));
280 bw.append(reqString);
283 requestMdRecord = DOMRequest.load(tFile);
286 // Resources included twice
287 reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrResourceStart + reqStrContentMdRecordSimpson +reqStrResourceAllEnd;
288 tFile = File.createTempFile("functionJunit", "request");
289 bw = new BufferedWriter(new FileWriter(tFile));
290 bw.append(reqString);
293 requestDoubleResources = DOMRequest.load(tFile);
296 // Content included twice - error
297 reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrContentMdRecordSimpson +reqStrResourceAllEnd;
298 tFile = File.createTempFile("functionJunit", "request");
299 bw = new BufferedWriter(new FileWriter(tFile));
300 bw.append(reqString);
304 requestDoubleContent = DOMRequest.load(tFile);
306 } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
307 // this is what it should do, so just continue
308 } catch (Exception e) {
309 fail("Unexpected exception for bad XML, e="+e);
312 // content included in both Resource and Action - ok
313 reqString = reqStrMainResourceStart + reqStrContentMdRecordSimpson + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd;
314 tFile = File.createTempFile("functionJunit", "request");
315 bw = new BufferedWriter(new FileWriter(tFile));
316 bw.append(reqString);
319 requestResourceActionContent = DOMRequest.load(tFile);
322 // Content included only in Action - missing content produces non-error result according to spec
323 reqString = reqStrMainResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrContentMdRecordSimpson + reqStrActionEnd + reqStrMainEnd;
324 tFile = File.createTempFile("functionJunit", "request");
325 bw = new BufferedWriter(new FileWriter(tFile));
326 bw.append(reqString);
329 requestContentInAction = DOMRequest.load(tFile);
334 // Test that Bad XML is caught
335 @SuppressWarnings("unused")
336 Request requestContentMisplaced = null;
337 @SuppressWarnings("unused")
338 Request requestMalformedContent = null;
341 // Bad XML - Content not under a Category
342 reqString = reqStrMainStart + reqStrContentMdRecordSimpson + reqStrResourceStart + reqStrResourceEnd + reqStrActionStart + reqStrActionEnd + reqStrMainEnd;
343 tFile = File.createTempFile("functionJunit", "request");
344 bw = new BufferedWriter(new FileWriter(tFile));
345 bw.append(reqString);
349 requestContentMisplaced = DOMRequest.load(tFile);
351 } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
352 // this is what it should do, so just continue
353 } catch (Exception e) {
354 fail("Unexpected exception for bad XML, e="+e);
357 // Bad XML - Content is not valid XML
358 reqString = reqStrMainResourceStart + reqStrMalformedContent + reqStrResourceAllEnd;
359 tFile = File.createTempFile("functionJunit", "request");
360 bw = new BufferedWriter(new FileWriter(tFile));
361 bw.append(reqString);
365 requestMalformedContent = DOMRequest.load(tFile);
367 } catch (com.att.research.xacml.std.dom.DOMStructureException e) {
368 // this is what it should do, so just continue
369 } catch (Exception e) {
370 fail("Unexpected exception for bad XML, e="+e);
373 } catch (Exception e) {
374 fail("Constructor initializing variables, e="+ e + " cause="+e.getCause());
387 public void testAccess_permitted() {
389 ExpressionResult res = null;
390 Boolean resValue = null;
392 FunctionDefinitionAccessPermitted fd = (FunctionDefinitionAccessPermitted) StdFunctions.FD_ACCESS_PERMITTED;
394 // check identity and type of the thing created
395 assertEquals(XACML3.ID_FUNCTION_ACCESS_PERMITTED, fd.getId());
396 assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId());
398 // just to be safe... If tests take too long these can probably be eliminated
399 assertFalse(fd.returnsBag());
403 // successful invoke returns true
405 arguments.add(attrUriResources);
406 arguments.add(attrXEmpty);
407 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
408 assertTrue(res.isOk());
409 resValue = (Boolean)res.getValue().getValue();
410 assertTrue(resValue);
414 // successful invoke returns false
417 // URI not in Request (ok - evaluate anyway)
419 // test for infinite loop
421 // second arg ok both with and without <Content> tag
423 arguments.add(attrUriResources);
424 arguments.add(attrXContentSpringer);
425 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
426 assertTrue(res.isOk());
427 resValue = (Boolean)res.getValue().getValue();
428 assertTrue(resValue);
431 arguments.add(attrUriResources);
432 arguments.add(attrXSpringer);
433 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
434 assertTrue(res.isOk());
435 resValue = (Boolean)res.getValue().getValue();
436 assertTrue(resValue);
438 // second arg not valid XML
440 arguments.add(attrUriResources);
441 arguments.add(attrXBadXML);
442 res = fd.evaluate(null, arguments);
443 assertFalse(res.getStatus().isOk());
444 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());
445 assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
447 // null Evaluation Context
449 arguments.add(attrUriNotCategory);
450 arguments.add(attrXContentSimpson);
451 res = fd.evaluate(null, arguments);
452 assertFalse(res.getStatus().isOk());
453 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());
454 assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
458 arguments.add(attrUriAction);
459 arguments.add(attrXContentSimpson);
460 res = fd.evaluate(new StdEvaluationContext(null, null, null), arguments);
461 assertFalse(res.getStatus().isOk());
462 assertEquals( "function:access-permitted Got null Request in EvaluationContext", res.getStatus().getStatusMessage());
463 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
468 arguments.add(attrUriNotCategory);
469 arguments.add(attrXContentSimpson);
470 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
471 assertFalse(res.getStatus().isOk());
472 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());
473 assertEquals("urn:oasis:names:tc:xacml:1.0:status:syntax-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
475 // first arg not attribute-category urn
477 arguments.add(attrXContentSimpson);
478 arguments.add(attrXContentSimpson);
479 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
480 assertFalse(res.getStatus().isOk());
481 assertEquals( "function:access-permitted Expected data type 'anyURI' saw 'string'", res.getStatus().getStatusMessage());
482 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
484 // second arg not string
486 arguments.add(attrUriAction);
487 arguments.add(attrUriAction);
488 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
489 assertFalse(res.getStatus().isOk());
490 assertEquals( "function:access-permitted Expected data type 'string' saw 'anyURI'", res.getStatus().getStatusMessage());
491 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
496 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
497 assertFalse(res.getStatus().isOk());
498 assertEquals( "function:access-permitted Expected 2 arguments, got 0", res.getStatus().getStatusMessage());
499 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
502 arguments.add(attrXContentSimpson);
503 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
504 assertFalse(res.getStatus().isOk());
505 assertEquals( "function:access-permitted Expected 2 arguments, got 1", res.getStatus().getStatusMessage());
506 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());
511 arguments.add(attrUriEmpty);
512 arguments.add(attrXContentSimpson);
513 arguments.add(attrXContentSimpson);
514 res = fd.evaluate(new StdEvaluationContext(requestMdRecord, null, null), arguments);
515 assertFalse(res.getStatus().isOk());
516 assertEquals( "function:access-permitted Expected 2 arguments, got 3", res.getStatus().getStatusMessage());
517 assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue());