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