Admin api tests w/ mocked authorization
[music.git] / src / main / java / org / onap / music / authentication / MusicAuthentication.java
1 /*
2  * ============LICENSE_START==========================================
3  * org.onap.music
4  * ===================================================================
5  *  Copyright (c) 2017 AT&T Intellectual Property
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  *
19  * ============LICENSE_END=============================================
20  * ====================================================================
21  */
22
23 package org.onap.music.authentication;
24
25 import java.util.HashMap;
26 import java.util.Map;
27
28 import javax.ws.rs.core.MediaType;
29
30 import org.apache.commons.jcs.access.CacheAccess;
31 import org.onap.music.datastore.PreparedQueryObject;
32 import org.onap.music.eelf.logging.EELFLoggerDelegate;
33 import org.onap.music.eelf.logging.format.AppMessages;
34 import org.onap.music.eelf.logging.format.ErrorSeverity;
35 import org.onap.music.eelf.logging.format.ErrorTypes;
36 import org.onap.music.exceptions.MusicServiceException;
37 import org.onap.music.authentication.MusicAuthenticator.Operation;
38 import org.onap.music.main.MusicCore;
39 import org.onap.music.main.MusicUtil;
40
41 import com.datastax.driver.core.DataType;
42 import com.datastax.driver.core.Row;
43 import com.sun.jersey.api.client.Client;
44 import com.sun.jersey.api.client.ClientResponse;
45 import com.sun.jersey.api.client.WebResource;
46
47 public class MusicAuthentication implements MusicAuthenticator {
48     
49      private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicAuthentication.class);
50     
51     /**
52      * authenticate user logic
53      *
54      * @param nameSpace
55      * @param userId
56      * @param password
57      * @param keyspace
58      * @param aid
59      * @param operation
60      * @return
61      * @throws Exception
62      */
63      @Deprecated
64     public static Map<String, Object> autheticateUser(String nameSpace, String userId,
65                     String password, String keyspace, String aid, String operation) {
66         logger.info(EELFLoggerDelegate.applicationLogger,"Inside User Authentication.......");
67         Map<String, Object> resultMap = new HashMap<>();
68         String uuid = null;
69         if(! MusicUtil.getIsCadi()) {
70             resultMap = CachingUtil.validateRequest(nameSpace, userId, password, keyspace, aid,
71                             operation);
72             if (!resultMap.isEmpty())
73                 return resultMap;
74             String isAAFApp = null;
75             try {
76                 isAAFApp= CachingUtil.isAAFApplication(nameSpace);
77             } catch(MusicServiceException e) {
78                 logger.error(e.getErrorMessage(), e);
79                resultMap.put("Exception", e.getMessage());
80                return resultMap;
81             }
82             if(isAAFApp == null) {
83                 resultMap.put("Exception", "Namespace: "+nameSpace+" doesn't exist. Please make sure ns(appName)"
84                         + " is correct and Application is onboarded.");
85                 return resultMap;
86             }
87             boolean isAAF = Boolean.parseBoolean(isAAFApp);
88             if (userId == null || password == null) {
89                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO  ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
90                 logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: " + userId
91                                 + " :: password: " + password);
92                 resultMap.put("Exception",
93                                 "UserId and Password are mandatory for the operation " + operation);
94                 return resultMap;
95             }
96             if(!isAAF && !(operation.equals("createKeySpace"))) {
97                 resultMap = CachingUtil.authenticateAIDUser(nameSpace, userId, password, keyspace);
98                 if (!resultMap.isEmpty())
99                     return resultMap;
100     
101             }
102             if (isAAF && nameSpace != null && userId != null && password != null) {
103                 boolean isValid = true;
104                 try {
105                      isValid = CachingUtil.authenticateAAFUser(nameSpace, userId, password, keyspace);
106                 } catch (Exception e) {
107                     logger.error(EELFLoggerDelegate.errorLogger,"Error while aaf authentication for user:" + userId);
108                     logger.error(EELFLoggerDelegate.errorLogger,"Error: "+ e.getMessage());
109                     logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.AUTHENTICATIONERROR  ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
110                     logger.error(EELFLoggerDelegate.errorLogger,"Got exception while AAF authentication for namespace " + nameSpace);
111                     resultMap.put("Exception", e.getMessage());
112                 }
113                 if (!isValid) {
114                     logger.error(EELFLoggerDelegate.errorLogger,"User not authenticated...", AppMessages.MISSINGINFO  ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
115                     resultMap.put("Exception", "User not authenticated...");
116                 }
117                 if (!resultMap.isEmpty())
118                     return resultMap;
119     
120             }
121         } else {
122             
123             String cachedKS = CachingUtil.getKSFromCadiCache(userId);
124             if(cachedKS != null && !cachedKS.equals(keyspace)) {
125                 resultMap.put("Exception", "User not authenticated to access this keyspace...");
126             }
127         }
128         
129         if (operation.equals("createKeySpace")) {
130             logger.info(EELFLoggerDelegate.applicationLogger,"AID is not provided. Creating new UUID for keyspace.");
131             PreparedQueryObject pQuery = new PreparedQueryObject();
132             pQuery.appendQueryString(
133                             "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering");
134             try {
135                 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
136                 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
137                 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
138                                 MusicUtil.DEFAULTKEYSPACENAME));
139             } catch (Exception e1) {
140                 logger.error(EELFLoggerDelegate.errorLogger, e1, "Can not authenticate for createkeyspace", AppMessages.MISSINGINFO  ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
141                 resultMap.put("Exception", "Cannot authenticate for createKeyspace");
142                 return resultMap;
143             }
144            
145
146             try {
147                 Row rs = MusicCore.get(pQuery).one();
148                 uuid = rs.getUUID("uuid").toString();
149                 resultMap.put("uuid", "existing");
150             } catch (Exception e) {
151                 logger.error(EELFLoggerDelegate.applicationLogger,"No UUID found in DB. So creating new UUID.");
152                 uuid = MusicUtil.generateUUID();
153                 resultMap.put("uuid", "new");
154             }
155             resultMap.put("aid", uuid);
156             CachingUtil.updateCadiCache(userId, keyspace);
157         }
158         
159         return resultMap;
160     }
161
162     @Override
163     public boolean authenticateAdmin(String authorization) {
164         logger.info(EELFLoggerDelegate.applicationLogger, "MusicCore.authenticateAdmin: ");
165         String userId = MusicUtil.extractBasicAuthentication(authorization).get(MusicUtil.USERID);
166         if(MusicUtil.getIsCadi()) {
167             CachingUtil.updateAdminUserCache(authorization, userId);
168             return true;
169         }
170         CacheAccess<String, String> adminCache = CachingUtil.getAdminUserCache();
171         if (authorization == null) {
172             logger.error(EELFLoggerDelegate.errorLogger, "Authorization cannot be empty...");
173             return false;
174         }
175         if (adminCache.get(authorization) != null && adminCache.get(authorization).equals(userId)) {
176             logger.info(EELFLoggerDelegate.applicationLogger, "MusicCore.authenticateAdmin: Validated against admincache.. ");
177             return true;
178         }
179         else {
180             Client client = Client.create();
181             String aafUrl = MusicUtil.getAafAdminUrl();
182             if (aafUrl==null) {
183                 logger.error(EELFLoggerDelegate.errorLogger, "Admin url is not set, please set in properties");
184                 return false;
185             }
186             
187             WebResource webResource = client.resource(
188                     MusicUtil.getAafAdminUrl().concat(userId).concat("/").concat(MusicUtil.getAdminAafRole()));
189
190             ClientResponse response = webResource.accept(MediaType.APPLICATION_JSON)
191                     .header("Authorization", authorization).get(ClientResponse.class);
192             if (response.getStatus() == 200) {
193                 CachingUtil.updateAdminUserCache(authorization, userId);
194                 return true;
195             }
196         }
197         return false;
198     }
199
200     @Override
201     public boolean authenticateUser(String namespace, String authorization, String keyspace,
202             String aid, Operation operation) {
203         logger.info(EELFLoggerDelegate.applicationLogger,"Inside User Authentication.......");
204         Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization);
205         String userId = userCredentials.get(MusicUtil.USERID);
206         String password = userCredentials.get(MusicUtil.PASSWORD);
207
208         Map<String, Object> resultMap = new HashMap<>();
209         String uuid = null;
210         if(! MusicUtil.getIsCadi()) {
211             resultMap = CachingUtil.validateRequest(namespace, userId, password, keyspace, aid,
212                             operation);
213             if (!resultMap.isEmpty())
214                 return false;
215             String isAAFApp = null;
216             try {
217                 isAAFApp= CachingUtil.isAAFApplication(namespace);
218             } catch(MusicServiceException e) {
219                 logger.error(e.getErrorMessage(), e);
220                resultMap.put("Exception", e.getMessage());
221                return false;
222             }
223             if(isAAFApp == null) {
224                 resultMap.put("Exception", "Namespace: "+namespace+" doesn't exist. Please make sure ns(appName)"
225                         + " is correct and Application is onboarded.");
226                 return false;
227             }
228             boolean isAAF = Boolean.parseBoolean(isAAFApp);
229             if (userId == null || password == null) {
230                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO  ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
231                 logger.error(EELFLoggerDelegate.errorLogger,"UserId/Password or more required headers is missing.");
232                 resultMap.put("Exception",
233                                 "UserId and Password are mandatory for the operation " + operation);
234                 return false;
235             }
236             if(!isAAF && !(operation==Operation.CREATE_KEYSPACE)) {
237                 resultMap = CachingUtil.authenticateAIDUser(namespace, userId, password, keyspace);
238                 if (!resultMap.isEmpty())
239                     return false;
240     
241             }
242             if (isAAF && namespace != null && userId != null && password != null) {
243                 boolean isValid = true;
244                 try {
245                      isValid = CachingUtil.authenticateAAFUser(namespace, userId, password, keyspace);
246                 } catch (Exception e) {
247                     logger.error(EELFLoggerDelegate.errorLogger,"Error while aaf authentication for user:" + userId);
248                     logger.error(EELFLoggerDelegate.errorLogger,"Error: "+ e.getMessage());
249                     logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.AUTHENTICATIONERROR  ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
250                     logger.error(EELFLoggerDelegate.errorLogger,"Got exception while AAF authentication for namespace " + namespace);
251                     resultMap.put("Exception", e.getMessage());
252                 }
253                 if (!isValid) {
254                     logger.error(EELFLoggerDelegate.errorLogger,"User not authenticated...", AppMessages.MISSINGINFO  ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
255                     resultMap.put("Exception", "User not authenticated...");
256                 }
257                 if (!resultMap.isEmpty())
258                     return false;
259     
260             }
261         } else {
262             
263             String cachedKS = CachingUtil.getKSFromCadiCache(userId);
264             if(cachedKS != null && !cachedKS.equals(keyspace)) {
265                 resultMap.put("Exception", "User not authenticated to access this keyspace...");
266                 return false;
267             }
268         }
269         
270         if (operation==Operation.CREATE_KEYSPACE) {
271             try {
272                 logger.info(EELFLoggerDelegate.applicationLogger,"AID is not provided. Creating new UUID for keyspace.");
273                 PreparedQueryObject pQuery = new PreparedQueryObject();
274                 pQuery.appendQueryString(
275                                 "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering");
276                 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), namespace));
277                 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
278                 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
279                                 MusicUtil.DEFAULTKEYSPACENAME));
280                 Row rs = MusicCore.get(pQuery).one();
281                 uuid = rs.getUUID("uuid").toString();
282                 resultMap.put("uuid", "existing");
283             } catch (Exception e) {
284                 logger.error(EELFLoggerDelegate.applicationLogger,"No UUID found in DB. So creating new UUID.");
285                 uuid = MusicUtil.generateUUID();
286                 resultMap.put("uuid", "new");
287             }
288             resultMap.put("aid", uuid);
289             CachingUtil.updateCadiCache(userId, keyspace);
290         }
291         return true;
292     }
293     
294 }