2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2019 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.onap.policy.xacml.std.pip.engines.aaf;
23 import com.att.research.xacml.api.Attribute;
24 import com.att.research.xacml.api.AttributeValue;
25 import com.att.research.xacml.api.Identifier;
26 import com.att.research.xacml.api.XACML3;
27 import com.att.research.xacml.api.pip.PIPException;
28 import com.att.research.xacml.api.pip.PIPFinder;
29 import com.att.research.xacml.api.pip.PIPRequest;
30 import com.att.research.xacml.api.pip.PIPResponse;
31 import com.att.research.xacml.std.IdentifierImpl;
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.StdPIPResponse;
37 import com.att.research.xacml.std.pip.engines.StdConfigurableEngine;
38 import com.att.research.xacml.util.XACMLProperties;
40 import java.io.IOException;
41 import java.util.ArrayList;
42 import java.util.Collection;
43 import java.util.HashMap;
44 import java.util.Iterator;
45 import java.util.List;
47 import java.util.Properties;
49 import org.apache.commons.logging.Log;
50 import org.apache.commons.logging.LogFactory;
51 import org.onap.policy.utils.AAFPolicyClient;
52 import org.onap.policy.utils.AAFPolicyException;
55 * PIP Engine for Implementing {@link com.att.research.xacml.std.pip.engines.ConfigurableEngine} interface to provide
56 * attribute retrieval from AAF interface.
60 public class AAFEngine extends StdConfigurableEngine {
62 public static final String DEFAULT_DESCRIPTION =
63 "PIP for authenticating aaf attributes using the AAF REST interface";
64 public static final String DEFAULT_ISSUER = "aaf";
66 private static final String SUCCESS = "Success";
68 public static final String AAF_RESULT = "AAF_RESULT";
69 public static final String AAF_RESPONSE = "AAF_RESPONSE";
71 public static final Identifier AAF_RESPONSE_ID = new IdentifierImpl(AAF_RESPONSE);
72 public static final Identifier AAF_RESULT_ID = new IdentifierImpl(AAF_RESULT);
75 private static final PIPRequest PIP_REQUEST_UID = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
76 new IdentifierImpl("AAF_ID"), XACML3.ID_DATATYPE_STRING);
77 private static final PIPRequest PIP_REQUEST_PASS = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
78 new IdentifierImpl("AAF_PASS"), XACML3.ID_DATATYPE_STRING);
79 private static final PIPRequest PIP_REQUEST_TYPE = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
80 new IdentifierImpl("AAF_TYPE"), XACML3.ID_DATATYPE_STRING);
81 private static final PIPRequest PIP_REQUEST_INSTANCE = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
82 new IdentifierImpl("AAF_INSTANCE"), XACML3.ID_DATATYPE_STRING);
83 private static final PIPRequest PIP_REQUEST_ACTION = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE,
84 new IdentifierImpl("AAF_ACTION"), XACML3.ID_DATATYPE_STRING);
86 private static final List<PIPRequest> mapRequiredAttributes = new ArrayList<>();
89 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_UID));
90 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_PASS));
91 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_TYPE));
92 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_INSTANCE));
93 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_ACTION));
96 private static final Map<PIPRequest, String> mapSupportedAttributes = new HashMap<>();
99 mapSupportedAttributes.put(
100 new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESPONSE_ID, XACML3.ID_DATATYPE_STRING),
102 mapSupportedAttributes.put(
103 new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESULT_ID, XACML3.ID_DATATYPE_BOOLEAN),
107 protected Log logger = LogFactory.getLog(this.getClass());
110 // default constructor
113 private PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) {
114 PIPResponse pipResponse = null;
116 pipResponse = pipFinder.getMatchingAttributes(pipRequest, this);
117 if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) {
118 this.logger.warn("Error retrieving " + pipRequest.getAttributeId().stringValue() + ": "
119 + pipResponse.getStatus().toString());
122 if (pipResponse != null && pipResponse.getAttributes().isEmpty()) {
123 this.logger.warn("No value for " + pipRequest.getAttributeId().stringValue());
126 } catch (PIPException ex) {
127 this.logger.error("PIPException getting subject-id attribute: " + ex.getMessage(), ex);
132 private String getValue(PIPResponse pipResponse) {
133 String result = null;
134 Collection<Attribute> listAttributes = pipResponse.getAttributes();
135 for (Attribute attribute : listAttributes) {
136 Iterator<AttributeValue<String>> iterAttributeValues = attribute.findValues(DataTypes.DT_STRING);
137 if (iterAttributeValues != null) {
138 while (iterAttributeValues.hasNext()) {
139 result = iterAttributeValues.next().getValue();
147 private synchronized String getResult(PIPFinder pipFinder) {
148 PIPResponse pipResponseUID = this.getAttribute(PIP_REQUEST_UID, pipFinder);
149 PIPResponse pipResponsePass = this.getAttribute(PIP_REQUEST_PASS, pipFinder);
150 PIPResponse pipResponseType = this.getAttribute(PIP_REQUEST_TYPE, pipFinder);
151 PIPResponse pipResponseAction = this.getAttribute(PIP_REQUEST_ACTION, pipFinder);
152 PIPResponse pipResponseInstance = this.getAttribute(PIP_REQUEST_INSTANCE, pipFinder);
153 String response = null;
154 // Evaluate AAF if we have all the required values.
155 if (pipResponseUID != null && pipResponsePass != null && pipResponseType != null && pipResponseAction != null
156 && pipResponseInstance != null) {
157 String userName = getValue(pipResponseUID);
158 String pass = getValue(pipResponsePass);
160 AAFPolicyClient aafClient = null;
161 Properties properties;
163 properties = XACMLProperties.getProperties();
164 logger.debug("environment : " + properties.getProperty("ENVIRONMENT"));
165 } catch (IOException e1) {
166 logger.error("Exception while getting the properties " + e1);
167 properties = new Properties();
168 properties.setProperty("AAF_LOG_LEVEL", "DEBUG");
170 if (userName != null && pass != null) {
172 aafClient = AAFPolicyClient.getInstance(properties);
173 } catch (AAFPolicyException e) {
174 logger.error("AAF configuration failed. " + e.getMessage() + e);
176 if (aafClient != null) {
177 if (aafClient.checkAuth(userName, pass)) {
178 String type = getValue(pipResponseType);
179 String instance = getValue(pipResponseInstance);
180 String action = getValue(pipResponseAction);
181 if (aafClient.checkPerm(userName, pass, type, instance, action)) {
182 response = SUCCESS + "Permissions Validated";
185 "No Permissions for " + userName + " to: " + type + ", " + instance + ", " + action;
188 response = "Authentication Failed for the given Values";
192 response = "ID and Password are not given";
196 response = "Insufficient Values to Evaluate AAF";
201 private void addStringAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId,
204 AttributeValue<String> attributeValue = null;
206 attributeValue = DataTypes.DT_STRING.createAttributeValue(value);
207 } catch (Exception ex) {
208 this.logger.error("Failed to convert " + value + " to an AttributeValue<String>", ex);
210 if (attributeValue != null) {
211 stdPIPResponse.addAttribute(
212 new StdMutableAttribute(category, attributeId, attributeValue, this.getIssuer(), false));
217 private void addBooleanAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId,
219 AttributeValue<Boolean> attributeValue = null;
221 attributeValue = DataTypes.DT_BOOLEAN.createAttributeValue(value);
222 } catch (Exception ex) {
223 this.logger.error("Failed to convert " + value + " to an AttributeValue<Boolean>", ex);
225 if (attributeValue != null) {
226 stdPIPResponse.addAttribute(
227 new StdMutableAttribute(category, attributeId, attributeValue, this.getIssuer(), false));
232 public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException {
234 * First check to see if the issuer is set and then match it
238 if ((string = pipRequest.getIssuer()) != null && !string.equals(this.getIssuer())) {
239 this.logger.debug("Requested issuer '" + string + "' does not match "
240 + (this.getIssuer() == null ? "null" : "'" + this.getIssuer() + "'"));
241 return StdPIPResponse.PIP_RESPONSE_EMPTY;
245 * Drop the issuer and see if the request matches any of our supported queries
247 PIPRequest pipRequestSupported = pipRequest.getIssuer() == null ? pipRequest
248 : new StdPIPRequest(pipRequest.getCategory(), pipRequest.getAttributeId(), pipRequest.getDataTypeId());
249 if (!mapSupportedAttributes.containsKey(pipRequestSupported)) {
250 this.logger.debug("Requested attribute '" + pipRequest.toString() + "' is not supported");
251 return StdPIPResponse.PIP_RESPONSE_EMPTY;
253 StdMutablePIPResponse stdPIPResponse = new StdMutablePIPResponse();
254 String response = this.getResult(pipFinder);
255 boolean result = false;
256 if (response != null && response.contains(SUCCESS)) {
259 this.addBooleanAttribute(stdPIPResponse, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESULT_ID, result);
260 this.addStringAttribute(stdPIPResponse, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESPONSE_ID, response);
261 return new StdPIPResponse(stdPIPResponse);
265 public void configure(String id, Properties properties) throws PIPException {
266 super.configure(id, properties);
267 if (this.getDescription() == null) {
268 this.setDescription(DEFAULT_DESCRIPTION);
270 if (this.getIssuer() == null) {
271 this.setIssuer(DEFAULT_ISSUER);
276 public Collection<PIPRequest> attributesRequired() {
277 List<PIPRequest> attributes = new ArrayList<>();
278 for (PIPRequest attribute : mapRequiredAttributes) {
279 attributes.add(new StdPIPRequest(attribute));
285 public Collection<PIPRequest> attributesProvided() {
286 List<PIPRequest> attributes = new ArrayList<>();
287 for (PIPRequest attribute : mapSupportedAttributes.keySet()) {
288 attributes.add(new StdPIPRequest(attribute));