3d9effe500f57d372e884dea4542a44e1c57a6d6
[policy/xacml-pdp.git] / tutorials / tutorial-xacml-application / src / main / java / org / onap / policy / tutorial / tutorial / TutorialTranslator.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  * ============LICENSE_END=========================================================
17  */
18
19 package org.onap.policy.tutorial.tutorial;
20
21 import com.att.research.xacml.api.DataTypeException;
22 import com.att.research.xacml.api.Decision;
23 import com.att.research.xacml.api.Identifier;
24 import com.att.research.xacml.api.Request;
25 import com.att.research.xacml.api.Response;
26 import com.att.research.xacml.api.Result;
27 import com.att.research.xacml.api.XACML3;
28 import com.att.research.xacml.std.IdentifierImpl;
29 import com.att.research.xacml.std.annotations.RequestParser;
30 import java.util.List;
31 import java.util.Map;
32 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
33 import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
34 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
35 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
36 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
37 import org.onap.policy.models.decisions.concepts.DecisionRequest;
38 import org.onap.policy.models.decisions.concepts.DecisionResponse;
39 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
40 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
41 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
42 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslator;
43 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyTranslatorUtils;
44
45 public class TutorialTranslator implements ToscaPolicyTranslator {
46
47     private static final Identifier ID_TUTORIAL_USER = new IdentifierImpl(ToscaDictionary.ID_URN_ONAP, "tutorial-user");
48     private static final Identifier ID_TUTORIAL_ENTITY =
49             new IdentifierImpl(ToscaDictionary.ID_URN_ONAP, "tutorial-entity");
50     private static final Identifier ID_TUTORIAL_PERM =
51             new IdentifierImpl(ToscaDictionary.ID_URN_ONAP, "tutorial-permission");
52
53     /**
54      * Convert Policy from TOSCA to XACML.
55      */
56     @SuppressWarnings("unchecked")
57     public PolicyType convertPolicy(ToscaPolicy toscaPolicy) throws ToscaPolicyConversionException {
58         //
59         // Here is our policy with a version and default combining algo
60         //
61         var newPolicyType = new PolicyType();
62         newPolicyType.setPolicyId(toscaPolicy.getMetadata().get("policy-id"));
63         newPolicyType.setVersion(toscaPolicy.getMetadata().get("policy-version"));
64         //
65         // When choosing the rule combining algorithm, be sure to be mindful of the
66         // setting xacml.att.policyFinderFactory.combineRootPolicies in the
67         // xacml.properties file. As that choice for ALL the policies together may have
68         // an impact on the decision rendered from each individual policy.
69         //
70         // In this case, we will only produce XACML rules for permissions. If no permission
71         // combo exists, then the default is to deny.
72         //
73         newPolicyType.setRuleCombiningAlgId(XACML3.ID_RULE_DENY_UNLESS_PERMIT.stringValue());
74         //
75         // Create the target for the Policy.
76         //
77         // For simplicity, let's just match on the action "authorize" and the user
78         //
79         var matchAction = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
80                 XACML3.ID_FUNCTION_STRING_EQUAL, "authorize", XACML3.ID_DATATYPE_STRING,
81                 XACML3.ID_ACTION_ACTION_ID, XACML3.ID_ATTRIBUTE_CATEGORY_ACTION);
82         Map<String, Object> props = toscaPolicy.getProperties();
83         var user = props.get("user").toString();
84         var matchUser = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(XACML3.ID_FUNCTION_STRING_EQUAL, user,
85                 XACML3.ID_DATATYPE_STRING, ID_TUTORIAL_USER, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
86         var anyOf = new AnyOfType();
87         //
88         // Create AllOf (AND) of just Policy Id
89         //
90         anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(matchAction, matchUser));
91         var target = new TargetType();
92         target.getAnyOf().add(anyOf);
93         newPolicyType.setTarget(target);
94         //
95         // Now add the rule for each permission
96         //
97         var ruleNumber = 0;
98         List<Object> permissions = (List<Object>) props.get("permissions");
99         for (Object permission : permissions) {
100
101             var matchEntity = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(XACML3.ID_FUNCTION_STRING_EQUAL,
102                     ((Map<String, String>) permission).get("entity"), XACML3.ID_DATATYPE_STRING, ID_TUTORIAL_ENTITY,
103                     XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
104
105             var matchPermission = ToscaPolicyTranslatorUtils.buildMatchTypeDesignator(
106                     XACML3.ID_FUNCTION_STRING_EQUAL, ((Map<String, String>) permission).get("permission"),
107                     XACML3.ID_DATATYPE_STRING, ID_TUTORIAL_PERM, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE);
108             anyOf = new AnyOfType();
109             anyOf.getAllOf().add(ToscaPolicyTranslatorUtils.buildAllOf(matchEntity, matchPermission));
110             target = new TargetType();
111             target.getAnyOf().add(anyOf);
112
113             var rule = new RuleType();
114             rule.setDescription("Default is to PERMIT if the policy matches.");
115             rule.setRuleId(newPolicyType.getPolicyId() + ":rule" + ruleNumber);
116
117             rule.setEffect(EffectType.PERMIT);
118             rule.setTarget(target);
119
120             newPolicyType.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
121
122             ruleNumber++;
123         }
124         return newPolicyType;
125     }
126
127     /**
128      * Convert ONAP DecisionRequest to XACML Request.
129      */
130     public Request convertRequest(DecisionRequest request) {
131         try {
132             return RequestParser.parseRequest(TutorialRequest.createRequest(request));
133         } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
134             // Empty
135         }
136         return null;
137     }
138
139     /**
140      * Convert XACML Response to ONAP DecisionResponse.
141      */
142     public DecisionResponse convertResponse(Response xacmlResponse) {
143         var decisionResponse = new DecisionResponse();
144         //
145         // Iterate through all the results
146         //
147         for (Result xacmlResult : xacmlResponse.getResults()) {
148             //
149             // Check the result
150             //
151             if (xacmlResult.getDecision() == Decision.PERMIT) {
152                 //
153                 // Just simply return a Permit response
154                 //
155                 decisionResponse.setStatus(Decision.PERMIT.toString());
156             } else {
157                 //
158                 // Just simply return a Deny response
159                 //
160                 decisionResponse.setStatus(Decision.DENY.toString());
161             }
162         }
163
164         return decisionResponse;
165     }
166
167 }