d06321d64e5d8c50c6d22a79cddb30d01247e308
[policy/engine.git] / ONAP-PDP-REST / src / main / java / org / onap / policy / pdp / rest / config / PDPApiAuth.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PDP-REST
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20 package org.onap.policy.pdp.rest.config;
21
22 import java.io.FileInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Base64;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Properties;
35 import java.util.StringTokenizer;
36
37 import org.onap.policy.api.PolicyEngineException;
38 import org.onap.policy.common.logging.eelf.MessageCodes;
39 import org.onap.policy.common.logging.flexlogger.FlexLogger;
40 import org.onap.policy.common.logging.flexlogger.Logger;
41 import org.onap.policy.rest.XACMLRestProperties;
42 import org.onap.policy.utils.AAFPolicyClient;
43 import org.onap.policy.utils.AAFPolicyException;
44 import org.onap.policy.utils.PolicyUtils;
45 import org.onap.policy.xacml.api.XACMLErrorConstants;
46
47 import com.att.research.xacml.util.XACMLProperties;
48
49 public class PDPApiAuth {
50     private static final Logger LOGGER = FlexLogger.getLogger(PDPApiAuth.class);
51
52     private static String environment = null;
53     private static Path clientPath = null;
54     private static Map<String,ArrayList<String>> clientMap = null;
55     private static Long oldModified = null;
56     private static AAFPolicyClient aafClient = null;
57
58     private PDPApiAuth(){
59         // Private Constructor
60     }
61
62     /*
63      * Set Property by reading the properties File.
64      */
65     public static void setProperty() {
66         environment = XACMLProperties.getProperty("ENVIRONMENT", "DEVL");
67         String clientFile = XACMLProperties.getProperty(XACMLRestProperties.PROP_PEP_IDFILE);
68         if(clientFile!=null){
69             clientPath = Paths.get(clientFile);
70         }
71         try {
72             aafClient = AAFPolicyClient.getInstance(XACMLProperties.getProperties());
73         } catch (AAFPolicyException | IOException e) {
74             LOGGER.error(MessageCodes.ERROR_SYSTEM_ERROR, e, "AAF Client Not instantiated properly.");
75         }
76     }
77
78     /*
79      * Return Environment value of the PDP servlet. 
80      */
81     public static String getEnvironment() {
82         if(environment==null){
83             setProperty();
84         }
85         return environment;
86     }
87
88     /*
89      * Security check for authentication and authorizations. 
90      */
91     public static boolean checkPermissions(String clientEncoding, String requestID,
92             String resource) {
93         try{
94             String[] userNamePass = PolicyUtils.decodeBasicEncoding(clientEncoding);
95             if(userNamePass==null || userNamePass.length==0){
96                 String usernameAndPassword = null;
97                 byte[] decodedBytes = Base64.getDecoder().decode(clientEncoding);
98                 usernameAndPassword = new String(decodedBytes, "UTF-8");
99                 StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
100                 String username = tokenizer.nextToken();
101                 String password = tokenizer.nextToken();
102                 userNamePass=  new String[]{username,  password};
103             }
104             LOGGER.info("User " + userNamePass[0] + " is Accessing Policy Engine API.");
105             Boolean result = false;
106             // Check Backward Compatibility. 
107             try{
108                 result = clientAuth(userNamePass);
109             }catch(Exception e){
110                 LOGGER.error(MessageCodes.ERROR_PERMISSIONS, e);
111             }
112             if(!result){
113                 String aafPolicyNameSpace = XACMLProperties.getProperty("policy.aaf.namespace");
114                 String aafResource = XACMLProperties.getProperty("policy.aaf.root.permission");
115                 String type = null;
116                 if(!userNamePass[0].contains("@") && aafPolicyNameSpace!= null){
117                     userNamePass[0] = userNamePass[0] + "@" + reverseNamespace(aafPolicyNameSpace);
118                 }else{
119                     LOGGER.info("No AAF NameSpace specified in properties");
120                 }
121                 if(aafResource != null){
122                     type = aafResource + "." + resource;
123                 }else{
124                     LOGGER.warn("No AAF Resource specified in properties");
125                     return false;
126                 }
127                 LOGGER.info("Contacting AAF in : "  + environment);
128                 result = aafClient.checkAuthPerm(userNamePass[0], userNamePass[1], type, environment, "*");
129             }
130             return result;
131         }catch(Exception e){
132             LOGGER.error(MessageCodes.ERROR_PERMISSIONS, e);
133             return false;
134         }
135     }
136
137     private static Boolean clientAuth(String[] userNamePass){
138         if(clientPath==null){
139             setProperty();
140         }
141         if (!clientPath.toFile().exists()) {
142             return false;
143         }else if(clientPath.toString().endsWith(".properties")) {
144             try {
145                 readProps(clientPath);
146                 if (clientMap.containsKey(userNamePass[0]) && clientMap.get(userNamePass[0]).get(0).equals(userNamePass[1])) {
147                     return true;
148                 }
149             }catch(PolicyEngineException e){
150                 LOGGER.error(MessageCodes.ERROR_PERMISSIONS, e);
151                 return false;
152             }
153         }
154         return false;
155     }
156
157     private static String reverseNamespace(String namespace) {
158         final List<String> components = Arrays.asList(namespace.split("\\."));
159         Collections.reverse(components);   
160         return String.join(".", components);
161     }
162
163     private static Map<String, ArrayList<String>> readProps(Path clientPath) throws PolicyEngineException{
164         if(oldModified!=null){
165             Long newModified = clientPath.toFile().lastModified();
166             if (newModified == oldModified) {
167                 return clientMap;
168             }
169         }
170         InputStream in;
171         Properties clientProp = new Properties();
172         try {
173             in = new FileInputStream(clientPath.toFile());
174             clientProp.load(in);
175         } catch (IOException e) {
176             LOGGER.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR , e);
177             throw new PolicyEngineException(XACMLErrorConstants.ERROR_SYSTEM_ERROR +"Cannot Load the Properties file", e);
178         }
179         // Read the Properties and Load the Clients and their scopes.
180         clientMap = new HashMap<>();
181         // 
182         for (Object propKey : clientProp.keySet()) {
183             String clientID = (String)propKey; 
184             String clientValue = clientProp.getProperty(clientID);
185             if (clientValue != null && clientValue.contains(",")) {
186                 ArrayList<String> clientValues = new ArrayList<>(Arrays.asList(clientValue.split("\\s*,\\s*")));
187                 if(clientValues.get(0)!=null || clientValues.get(1)!=null || clientValues.get(0).isEmpty() || clientValues.get(1).isEmpty()){
188                     clientMap.put(clientID, clientValues);
189                 }
190             }
191         }
192         if (clientMap.isEmpty()) {
193             LOGGER.debug(XACMLErrorConstants.ERROR_PERMISSIONS + "No Clients ID , Client Key and Scopes are available. Cannot serve any Clients !!");
194             throw new PolicyEngineException("Empty Client file");
195         }
196         oldModified = clientPath.toFile().lastModified();
197         return clientMap;
198     }
199 }