a4b6cc24cd13265d5cecedc7cf7217e388ed55ae
[portal.git] / ecomp-portal-BE-common / src / main / java / org / onap / portalapp / portal / utils / EcompPortalUtils.java
1 /*-
2  * ============LICENSE_START==========================================
3  * ONAP Portal
4  * ===================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ===================================================================
7  *
8  * Unless otherwise specified, all software contained herein is licensed
9  * under the Apache License, Version 2.0 (the "License");
10  * you may not use this software except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *             http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * Unless otherwise specified, all documentation contained herein is licensed
22  * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
23  * you may not use this documentation except in compliance with the License.
24  * You may obtain a copy of the License at
25  *
26  *             https://creativecommons.org/licenses/by/4.0/
27  *
28  * Unless required by applicable law or agreed to in writing, documentation
29  * distributed under the License is distributed on an "AS IS" BASIS,
30  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31  * See the License for the specific language governing permissions and
32  * limitations under the License.
33  *
34  * ============LICENSE_END============================================
35  *
36  * 
37  */
38 package org.onap.portalapp.portal.utils;
39
40 import java.io.IOException;
41 import java.net.InetAddress;
42 import java.net.UnknownHostException;
43 import java.nio.charset.Charset;
44 import java.text.SimpleDateFormat;
45 import java.util.ArrayList;
46 import java.util.Base64;
47 import java.util.Date;
48 import java.util.List;
49
50 import javax.servlet.http.HttpServletResponse;
51 import javax.xml.bind.DatatypeConverter;
52
53 import org.apache.commons.lang.StringUtils;
54 import org.hibernate.Session;
55 import org.hibernate.Transaction;
56 import org.onap.portalapp.portal.domain.EPUser;
57 import org.onap.portalapp.portal.logging.format.EPAppMessagesEnum;
58 import org.onap.portalapp.portal.logging.logic.EPLogUtil;
59 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
60 import org.onap.portalsdk.core.onboarding.util.CipherUtil;
61 import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
62 import org.onap.portalsdk.core.util.SystemProperties;
63 import org.slf4j.MDC;
64 import org.springframework.http.HttpHeaders;
65 import org.springframework.http.MediaType;
66
67 import com.fasterxml.jackson.core.JsonProcessingException;
68 import com.fasterxml.jackson.databind.ObjectMapper;
69
70 public class EcompPortalUtils {
71
72         private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(EcompPortalUtils.class);
73         
74         private static final String FUNCTION_PIPE = "|";
75         
76         // TODO: GLOBAL_LOGIN_URL is the same as in SessionTimeoutInterceptor.
77         // It should be defined in SystemProperties.
78         private static final String GLOBAL_LOGIN_URL = "global-login-url";
79         
80         // It is a regular expression used for while creating a External Central Auth Role 
81         public static final String EXTERNAL_CENTRAL_AUTH_ROLE_HANDLE_SPECIAL_CHARACTERS = "([^A-Z^a-z^0-9^\\.^%^(^)^=^:])";
82         
83         // regex for alphanumeric , dashes and underscore
84                 public static final String SEARCH_USERS_REGEX = "(^[a-zA-Z0-9_-]*$)";
85
86         /**
87          * @param orgUserId
88          *            User ID to validate
89          * @return true if orgUserId is not empty and contains only alphanumeric, false
90          *         otherwise
91          */
92         public static boolean legitimateUserId(String orgUserId) {
93                 return orgUserId.matches("^[a-zA-Z0-9]+$");
94         }
95
96         /**
97          * Splits the string into a list of tokens using the specified regular
98          * expression
99          * 
100          * @param source
101          *            String to split
102          * @param regex
103          *            tokens
104          * @return List of tokens split from the source
105          */
106         public static List<String> parsingByRegularExpression(String source, String regex) {
107                 List<String> tokens = new ArrayList<String>();
108                 if (source != null && source.length() > 0) {
109                         String[] parsed = source.split(regex);
110                         for (String token : parsed) {
111                                 if (token.length() > 0) {
112                                         tokens.add(token);
113                                 }
114                         }
115                 }
116                 return tokens;
117         }
118
119         /**
120          * Builds a JSON object with error code and message information.
121          * 
122          * @param errorCode
123          *            error code
124          * @param errorMessage
125          *            message
126          * @return JSON object as a String
127          */
128         public static String jsonErrorMessageResponse(int errorCode, String errorMessage) {
129                 return "{\"error\":{\"code\":" + errorCode + "," + "\"message\":\"" + errorMessage + "\"}}";
130         }
131
132         /**
133          * Builds a JSON object with the specified message
134          * 
135          * @param message
136          *            Message to embed
137          * @return JSON object as a String
138          */
139         public static String jsonMessageResponse(String message) {
140                 return String.format("{\"message\":\"%s\"}", message);
141         }
142
143         /**
144          * Serializes the specified object as JSON and writes the result to the debug
145          * log. If serialization fails, logs a message to the error logger.
146          * 
147          * @param logger
148          *            Logger for the class where the object was built; the logger
149          *            carries the class name.
150          * @param source
151          *            First portion of the log message
152          * @param msg
153          *            Second portion of the log message
154          * @param obj
155          *            Object to serialize as JSON
156          */
157         public static void logAndSerializeObject(EELFLoggerDelegate logger, String source, String msg, Object obj) {
158                 try {
159                         String objectAsJson = new ObjectMapper().writeValueAsString(obj);
160                         logger.debug(EELFLoggerDelegate.debugLogger,
161                                         String.format("source= [%s]; %s [%s];", source, msg, objectAsJson));
162                 } catch (JsonProcessingException e) {
163                         logger.warn(EELFLoggerDelegate.errorLogger, "logAndSerializedObject failed to serialize", e);
164                         EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeInvalidJsonInput, e);
165                 } catch (Exception e) {
166                         logger.error(EELFLoggerDelegate.errorLogger, "logAndSerializedObject failed", e);
167                         EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeInvalidJsonInput, e);
168                 }
169         }
170
171         /**
172          * Serializes the specified object as JSON and writes the result to the debug
173          * log. If serialization fails, logs a message to the error logger.
174          * 
175          * @param source
176          *            First portion of the log message
177          * @param msg
178          *            Second portion of the log message
179          * @param obj
180          *            Object to serialize as JSON
181          */
182         public static void logAndSerializeObject(String source, String msg, Object obj) {
183                 logAndSerializeObject(logger, source, msg, obj);
184         }
185
186         public static void rollbackTransaction(Transaction transaction, String errorMessage) {
187                 logger.error(EELFLoggerDelegate.errorLogger, errorMessage);
188                 try {
189                         if (transaction != null) {
190                                 transaction.rollback();
191                         }
192                 } catch (Exception e) {
193                         EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeExecuteRollbackError, e);
194                         logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while performing a rollback transaction",
195                                         e);
196                 }
197         }
198
199         public static void closeLocalSession(Session localSession, String errorMessage) {
200                 logger.error(EELFLoggerDelegate.errorLogger, errorMessage);
201                 try {
202                         if (localSession != null) {
203                                 localSession.close();
204                         }
205                 } catch (Exception e) {
206                         EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoCloseSessionError, e);
207                         logger.error(EELFLoggerDelegate.errorLogger, errorMessage + ", closeLocalSession exception", e);
208                 }
209         }
210
211         /**
212          * Set response status to Unauthorized if user == null and to Forbidden in all
213          * (!) other cases. Logging is not performed if invocator == null
214          * 
215          * @param user
216          *            User object
217          * @param response
218          *            HttpServletResponse
219          * @param invocator
220          *            may be null
221          */
222         public static void setBadPermissions(EPUser user, HttpServletResponse response, String invocator) {
223                 if (user == null) {
224                         String loginUrl = SystemProperties.getProperty(EPCommonSystemProperties.LOGIN_URL_NO_RET_VAL);
225                         response.setHeader(GLOBAL_LOGIN_URL, loginUrl);
226                         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
227                         MDC.put(EPCommonSystemProperties.RESPONSE_CODE, Integer.toString(HttpServletResponse.SC_UNAUTHORIZED));
228                 } else {
229                         response.setStatus(HttpServletResponse.SC_FORBIDDEN);
230                         MDC.put(EPCommonSystemProperties.RESPONSE_CODE, Integer.toString(HttpServletResponse.SC_FORBIDDEN));
231                 }
232                 if (invocator != null) {
233                         logger.warn(EELFLoggerDelegate.errorLogger,
234                                         invocator + ", permissions problem, response status = " + response.getStatus());
235                 }
236         }
237
238         public static int getExternalAppResponseCode() {
239                 String responseCode = MDC.get(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE);
240                 int responseCodeInt = 0;
241                 try {
242                         if (responseCode != null && responseCode != "") {
243                                 responseCodeInt = Integer.valueOf(responseCode);
244                         }
245                 } catch (Exception e) {
246                         logger.error(EELFLoggerDelegate.errorLogger, "getExternalAppResponseCode failed", e);
247                 }
248                 return responseCodeInt;
249         }
250
251         // This method might be just for testing purposes.
252         public static void setExternalAppResponseCode(int responseCode) {
253                 try {
254                         String code = String.valueOf(responseCode);
255                         MDC.put(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE,code );
256                         code=StringUtils.EMPTY;
257                 } catch (Exception e) {
258                         logger.error(EELFLoggerDelegate.errorLogger, "setExternalAppResponseCode failed", e);
259                 }
260         }
261
262         public static String getHTTPStatusString(int httpStatusCode) {
263                 String httpStatusString = "unknown_error";
264                 try {
265                         httpStatusString = org.springframework.http.HttpStatus.valueOf(httpStatusCode).name();
266                         if (httpStatusString != null) {
267                                 httpStatusString = httpStatusString.toLowerCase();
268                         }
269                 } catch (Exception e) {
270                         logger.error(EELFLoggerDelegate.errorLogger, "getHTTPStatusString failed", e);
271                 }
272                 return httpStatusString;
273         }
274
275         public static String getFEErrorString(Boolean internal, int responseCode) {
276                 // Return a String like the following:
277                 // "Internal Onap Error: 500 internal_server_error" or
278                 // "External App Error: 404 not_found"
279                 // TODO: create our own Ecomp error codes, starting with 1000 and up.
280                 String internalExternalString = internal ? "Ecomp Error: " : "App Error: ";
281                 String httpStatusString = "unknown_error";
282                 try {
283                         if (responseCode < 1000) {
284                                 httpStatusString = getHTTPStatusString(responseCode);
285                         }
286                 } catch (Exception e) {
287                         logger.error(EELFLoggerDelegate.errorLogger, "getFEErrorString failed", e);
288                 }
289                 String responseString = internalExternalString + responseCode + " " + httpStatusString;
290                 return responseString;
291         }
292
293         public static boolean isProductionBuild() {
294                 boolean productionBuild = true;
295                 String epVersion = EcompVersion.buildNumber;
296                 if (epVersion != null) {
297                         int buildNum = epVersion.lastIndexOf('.');
298                         if (buildNum > 0) {
299                                 int buildNumber = Integer.parseInt(epVersion.substring(buildNum + 1));
300                                 if (buildNumber < 3000) // Production versions are 3000+, (ie
301                                                                                 // 1.0.3003)
302                                 {
303                                         productionBuild = false;
304                                 }
305                         }
306                 }
307                 return productionBuild;
308         }
309
310         public static String getMyIpAdddress() {
311                 InetAddress ip;
312                 String localIp;
313                 try {
314                         ip = InetAddress.getLocalHost();
315                         localIp = ip.getHostAddress();
316                 } catch (UnknownHostException e) {
317                         localIp = "unknown";
318                         logger.error(EELFLoggerDelegate.errorLogger, "getMyIpAdddress failed ", e);
319                 }
320                 return localIp;
321         }
322
323         public static String getMyHostName() {
324                 InetAddress ip;
325                 String hostName;
326                 try {
327                         ip = InetAddress.getLocalHost();
328                         hostName = ip.getHostName();
329                 } catch (UnknownHostException e) {
330                         hostName = "unknown";
331                         logger.error(EELFLoggerDelegate.errorLogger, "getMyHostName failed", e);
332                 }
333                 return hostName;
334         }
335
336         /**
337          * Returns a default property if the expected one is not available
338          * 
339          * @param property
340          *            Key
341          * @param defaultValue
342          *            default Value
343          * @return Default value if property is not defined or yields the empty string;
344          *         else the property value.
345          */
346         public static String getPropertyOrDefault(String property, String defaultValue) {
347                 if (!SystemProperties.containsProperty(property))
348                         return defaultValue;
349                 String value = SystemProperties.getProperty(property);
350                 if (value == null || "".equals(value))
351                         return defaultValue;
352                 return value;
353         }
354
355         /**
356          * Calculates the time duration of a function call for logging purpose. It
357          * stores the result by using "MDC.put(SystemProperties.MDC_TIMER,
358          * timeDifference);" It is important to call
359          * "MDC.remove(SystemProperties.MDC_TIMER);" after this method call to clean up
360          * the record in MDC
361          *
362          * @param beginDateTime
363          *            the given begin time for the call
364          * @param endDateTime
365          *            the given end time for the call
366          * 
367          */
368         public static void calculateDateTimeDifferenceForLog(String beginDateTime, String endDateTime) {
369                 if (beginDateTime != null && endDateTime != null) {
370                         try {
371                                 SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
372
373                                 Date beginDate = ecompLogDateFormat.parse(beginDateTime);
374                                 Date endDate = ecompLogDateFormat.parse(endDateTime);
375                                 String timeDifference = String.format("%d", endDate.getTime() - beginDate.getTime());
376                                 MDC.put(SystemProperties.MDC_TIMER, timeDifference);
377                         } catch (Exception e) {
378                                 logger.error(EELFLoggerDelegate.errorLogger, "calculateDateTimeDifferenceForLog failed", e);
379                         }
380                 }
381         }
382
383         /**
384          * Answers the protocol to use.
385          * 
386          * @return Protocol name from property file; defaults to https.
387          */
388         public static String widgetMsProtocol() {
389                 return getPropertyOrDefault(EPCommonSystemProperties.WIDGET_MS_PROTOCOL, "https");
390         }
391
392         /**
393          * Answers the host to use.
394          * 
395          * @return Host name from property file; defaults to localhost.
396          */
397         public static String localOrDockerHost() {
398                 return getPropertyOrDefault(EPCommonSystemProperties.WIDGET_MS_HOSTNAME, "localhost");
399         }
400
401         /**
402          * It returns headers where username and password of external central auth is
403          * encoded to base64
404          * 
405          * @return header which contains external central auth username and password
406          *         base64 encoded
407          * @throws Exception
408          *             if unable to decrypt the password
409          */
410         public static HttpHeaders base64encodeKeyForAAFBasicAuth() throws Exception {
411                 String userName = "";
412                 String decryptedPass = "";
413                 if (EPCommonSystemProperties.containsProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_AUTH_USER_NAME)
414                                 && EPCommonSystemProperties.containsProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_AUTH_PASSWORD)) {
415                         decryptedPass = SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_AUTH_PASSWORD);
416                         userName = SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_AUTH_USER_NAME);
417                 }
418                 String decPass = decrypted(decryptedPass);
419                 String usernamePass = userName + ":" + decPass;
420                 String encToBase64 = String.valueOf((DatatypeConverter.printBase64Binary(usernamePass.getBytes())));
421                 HttpHeaders headers = new HttpHeaders();
422                 headers.add("Authorization", "Basic " + encToBase64);
423                 headers.setContentType(MediaType.APPLICATION_JSON);
424                 return headers;
425         }
426
427         private static String decrypted(String encrypted) throws Exception {
428                 String result = "";
429                 if (encrypted != null && encrypted.length() > 0) {
430                         try {
431                                 result = CipherUtil.decryptPKC(encrypted, SystemProperties.getProperty(SystemProperties.Decryption_Key));
432                         } catch (Exception e) {
433                                 logger.error(EELFLoggerDelegate.errorLogger, "decryptedPassword failed", e);
434                                 throw e;
435                         }
436                 }
437                 return result;
438         }
439
440         public static String truncateString(String originString, int size){
441                 if(originString.length()>=size){
442                         StringBuilder stringBuilder = new StringBuilder();
443                         stringBuilder.append(originString);
444                         stringBuilder.setLength(size);
445                         stringBuilder.append("...");
446                         return stringBuilder.toString();
447                 }
448                 return originString;
449         }
450         
451         /**
452          * 
453          * If function code value has any pipes it does pipe filter and 
454          * returns value.
455          * 
456          * @param functionCode
457          * @return function instance without pipe
458          */
459         public static String getFunctionCode(String functionCode) {
460                 String finalFunctionCodeVal = "";
461                 if (functionCode.contains(FUNCTION_PIPE)) {
462                         int count = StringUtils.countMatches(functionCode, FUNCTION_PIPE);
463                         if (count == 2)
464                                 finalFunctionCodeVal = functionCode.substring(
465                                                 functionCode.indexOf(FUNCTION_PIPE) + 1,
466                                                 functionCode.lastIndexOf(FUNCTION_PIPE));
467                         else
468                                 finalFunctionCodeVal = functionCode
469                                                 .substring(functionCode.lastIndexOf(FUNCTION_PIPE) + 1);
470                 } else{
471                         finalFunctionCodeVal = functionCode;
472                 }
473                 return finalFunctionCodeVal;
474         }
475         
476         /**
477          * 
478          * If function code value has any pipes it does pipe filter and 
479          * returns value.
480          * 
481          * @param functionCode
482          * @return function Type without pipe
483          */
484         public static String getFunctionType(String functionCode) {
485                 String finalFunctionCodeVal = "";
486                 if (functionCode.contains(FUNCTION_PIPE)) {
487                         int count = StringUtils.countMatches(functionCode, FUNCTION_PIPE);
488                         if (count == 2){
489                                 String[] getTypeValue = functionCode.split("\\"+FUNCTION_PIPE);         
490                                 finalFunctionCodeVal = getTypeValue[0];
491                         }
492                 } else{
493                         finalFunctionCodeVal = functionCode;
494                 }
495                 return finalFunctionCodeVal;
496         }
497         
498         /**
499          * 
500          * If function code value has any pipes it does pipe filter and 
501          * returns value.
502          * 
503          * @param functionCode
504          * @return function Action without pipe
505          */
506         public static String getFunctionAction(String functionCode) {
507                 String finalFunctionCodeVal = "";
508                 if (functionCode.contains(FUNCTION_PIPE)) {
509                         int count = StringUtils.countMatches(functionCode, FUNCTION_PIPE);
510                         if (count == 2)
511                                 finalFunctionCodeVal = functionCode.substring(
512                                                 functionCode.lastIndexOf(FUNCTION_PIPE)+1);
513                 } else{
514                         finalFunctionCodeVal = functionCode;
515                 }
516                 return finalFunctionCodeVal;
517         }
518         
519         /**
520          * 
521          * It check whether the external auth namespace is matching with current namespace exists in local DB
522          * 
523          * @param permTypeVal
524          * @param appNamespaceVal
525          * @return true or false
526          */
527         public static boolean checkNameSpaceMatching(String permTypeVal, String appNamespaceVal) {
528                 String[] typeNamespace = permTypeVal.split("\\.");
529                 String[] appNamespace = appNamespaceVal.split("\\.");
530                 boolean isNamespaceMatching = true;
531                 if (appNamespace.length <= typeNamespace.length) {
532                         for (int k = 0; k < appNamespace.length; k++) {
533                                 if (!appNamespace[k].equals(typeNamespace[k]))
534                                         isNamespaceMatching = false;
535                         }
536                 } else {
537                         isNamespaceMatching = false;
538                 }
539                 return isNamespaceMatching;
540         }
541         
542         public static boolean checkIfRemoteCentralAccessAllowed() {
543                 boolean result = false;
544                 String rmtCentralAccess = SystemProperties.getProperty(EPCommonSystemProperties.REMOTE_CENTRALISED_SYSTEM_ACCESS);
545                 if(rmtCentralAccess == null) {
546                 logger.error(EELFLoggerDelegate.errorLogger, "Please check in system.properties whether the property exists or not!");
547                         return false;
548                 }else if(new Boolean(rmtCentralAccess)){
549                 logger.debug(EELFLoggerDelegate.debugLogger, "checkIfRemoteCentralAccessAllowed: {}",rmtCentralAccess);
550                         result = true;
551                 }
552                 return result;
553         }
554         
555         /**
556          * 
557          * It validates whether given string is JSON or not
558          * 
559          * @param jsonInString
560          * @return true or false
561          */
562           public static boolean isJSONValid(String jsonInString ) {
563                     try {
564                        final ObjectMapper mapper = new ObjectMapper();
565                        mapper.readTree(jsonInString);
566                        return true;
567                     } catch (IOException e) {
568                         logger.error(EELFLoggerDelegate.errorLogger, "Failed to parse Json!", e);
569                        return false;
570                     }
571                   }
572           /**
573            * 
574            *  It retrieves account information from input String
575            * 
576            * @param authValue
577            * @return Array of Account information
578            * 
579            */
580           public static String[] getUserNamePassword(String authValue) {
581                         String base64Credentials = authValue.substring("Basic".length()).trim();
582                         String credentials = new String(Base64.getDecoder().decode(base64Credentials), Charset.forName("UTF-8"));
583                         final String[] values = credentials.split(":", 2);
584                         return values;
585                 }
586 }