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=========================================================
20 package org.openecomp.policy.xacml.std.pip.engines.aaf;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
28 import java.util.Properties;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.openecomp.policy.utils.AAFPolicyClient;
33 import org.openecomp.policy.utils.AAFPolicyException;
35 import com.att.research.xacml.api.Attribute;
36 import com.att.research.xacml.api.AttributeValue;
37 import com.att.research.xacml.api.Identifier;
38 import com.att.research.xacml.api.XACML3;
39 import com.att.research.xacml.api.pip.PIPException;
40 import com.att.research.xacml.api.pip.PIPFinder;
41 import com.att.research.xacml.api.pip.PIPRequest;
42 import com.att.research.xacml.api.pip.PIPResponse;
43 import com.att.research.xacml.std.IdentifierImpl;
44 import com.att.research.xacml.std.StdMutableAttribute;
45 import com.att.research.xacml.std.datatypes.DataTypes;
46 import com.att.research.xacml.std.pip.StdMutablePIPResponse;
47 import com.att.research.xacml.std.pip.StdPIPRequest;
48 import com.att.research.xacml.std.pip.StdPIPResponse;
49 import com.att.research.xacml.std.pip.engines.StdConfigurableEngine;
52 * PIP Engine for Implementing {@link com.att.research.xacml.std.pip.engines.ConfigurableEngine} interface to provide
53 * attribute retrieval from AT&T AAF interface.
57 public class AAFEngine extends StdConfigurableEngine {
59 public static final String DEFAULT_DESCRIPTION = "PIP for authenticating aaf attributes using the AT&T AAF REST interface";
60 public static final String DEFAULT_ISSUER = "att-aaf";
62 private static final String SUCCESS = "Success";
64 public static final String AAF_RESULT= "AAF_RESULT";
65 public static final String AAF_RESPONSE= "AAF_RESPONSE";
67 public static final Identifier AAF_RESPONSE_ID = new IdentifierImpl(AAF_RESPONSE);
68 public static final Identifier AAF_RESULT_ID = new IdentifierImpl(AAF_RESULT);
71 private static final PIPRequest PIP_REQUEST_UID = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_ID"), XACML3.ID_DATATYPE_STRING);
72 private static final PIPRequest PIP_REQUEST_PASS = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_PASS"), XACML3.ID_DATATYPE_STRING);
73 private static final PIPRequest PIP_REQUEST_TYPE = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_TYPE"), XACML3.ID_DATATYPE_STRING);
74 private static final PIPRequest PIP_REQUEST_INSTANCE = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_INSTANCE"), XACML3.ID_DATATYPE_STRING);
75 private static final PIPRequest PIP_REQUEST_ACTION = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_ACTION"), XACML3.ID_DATATYPE_STRING);
76 private static final PIPRequest PIP_REQUEST_ENV = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("AAF_ENVIRONMENT"), XACML3.ID_DATATYPE_STRING);
78 private static final List<PIPRequest> mapRequiredAttributes = new ArrayList<PIPRequest>();
80 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_UID));
81 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_PASS));
82 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_TYPE));
83 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_INSTANCE));
84 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_ACTION));
85 mapRequiredAttributes.add(new StdPIPRequest(PIP_REQUEST_ENV));
88 private static final Map<PIPRequest, String> mapSupportedAttributes = new HashMap<PIPRequest, String>();
90 mapSupportedAttributes.put(new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESPONSE_ID, XACML3.ID_DATATYPE_STRING), "response");
91 mapSupportedAttributes.put(new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESULT_ID, XACML3.ID_DATATYPE_BOOLEAN), "result");
94 protected Log logger = LogFactory.getLog(this.getClass());
99 private PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) {
100 PIPResponse pipResponse = null;
102 pipResponse = pipFinder.getMatchingAttributes(pipRequest, this);
103 if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) {
104 this.logger.warn("Error retrieving " + pipRequest.getAttributeId().stringValue() + ": " + pipResponse.getStatus().toString());
107 if (pipResponse.getAttributes().size() == 0) {
108 this.logger.warn("No value for " + pipRequest.getAttributeId().stringValue());
111 } catch (PIPException ex) {
112 this.logger.error("PIPException getting subject-id attribute: " + ex.getMessage(), ex);
117 private String getValue(PIPResponse pipResponse){
118 String result = null;
119 Collection<Attribute> listAttributes = pipResponse.getAttributes();
120 for(Attribute attribute: listAttributes){
121 Iterator<AttributeValue<String>> iterAttributeValues = attribute.findValues(DataTypes.DT_STRING);
122 if(iterAttributeValues!=null) {
123 while(iterAttributeValues.hasNext()){
124 result = iterAttributeValues.next().getValue();
132 private synchronized String getResult(PIPFinder pipFinder) {
133 PIPResponse pipResponseUID = this.getAttribute(PIP_REQUEST_UID, pipFinder);
134 PIPResponse pipResponsePass = this.getAttribute(PIP_REQUEST_PASS, pipFinder);
135 PIPResponse pipResponseType = this.getAttribute(PIP_REQUEST_TYPE, pipFinder);
136 PIPResponse pipResponseAction = this.getAttribute(PIP_REQUEST_ACTION, pipFinder);
137 PIPResponse pipResponseInstance = this.getAttribute(PIP_REQUEST_INSTANCE, pipFinder);
138 PIPResponse pipResponseEnv = this.getAttribute(PIP_REQUEST_ENV, pipFinder);
139 String response = null;
140 // Evaluate AAF if we have all the required values.
141 if(pipResponseUID!=null && pipResponsePass!=null && pipResponseType != null && pipResponseAction!= null && pipResponseInstance!=null && pipResponseEnv!=null){
142 // Check the Environment.
143 String environment = getValue(pipResponseEnv);
144 if(environment == null){
145 response = "Environment Value is not set. ";
147 String userName = getValue(pipResponseUID);
148 String pass = getValue(pipResponsePass);
149 AAFPolicyClient aafClient = null;
150 Properties properties = new Properties();
151 if(environment.equalsIgnoreCase("PROD")){
152 properties.setProperty("ENVIRONMENT", "PROD");
153 }else if(environment.equalsIgnoreCase("TEST")){
154 properties.setProperty("ENVIRONMENT", "TEST");
156 properties.setProperty("ENVIRONMENT", "DEVL");
158 logger.debug("environment : " + environment);
159 if(userName!=null && pass!=null){
161 aafClient = AAFPolicyClient.getInstance(properties);
162 } catch (AAFPolicyException e) {
163 logger.error("AAF configuration failed. " + e.getMessage());
166 if(aafClient.checkAuth(userName, pass)){
167 String type = getValue(pipResponseType);
168 String instance = getValue(pipResponseInstance);
169 String action = getValue(pipResponseAction);
170 if(aafClient.checkPerm(userName, pass, type, instance, action)){
171 response = SUCCESS + "Permissions Validated";
173 response = "No Permissions for "+userName+" to: "+type+", "+instance+", "+action;
176 response = "Authentication Failed for the given Values";
180 response = "ID and Password are not given";
184 response = "Insufficient Values to Evaluate AAF";
189 private void addStringAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, String value) {
191 AttributeValue<String> attributeValue = null;
193 attributeValue = DataTypes.DT_STRING.createAttributeValue(value);
194 } catch (Exception ex) {
195 this.logger.error("Failed to convert " + value + " to an AttributeValue<String>", ex);
197 if (attributeValue != null) {
198 stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, this.getIssuer(), false));
203 private void addBooleanAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, boolean value) {
204 AttributeValue<Boolean> attributeValue = null;
206 attributeValue = DataTypes.DT_BOOLEAN.createAttributeValue(value);
207 } catch (Exception ex) {
208 this.logger.error("Failed to convert " + value + " to an AttributeValue<Boolean>", ex);
210 if (attributeValue != null) {
211 stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, this.getIssuer(), false));
216 public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException {
218 * First check to see if the issuer is set and then match it
221 if ((string = pipRequest.getIssuer()) != null) {
222 if (!string.equals(this.getIssuer())) {
223 this.logger.debug("Requested issuer '" + string + "' does not match " + (this.getIssuer() == null ? "null" : "'" + this.getIssuer() + "'"));
224 return StdPIPResponse.PIP_RESPONSE_EMPTY;
229 * Drop the issuer and see if the request matches any of our supported queries
231 PIPRequest pipRequestSupported = (pipRequest.getIssuer() == null ? pipRequest : new StdPIPRequest(pipRequest.getCategory(), pipRequest.getAttributeId(), pipRequest.getDataTypeId()));
232 if (!mapSupportedAttributes.containsKey(pipRequestSupported)) {
233 this.logger.debug("Requested attribute '" + pipRequest.toString() + "' is not supported");
234 return StdPIPResponse.PIP_RESPONSE_EMPTY;
236 StdMutablePIPResponse stdPIPResponse = new StdMutablePIPResponse();
237 String response = this.getResult(pipFinder);
238 boolean result = false;
239 if(response.contains(SUCCESS)){
242 this.addBooleanAttribute(stdPIPResponse, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESULT_ID, result);
243 this.addStringAttribute(stdPIPResponse, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, AAF_RESPONSE_ID, response);
244 return new StdPIPResponse(stdPIPResponse);
248 public void configure(String id, Properties properties) throws PIPException {
249 super.configure(id, properties);
250 if (this.getDescription() == null) {
251 this.setDescription(DEFAULT_DESCRIPTION);
253 if (this.getIssuer() == null) {
254 this.setIssuer(DEFAULT_ISSUER);
259 public Collection<PIPRequest> attributesRequired() {
260 List<PIPRequest> attributes = new ArrayList<PIPRequest>();
261 for (PIPRequest attribute: mapRequiredAttributes) {
262 attributes.add(new StdPIPRequest(attribute));
268 public Collection<PIPRequest> attributesProvided() {
269 List<PIPRequest> attributes = new ArrayList<PIPRequest>();
270 for (PIPRequest attribute : mapSupportedAttributes.keySet()) {
271 attributes.add(new StdPIPRequest(attribute));