Misc XACML code coverage
[policy/xacml-pdp.git] / applications / common / src / main / java / org / onap / policy / pdp / xacml / application / common / std / StdOnapPip.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2019-2020 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  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.pdp.xacml.application.common.std;
22
23 import com.att.research.xacml.api.Attribute;
24 import com.att.research.xacml.api.AttributeValue;
25 import com.att.research.xacml.api.DataTypeException;
26 import com.att.research.xacml.api.Identifier;
27 import com.att.research.xacml.api.XACML3;
28 import com.att.research.xacml.api.pip.PIPException;
29 import com.att.research.xacml.api.pip.PIPFinder;
30 import com.att.research.xacml.api.pip.PIPRequest;
31 import com.att.research.xacml.api.pip.PIPResponse;
32 import com.att.research.xacml.std.StdMutableAttribute;
33 import com.att.research.xacml.std.datatypes.DataTypes;
34 import com.att.research.xacml.std.pip.StdMutablePIPResponse;
35 import com.att.research.xacml.std.pip.StdPIPRequest;
36 import com.att.research.xacml.std.pip.engines.StdConfigurableEngine;
37
38 import java.math.BigInteger;
39 import java.util.Base64;
40 import java.util.Collection;
41 import java.util.Collections;
42 import java.util.Iterator;
43 import java.util.Properties;
44
45 import javax.persistence.EntityManager;
46 import javax.persistence.Persistence;
47 import org.onap.policy.pdp.xacml.application.common.ToscaDictionary;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51
52 public abstract class StdOnapPip extends StdConfigurableEngine {
53     protected static Logger logger = LoggerFactory.getLogger(StdOnapPip.class);
54
55     protected static final PIPRequest PIP_REQUEST_ACTOR   = new StdPIPRequest(
56             XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
57             ToscaDictionary.ID_RESOURCE_GUARD_ACTOR,
58             XACML3.ID_DATATYPE_STRING);
59
60     protected static final PIPRequest PIP_REQUEST_RECIPE  = new StdPIPRequest(
61             XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
62             ToscaDictionary.ID_RESOURCE_GUARD_RECIPE,
63             XACML3.ID_DATATYPE_STRING);
64
65     protected static final PIPRequest PIP_REQUEST_TARGET  = new StdPIPRequest(
66             XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
67             ToscaDictionary.ID_RESOURCE_GUARD_TARGETID,
68             XACML3.ID_DATATYPE_STRING);
69
70     protected Properties properties;
71     protected EntityManager em;
72     protected String issuer;
73
74     public StdOnapPip() {
75         super();
76     }
77
78     @Override
79     public Collection<PIPRequest> attributesProvided() {
80         return Collections.emptyList();
81     }
82
83     @Override
84     public void configure(String id, Properties properties) throws PIPException {
85         super.configure(id, properties);
86         logger.info("Configuring historyDb PIP {}", properties);
87         this.properties = properties;
88         //
89         // Create our entity manager
90         //
91         em = null;
92         try {
93             //
94             // In case there are any overloaded properties for the JPA
95             //
96             Properties emProperties = new Properties();
97             emProperties.putAll(properties);
98
99             //
100             // Need to decode the password before creating the EntityManager
101             //
102             String decodedPassword = new String(Base64.getDecoder()
103                     .decode(emProperties.getProperty("javax.persistence.jdbc.password")));
104             emProperties.setProperty("javax.persistence.jdbc.password", decodedPassword);
105
106             //
107             // Create the entity manager factory
108             //
109             em = Persistence.createEntityManagerFactory(
110                     properties.getProperty(this.issuer + ".persistenceunit"),
111                     emProperties).createEntityManager();
112         } catch (Exception e) {
113             logger.error("Persistence failed {} operations history db {}", e.getLocalizedMessage(), e);
114         }
115     }
116
117     protected String getAttribute(PIPFinder pipFinder, PIPRequest pipRequest) {
118         //
119         // Get the actor value
120         //
121         PIPResponse pipResponse = this.getAttribute(pipRequest, pipFinder);
122         if (pipResponse == null) {
123             logger.error("Need actor attribute which is not found");
124             return null;
125         }
126         //
127         // Find the actor
128         //
129         return findFirstAttributeValue(pipResponse);
130     }
131
132     protected PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) {
133         PIPResponse pipResponse = null;
134         try {
135             pipResponse = pipFinder.getMatchingAttributes(pipRequest, this);
136             if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) {
137                 logger.info("get attribute error retrieving {}: {}", pipRequest.getAttributeId(),
138                                 pipResponse.getStatus());
139                 pipResponse = null;
140             }
141             if (pipResponse != null && pipResponse.getAttributes().isEmpty()) {
142                 logger.info("No value for {}", pipRequest.getAttributeId());
143                 pipResponse = null;
144             }
145         } catch (PIPException ex) {
146             logger.error("PIPException getting subject-id attribute: " + ex.getMessage(), ex);
147         }
148         return pipResponse;
149     }
150
151     protected String findFirstAttributeValue(PIPResponse pipResponse) {
152         for (Attribute attribute: pipResponse.getAttributes()) {
153             Iterator<AttributeValue<String>> iterAttributeValues    = attribute.findValues(DataTypes.DT_STRING);
154             while (iterAttributeValues.hasNext()) {
155                 String value   = iterAttributeValues.next().getValue();
156                 if (value != null) {
157                     return value;
158                 }
159             }
160         }
161         return null;
162     }
163
164     protected void addIntegerAttribute(StdMutablePIPResponse stdPipResponse, Identifier category,
165             Identifier attributeId, int value, PIPRequest pipRequest) {
166         AttributeValue<BigInteger> attributeValue   = null;
167         try {
168             attributeValue  = makeInteger(value);
169         } catch (Exception e) {
170             logger.error("Failed to convert {} to integer {}", value, e);
171         }
172         if (attributeValue != null) {
173             stdPipResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue,
174                     pipRequest.getIssuer(), false));
175         }
176     }
177
178     protected void addLongAttribute(StdMutablePIPResponse stdPipResponse, Identifier category,
179             Identifier attributeId, long value, PIPRequest pipRequest) {
180         AttributeValue<BigInteger> attributeValue   = null;
181         try {
182             attributeValue  = makeLong(value);
183         } catch (Exception e) {
184             logger.error("Failed to convert {} to long {}", value, e);
185         }
186         if (attributeValue != null) {
187             stdPipResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue,
188                     pipRequest.getIssuer(), false));
189         }
190     }
191
192     protected void addStringAttribute(StdMutablePIPResponse stdPipResponse, Identifier category, Identifier attributeId,
193             String value, PIPRequest pipRequest) {
194         AttributeValue<String> attributeValue = null;
195         try {
196             attributeValue = makeString(value);
197         } catch (Exception ex) {
198             logger.error("Failed to convert {} to an AttributeValue<String>", value, ex);
199         }
200         if (attributeValue != null) {
201             stdPipResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue,
202                     pipRequest.getIssuer(), false));
203         }
204     }
205
206     // these may be overridden by junit tests
207
208     protected AttributeValue<BigInteger> makeInteger(int value) throws DataTypeException {
209         return DataTypes.DT_INTEGER.createAttributeValue(value);
210     }
211
212     protected AttributeValue<BigInteger> makeLong(long value) throws DataTypeException {
213         return DataTypes.DT_INTEGER.createAttributeValue(value);
214     }
215
216     protected AttributeValue<String> makeString(String value) throws DataTypeException {
217         return DataTypes.DT_STRING.createAttributeValue(value);
218     }
219
220 }