From e21f8e6b83642c2731f8401dc43434dffe93dc26 Mon Sep 17 00:00:00 2001 From: Yuli Shlosberg Date: Thu, 14 Nov 2019 15:25:32 +0200 Subject: add security-util-lib to Onap This lib provides security layer filters and mainly used in sdc project. It base on third party projects e.g. Cadi and Portal Issue-ID: SDC-2656 Signed-off-by: Yuli Shlosberg Change-Id: Iae1a78f0960386e9bdc0994fbac09a24e041cb54 --- .gitignore | 1 + pom.xml | 8 +- security-util-lib/pom.xml | 161 +++++ .../onap/sdc/security/AuthenticationCookie.java | 106 ++++ .../sdc/security/AuthenticationCookieUtils.java | 137 +++++ .../java/org/onap/sdc/security/CipherUtil.java | 142 +++++ .../org/onap/sdc/security/CipherUtilException.java | 64 ++ .../onap/sdc/security/IPortalConfiguration.java | 47 ++ .../ISessionValidationCookieConfiguration.java | 32 + .../ISessionValidationFilterConfiguration.java | 32 + .../onap/sdc/security/IUsersThreadLocalHolder.java | 27 + .../main/java/org/onap/sdc/security/Passwords.java | 190 ++++++ .../java/org/onap/sdc/security/PortalClient.java | 220 +++++++ .../org/onap/sdc/security/RedirectException.java | 46 ++ .../org/onap/sdc/security/RepresentationUtils.java | 76 +++ .../security/RestrictionAccessFilterException.java | 28 + .../java/org/onap/sdc/security/SecurityUtil.java | 153 +++++ .../filters/FilterServletOutputStream.java | 58 ++ .../onap/sdc/security/filters/ResponceWrapper.java | 73 +++ .../security/filters/RestrictionAccessFilter.java | 194 ++++++ .../onap/sdc/security/filters/SampleFilter.java | 175 ++++++ .../security/filters/SessionValidationFilter.java | 217 +++++++ .../security/logging/api/ILogConfiguration.java | 47 ++ .../security/logging/api/ILogFieldsHandler.java | 188 ++++++ .../org/onap/sdc/security/logging/api/ILogger.java | 42 ++ .../logging/elements/ErrorLogOptionalData.java | 70 +++ .../logging/elements/FunctionalInterfaces.java | 597 ++++++++++++++++++ .../security/logging/elements/HttpResponse.java | 68 +++ .../logging/elements/LogFieldsMdcHandler.java | 533 ++++++++++++++++ .../sdc/security/logging/elements/LoggerAudit.java | 196 ++++++ .../sdc/security/logging/elements/LoggerBase.java | 230 +++++++ .../sdc/security/logging/elements/LoggerDebug.java | 76 +++ .../sdc/security/logging/elements/LoggerError.java | 163 +++++ .../security/logging/elements/LoggerFactory.java | 77 +++ .../security/logging/elements/LoggerMetric.java | 234 +++++++ .../logging/elements/LoggerSupportability.java | 101 +++ .../security/logging/enums/EcompErrorSevirity.java | 24 + .../logging/enums/EcompHeadersConstants.java | 35 ++ .../logging/enums/EcompLoggerErrorCode.java | 64 ++ .../onap/sdc/security/logging/enums/LogLevel.java | 30 + .../sdc/security/logging/enums/LogMarkers.java | 39 ++ .../logging/enums/LoggerSupportabilityActions.java | 85 +++ .../onap/sdc/security/logging/enums/Severity.java | 40 ++ .../sdc/security/logging/enums/StatusCode.java | 38 ++ .../onap/sdc/security/logging/wrappers/Logger.java | 676 +++++++++++++++++++++ .../security/logging/wrappers/LoggerSdcAudit.java | 167 +++++ .../logging/wrappers/LoggerSdcMetrics.java | 59 ++ .../logging/wrappers/LoggerSdcUtilBase.java | 210 +++++++ .../org/onap/sdc/security/utils/RestUtils.java | 68 +++ .../onap/sdc/security/utils/SecurityLogsUtils.java | 31 + .../src/main/resources/key.properties | 41 ++ .../security/AuthenticationCookieUtilsTest.java | 75 +++ .../java/org/onap/sdc/security/CipherUtilTest.java | 76 +++ .../java/org/onap/sdc/security/PasswordsTest.java | 97 +++ .../onap/sdc/security/RepresentationUtilsTest.java | 54 ++ .../java/org/onap/sdc/security/RestUtilsTest.java | 60 ++ .../org/onap/sdc/security/SecurityUtilTest.java | 50 ++ .../filters/RestrictionAccessFilterTest.java | 207 +++++++ .../filters/SessionValidationFilterTest.java | 237 ++++++++ 59 files changed, 7271 insertions(+), 1 deletion(-) create mode 100644 security-util-lib/pom.xml create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/AuthenticationCookie.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/AuthenticationCookieUtils.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/CipherUtil.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/CipherUtilException.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/IPortalConfiguration.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/ISessionValidationCookieConfiguration.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/ISessionValidationFilterConfiguration.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/IUsersThreadLocalHolder.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/Passwords.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/PortalClient.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/RedirectException.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/RepresentationUtils.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/RestrictionAccessFilterException.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/SecurityUtil.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/filters/FilterServletOutputStream.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/filters/ResponceWrapper.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/filters/RestrictionAccessFilter.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/filters/SampleFilter.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/filters/SessionValidationFilter.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogConfiguration.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogFieldsHandler.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogger.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/ErrorLogOptionalData.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/FunctionalInterfaces.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/HttpResponse.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LogFieldsMdcHandler.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerAudit.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerBase.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerDebug.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerError.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerFactory.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerMetric.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerSupportability.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompErrorSevirity.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompHeadersConstants.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompLoggerErrorCode.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LogLevel.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LogMarkers.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LoggerSupportabilityActions.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/Severity.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/StatusCode.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/Logger.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcAudit.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcMetrics.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcUtilBase.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/utils/RestUtils.java create mode 100644 security-util-lib/src/main/java/org/onap/sdc/security/utils/SecurityLogsUtils.java create mode 100644 security-util-lib/src/main/resources/key.properties create mode 100644 security-util-lib/src/test/java/org/onap/sdc/security/AuthenticationCookieUtilsTest.java create mode 100644 security-util-lib/src/test/java/org/onap/sdc/security/CipherUtilTest.java create mode 100644 security-util-lib/src/test/java/org/onap/sdc/security/PasswordsTest.java create mode 100644 security-util-lib/src/test/java/org/onap/sdc/security/RepresentationUtilsTest.java create mode 100644 security-util-lib/src/test/java/org/onap/sdc/security/RestUtilsTest.java create mode 100644 security-util-lib/src/test/java/org/onap/sdc/security/SecurityUtilTest.java create mode 100644 security-util-lib/src/test/java/org/onap/sdc/security/filters/RestrictionAccessFilterTest.java create mode 100644 security-util-lib/src/test/java/org/onap/sdc/security/filters/SessionValidationFilterTest.java diff --git a/.gitignore b/.gitignore index 64189eb..df2f954 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ debug-logs/ *.log .idea/ *.iml +*.orig diff --git a/pom.xml b/pom.xml index a035ccb..6baf07b 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,7 @@ UTF-8 2.23.4 4.12 + 1.5.0 2.17 snapshots releases @@ -54,6 +55,7 @@ session-lib zusammen-lib versioning-lib + security-util-lib @@ -75,6 +77,11 @@ + + org.onap.logging-analytics + logging-slf4j + ${logging-slf4j.version} + org.springframework.boot spring-boot-starter @@ -159,4 +166,3 @@ - diff --git a/security-util-lib/pom.xml b/security-util-lib/pom.xml new file mode 100644 index 0000000..5f96522 --- /dev/null +++ b/security-util-lib/pom.xml @@ -0,0 +1,161 @@ + + + + security-util-lib + security-util-lib + + org.onap.sdc.sdc-be-common + sdc-be-common-parent + 1.0.0-SNAPSHOT + + + 4.0.0 + security util library + + + + ${project.basedir}/target/jacoco.exec + + + 2.5.0 + 3.3.2 + 18.0 + 4.5.3 + 2.27 + 1.1 + 4.7 + + + ${project.build.sourceEncoding} + true + ${project.basedir} + . + **/scripts/**/* + **/test/**/*,**/tests/**/* + app/**/*.js,server-mock/**/*.js,src/**/*.js,src/main/**/*.java + ${project.version} + + + + + + + org.functionaljava + functionaljava + ${functionaljava.version} + + + + + org.onap.portal.sdk + epsdk-fw + ${portal.version} + compile + + + com.att.nsa + cambriaClient + + + slf4j-log4j12 + org.slf4j + + + powermock-api-mockito + org.powermock + + + org.onap.aaf.authz + aaf-cadi-aaf + + + aaf-cadi-core + org.onap.aaf.authz + + + commons-codec + commons-codec + + + + + + org.apache.commons + commons-lang3 + ${lang3.version} + compile + + + + com.google.guava + guava + ${guava.version} + compile + + + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + compile + + + org.glassfish.jersey.ext + jersey-bean-validation + ${jersey-bom.version} + + + com.googlecode.json-simple + json-simple + ${json-simple.version} + + + org.projectlombok + lombok + + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.8 + + + + prepare-agent + + prepare-agent + + + ${sonar.jacoco.reportPath} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + ${argLine} -Xmx2048m + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + + org.sonarsource.scanner.maven + sonar-maven-plugin + 3.0.2 + + + + diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/AuthenticationCookie.java b/security-util-lib/src/main/java/org/onap/sdc/security/AuthenticationCookie.java new file mode 100644 index 0000000..9440eea --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/AuthenticationCookie.java @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import java.util.Set; +import lombok.Getter; +import lombok.Setter; + +public class AuthenticationCookie { + + @Getter @Setter + private String userID; + @Getter @Setter + private String firstName; + @Getter @Setter + private String lastName; + @Getter @Setter + private Set roles; + @Getter @Setter + private long maxSessionTime; + @Getter @Setter + private long currentSessionTime; + + private AuthenticationCookie() { + } + + public AuthenticationCookie(AuthenticationCookie authenticationCookie){ + this.userID = authenticationCookie.userID; + this.firstName = authenticationCookie.firstName; + this.lastName = authenticationCookie.lastName; + this.roles = authenticationCookie.roles; + this.maxSessionTime = authenticationCookie.maxSessionTime; + this.currentSessionTime = authenticationCookie.currentSessionTime; + } + + /** + * Create new cookie with max_session_time and current_session_time started with same value + * @param userId + */ + public AuthenticationCookie(String userId) { + this.userID =userId; + long currentTimeMilliSec = System.currentTimeMillis(); + this.maxSessionTime = currentTimeMilliSec; + this.currentSessionTime = currentTimeMilliSec; + } + + /** + * Create new cookie with max_session_time and current_session_time started with same value + * @param userId + */ + public AuthenticationCookie(String userId, String firstName, String lastName) { + this(userId); + this.firstName = firstName; + this.lastName = lastName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AuthenticationCookie)) return false; + + AuthenticationCookie that = (AuthenticationCookie) o; + + if (getMaxSessionTime() != that.getMaxSessionTime()) return false; + if (getCurrentSessionTime() != that.getCurrentSessionTime()) return false; + if (getUserID() != null ? !getUserID().equals(that.getUserID()) : that.getUserID() != null) return false; + return getRoles() != null ? getRoles().containsAll(that.getRoles()) : that.getRoles() == null; + } + + @Override + public int hashCode() { + int result = getUserID() != null ? getUserID().hashCode() : 0; + result = 31 * result + (getRoles() != null ? getRoles().hashCode() : 0); + result = 31 * result + (int) (getMaxSessionTime() ^ (getMaxSessionTime() >>> 32)); + result = 31 * result + (int) (getCurrentSessionTime() ^ (getCurrentSessionTime() >>> 32)); + return result; + } + + @Override + public String toString() { + return "AuthenticationCookie{" + + "userID='" + userID + '\'' + + ", roles=" + roles + + ", maxSessionTime=" + maxSessionTime + + ", currentSessionTime=" + currentSessionTime + + '}'; + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/AuthenticationCookieUtils.java b/security-util-lib/src/main/java/org/onap/sdc/security/AuthenticationCookieUtils.java new file mode 100644 index 0000000..7cb1907 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/AuthenticationCookieUtils.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security; + +import org.onap.sdc.security.filters.SessionValidationFilter; +import org.onap.sdc.security.logging.wrappers.Logger; + +import javax.servlet.http.Cookie; +import java.io.IOException; + +public class AuthenticationCookieUtils { + + private static final Logger log = Logger.getLogger(SessionValidationFilter.class.getName()); + + /** + * Update given cookie session time value to current time + * + * @param cookie + * @param filterConfiguration + * @return + * @throws CipherUtilException + * @throws IOException + */ + public static Cookie updateSessionTime(Cookie cookie, ISessionValidationFilterConfiguration filterConfiguration) throws CipherUtilException, IOException { + AuthenticationCookie authenticationCookie = getAuthenticationCookie(cookie, filterConfiguration); + long newTime = System.currentTimeMillis(); + log.debug("SessionValidationFilter: Going to set new session time in cookie, old value: {}, new value: {}", authenticationCookie.getCurrentSessionTime(), newTime); + authenticationCookie.setCurrentSessionTime(newTime); + String encryptedCookie = getEncryptedCookie(authenticationCookie, filterConfiguration); + return createUpdatedCookie(cookie, encryptedCookie, filterConfiguration); + } + + /** + * Create new Cookie object with same attributes as original cookie + * @param cookie + * @param encryptedCookie + * @param cookieConfiguration + * @return + */ + public static Cookie createUpdatedCookie(Cookie cookie, String encryptedCookie, ISessionValidationCookieConfiguration cookieConfiguration) { + Cookie updatedCookie = new Cookie(cookie.getName(), encryptedCookie ); + updatedCookie.setPath(cookieConfiguration.getCookiePath()); + updatedCookie.setDomain(cookieConfiguration.getCookieDomain()); + updatedCookie.setHttpOnly(cookieConfiguration.isCookieHttpOnly()); + return updatedCookie; + } + + /** + * Convert AuthenticationCookie to JSON and encrypt with given key + * + * @param authenticationCookie + * @param filterConfiguration + * @return + * @throws IOException + * @throws CipherUtilException + */ + public static String getEncryptedCookie(AuthenticationCookie authenticationCookie, ISessionValidationFilterConfiguration filterConfiguration) throws IOException, CipherUtilException { + String changedCookieJson = RepresentationUtils.toRepresentation(authenticationCookie); + return CipherUtil.encryptPKC(changedCookieJson, filterConfiguration.getSecurityKey()); + } + + /** + * Decrypt given Cookie to JSON and convert to AuthenticationCookie object + * + * @param cookie + * @return + * @throws CipherUtilException + */ + public static AuthenticationCookie getAuthenticationCookie(Cookie cookie, ISessionValidationFilterConfiguration filterConfiguration) throws CipherUtilException { + String originalCookieJson = CipherUtil.decryptPKC(cookie.getValue(), filterConfiguration.getSecurityKey()); + return RepresentationUtils.fromRepresentation(originalCookieJson, AuthenticationCookie.class); + } + + /** + * session expired if session was idle or max time reached + * + * @param cookie + * @param filterConfiguration + * @return + * @throws CipherUtilException + */ + public static boolean isSessionExpired(Cookie cookie, ISessionValidationFilterConfiguration filterConfiguration) throws CipherUtilException { + AuthenticationCookie authenticationCookie = getAuthenticationCookie(cookie, filterConfiguration); + return isSessionExpired(authenticationCookie, filterConfiguration); + } + + /** + * session expired if session was idle or max time reached + * + * @param authenticationCookie + * @param filterConfiguration + * @return + */ + public static boolean isSessionExpired(AuthenticationCookie authenticationCookie, ISessionValidationFilterConfiguration filterConfiguration) { + long sessionExpirationDate = authenticationCookie.getMaxSessionTime() + filterConfiguration.getMaxSessionTimeOut(); + long sessionTime = authenticationCookie.getCurrentSessionTime(); + long currentTime = System.currentTimeMillis(); + log.debug("SessionValidationFilter: Checking if session expired: session time: {}, expiration time: {}, current time: {}", sessionTime, sessionExpirationDate, currentTime); + return currentTime > sessionExpirationDate || isSessionIdle(sessionTime, currentTime, filterConfiguration); + } + + + + /** + * Session is idle if wasn't updated ( wasn't in use ) for more then value from filter configuration + * + * @param sessionTimeValue + * @param currentTime + * @param filterConfiguration + * @return + */ + private static boolean isSessionIdle(long sessionTimeValue, long currentTime, ISessionValidationFilterConfiguration filterConfiguration) { + long currentIdleTime = currentTime - sessionTimeValue; + long maxIdleTime = filterConfiguration.getSessionIdleTimeOut(); + log.debug("SessionValidationFilter: Checking if session idle: session time: {}, current idle time: {}, max idle time: {}", currentTime, currentIdleTime, maxIdleTime); + return currentIdleTime >= maxIdleTime; + } + + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/CipherUtil.java b/security-util-lib/src/main/java/org/onap/sdc/security/CipherUtil.java new file mode 100644 index 0000000..a51d3ff --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/CipherUtil.java @@ -0,0 +1,142 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import java.security.SecureRandom; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.ArrayUtils; +import org.onap.sdc.security.logging.elements.ErrorLogOptionalData; +import org.onap.sdc.security.logging.elements.LogFieldsMdcHandler; +import org.onap.sdc.security.logging.enums.EcompLoggerErrorCode; +import org.onap.sdc.security.logging.wrappers.Logger; + +public class CipherUtil { + private static Logger log = Logger.getLogger( CipherUtil.class.getName()); + private static final String ALGORITHM = "AES"; + private static final String ALGORYTHM_DETAILS = ALGORITHM + "/CBC/PKCS5PADDING"; + private static final String CIPHER_PROVIDER = "SunJCE"; + private static final int BLOCK_SIZE = 128; + private static final int BYTE_SIZE = 8; + private static final int IV_SIZE = BLOCK_SIZE / BYTE_SIZE; + private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + private static final String ALGORITHM_NAME = "SHA1PRNG"; + + /** + * Encrypt the text using the secret key in key.properties file + * + * @param value string to encrypt + * @return The encrypted string + * @throws CipherUtilException + * In case of issue with the encryption + */ + public static String encryptPKC(String value, String base64key) throws CipherUtilException { + Cipher cipher; + byte[] iv = new byte[IV_SIZE]; + byte[] finalByte; + try { + cipher = Cipher.getInstance(ALGORYTHM_DETAILS, CIPHER_PROVIDER); + SecureRandom secureRandom = SecureRandom.getInstance(ALGORITHM_NAME); + secureRandom.nextBytes(iv); + IvParameterSpec ivspec = new IvParameterSpec(iv); + cipher.init(Cipher.ENCRYPT_MODE, getSecretKeySpec(base64key), ivspec); + finalByte = cipher.doFinal(value.getBytes()); + + } catch (Exception ex) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), new ErrorLogOptionalData(), "encrypt failed", ex); + throw new CipherUtilException(ex); + } + return Base64.encodeBase64String(addAll(iv, finalByte)); + } + + /** + * Decrypts the text using the secret key in key.properties file. + * + * @param message + * The encrypted string that must be decrypted using the ONAP Portal + * Encryption Key + * @return The String decrypted + * @throws CipherUtilException + * if any decryption step fails + */ + + public static String decryptPKC(String message, String base64key) throws CipherUtilException { + byte[] encryptedMessage = Base64.decodeBase64(message); + Cipher cipher; + byte[] decrypted; + try { + cipher = Cipher.getInstance(ALGORYTHM_DETAILS, CIPHER_PROVIDER); + IvParameterSpec ivspec = new IvParameterSpec(subarray(encryptedMessage, 0, IV_SIZE)); + byte[] realData = subarray(encryptedMessage, IV_SIZE, encryptedMessage.length); + cipher.init(Cipher.DECRYPT_MODE, getSecretKeySpec(base64key), ivspec); + decrypted = cipher.doFinal(realData); + + } catch (Exception ex) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), new ErrorLogOptionalData(),"decrypt failed", ex); + throw new CipherUtilException(ex); + } + return new String(decrypted); + } + + private static SecretKeySpec getSecretKeySpec(String keyString) { + byte[] key = Base64.decodeBase64(keyString); + return new SecretKeySpec(key, ALGORITHM); + } + + private static byte[] addAll(byte[] array1, byte[] array2) { + if (array1 == null) { + return ArrayUtils.clone(array2); + } else if (array2 == null) { + return ArrayUtils.clone(array1); + } else { + byte[] joinedArray = new byte[array1.length + array2.length]; + System.arraycopy(array1, 0, joinedArray, 0, array1.length); + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + return joinedArray; + } + } + + private static byte[] subarray(byte[] array, int startIndexInclusive, int endIndexExclusive) { + if (array == null) { + return null; + } else { + if (startIndexInclusive < 0) { + startIndexInclusive = 0; + } + + if (endIndexExclusive > array.length) { + endIndexExclusive = array.length; + } + + int newSize = endIndexExclusive - startIndexInclusive; + if (newSize <= 0) { + return EMPTY_BYTE_ARRAY; + } else { + byte[] subarray = new byte[newSize]; + System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); + return subarray; + } + } + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/CipherUtilException.java b/security-util-lib/src/main/java/org/onap/sdc/security/CipherUtilException.java new file mode 100644 index 0000000..254e862 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/CipherUtilException.java @@ -0,0 +1,64 @@ +package org.onap.sdc.security; + + + /* ============LICENSE_START========================================== + * ONAP Portal SDK + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================ + * + * + */ + +@SuppressWarnings("serial") +public class CipherUtilException extends Exception { + + public CipherUtilException() { + super(); + } + + public CipherUtilException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public CipherUtilException(String message, Throwable cause) { + super(message, cause); + } + + public CipherUtilException(String message) { + super(message); + } + + public CipherUtilException(Throwable cause) { + super(cause); + } + +} \ No newline at end of file diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/IPortalConfiguration.java b/security-util-lib/src/main/java/org/onap/sdc/security/IPortalConfiguration.java new file mode 100644 index 0000000..d9e2c43 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/IPortalConfiguration.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security; + +/** + * Configuration for Cookie object , have to be same over all components of application + */ +public interface IPortalConfiguration { + + String getPortalApiPrefix(); + long getMaxIdleTime(); + String getUserAttributeName(); + boolean IsUseRestForFunctionalMenu(); + String getPortalApiImplClass(); + String getRoleAccessCentralized(); + boolean getUebListenersEnable(); + String getEcompRedirectUrl(); + String getEcompRestUrl(); + String getPortalUser(); + String getPortalPass(); + String getPortalAppName(); + String getUebAppKey(); + String getAafNamespace(); + + String getAuthNamespace(); + String getCspCookieName(); + String getCspGateKeeperProdKey(); + String getExtReqConnectionTimeout(); + String getExtReqReadTimeout(); +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/ISessionValidationCookieConfiguration.java b/security-util-lib/src/main/java/org/onap/sdc/security/ISessionValidationCookieConfiguration.java new file mode 100644 index 0000000..f1fb949 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/ISessionValidationCookieConfiguration.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +/** + * Configuration for Cookie object , have to be same over all components of application + */ +public interface ISessionValidationCookieConfiguration { + + String getCookieName(); + String getCookieDomain(); + String getCookiePath(); + boolean isCookieHttpOnly(); +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/ISessionValidationFilterConfiguration.java b/security-util-lib/src/main/java/org/onap/sdc/security/ISessionValidationFilterConfiguration.java new file mode 100644 index 0000000..0ce71eb --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/ISessionValidationFilterConfiguration.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import java.util.List; + +public interface ISessionValidationFilterConfiguration extends ISessionValidationCookieConfiguration { + String getSecurityKey(); + long getMaxSessionTimeOut(); + long getSessionIdleTimeOut(); // max idle time for session + String getRedirectURL(); + List getExcludedUrls(); // comma separated URLs, like this "/config,/configmgr,/rest,/kibanaProxy" +} + diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/IUsersThreadLocalHolder.java b/security-util-lib/src/main/java/org/onap/sdc/security/IUsersThreadLocalHolder.java new file mode 100644 index 0000000..4b61356 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/IUsersThreadLocalHolder.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +public interface IUsersThreadLocalHolder { + + public void setUserContext(AuthenticationCookie authenticationCookie); + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/Passwords.java b/security-util-lib/src/main/java/org/onap/sdc/security/Passwords.java new file mode 100644 index 0000000..2cbd993 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/Passwords.java @@ -0,0 +1,190 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import org.apache.commons.codec.DecoderException; +import org.onap.sdc.security.logging.elements.ErrorLogOptionalData; +import org.onap.sdc.security.logging.elements.LogFieldsMdcHandler; +import org.onap.sdc.security.logging.enums.EcompLoggerErrorCode; +import org.onap.sdc.security.logging.wrappers.Logger; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Arrays; + +import static org.apache.commons.codec.binary.Hex.decodeHex; + +public class Passwords { + + private static Logger log = Logger.getLogger( Passwords.class.getName()); + private static final int SALT = 0; + private static final int HASH = 1; + private static final String HASH_ALGORITHM = "SHA-256"; + + /** + * static utility class + */ + private Passwords() { + } + + /** + * the method calculates a hash with a generated salt for the given password + * + * @param password + * @return a "salt:hash" value + */ + public static String hashPassword(String password) { + if (password!=null){ + byte[] salt = getNextSalt(); + byte byteData[] = hash(salt, password.getBytes()); + if (byteData != null) { + return toHex(salt) + ":" + toHex(byteData); + } + } + return null; + } + + /** + * the method checks if the given password matches the calculated hash + * + * @param password + * @param expectedHash + * @return + */ + public static boolean isExpectedPassword(String password, String expectedHash) { + if (password==null && expectedHash==null) + return true; + if (password==null || expectedHash==null) //iff exactly 1 is null + return false; + if (!expectedHash.contains(":")){ + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), new ErrorLogOptionalData(),"invalid password expecting hash at the prefix of the password (ex. e0277df331f4ff8f74752ac4a8fbe03b:6dfbad308cdf53c9ff2ee2dca811ee92f1b359586b33027580e2ff92578edbd0)\n" + + "\t\t\t"); + return false; + } + String[] params = expectedHash.split(":"); + return isExpectedPassword(password, params[SALT], params[HASH]); + } + + /** + * the method checks if the given password matches the calculated hash + * + * @param password + * @param salt + * @param hash + * the hash generated using the salt + * @return true if the password matched the hash + */ + public static boolean isExpectedPassword(String password, String salt, String hash) { + if ( password == null && hash == null ) + return true; + if ( salt == null ){ + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), new ErrorLogOptionalData(),"salt must be initialized"); + return false; + } + //unintialized params + if ( password == null || hash == null ) + return false; + byte[] saltBytes = fromHex(salt); + byte[] hashBytes = fromHex(hash); + + byte byteData[] = hash(saltBytes, password.getBytes()); + if (byteData != null) { + return Arrays.equals(byteData, hashBytes); + } + return false; + } + + public static void main(String[] args) { + if (args.length > 1 || args.length > 0) { + System.out.println("[" + hashPassword(args[0]) + "]"); + } else { + System.out.println("no passward passed."); + } + + } + + /** + * Returns a random salt to be used to hash a password. + * + * @return a 16 bytes random salt + */ + private static byte[] getNextSalt() { + byte[] salt = new byte[16]; + new SecureRandom().nextBytes(salt); + return salt; + } + + /** + * hase's the salt and value using the chosen algorithm + * + * @param salt + * @param password + * @return an array of bytes resulting from the hash + */ + private static byte[] hash(byte[] salt, byte[] password) { + MessageDigest md; + byte[] byteData = null; + try { + md = MessageDigest.getInstance(HASH_ALGORITHM); + md.update(salt); + md.update(password); + byteData = md.digest(); + } catch (NoSuchAlgorithmException e) { + System.out.println("invalid algorithm name"); + } + return byteData; + } + + /** + * Converts a string of hexadecimal characters into a byte array. + * + * @param hex + * the hex string + * @return the hex string decoded into a byte array + */ + private static byte[] fromHex(String hex) { + if ( hex == null ) + return null; + byte[] binary = new byte[hex.length() / 2]; + for (int i = 0; i < binary.length; i++) { + binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16); + } + return binary; + } + + /** + * Converts a byte array into a hexadecimal string. + * + * @param array + * the byte array to convert + * @return a length*2 character string encoding the byte array + */ + private static String toHex(byte[] array) { + BigInteger bi = new BigInteger(1, array); + String hex = bi.toString(16); + int paddingLength = (array.length * 2) - hex.length(); + if (paddingLength > 0) + return String.format("%0" + paddingLength + "d", 0) + hex; + else + return hex; + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/PortalClient.java b/security-util-lib/src/main/java/org/onap/sdc/security/PortalClient.java new file mode 100644 index 0000000..bba8da9 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/PortalClient.java @@ -0,0 +1,220 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import com.google.common.annotations.VisibleForTesting; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; +import org.onap.portalsdk.core.onboarding.exception.PortalAPIException; +import org.onap.portalsdk.core.onboarding.util.PortalApiProperties; +import org.onap.portalsdk.core.restful.domain.EcompUser; +import org.onap.sdc.security.logging.elements.LogFieldsMdcHandler; +import org.onap.sdc.security.logging.enums.EcompLoggerErrorCode; +import org.onap.sdc.security.logging.wrappers.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import java.io.IOException; +import java.security.InvalidParameterException; +import java.util.Base64; +import static org.onap.portalsdk.core.onboarding.util.CipherUtil.decryptPKC; +import static org.onap.sdc.security.utils.SecurityLogsUtils.PORTAL_TARGET_ENTITY; +import static org.onap.sdc.security.utils.SecurityLogsUtils.fullOptionalData; + + +@Component/*("portalUtils")*/ +public class PortalClient { + + private static final Logger log = Logger.getLogger(PortalClient.class.getName()); + private final CloseableHttpClient httpClient; + private static final String GET_ROLES_PORTAL_URL = "/v4/user/%s"; + private static final String UEB_KEY = "uebkey"; + private static final String AUTHORIZATION = "Authorization"; + private static final String CONTENT_TYPE_HEADER = "Content-Type"; + private final PortalConfiguration portalConfiguration; + private static final String RECEIVED_NULL_ROLES = "Received null roles for user"; + private static final String RECEIVED_MULTIPLE_ROLES = "Received multiple roles for user {}"; + private static final String RECEIVED_MULTIPLE_ROLES2 = "Received multiple roles for user"; + +/* @Autowired + public PortalClient(CloseableHttpClient httpClient) { + try { + this.portalConfiguration = new PortalConfiguration(); + } catch (org.onap.portalsdk.core.onboarding.exception.CipherUtilException e) { + throw new RestrictionAccessFilterException(e); + } + this.httpClient = httpClient; + }*/ + + @Autowired + public PortalClient(CloseableHttpClient httpClient, IPortalConfiguration portalConfiguration) { + try { + this.portalConfiguration = new PortalConfiguration(portalConfiguration); + } catch (org.onap.portalsdk.core.onboarding.exception.CipherUtilException e) { + throw new RestrictionAccessFilterException(e); + } + this.httpClient = httpClient; + } + + public String fetchUserRolesFromPortal(String userId) { + String fetchedUserRoleFromPortal; + try { + EcompUser ecompUser = extractObjectFromResponseJson(getResponseFromPortal(userId)); + log.debug("GET USER ROLES response for user {}: {}", userId, ecompUser); + checkIfSingleRoleProvided(ecompUser); + fetchedUserRoleFromPortal = ecompUser.getRoles().stream().findFirst().get().getName(); + } catch (IOException | PortalAPIException e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), + fullOptionalData(PORTAL_TARGET_ENTITY, "/fetchRolesFromPortal"),"GET USER ROLES from portal failed: {}", e.getMessage()); + log.debug("Fetching user roles from Portal failed", e); + throw new RestrictionAccessFilterException(e); + } + return fetchedUserRoleFromPortal; + } + + + + public static void checkIfSingleRoleProvided(EcompUser user) throws PortalAPIException { + if(user.getRoles() == null) { + log.debug(RECEIVED_NULL_ROLES, user); + //BeEcompErrorManager.getInstance().logInvalidInputError(CHECK_ROLES, RECEIVED_NULL_ROLES, BeEcompErrorManager.ErrorSeverity.ERROR); + throw new PortalAPIException(RECEIVED_NULL_ROLES + user); + }else if(user.getRoles().size() > 1) { + log.debug(RECEIVED_MULTIPLE_ROLES, user); + //BeEcompErrorManager.getInstance().logInvalidInputError(CHECK_ROLES, RECEIVED_MULTIPLE_ROLES2, BeEcompErrorManager.ErrorSeverity.ERROR); + throw new PortalAPIException(RECEIVED_MULTIPLE_ROLES2 + user); + } + } + + private String getResponseFromPortal(String userId) throws IOException { + HttpGet httpGet = createHttpGetRequest(userId); + CloseableHttpResponse httpResponse = this.httpClient.execute(httpGet); + //Json extraction is handled inside this function due to IO Stream issues. + JSONObject jsonFromResponse = (JSONObject) JSONValue.parse(EntityUtils.toString(httpResponse.getEntity())); + httpResponse.close(); + return jsonFromResponse.toString(); + } + + private EcompUser extractObjectFromResponseJson(String jsonFromResponse) { + return RepresentationUtils.fromRepresentation(jsonFromResponse, EcompUser.class); + } + + private HttpGet createHttpGetRequest(String userId) { + final String url = String.format(portalConfiguration.getEcompPortalRestURL() + GET_ROLES_PORTAL_URL, userId); + log.debug("Going to execute an http get to the following URL: {}", url); + + HttpGet httpGet = new HttpGet(url); + String encodedBasicAuthCred = Base64.getEncoder() + .encodeToString((portalConfiguration.getDecryptedPortalUser() + ":" + + portalConfiguration.getDecryptedPortalPassword()) + .getBytes()); + httpGet.setHeader(UEB_KEY, portalConfiguration.getUebKey()); + httpGet.setHeader(AUTHORIZATION, "Basic " + encodedBasicAuthCred); + httpGet.setHeader(CONTENT_TYPE_HEADER, "application/json"); + return httpGet; + } + + private static class PortalConfiguration { + private static final String PROPERTY_NOT_SET = "%s property value is not set in portal.properties file"; + private String decryptedPortalUser; + private String decryptedPortalPassword; + private String ecompPortalRestURL; + private String decryptedPortalAppName; + private String uebKey; + + private PortalConfiguration() throws org.onap.portalsdk.core.onboarding.exception.CipherUtilException { + this.decryptedPortalUser = decryptPKC(getPortalProperty(PortalPropertiesEnum.USER.value())); + this.decryptedPortalPassword = decryptPKC(getPortalProperty(PortalPropertiesEnum.PASSWORD.value())); + this.decryptedPortalAppName = decryptPKC(getPortalProperty(PortalPropertiesEnum.APP_NAME.value())); + this.ecompPortalRestURL = getPortalProperty(PortalPropertiesEnum.ECOMP_REST_URL.value()); + this.uebKey = getPortalProperty(PortalPropertiesEnum.UEB_APP_KEY.value()); + + } + + private PortalConfiguration(IPortalConfiguration portalConfiguration) throws org.onap.portalsdk.core.onboarding.exception.CipherUtilException { + this.decryptedPortalUser = decryptPKC(portalConfiguration.getPortalUser()); + this.decryptedPortalPassword = decryptPKC(portalConfiguration.getPortalPass()); + this.decryptedPortalAppName = decryptPKC(portalConfiguration.getPortalAppName()); + this.ecompPortalRestURL = portalConfiguration.getEcompRestUrl(); + this.uebKey = portalConfiguration.getUebAppKey(); + + } + + public static String getPropertyNotSet() { + return PROPERTY_NOT_SET; + } + + public String getDecryptedPortalUser() { + return decryptedPortalUser; + } + + public String getDecryptedPortalPassword() { + return decryptedPortalPassword; + } + + public String getEcompPortalRestURL() { + return ecompPortalRestURL; + } + + public String getDecryptedPortalAppName() { + return decryptedPortalAppName; + } + + public String getUebKey() { + return uebKey; + } + + @VisibleForTesting + String getPortalProperty(String key) { + String value = PortalApiProperties.getProperty(key); + if (StringUtils.isEmpty(value)) { + throw new InvalidParameterException(String.format(PROPERTY_NOT_SET, key)); + } + return value; + } + + } + + public enum PortalPropertiesEnum { + APP_NAME("portal_app_name"), + ECOMP_REST_URL("ecomp_rest_url"), + PASSWORD("portal_pass"), + UEB_APP_KEY("ueb_app_key"), + USER("portal_user"); + + private final String value; + + PortalPropertiesEnum(String value) { + this.value = value; + } + + public String value() { + return value; + } + } + +} + + diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/RedirectException.java b/security-util-lib/src/main/java/org/onap/sdc/security/RedirectException.java new file mode 100644 index 0000000..f2edb92 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/RedirectException.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +/** + * This exception should be thrown when redirection needed in filter flow + */ +public class RedirectException extends Exception { + + public RedirectException() { + } + + public RedirectException(String message) { + super(message); + } + + public RedirectException(String message, Throwable cause) { + super(message, cause); + } + + public RedirectException(Throwable cause) { + super(cause); + } + + public RedirectException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/RepresentationUtils.java b/security-util-lib/src/main/java/org/onap/sdc/security/RepresentationUtils.java new file mode 100644 index 0000000..af0dcc6 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/RepresentationUtils.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import org.onap.sdc.security.logging.elements.ErrorLogOptionalData; +import org.onap.sdc.security.logging.elements.LogFieldsMdcHandler; +import org.onap.sdc.security.logging.enums.EcompLoggerErrorCode; +import org.onap.sdc.security.logging.wrappers.Logger; + +import java.io.IOException; + +public class RepresentationUtils { + + private static final Logger log = Logger.getLogger(RepresentationUtils.class.getName()); + + /** + * Build JSON Representation of given Object + * + * @param elementToRepresent + * @return + * @throws IOException + */ + public static String toRepresentation(T elementToRepresent) throws IOException { + + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + return mapper.writeValueAsString(elementToRepresent); + } + + /** + * Convert JSON representation to given class + * + * @param json + * @param clazz + * @param + * @return + */ + public static T fromRepresentation(String json, Class clazz) { + ObjectMapper mapper = new ObjectMapper(); + T object = null; + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + try { + object = mapper.readValue(json, clazz); + } catch (Exception e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(),new ErrorLogOptionalData(), + "Error when parsing JSON of object of type {}", clazz.getSimpleName(), e); + } // return null in case of exception + + return object; + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/RestrictionAccessFilterException.java b/security-util-lib/src/main/java/org/onap/sdc/security/RestrictionAccessFilterException.java new file mode 100644 index 0000000..5e62f28 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/RestrictionAccessFilterException.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +public class RestrictionAccessFilterException extends RuntimeException { + + public RestrictionAccessFilterException(Exception exception) { + super(exception); + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/SecurityUtil.java b/security-util-lib/src/main/java/org/onap/sdc/security/SecurityUtil.java new file mode 100644 index 0000000..98410d2 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/SecurityUtil.java @@ -0,0 +1,153 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import fj.data.Either; +import org.onap.sdc.security.logging.wrappers.Logger; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; + +public class SecurityUtil { + + private static final Logger LOG = Logger.getLogger( SecurityUtil.class ); + private static final byte[] KEY = new byte[]{-64,5,-32 ,-117 ,-44,8,-39, 1, -9, 36,-46,-81, 62,-15,-63,-75}; + public static final SecurityUtil INSTANCE = new SecurityUtil(); + public static final String ALGORITHM = "AES" ; + public static final String CHARSET = StandardCharsets.UTF_8.name(); + + public static Key secKey = null ; + + /** + * + * cmd commands >$PROGRAM_NAME decrypt "$ENCRYPTED_MSG" + * >$PROGRAM_NAME encrypt "message" + **/ + + private SecurityUtil(){ super(); } + + static { + try{ + secKey = generateKey( KEY, ALGORITHM ); + } + catch(Exception e){ + LOG.warn("cannot generate key for {}", ALGORITHM); + } + } + + + + public static Key generateKey(final byte[] KEY, String algorithm){ + return new SecretKeySpec(KEY, algorithm); + } + + //obfuscates key prefix -> ********** + public String obfuscateKey(String sensitiveData){ + + if (sensitiveData != null){ + int len = sensitiveData.length(); + StringBuilder builder = new StringBuilder(sensitiveData); + for (int i=0; i encrypt(String strDataToEncrypt){ + if (strDataToEncrypt != null ){ + try { + LOG.debug("Encrypt key -> {}", secKey); + Cipher aesCipherForEncryption = Cipher.getInstance("AES"); // Must specify the mode explicitly as most JCE providers default to ECB mode!! + aesCipherForEncryption.init(Cipher.ENCRYPT_MODE, secKey); + byte[] byteDataToEncrypt = strDataToEncrypt.getBytes(); + byte[] byteCipherText = aesCipherForEncryption.doFinal(byteDataToEncrypt); + String strCipherText = new String( Base64.getMimeEncoder().encode(byteCipherText), CHARSET ); + LOG.debug("Cipher Text generated using AES is {}", strCipherText); + return Either.left(strCipherText); + } catch( NoSuchAlgorithmException | UnsupportedEncodingException e){ + LOG.warn( "cannot encrypt data unknown algorithm or missing encoding for {}" ,secKey.getAlgorithm()); + } catch( InvalidKeyException e){ + LOG.warn( "invalid key recieved - > {} | {}" , Base64.getDecoder().decode( secKey.getEncoded() ), e.getMessage() ); + } catch( IllegalBlockSizeException | BadPaddingException | NoSuchPaddingException e){ + LOG.warn( "bad algorithm definition (Illegal Block Size or padding), please review you algorithm block&padding" , e.getMessage() ); + } + } + return Either.right("Cannot encrypt "+strDataToEncrypt); + } + + /** + * Decrypt the Data + * @param byteCipherText - should be valid bae64 input in the length of 16bytes + * @param isBase64Decoded - is data already base64 encoded&aligned to 16 bytes + * a. Initialize a new instance of Cipher for Decryption (normally don't reuse the same object) + * b. Decrypt the cipher bytes using doFinal method + */ + public Either decrypt(byte[] byteCipherText , boolean isBase64Decoded){ + if (byteCipherText != null){ + byte[] alignedCipherText = byteCipherText; + try{ + if (isBase64Decoded) + alignedCipherText = Base64.getDecoder().decode(byteCipherText); + LOG.debug("Decrypt key -> "+secKey.getEncoded()); + Cipher aesCipherForDecryption = Cipher.getInstance("AES"); // Must specify the mode explicitly as most JCE providers default to ECB mode!! + aesCipherForDecryption.init(Cipher.DECRYPT_MODE, secKey); + byte[] byteDecryptedText = aesCipherForDecryption.doFinal(alignedCipherText); + String strDecryptedText = new String(byteDecryptedText); + LOG.debug("Decrypted Text message is: {}" , obfuscateKey( strDecryptedText )); + return Either.left(strDecryptedText); + } catch( NoSuchAlgorithmException e){ + LOG.warn( "cannot encrypt data unknown algorithm or missing encoding for {}" ,secKey.getAlgorithm()); + } catch( InvalidKeyException e){ + LOG.warn( "invalid key recieved - > {} | {}" , Base64.getDecoder().decode( secKey.getEncoded() ), e.getMessage() ); + } catch( IllegalBlockSizeException | BadPaddingException | NoSuchPaddingException e){ + LOG.warn( "bad algorithm definition (Illegal Block Size or padding), please review you algorithm block&padding" , e.getMessage() ); + } + } + return Either.right("Decrypt FAILED"); + } + + public Either decrypt(String byteCipherText){ + try { + return decrypt(byteCipherText.getBytes(CHARSET),true); + } catch( UnsupportedEncodingException e ){ + LOG.warn( "Missing encoding for {} | {} " ,secKey.getAlgorithm() , e.getMessage()); + } + return Either.right("Decrypt FAILED"); + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/filters/FilterServletOutputStream.java b/security-util-lib/src/main/java/org/onap/sdc/security/filters/FilterServletOutputStream.java new file mode 100644 index 0000000..95cb519 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/filters/FilterServletOutputStream.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.filters; + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +public class FilterServletOutputStream extends ServletOutputStream { + + private DataOutputStream stream; + + public FilterServletOutputStream(OutputStream output) { + stream = new DataOutputStream(output); + } + + public void write(int b) throws IOException { + stream.write(b); + } + + public void write(byte[] b) throws IOException { + stream.write(b); + } + + public void write(byte[] b, int off, int len) throws IOException { + stream.write(b,off,len); + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/filters/ResponceWrapper.java b/security-util-lib/src/main/java/org/onap/sdc/security/filters/ResponceWrapper.java new file mode 100644 index 0000000..02b19aa --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/filters/ResponceWrapper.java @@ -0,0 +1,73 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.filters; + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; +import java.io.ByteArrayOutputStream; +import java.io.CharArrayWriter; +import java.io.IOException; +import java.io.PrintWriter; + +public class ResponceWrapper extends HttpServletResponseWrapper { + private ByteArrayOutputStream output; + private int contentLength; + private String contentType; + + public ResponceWrapper(HttpServletResponse response) { + super(response); + output = new ByteArrayOutputStream(); + } + + public byte[] getData() { + return output.toByteArray(); + } + + public ServletOutputStream getOutputStream() { + return new FilterServletOutputStream(output); + } + + public PrintWriter getWriter() { + return new PrintWriter(getOutputStream(), true); + } + + public void setContentLength(int length) { + this.contentLength = length; + super.setContentLength(length); + } + + public int getContentLength() { + return contentLength; + } + + public void setContentType(String type) { + this.contentType = type; + super.setContentType(type); + } + + + public String getContentType() { + return contentType; + + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/filters/RestrictionAccessFilter.java b/security-util-lib/src/main/java/org/onap/sdc/security/filters/RestrictionAccessFilter.java new file mode 100644 index 0000000..1b53882 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/filters/RestrictionAccessFilter.java @@ -0,0 +1,194 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.filters; + +import com.google.common.annotations.VisibleForTesting; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.onap.sdc.security.*; +import org.onap.sdc.security.logging.wrappers.*; +import org.onap.sdc.security.logging.elements.*; +import org.onap.sdc.security.logging.enums.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.onap.sdc.security.utils.SecurityLogsUtils.PORTAL_TARGET_ENTITY; +import static org.onap.sdc.security.utils.SecurityLogsUtils.fullOptionalData; + +@Component("restrictionAccessFilter") +public class RestrictionAccessFilter extends SessionValidationFilter { + + private final ISessionValidationFilterConfiguration filterConfiguration; + + private static final Logger log = Logger.getLogger(RestrictionAccessFilter.class.getName()); + private static final String LOCATION_HEADER = "RedirectLocation"; + + private static final String SESSION_IS_EXPIRED_MSG = "Session is expired for user %s"; + protected static final String CSP_USER_ID = "HTTP_CSP_ID"; + + private PortalClient portalClient; + private IUsersThreadLocalHolder threadLocalUtils; + + @Autowired + public RestrictionAccessFilter(ISessionValidationFilterConfiguration configuration, + IUsersThreadLocalHolder threadLocalUtils,PortalClient portalClient) { + this.filterConfiguration = configuration; + this.threadLocalUtils = threadLocalUtils; + this.portalClient = portalClient; + } + + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + super.doFilter(servletRequest, servletResponse,filterChain); + } + + @Override + protected Cookie addRoleToCookie(Cookie cookie) throws RedirectException { + AuthenticationCookie authenticationCookie; + Set updatedRolesSet = new HashSet<>(); + try { + log.debug("Adding the role to the cookie."); + authenticationCookie = getAuthenticationCookie(cookie); + if (!CollectionUtils.isEmpty(authenticationCookie.getRoles())) { + log.debug("Cookie already contains a role in its set of roles authenticationCookie Roles: {}", + authenticationCookie.getRoles()); + threadLocalUtils.setUserContext(authenticationCookie); + return cookie; + } + String fetchedRole = portalClient.fetchUserRolesFromPortal(authenticationCookie.getUserID()); + log.debug("addRoleToCookie: Finished fetching user role from Portal. Adding it to the cookie"); + updatedRolesSet.add(fetchedRole); + authenticationCookie.setRoles(updatedRolesSet); + String changedCookieJson = RepresentationUtils.toRepresentation(authenticationCookie); + log.debug("addRoleToCookie: Changed cookie Json: {}", changedCookieJson); + cookie.setValue(CipherUtil.encryptPKC(changedCookieJson, getFilterConfiguration().getSecurityKey())); + threadLocalUtils.setUserContext(authenticationCookie); + } catch (IOException e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), fullOptionalData(PORTAL_TARGET_ENTITY, "/fetchRolesFromPortal"),"Exception: {}", e.getMessage()); + throw new RestrictionAccessFilterException(e); + } catch (CipherUtilException e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), fullOptionalData(PORTAL_TARGET_ENTITY, "/fetchRolesFromPortal"),"Exception: {}", e.getMessage()); + throw new RedirectException(e); + } + return cookie; + } + + private AuthenticationCookie getAuthenticationCookie(Cookie cookie) throws CipherUtilException { + AuthenticationCookie authenticationCookie; + String originalCookieJson = retrieveOriginalCookieJson(cookie); + authenticationCookie = getAuthenticationCookie(originalCookieJson); + return authenticationCookie; + } + + @Override + public void authorizeUserOnSessionExpiration(AuthenticationCookie authenticationCookie, Cookie[] cookies) + throws RedirectException { + log.debug("Portal fetch user role is enabled"); + if (!isAuthenticatedUserSimilarToCspUser(authenticationCookie, cookies) || + areUserRolesChanged(authenticationCookie)) { + String msg = String.format(SESSION_IS_EXPIRED_MSG, authenticationCookie.getUserID()); + log.debug(msg); + throw new RedirectException(msg); + } + } + + @Override + protected void handleRedirectException(HttpServletResponse httpServletResponse) throws IOException { + + httpServletResponse.setHeader(LOCATION_HEADER, filterConfiguration.getRedirectURL()); + httpServletResponse.setStatus(403); + httpServletResponse.setContentType("application/json"); + httpServletResponse.setCharacterEncoding("UTF-8"); + httpServletResponse.getWriter().write(RepresentationUtils.toRepresentation + ("Your session has expired. Please close the SDC tab and re-enter the SDC application.")); + } + + private boolean areUserRolesChanged(AuthenticationCookie authenticationCookie) { + String cookieRole = ""; + if (!CollectionUtils.isEmpty(authenticationCookie.getRoles())) { + log.debug("Cookie contains a role in its set of roles: {}", authenticationCookie.getRoles().toString()); + cookieRole = (String) authenticationCookie.getRoles().iterator().next(); + } + // TODO: For future reference, when multi roles exist replace to something like: + // TODO: authenticationCookie.getRoles().stream().forEach((role) -> areRolesEqual = areRolesEqual(user.getRole(), role)); + log.debug("Fetching roles from portal for user {}", authenticationCookie.getUserID()); + String portalRole = portalClient.fetchUserRolesFromPortal(authenticationCookie.getUserID()); + log.debug("{} user role on portal is {}, in the cookie is {}", portalRole, cookieRole); + return StringUtils.isEmpty(cookieRole) || !cookieRole.equalsIgnoreCase(portalRole); + } + + private boolean isAuthenticatedUserSimilarToCspUser(AuthenticationCookie cookie, Cookie[] cookies) throws RedirectException { + String cspUserId = getCookieValue(cookies, CSP_USER_ID); + if (cspUserId != null && cspUserId.equals(cookie.getUserID())) { + log.debug("Auth and CSP user IDs are same: {}", cookie.getUserID()); + return true; + } + return false; + } + + @VisibleForTesting + public String getCookieValue(Cookie[] cookies, String name) throws RedirectException { + if (ArrayUtils.isNotEmpty(cookies)) { + List foundCookies = Arrays.stream(cookies) + .filter(c -> c.getName().endsWith(name)) + .collect(Collectors.toList()); + if (foundCookies.size() > 0) { + log.debug("getCookieValue: Found {} cookies with name: {}", foundCookies.size(), name); + return foundCookies.get(0).getValue(); + } + } + throw new RedirectException("No cookies found with name " + name); + } + + @Override + public ISessionValidationFilterConfiguration getFilterConfiguration() { + return filterConfiguration; + } + + private boolean areRolesEqual(String role, String roleFromDB) { + return !StringUtils.isEmpty(role) && role.equalsIgnoreCase(roleFromDB); + } + + private String retrieveOriginalCookieJson(Cookie cookie) throws CipherUtilException { + return CipherUtil.decryptPKC(cookie.getValue(), filterConfiguration.getSecurityKey()); + } + + private AuthenticationCookie getAuthenticationCookie(String originalCookieJson) { + return RepresentationUtils.fromRepresentation(originalCookieJson, AuthenticationCookie.class); + } + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/filters/SampleFilter.java b/security-util-lib/src/main/java/org/onap/sdc/security/filters/SampleFilter.java new file mode 100644 index 0000000..853c40d --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/filters/SampleFilter.java @@ -0,0 +1,175 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.filters; + +import org.onap.sdc.security.AuthenticationCookie; +import org.onap.sdc.security.ISessionValidationFilterConfiguration; +import org.onap.sdc.security.RedirectException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SampleFilter extends SessionValidationFilter { + + static final String FAILED_ON_USER_AUTH = "failedOnUserAuth"; + static final String FAILED_ON_ROLE = "failedOnRole"; + + private static class Configuration implements ISessionValidationFilterConfiguration { + + private String securityKey = "AGLDdG4D04BKm2IxIWEr8o=="; + private long maxSessionTimeOut = 24*60*60*1000; + private long sessionIdleTimeOut = 60*60*1000; + private String redirectURL = "http://portal.api.simpledemo.onap.org:8989/ECOMPPORTAL/login.htm"; + private List excludedUrls = new ArrayList<>(Arrays.asList("/config","/configmgr","/rest","/kibanaProxy","/healthcheck","/upload.*")); + private String cookieName = "kuku"; + private final String cookieDomain = ""; + private final String cookiePath = "/"; + private boolean isCookieHttpOnly = true; + + private static final Configuration instance = new Configuration(); + + + private Configuration() { + } + + public static Configuration getInstance(){ + return instance; + } + + // --- set method only for tests START --- + private void setSecurityKey(String securityKey) { + this.securityKey = securityKey; + } + + private void setMaxSessionTimeOut(long maxSessionTimeOut) { + this.maxSessionTimeOut = maxSessionTimeOut; + } + + private void setCookieName(String cookieName) { + this.cookieName = cookieName; + } + + private void setRedirectURL(String redirectURL) { + this.redirectURL = redirectURL; + } + + private void setExcludedUrls(List excludedUrls) { + this.excludedUrls = excludedUrls; + } + // --- set method only for tests START --- + + @Override + public String getSecurityKey() { + return securityKey; + } + + @Override + public long getMaxSessionTimeOut() { + return maxSessionTimeOut; + } + + @Override + public long getSessionIdleTimeOut() { + return sessionIdleTimeOut; + } + + @Override + public String getCookieName() { + return cookieName; + } + + @Override + public String getCookieDomain() { + return cookieDomain; + } + + @Override + public String getCookiePath() { + return cookiePath; + } + + @Override + public boolean isCookieHttpOnly() { + return isCookieHttpOnly; + } + + @Override + public String getRedirectURL() { + return redirectURL; + } + + @Override + public List getExcludedUrls() { + return excludedUrls; + } + + } + + // --- set methods only for tests START --- + public void setSecurityKey(String securityKey) { + Configuration.getInstance().setSecurityKey(securityKey); + } + + public void setMaxSessionTimeOut(long maxSessionTimeOut) { + Configuration.getInstance().setMaxSessionTimeOut(maxSessionTimeOut); + } + + public void setCookieName(String cookieName) { + Configuration.getInstance().setCookieName(cookieName); + } + + public void setRedirectURL(String redirectURL) { + Configuration.getInstance().setRedirectURL(redirectURL); + } + + public void setExcludedUrls(List excludedUrls) { + Configuration.getInstance().setExcludedUrls(excludedUrls); + } + // --- set methods only for tests END --- + + @Override + public ISessionValidationFilterConfiguration getFilterConfiguration() { + return Configuration.getInstance(); + } + + @Override + protected Cookie addRoleToCookie(Cookie updatedCookie) { + return updatedCookie; + } + + @Override + protected void authorizeUserOnSessionExpiration(AuthenticationCookie authenticationCookie, Cookie[] cookies) throws RedirectException { + if (FAILED_ON_USER_AUTH.equals(authenticationCookie.getUserID())) { + throw new RedirectException(); + } + } + + @Override + protected void handleRedirectException(HttpServletResponse httpResponse) throws IOException { + //do nothing in this implementation + } + +} + + diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/filters/SessionValidationFilter.java b/security-util-lib/src/main/java/org/onap/sdc/security/filters/SessionValidationFilter.java new file mode 100644 index 0000000..87780ae --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/filters/SessionValidationFilter.java @@ -0,0 +1,217 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.filters; + +import org.onap.sdc.security.*; +import org.onap.sdc.security.logging.elements.ErrorLogOptionalData; +import org.onap.sdc.security.logging.elements.LogFieldsMdcHandler; +import org.onap.sdc.security.logging.enums.EcompLoggerErrorCode; +import org.onap.sdc.security.logging.wrappers.Logger; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +public abstract class SessionValidationFilter implements Filter { + private static final Logger log = Logger.getLogger(SessionValidationFilter.class.getName()); + private ISessionValidationFilterConfiguration filterConfiguration; + private List excludedUrls; + + public abstract ISessionValidationFilterConfiguration getFilterConfiguration(); + protected abstract Cookie addRoleToCookie(Cookie updatedCookie) throws RedirectException; + protected abstract void authorizeUserOnSessionExpiration(AuthenticationCookie authenticationCookie, Cookie[] cookies) throws RedirectException; + protected abstract void handleRedirectException(HttpServletResponse httpResponse) throws IOException; + + @Override + public final void init(FilterConfig filterConfig) { + filterConfiguration = getFilterConfiguration(); + excludedUrls = filterConfiguration.getExcludedUrls(); + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + final HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; + final HttpServletResponse httpResponse = (HttpServletResponse) servletResponse; + + long starTime = System.nanoTime(); + if (log.isDebugEnabled()) { + log.debug("SessionValidationFilter: Validation started, received request with URL {}", httpRequest.getRequestURL()); + } + + try { + if (isValidationRequired(servletRequest, servletResponse, filterChain, httpRequest)){ + List cookies = extractAuthenticationCookies(httpRequest.getCookies()); + if (log.isDebugEnabled()) { + log.debug("doFilter: the cookies we received from extractAuthenticationCookies, before processRequest: {}", cookies); + } + + Cookie extractedCookie = cookies.get(0); + processRequest(httpRequest, extractedCookie); + + // response processing + if (log.isDebugEnabled()) { + log.debug("SessionValidationFilter: Cookie from request {} is valid, passing request to session extension ...", httpRequest.getRequestURL()); + } + Cookie updatedCookie = processResponse(extractedCookie); + + cleanResponseFromLeftoverCookies(httpResponse, cookies); + + if (log.isDebugEnabled()) { + log.debug("SessionValidationFilter: request {} passed all validations, passing request to endpoint ...", httpRequest.getRequestURL()); + } + httpResponse.addCookie(updatedCookie); + filterChain.doFilter(servletRequest, httpResponse); + } + } catch (RedirectException e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), new ErrorLogOptionalData(),"Exception is thrown while authenticating cookie: {}", e.getMessage()); + handleRedirectException(httpResponse); + } + long durationSec = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - starTime); + long durationMil = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - starTime); + if (log.isDebugEnabled()) { + log.debug("SessionValidationFilter: Validation ended, running time for URL {} is: {} seconds {} milliseconds", httpRequest.getPathInfo(), durationSec, durationMil); + } + } + + + private boolean isValidationRequired(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain, HttpServletRequest httpRequest) throws IOException, ServletException, RedirectException { + if (isUrlFromWhiteList(httpRequest)) { + log.debug("SessionValidationFilter: URL {} excluded from access validation , passing request to endpoint ... ", httpRequest.getRequestURL()); + filterChain.doFilter(servletRequest, servletResponse); + return false; + + } else if (!isCookiePresent(httpRequest.getCookies())) { + //redirect to portal app + log.debug("SessionValidationFilter: Cookie from request {} is not valid, redirecting request to portal", httpRequest.getRequestURL()); + throw new RedirectException(String.format("Cookie from request %s is not valid", httpRequest.getRequestURL() )); + } + return true; + } + + private void processRequest(HttpServletRequest httpRequest, Cookie cookie) throws RedirectException { + AuthenticationCookie authenticationCookie; + try { + authenticationCookie = AuthenticationCookieUtils.getAuthenticationCookie(cookie, filterConfiguration); + } + catch (CipherUtilException e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), new ErrorLogOptionalData(),"SessionValidationFilter: Cookie decryption error : {}", e.getMessage()); + throw new RedirectException("Cookie decryption error"); + } + if (AuthenticationCookieUtils.isSessionExpired(authenticationCookie, filterConfiguration)) { + if (log.isDebugEnabled()) { + log.debug("SessionValidationFilter:session is expired for URL {}", httpRequest.getRequestURL()); + } + authorizeUserOnSessionExpiration(authenticationCookie, httpRequest.getCookies()); + } + if (log.isDebugEnabled()) { + log.debug("SessionValidationFilter: Role is valid"); + } + } + + private Cookie processResponse(Cookie cookie) throws IOException, RedirectException { + Cookie updatedCookie; + try { + updatedCookie = AuthenticationCookieUtils.updateSessionTime(cookie, filterConfiguration); + } catch (CipherUtilException e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), new ErrorLogOptionalData(),"SessionValidationFilter: Cookie cipher error {}", e.getMessage()); + if (log.isDebugEnabled()) { + log.debug("SessionValidationFilter: Cookie cipher error : {}", e.getMessage(), e); + } + throw new RedirectException(e); + } + return addRoleToCookie(updatedCookie); + } + + private boolean isCookiePresent(Cookie[] cookies) { + if (cookies == null) { + return false; + } + String actualCookieName = filterConfiguration.getCookieName(); + boolean isPresent = Arrays.stream(cookies).anyMatch(c -> isCookieNameMatch(actualCookieName, c)); + if (!isPresent) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LogFieldsMdcHandler.getInstance().getServiceName(), new ErrorLogOptionalData(),"SessionValidationFilter: Session Validation Cookie missing "); + return false; + } + return true; + } + + private List extractAuthenticationCookies(Cookie[] cookies) { + String actualCookieName = filterConfiguration.getCookieName(); + if (log.isDebugEnabled()) { + Arrays.stream(cookies).forEach(c->log.debug("SessionValidationFilter: Cookie name {}", c.getName())); + log.debug("SessionValidationFilter: Extracting authentication cookies, {} cookies in request", cookies.length); + } + List authenticationCookies = Arrays.stream(cookies).filter(c -> isCookieNameMatch(actualCookieName, c)).collect(Collectors.toList()); + if (log.isDebugEnabled()) { + log.debug("SessionValidationFilter: Extracted {} authentication cookies from request", authenticationCookies.size()); + } + if( authenticationCookies.size() > 1 && log.isDebugEnabled()) { + authenticationCookies.forEach( cookie -> log.debug("SessionValidationFilter: Multiple cookies found cookie name, {} cookie value {}", cookie.getName(), cookie.getValue())); + } + return authenticationCookies; + } + + + // use contains for matching due issue with ecomp portal ( change cookie name, add prefix ), temp solution + private boolean isCookieNameMatch(String actualCookieName, Cookie c) { + return c.getName().contains(actualCookieName); + } + + private boolean isUrlFromWhiteList(HttpServletRequest httpRequest) { + if (httpRequest.getPathInfo() == null){ + final String servletPath = httpRequest.getServletPath().toLowerCase(); + log.debug("SessionValidationFilter: pathInfo is null, trying to check by servlet path white list validation -> ServletPath: {} ", servletPath); + return excludedUrls.stream(). + anyMatch(servletPath::matches); + } + String pathInfo = httpRequest.getPathInfo().toLowerCase(); + log.debug("SessionValidationFilter: white list validation -> PathInfo: {} ", pathInfo); + return excludedUrls.stream(). + anyMatch(pathInfo::matches); + } + + private void cleanResponseFromLeftoverCookies(HttpServletResponse httpResponse, List cookiesList) { + for (Cookie cookie:cookiesList){ + Cookie cleanCookie = AuthenticationCookieUtils.createUpdatedCookie(cookie, null, filterConfiguration); + cleanCookie.setMaxAge(0); + if (log.isDebugEnabled()) { + log.debug("SessionValidationFilter Cleaning Cookie cookie name: {} added to response", cleanCookie.getName()); + } + httpResponse.addCookie(cleanCookie); + } + } + + @Override + public void destroy() { + + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogConfiguration.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogConfiguration.java new file mode 100644 index 0000000..3077662 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogConfiguration.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security.logging.api; + +public interface ILogConfiguration { + + String MDC_SERVICE_INSTANCE_ID = "ServiceInstanceId"; + String MDC_SERVER_IP_ADDRESS = "ServerIPAddress"; + String MDC_REMOTE_HOST = "RemoteHost"; + String MDC_AUDIT_MESSAGE = "AuditMessage"; + String MDC_END_TIMESTAMP = "EndTimestamp"; + String MDC_ELAPSED_TIME = "ElapsedTime"; + String MDC_PROCESS_KEY = "ProcessKey"; + String MDC_TARGET_VIRTUAL_ENTITY = "TargetVirtualEntity"; + String MDC_ERROR_CATEGORY = "ErrorCategory"; + String MDC_ERROR_CODE = "ErrorCode"; + String MDC_ERROR_DESC = "ErrorDescription"; + String MDC_CLASS_NAME = "ClassName"; + String MDC_OPT_FIELD1 = "CustomField1"; + String MDC_OPT_FIELD2 = "CustomField2"; + String MDC_OPT_FIELD3 = "CustomField3"; + String MDC_OPT_FIELD4 = "CustomField4"; + String MDC_SUPPORTABLITY_ACTION = "SupportablityAction"; + String MDC_SUPPORTABLITY_CSAR_UUID="SupportablityCsarUUID"; + String MDC_SUPPORTABLITY_CSAR_VERSION="SupportablityCsarVersion"; + String MDC_SUPPORTABLITY_COMPONENT_NAME = "SupportablityComponentName"; + String MDC_SUPPORTABLITY_COMPONENT_UUID = "SupportablityComponentUUID"; + String MDC_SUPPORTABLITY_COMPONENT_VERSION="SupportablityComponentVersion"; + String MDC_SUPPORTABLITY_STATUS_CODE = "SupportablityStatus"; +} \ No newline at end of file diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogFieldsHandler.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogFieldsHandler.java new file mode 100644 index 0000000..098dfcb --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogFieldsHandler.java @@ -0,0 +1,188 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security.logging.api; + + +import org.onap.sdc.security.logging.enums.Severity; + +/** + * Created by dd4296 on 12/25/2017. + */ +public interface ILogFieldsHandler { + void startAuditTimer(); + + void startMetricTimer(); + + void stopAuditTimer(); + + void stopMetricTimer(); + + void setClassName(String className); + + void setServerFQDN(String serverFQDN); + + void setServerIPAddress(String serverIPAddress); + + // intended for setting this parameter in a given thread + void setServerFQDNInternally(); + + // intended for setting this parameter in a given thread + void setServerIPAddressInternally(); + + void setInstanceUUID(String instanceUUID); + + void setProcessKey(String processKey); + + void setAlertSeverity(Severity alertSeverity); + + void setOptCustomField1(String customField1); + + void setOptCustomField2(String customField2); + + void setOptCustomField3(String customField3); + + void setOptCustomField4(String customField4); + + void setKeyRequestId(String keyRequestId); + + void setRemoteHost(String remoteHost); + + void setServiceName(String serviceName); + + void setStatusCode(String statusCode); + + void setPartnerName(String partnerName); + + void setResponseCode(int responseCode); + + void setResponseDesc(String responseDesc); + + void setServiceInstanceId(String serviceInstanceId); + + void setTargetEntity(String targetEntity); + + void setTargetServiceName(String targetServiceName); + + void setTargetVirtualEntity(String targetVirtualEntity); + + void setErrorCode(int errorCode); + + void setErrorCategory(String errorCategory); + + String getErrorCode(); + + String getServiceName(); + + String getTargetEntity(); + + String getTargetServiceName(); + + String getErrorCategory(); + + void clear(); + + boolean isMDCParamEmpty(String mdcKeyName); + + String getFqdn(); + + String getHostAddress(); + + String getKeyRequestId(); + + void removeStatusCode(); + + void removePartnerName(); + + void removeResponseCode(); + + void removeResponseDesc(); + + void removeServiceInstanceId(); + + void removeTargetEntity(); + + void removeTargetServiceName(); + + void removeTargetVirtualEntity(); + + void removeErrorCode(); + + void removeErrorCategory(); + + void removeErrorDescription(); + + void setAuditMessage(String message); + + String getAuditMessage(); + + //service supportability [US 496441] + + String getSupportablityAction(); + + String getSupportablityCsarUUID(); + + String getSupportablityCsarVersion(); + + String getSupportablityComponentName(); + + String getSupportablityComponentUUID(); + + String getSupportablityComponentVersion(); + + String getSupportablityStatusCode(); + + void setSupportablityAction(String action); + + void setSupportablityCsarUUID(String uuid); + + void setSupportablityCsarVersion(String version); + + void setSupportablityComponentName(String name); + + void setSupportablityComponentUUID(String UUID); + + void setSupportablityComponentVersion(String version); + + void setSupportablityStatusCode(String statusCode); + + void removeSupportablityAction(); + + void removeSupportablityComponentName(); + + void removeSupportablityComponentUUID(); + + void removeSupportablityComponentVersion(); + + void removeSupportablityCsarUUID(); + + void removeSupportablityCsarVersion(); + + void removeSupportablityStatusCode(); + + String getPartnerName(); + + String getRemoteHost(); + + String getServerIpAddress(); + + void setKeyInvocationId(String invocationId); + + CharSequence getKeyInvocationId(); +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogger.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogger.java new file mode 100644 index 0000000..ee7ba0d --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/api/ILogger.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security.logging.api; + +import org.onap.sdc.security.logging.enums.LogLevel; +import org.slf4j.Marker; + +import java.util.List; + +/** + * Created by dd4296 on 12/24/2017. + */ +public interface ILogger { + void log(LogLevel logLevel, String message); + void log(Marker marker, LogLevel logLevel, String message); + void log(LogLevel logLevel, String message, Object... params); + void log(Marker marker, LogLevel logLevel, String message, Object... params); + void log(LogLevel logLevel, String message, Throwable throwable); + List getMandatoryFields(); + ILogger clear(); + ILogger startTimer(); + ILogger setKeyRequestId(String keyRequestId); + + ILogger setKeyInvocationId(String keyInvocationId); +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/ErrorLogOptionalData.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/ErrorLogOptionalData.java new file mode 100644 index 0000000..f6f1b79 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/ErrorLogOptionalData.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security.logging.elements; + +public class ErrorLogOptionalData { + private String targetEntity; + private String targetServiceName; + + public ErrorLogOptionalData() { + } + + String getTargetEntity() { + return targetEntity; + } + + private void setTargetEntity(String targetEntity) { + this.targetEntity = targetEntity; + } + + String getTargetServiceName() { + return targetServiceName; + } + + private void setTargetServiceName(String targetServiceName) { + this.targetServiceName = targetServiceName; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + private final ErrorLogOptionalData instance; + + private Builder() { + instance = new ErrorLogOptionalData(); + } + + public Builder targetEntity(String targetEntity) { + instance.setTargetEntity(targetEntity); + return this; + } + + public Builder targetServiceName(String targetServiceName) { + instance.setTargetServiceName(targetServiceName); + return this; + } + + public ErrorLogOptionalData build() { + return instance; + } + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/FunctionalInterfaces.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/FunctionalInterfaces.java new file mode 100644 index 0000000..03a9747 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/FunctionalInterfaces.java @@ -0,0 +1,597 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.elements; + +import fj.F; +import fj.data.Either; +import org.apache.commons.lang3.math.NumberUtils; +import org.apache.commons.lang3.time.StopWatch; +import org.onap.sdc.security.logging.enums.EcompErrorSevirity; +import org.onap.sdc.security.logging.enums.EcompLoggerErrorCode; +import org.onap.sdc.security.logging.wrappers.Logger; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; + +import static org.apache.commons.lang3.StringUtils.EMPTY; + +/** + * Class For Functional interfaces And Functional Methods + * + * @author mshitrit + * + */ +public class FunctionalInterfaces { + private static final int DEFAULT_REDO_INTERVAL_TIME_MS = 50; + private static final int DEFAULT_MAX_WAIT_TIME_MS = 10000; + private static final Logger LOGGER = Logger.getLogger(FunctionalInterfaces.class.getName()); + + /** + * This is an interface of a List that implements Serializable + * + * @author mshitrit + * + * @param + */ + public interface SerializableList extends List, Serializable { + } + + /** + * @author mshitrit Consumer that takes two parameters + * @param + * @param + */ + public interface ConsumerTwoParam { + /** + * Same Accept method, but takes two parameters + * + * @param t1 + * @param t2 + */ + void accept(T1 t1, T2 t2); + } + + /** + * @author mshitrit Function that takes two parameters + * @param + * @param + * @param + */ + public interface FunctionTwoParam { + /** + * Same apply method, but takes two parameters + * + * @param t1 + * @param t2 + * @return + */ + R apply(T1 t1, T2 t2); + } + + /** + * @author mshitrit Function that throws an exception + * @param + * @param + * @param + */ + public interface FunctionThrows { + /** + * Same apply method, but throws an exception + * + * @param t + * @return + */ + R apply(T t) throws E; + } + + public interface FunctionTwoParamThrows { + /** + * Same apply method, but throws an exception + * + * @param t1 + * @param t2 + * @return + */ + R apply(T1 t1, T2 t2) throws E; + } + + /** + * @author mshitrit Supplier that throws an exception + * @param + * @param + */ + public interface SupplierThrows { + /** + * Same get method, but throws an exception + * + * @return + * @throws E + */ + R get() throws E; + } + + /** + * @author mshitrit Consumer that throws an exception + * @param + * @param + */ + public interface ConsumerThrows { + /** + * Same accept, but throws an exception + * + * @param t + * @throws E + */ + void accept(T t) throws E; + } + + /** + * @author mshitrit Runnable that throws an exception + * @param + */ + public interface RunnableThrows { + /** + * Same run, but throws an exception + * + * @throws E + */ + void run() throws E; + } + + /** + * Runs a method that declares throwing an Exception and has a return value. + *
+ * In case Exception Occurred replaces it with FunctionalAttException.
+ * This is useful for two cases:
+ * 1.using methods that throws exceptions in streams.
+ * 2.replacing declared exception with undeclared exception (Runtime).
+ * See below Use Case:
+ * Instead of: intList.stream().map(e -> fooThrowsAndReturnsBoolean(e)); - + * does not compile !
+ * Use This : intList.stream().map(e -> swallowException( () -> + * fooThrowsAndReturnsBoolean(e))); - compiles !
+ * + * @param methodToRun + * @return + */ + public static R swallowException(SupplierThrows methodToRun) { + try { + return methodToRun.get(); + } catch (Exception e) { + throw new FunctionalAttException(e); + } + } + + /** + * Runs a method that declares throwing an Exception without return value. + *
+ * In case Exception Occurred replaces it with FunctionalAttException.
+ * This is useful for two cases:
+ * 1.using methods that throws exceptions in streams.
+ * 2.replacing declared exception with undeclared exception (Runtime).
+ * See below Use Case:
+ * + * @param methodToRun + */ + public static void swallowException(RunnableThrows methodToRun) { + + SupplierThrows runnableWrapper = () -> { + methodToRun.run(); + return true; + }; + swallowException(runnableWrapper); + } + + private static class FunctionalAttException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private FunctionalAttException(Exception e) { + super(e); + } + } + + /** + * Runs the given method.
+ * Verify the method result against the resultVerifier.
+ * If verification passed returns the result.
+ * If Verification failed keeps retrying until it passes or until 10 seconds + * pass.
+ * If Exception Occurred keeps retrying until it passes or until 10 seconds + * pass,
+ * If last retry result caused an exception - it is thrown. + * + * @param methodToRun + * given Method + * @param resultVerifier + * verifier for the method result + * @return + */ + public static R retryMethodOnResult(Supplier methodToRun, Function resultVerifier) { + return retryMethodOnResult(methodToRun, resultVerifier, DEFAULT_MAX_WAIT_TIME_MS, + DEFAULT_REDO_INTERVAL_TIME_MS); + } + + /** + * Runs the given method.
+ * Verify the method result against the resultVerifier.
+ * If verification passed returns the result.
+ * If Verification failed keeps retrying until it passes or until maxWait + * pass.
+ * If Exception Occurred keeps retrying until it passes or until maxWait + * pass,
+ * If last retry result caused an exception - it is thrown. + * + * @param methodToRun + * given Method + * @param resultVerifier + * verifier for the method result + * @param maxWaitMS + * @param retryIntervalMS + * @return + */ + public static R retryMethodOnResult(Supplier methodToRun, Function resultVerifier, + long maxWaitMS, long retryIntervalMS) { + boolean stopSearch = false; + R ret = null; + int timeElapsed = 0; + FunctionalAttException functionalExceotion = null; + boolean isExceptionInLastTry = false; + while (!stopSearch) { + try { + ret = methodToRun.get(); + stopSearch = resultVerifier.apply(ret); + isExceptionInLastTry = false; + } catch (Exception e) { + functionalExceotion = new FunctionalAttException(e); + isExceptionInLastTry = true; + + } finally { + sleep(retryIntervalMS); + timeElapsed += retryIntervalMS; + if (timeElapsed > maxWaitMS) { + stopSearch = true; + } + } + + } + if (isExceptionInLastTry) { + throw functionalExceotion; + } else { + return ret; + } + + } + + /** + * Runs the given method.
+ * Verify the method result against the resultVerifier.
+ * If verification passed returns the result.
+ * If Verification failed keeps retrying until maxRetries reached.
+ * If Exception Occurred keeps retrying until it passes or until maxRetries + * reached,
+ * If last retry result caused an exception - it is thrown. + * + * @param methodToRun + * given Method + * @param resultVerifier + * verifier for the method result + * @param maxRetries + * @return + */ + public static R retryMethodOnResult(Supplier methodToRun, Function resultVerifier, + long maxRetries) { + boolean stopSearch = false; + R ret = null; + int retriesCount = 0; + FunctionalAttException functionalExceotion = null; + boolean isExceptionInLastTry = false; + while (!stopSearch) { + try { + ret = methodToRun.get(); + stopSearch = resultVerifier.apply(ret); + isExceptionInLastTry = false; + } catch (Exception e) { + functionalExceotion = new FunctionalAttException(e); + isExceptionInLastTry = true; + } finally { + if (++retriesCount >= maxRetries) { + stopSearch = true; + } + } + } + if (isExceptionInLastTry) { + throw functionalExceotion; + } else { + return ret; + } + } + + public static R retryMethodOnException(SupplierThrows methodToRun, + Function exceptionVerifier, long maxRetries) throws Exception { + boolean stopSearch = false; + R ret = null; + int retriesCount = 0; + Exception exception = null; + while (!stopSearch) { + try { + exception = null; + ret = methodToRun.get(); + stopSearch = true; + } + catch (Exception e) { + exception = e; + stopSearch = exceptionVerifier.apply(e); + } + finally { + if (++retriesCount >= maxRetries) { + stopSearch = true; + } + } + } + if (exception != null) { + throw exception; + } + else { + return ret; + } + } + + /** + * Runs the given method.
+ * In case exception occurred runs the method again either until succeed or + * until 10 seconds pass. + * + * @param methodToRun + * given method + * @return + */ + + public static R retryMethodOnException(Supplier methodToRun) { + Function dummyVerifier = someResult -> true; + return retryMethodOnResult(methodToRun, dummyVerifier, DEFAULT_MAX_WAIT_TIME_MS, DEFAULT_REDO_INTERVAL_TIME_MS); + } + + /** + * Runs the given method.
+ * In case exception occurred runs the method again either until succeed or + * until 10 seconds pass. + * + * @param methodToRun + * given method + */ + public static void retryMethodOnException(Runnable methodToRun) { + Function dummyVerifier = someResult -> true; + Supplier dummySupplier = () -> { + methodToRun.run(); + return true; + }; + retryMethodOnResult(dummySupplier, dummyVerifier, DEFAULT_MAX_WAIT_TIME_MS, DEFAULT_REDO_INTERVAL_TIME_MS); + } + + /** + * Same as Thread.sleep but throws a FunctionalAttException + * (RuntimeException) instead of InterruptedException.
+ * + * @param millis + */ + public static void sleep(long millis) { + swallowException(() -> Thread.sleep(millis)); + + } + + /** + * Converts Either containing right value to another either with different + * type of left value and the same type of right value. + * + * @param eitherToConvert + * @return + */ + public static Either convertEitherRight(Either eitherToConvert) { + if (eitherToConvert.isLeft()) { + throw new UnsupportedOperationException("Can not convert either right value because it has left value"); + } else { + return Either.right(eitherToConvert.right().value()); + } + + } + + /** + * Converts Either containing left value to another either with different + * type of right value and the same type of left value. + * + * @param eitherToConvert + * @return + */ + public static Either convertEitherLeft(Either eitherToConvert) { + if (eitherToConvert.isLeft()) { + throw new UnsupportedOperationException("Can not convert either left value because it has right value"); + } else { + return Either.left(eitherToConvert.left().value()); + } + + } + + /** + * Returns enum value for a field
+ * + * @param fieldValue + * @param values + * @param enumValueGetter + * @return + */ + public static > T getEnumValueByFieldValue(String fieldValue, T[] values, + Function enumValueGetter, T defaultValue) { + return getEnumValueByFieldValue(fieldValue, values, enumValueGetter, defaultValue, true); + + } + + + public static > T getEnumValueByFieldValue(String fieldValue, T[] values, + Function enumValueGetter, T defaultValue, boolean isCaseSensetive ){ + + final Predicate predicate; + if( isCaseSensetive ){ + predicate = e -> fieldValue.equals(enumValueGetter.apply(e)); + } + else{ + predicate = e -> fieldValue.equalsIgnoreCase(enumValueGetter.apply(e)); + } + Optional optionalFound = + // Stream of values of enum + Arrays.asList(values).stream(). + // Filter in the one that match the field + filter(predicate). + // collect + findAny(); + T ret; + ret = optionalFound.isPresent() ? optionalFound.get() : defaultValue; + return ret; + + } + + /** + * This method runs the given method.
+ * In case given method finished running within timeoutInMs limit it returns + * Either which left value is the result of the method that ran.
+ * In case given method did not finish running within timeoutInMs limit it + * returns Either which right value is false.
+ * + * @param supplier + * @param timeoutInMs + * - if 0 or lower no timeout is used + * @return + */ + public static Either runMethodWithTimeOut(Supplier supplier, long timeoutInMs) { + Either result; + if (timeoutInMs <= NumberUtils.LONG_ZERO) { + result = Either.left(supplier.get()); + } else { + ExecutorService pool = Executors.newSingleThreadExecutor(); + Future future = pool.submit(supplier::get); + try { + T calcValue = future.get(timeoutInMs, TimeUnit.MILLISECONDS); + result = Either.left(calcValue); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + LOGGER.debug("method run was canceled because it has passed its time limit of {} MS", timeoutInMs, e); + result = Either.right(false); + } finally { + pool.shutdownNow(); + } + } + return result; + } + + public static F convertToFunction(Consumer consumer) { + return t -> { + try { + consumer.accept(t); + return true; + } catch (Exception e) { + return false; + } + }; + } + + /** + * Wraps the execution of the Runnable with try catch.
+ * In case exception occurred returns Optional containing the + * resultOnException.
+ * Otherwise returns an Empty optional. + * + * @param runnable + * @param resultOnException + * @return + */ + public static Optional wrapWithTryCatch(RunnableThrows runnable, + T resultOnException) { + Optional optionalError; + try { + runnable.run(); + optionalError = Optional.empty(); + } catch (Exception e) { + logException(e); + optionalError = Optional.of(resultOnException); + } + return optionalError; + } + + /** + * Runs the given method.
+ * In case the method passes without any Assertion Errors finishes.
+ * In case there is an assertion error keeps running the method every retryIntervalMS.
until there is no Errors or maxWaitTimeMs has passed.
+ * If there are still Assertion Errors in the last Run they are returned to the user.
+ * + * @param methodToRun + * @param maxWaitTimeMs + * @param retryIntervalMS + */ + public static void retryMethodOnException (Runnable methodToRun, long maxWaitTimeMs, long retryIntervalMS) { + if (maxWaitTimeMs <= 0) { + throw new UnsupportedOperationException("Number maxWaitTimeMs be greater than 0"); + } + StopWatch watch = new StopWatch(); + watch.start(); + + boolean isLastTry = false; + while (!isLastTry) { + isLastTry = watch.getTime() + retryIntervalMS > maxWaitTimeMs; + if (isLastTry) { + methodToRun.run(); + } + else { + try { + methodToRun.run(); + break; + } catch (Exception e) { + wrapWithTryCatch(() -> Thread.sleep(retryIntervalMS)); + } + } + } + + + } + + /** + * Wraps the execution of the Runnable with try catch.
+ * In case exception occurred logs the Exception.
+ * resultOnException.
+ * Otherwise returns an Empty optional. + * + * @param runnable + * @return + */ + public static void wrapWithTryCatch(RunnableThrows runnable) { + wrapWithTryCatch(runnable, null); + } + + private static void logException(Exception e) { + LOGGER.error(EcompErrorSevirity.ERROR, EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, EMPTY, EMPTY, EMPTY, EMPTY); + LOGGER.debug("Error was caught ", e); + } + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/HttpResponse.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/HttpResponse.java new file mode 100644 index 0000000..57aaf3c --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/HttpResponse.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.elements; + +import org.apache.commons.lang3.StringUtils; + +public class HttpResponse { + private final T response; + private final int statusCode; + private final String description; + + public HttpResponse(T response, int statusCode) { + this.response = response; + this.statusCode = statusCode; + this.description = StringUtils.EMPTY; + } + + public HttpResponse(T response, int statusCode, String description) { + this.response = response; + this.statusCode = statusCode; + this.description = description; + } + + public T getResponse() { + return response; + } + + public int getStatusCode() { + return statusCode; + } + + public String getDescription() { + return description; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("HttpResponse [response="); + builder.append(response); + builder.append(", statusCode="); + builder.append(statusCode); + builder.append(", description="); + builder.append(description); + builder.append("]"); + return builder.toString(); + } + + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LogFieldsMdcHandler.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LogFieldsMdcHandler.java new file mode 100644 index 0000000..3d600e8 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LogFieldsMdcHandler.java @@ -0,0 +1,533 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.elements; + +import org.apache.commons.lang3.StringUtils; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.onap.sdc.security.logging.api.ILogConfiguration; +import org.onap.sdc.security.logging.api.ILogFieldsHandler; +import org.onap.sdc.security.logging.enums.EcompHeadersConstants; +import org.onap.sdc.security.logging.enums.Severity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +import javax.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; + +import static java.lang.Integer.valueOf; + +public class LogFieldsMdcHandler implements ILogFieldsHandler { + + private static LogFieldsMdcHandler instanceMdcWrapper = new LogFieldsMdcHandler(); + + public static LogFieldsMdcHandler getInstance() { + return instanceMdcWrapper; + } + + private final static String dateFormatPattern = "yyyy-MM-dd HH:mm:ss.SSSz"; + private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter + .ofPattern(dateFormatPattern); + protected static Logger log = LoggerFactory.getLogger(LogFieldsMdcHandler.class.getName()); + protected static String hostAddress; + protected static String fqdn; + + static { + try { + hostAddress = InetAddress.getLocalHost().getHostAddress(); + fqdn = InetAddress.getByName(hostAddress).getCanonicalHostName(); + } catch (Exception ex) { + log.error("failed to get machine parameters", ex); + } + } + + @Override + public void startAuditTimer() { + if (StringUtils.isEmpty(MDC.get(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP))) { + MDC.put(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP, generatedTimeNow()); + } + } + + @Override + public void startMetricTimer() { + if (StringUtils.isEmpty(MDC.get(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP))) { + MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP, generatedTimeNow()); + } + } + + @Override + public void stopAuditTimer() { + //set start time if it is not set yet + startAuditTimer(); + MDC.put(ILogConfiguration.MDC_END_TIMESTAMP, generatedTimeNow()); + setElapsedTime(MDC.get(ONAPLogConstants.MDCs.ENTRY_TIMESTAMP)); + } + + @Override + public void stopMetricTimer() { + //set start time if it is not set yet + startMetricTimer(); + MDC.put(ILogConfiguration.MDC_END_TIMESTAMP, generatedTimeNow()); + setElapsedTime(MDC.get(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP)); + } + + @Override + public void setClassName(String className) { + MDC.put(ILogConfiguration.MDC_CLASS_NAME, className); + } + + @Override + public void setServerFQDN(String serverFQDN) { + MDC.put(ONAPLogConstants.MDCs.SERVER_FQDN, serverFQDN); + } + + @Override + public void setServerIPAddress(String serverIPAddress) { + MDC.put(ILogConfiguration.MDC_SERVER_IP_ADDRESS, serverIPAddress); + } + + @Override + public void setServerFQDNInternally() { + setServerFQDN(fqdn); + } + + @Override + public void setServerIPAddressInternally() { + setServerIPAddress(hostAddress); + } + + @Override + public void setInstanceUUID(String instanceUUID) { + MDC.put(ONAPLogConstants.MDCs.INSTANCE_UUID, instanceUUID); + } + + @Override + public void setProcessKey(String processKey) { + MDC.put(ILogConfiguration.MDC_PROCESS_KEY, processKey); + } + + @Override + public void setAlertSeverity(Severity alertSeverity) { + MDC.put(ONAPLogConstants.MDCs.RESPONSE_SEVERITY, String.valueOf(alertSeverity.getSeverityType())); + } + + @Override + public void setOptCustomField1(String customField1) { + MDC.put(ILogConfiguration.MDC_OPT_FIELD1, customField1); + } + + @Override + public void setOptCustomField2(String customField2) { + MDC.put(ILogConfiguration.MDC_OPT_FIELD2, customField2); + } + + @Override + public void setOptCustomField3(String customField3) { + MDC.put(ILogConfiguration.MDC_OPT_FIELD3, customField3); + } + + @Override + public void setOptCustomField4(String customField4) { + MDC.put(ILogConfiguration.MDC_OPT_FIELD4, customField4); + } + + @Override + public void setKeyRequestId(String keyRequestId) { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, + keyRequestId); // eg. servletRequest.getSession().getId() + } + + @Override + public void setKeyInvocationId(String invocationId ) { + MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, + invocationId); + } + + @Override + public void setRemoteHost(String remoteHost) { + MDC.put(ILogConfiguration.MDC_REMOTE_HOST, remoteHost); + } + + @Override + public void setServiceName(String serviceName) { + MDC.put(ONAPLogConstants.MDCs.SERVICE_NAME, serviceName); + } + + @Override + public void setStatusCode(String statusCode) { + MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, statusCode); + } + + @Override + public void setPartnerName(String partnerName) { + MDC.put(ONAPLogConstants.MDCs.PARTNER_NAME, partnerName); + } + + @Override + public void setResponseCode(int responseCode) { + MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, Integer.toString(responseCode)); + } + + @Override + public void setResponseDesc(String responseDesc) { + MDC.put(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION, responseDesc); + } + + @Override + public void setServiceInstanceId(String serviceInstanceId) { + MDC.put(ILogConfiguration.MDC_SERVICE_INSTANCE_ID, serviceInstanceId); + } + + @Override + public void setTargetEntity(String targetEntity) { + MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, targetEntity); + } + + @Override + public void setTargetServiceName(String targetServiceName) { + MDC.put(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME, targetServiceName); + } + + @Override + public void setTargetVirtualEntity(String targetVirtualEntity) { + MDC.put(ILogConfiguration.MDC_TARGET_VIRTUAL_ENTITY, targetVirtualEntity); + } + + @Override + public void setErrorCode(int errorCode) { + MDC.put(ILogConfiguration.MDC_ERROR_CODE, valueOf(errorCode).toString()); + } + + @Override + public void setErrorCategory(String errorCategory) { + MDC.put(ILogConfiguration.MDC_ERROR_CATEGORY, errorCategory); + } + + @Override + public String getErrorCode() { + return MDC.get(ILogConfiguration.MDC_ERROR_CODE); + } + + @Override + public String getServiceName() { + return MDC.get(ONAPLogConstants.MDCs.SERVICE_NAME); + } + + @Override + public String getErrorCategory() { + return MDC.get(ILogConfiguration.MDC_ERROR_CATEGORY); + } + + @Override + public void clear() { + MDC.clear(); + } + + @Override + public boolean isMDCParamEmpty(String mdcKeyName) { + return StringUtils.isEmpty(MDC.get(mdcKeyName)); + } + + @Override + public String getFqdn() { + return fqdn; + } + + @Override + public String getHostAddress() { + return hostAddress; + } + + @Override + public String getKeyRequestId() { + return MDC.get(ONAPLogConstants.MDCs.REQUEST_ID); + } + + @Override + public String getTargetEntity() { + return MDC.get(ONAPLogConstants.MDCs.TARGET_ENTITY); + } + + @Override + public String getTargetServiceName() { + return MDC.get(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME); + } + + @Override + public void removeStatusCode() { + MDC.remove(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE); + } + + @Override + public void removePartnerName() { + MDC.remove(ONAPLogConstants.MDCs.PARTNER_NAME); + } + + @Override + public void removeResponseCode() { + MDC.remove(ONAPLogConstants.MDCs.RESPONSE_CODE); + } + + @Override + public void removeResponseDesc() { + MDC.remove(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION); + } + + @Override + public void removeServiceInstanceId() { + MDC.remove(ILogConfiguration.MDC_SERVICE_INSTANCE_ID); + } + + @Override + public void removeTargetEntity() { + MDC.remove(ONAPLogConstants.MDCs.TARGET_ENTITY); + } + + @Override + public void removeTargetServiceName() { + MDC.remove(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME); + } + + @Override + public void removeTargetVirtualEntity() { + MDC.remove(ILogConfiguration.MDC_TARGET_VIRTUAL_ENTITY); + } + + @Override + public void removeErrorCode() { + MDC.remove(ILogConfiguration.MDC_ERROR_CODE); + } + + @Override + public void removeErrorCategory() { + MDC.remove(ILogConfiguration.MDC_ERROR_CATEGORY); + } + + @Override + public void removeErrorDescription() { + MDC.remove(ILogConfiguration.MDC_ERROR_DESC); + } + + @Override + public void setAuditMessage(String message) { + MDC.put(ILogConfiguration.MDC_AUDIT_MESSAGE, message); + } + + @Override + public String getAuditMessage() { + return MDC.get(ILogConfiguration.MDC_AUDIT_MESSAGE); + } + + + @Override + public String getSupportablityStatusCode() { + return MDC.get(ILogConfiguration.MDC_SUPPORTABLITY_STATUS_CODE); + } + + @Override + public String getSupportablityAction() { + return MDC.get(ILogConfiguration.MDC_SUPPORTABLITY_ACTION); + + } + + + @Override + public String getRemoteHost() { + return MDC.get(ILogConfiguration.MDC_REMOTE_HOST); + } + + @Override + public String getServerIpAddress() { + return MDC.get(ILogConfiguration.MDC_SERVER_IP_ADDRESS); + } + +// @Override +// public String getSupportablityCsarName() { +// return MDC.get(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_NAME); +// } + + @Override + public String getSupportablityCsarUUID() { + return MDC.get(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_UUID); + } + + @Override + public String getSupportablityCsarVersion() { + return MDC.get(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_VERSION); + + } + + @Override + public String getSupportablityComponentName() { + return MDC.get(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_NAME); + } + + @Override + public String getSupportablityComponentUUID() { + return MDC.get(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_UUID); + + } + + @Override + public String getSupportablityComponentVersion() { + return MDC.get(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_VERSION); + } + + @Override + public CharSequence getKeyInvocationId() { + return null; + } + + @Override + public void setSupportablityStatusCode(String statusCode) { + MDC.put(ILogConfiguration.MDC_SUPPORTABLITY_STATUS_CODE, statusCode); + } + + @Override + public void setSupportablityAction(String action) { + MDC.put(ILogConfiguration.MDC_SUPPORTABLITY_ACTION, action); + } + +// @Override +// public void setSupportablityCsarName(String name) { +// MDC.put(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_NAME, name); +// } + + @Override + public void setSupportablityCsarUUID(String uuid) { + MDC.put(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_UUID, uuid); + } + + @Override + public void setSupportablityCsarVersion(String version) { + MDC.put(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_VERSION, version); + } + + @Override + public void setSupportablityComponentName(String name) { + MDC.put(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_NAME, name); + } + + @Override + public void setSupportablityComponentUUID(String uuid) { + MDC.put(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_UUID, uuid); + } + + @Override + public void setSupportablityComponentVersion(String version) { + MDC.put(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_VERSION, version); + } + + @Override + public void removeSupportablityAction() { + MDC.remove(ILogConfiguration.MDC_SUPPORTABLITY_ACTION); + } + + @Override + public void removeSupportablityComponentName() { + MDC.remove(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_NAME); + } + + @Override + public void removeSupportablityComponentUUID() { + MDC.remove(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_UUID); + } + + @Override + public void removeSupportablityComponentVersion() { + MDC.remove(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_VERSION); + } + +// @Override +// public void removeSupportablityCsarName() { +// MDC.remove(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_NAME); +// } + + @Override + public void removeSupportablityCsarUUID() { + MDC.remove(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_UUID); + } + + @Override + public void removeSupportablityCsarVersion() { + MDC.remove(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_VERSION); + } + + @Override + public void removeSupportablityStatusCode() { + MDC.remove(ILogConfiguration.MDC_SUPPORTABLITY_STATUS_CODE); + } + + @Override + public String getPartnerName() { + return MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME); + } + + private void setElapsedTime(String beginTimestamp) { + try { + final LocalDateTime startTime = LocalDateTime.parse(beginTimestamp, dateTimeFormatter); + final LocalDateTime endTime = LocalDateTime + .parse(MDC.get(ILogConfiguration.MDC_END_TIMESTAMP), dateTimeFormatter); + final Duration timeDifference = Duration.between(startTime, endTime); + + MDC.put(ILogConfiguration.MDC_ELAPSED_TIME, String.valueOf(timeDifference.toMillis())); + + } catch (Exception ex) { + log.error("failed to calculate elapsed time", ex); + } + } + + private String generatedTimeNow() { + return dateTimeFormatter + .withZone(ZoneOffset.UTC) + .format(Instant.now()); + } + + public void collectRequestInfoForErrorAndDebugLogging(HttpServletRequest httpRequest) { + LogFieldsMdcHandler.getInstance().clear(); + String partnerName = LoggerBase.getPartnerName(httpRequest); + LogFieldsMdcHandler.getInstance().setPartnerName(partnerName); + + String serviceInstanceID = httpRequest.getHeader(EcompHeadersConstants.X_ECOMP_SERVICE_ID_HEADER); + LogFieldsMdcHandler.getInstance().setServiceInstanceId(serviceInstanceID); + + LogFieldsMdcHandler.getInstance().setRemoteHost(httpRequest.getRemoteHost()); + LogFieldsMdcHandler.getInstance().setServerIPAddress(httpRequest.getLocalAddr()); + + String requestId = LoggerBase.getRequestId(httpRequest); + LogFieldsMdcHandler.getInstance().setKeyRequestId(requestId); + + LogFieldsMdcHandler.getInstance().setServiceName(httpRequest.getRequestURI()); + } + + public void addInfoForErrorAndDebugLogging(String partnerName){ + LogFieldsMdcHandler.getInstance().clear(); + LogFieldsMdcHandler.getInstance().setPartnerName(partnerName); + + String requestId = LoggerBase.generateKeyRequestId(); + LogFieldsMdcHandler.getInstance().setKeyRequestId(requestId); + } +} \ No newline at end of file diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerAudit.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerAudit.java new file mode 100644 index 0000000..6ec4fe6 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerAudit.java @@ -0,0 +1,196 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security.logging.elements; + + +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.onap.sdc.security.logging.api.ILogConfiguration; +import org.onap.sdc.security.logging.api.ILogFieldsHandler; +import org.onap.sdc.security.logging.enums.EcompLoggerErrorCode; +import org.onap.sdc.security.logging.enums.Severity; +import org.slf4j.Logger; +import org.slf4j.MDC; +import org.slf4j.MarkerFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class LoggerAudit extends LoggerBase { + private static ArrayList mandatoryFields = new ArrayList<>(Arrays.asList( + ONAPLogConstants.MDCs.ENTRY_TIMESTAMP, + ILogConfiguration.MDC_END_TIMESTAMP, + ONAPLogConstants.MDCs.REQUEST_ID, + ONAPLogConstants.MDCs.SERVICE_NAME, + ONAPLogConstants.MDCs.PARTNER_NAME, + ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, + ONAPLogConstants.MDCs.RESPONSE_CODE, + ILogConfiguration.MDC_SERVICE_INSTANCE_ID, + ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION, + ILogConfiguration.MDC_ELAPSED_TIME, + ILogConfiguration.MDC_SERVER_IP_ADDRESS, + ONAPLogConstants.MDCs.SERVER_FQDN)); + + private static ArrayList optionalFields = new ArrayList<>(Arrays.asList( + ONAPLogConstants.MDCs.INSTANCE_UUID, + ONAPLogConstants.MDCs.RESPONSE_SEVERITY, + ILogConfiguration.MDC_REMOTE_HOST, + ILogConfiguration.MDC_CLASS_NAME, + ILogConfiguration.MDC_PROCESS_KEY, + ILogConfiguration.MDC_OPT_FIELD1, + ILogConfiguration.MDC_OPT_FIELD2, + ILogConfiguration.MDC_OPT_FIELD3, + ILogConfiguration.MDC_OPT_FIELD4)); + + LoggerAudit(ILogFieldsHandler ecompMdcWrapper, Logger logger) { + //TODO Andrey, set default marker + super (ecompMdcWrapper, MarkerFactory.getMarker(ONAPLogConstants.Markers.ENTRY.getName()), logger); + //put the remote host and FQDN values from another thread if they are set + ecompMdcWrapper.setServerIPAddressInternally(); + ecompMdcWrapper.setServerFQDNInternally(); + } + + @Override + public LoggerAudit startTimer() { + ecompLogFieldsHandler.startAuditTimer(); + return this; + } + + public LoggerAudit stopTimer() { + ecompLogFieldsHandler.stopAuditTimer(); + return this; + } + + public LoggerAudit setInstanceUUID(String instanceUUID) { + ecompLogFieldsHandler.setInstanceUUID(instanceUUID); + return this; + } + + public LoggerAudit setOptClassName(String className) { + MDC.put("ClassName", className); + return this; + } + + public LoggerAudit setOptProcessKey(String processKey) { + ecompLogFieldsHandler.setProcessKey(processKey); + return this; + } + + public LoggerAudit setOptAlertSeverity(Severity alertSeverity) { + ecompLogFieldsHandler.setAlertSeverity(alertSeverity); + return this; + } + + // log optional parameter + public LoggerAudit setOptCustomField1(String customField1) { + ecompLogFieldsHandler.setOptCustomField1(customField1); + return this; + } + + // log optional parameter + public LoggerAudit setOptCustomField2(String customField2) { + ecompLogFieldsHandler.setOptCustomField2(customField2); + return this; + } + + // log optional parameter + public LoggerAudit setOptCustomField3(String customField3) { + ecompLogFieldsHandler.setOptCustomField3(customField3); + return this; + } + + public LoggerAudit setOptCustomField4(String customField4) { + ecompLogFieldsHandler.setOptCustomField4(customField4); + return this; + } + + @Override + public LoggerAudit setKeyRequestId(String keyRequestId) { + return (LoggerAudit) super.setKeyRequestId(keyRequestId); + } + + @Override + public LoggerAudit setKeyInvocationId(String keyInvocationId) { + ecompLogFieldsHandler.setKeyInvocationId(keyInvocationId); + return this; + } + + public LoggerAudit setRemoteHost(String remoteHost) { + ecompLogFieldsHandler.setRemoteHost(remoteHost); + return this; + } + + public LoggerAudit setServiceName(String serviceName) { + ecompLogFieldsHandler.setServiceName(serviceName); + return this; + } + + public LoggerAudit setStatusCodeByResponseCode(String responseCode) { + String respStatus = Integer.parseInt(responseCode) / 100 == 2 ? ONAPLogConstants.ResponseStatus.COMPLETE.name() : ONAPLogConstants.ResponseStatus.ERROR.name(); + ecompLogFieldsHandler.setStatusCode(respStatus); + return this; + } + + public LoggerAudit setStatusCode(String statusCode) { + ecompLogFieldsHandler.setStatusCode(statusCode); + return this; + } + + + public LoggerAudit setPartnerName(String partnerName) { + ecompLogFieldsHandler.setPartnerName(partnerName); + return this; + } + + public LoggerAudit setResponseCode(EcompLoggerErrorCode responseCode) { + ecompLogFieldsHandler.setResponseCode(responseCode.getErrorCode()); + return this; + } + + public LoggerAudit setResponseDesc(String responseDesc) { + ecompLogFieldsHandler.setResponseDesc(responseDesc); + return this; + } + + public LoggerAudit setOptServiceInstanceId(String serviceInstanceId) { + ecompLogFieldsHandler.setServiceInstanceId(serviceInstanceId); + return this; + } + + public String getAuditMessage() { + return ecompLogFieldsHandler.getAuditMessage(); + } + + + @Override + public List getMandatoryFields() { + return Collections.unmodifiableList(mandatoryFields); + } + + @Override + public LoggerAudit clear() { + super.clear(); + ecompLogFieldsHandler.setServerFQDNInternally(); + ecompLogFieldsHandler.setServerIPAddressInternally(); + return this; + } + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerBase.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerBase.java new file mode 100644 index 0000000..4e3d30f --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerBase.java @@ -0,0 +1,230 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.elements; + +import com.google.common.annotations.VisibleForTesting; +import org.apache.commons.lang3.StringUtils; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.onap.sdc.security.logging.api.ILogFieldsHandler; +import org.onap.sdc.security.logging.api.ILogger; +import org.onap.sdc.security.logging.enums.EcompHeadersConstants; +import org.onap.sdc.security.logging.enums.LogLevel; +import org.onap.sdc.security.logging.enums.LogMarkers; +import org.slf4j.Logger; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + + +public abstract class LoggerBase implements ILogger { + private final Logger myLogger; + private final Marker myMarker; + protected final ILogFieldsHandler ecompLogFieldsHandler; + private final static String missingLogFieldsMsg = "mandatory parameters for ECOMP logging, missing fields: %s, original message: %s"; + + LoggerBase(ILogFieldsHandler ecompLogFieldsHandler, Marker marker, Logger logger) { + this.ecompLogFieldsHandler = ecompLogFieldsHandler; + this.myMarker = marker; + this.myLogger = logger; + setKeyRequestIdIfNotSetYet(); + } + + public static String generateKeyRequestId() { + return UUID.randomUUID().toString(); + } + + public static String getRequestId(HttpServletRequest httpRequest) { + String onapRequestId = httpRequest.getHeader(ONAPLogConstants.Headers.REQUEST_ID); + String requestId = httpRequest.getHeader(EcompHeadersConstants.X_REQUEST_ID); + String transactionReId = httpRequest.getHeader(EcompHeadersConstants.X_TRANSACTION_ID_HEADER); + String ecompRequestId = httpRequest.getHeader(EcompHeadersConstants.X_ECOMP_REQUEST_ID_HEADER); + return Arrays.asList(onapRequestId, requestId, transactionReId, ecompRequestId).stream() + .filter(id -> !StringUtils.isEmpty(id)).findFirst().orElse(generateKeyRequestId()); + } + + public static String getPartnerName(HttpServletRequest httpRequest) { + String userId = httpRequest.getHeader(EcompHeadersConstants.USER_ID_HEADER); + String onapPartnerName = httpRequest.getHeader(ONAPLogConstants.Headers.PARTNER_NAME); + String reqUri = httpRequest.getHeader(EcompHeadersConstants.USER_AGENT_HEADER); + return Arrays.asList(userId, onapPartnerName, reqUri).stream() + .filter(pn-> !StringUtils.isEmpty(pn)).findFirst().orElse(EcompHeadersConstants.PartnerName_Unknown); + } + + protected void setKeyRequestIdIfNotSetYet() { + if (StringUtils.isEmpty(ecompLogFieldsHandler.getKeyRequestId())) { + setKeyRequestId(generateKeyRequestId()); + } + } + + protected void setKeyInvocationIdIfNotSetYet() { + if (StringUtils.isEmpty(ecompLogFieldsHandler.getKeyInvocationId())) { + setKeyInvocationId("IDAN--setKeyInvocationIdIfNotSetYet"); + } + } + + private void validateMandatoryFields(String originMsg) { + // this method only checks if the mandatory fields have been initialized + String filedNameThatHasNotBeenInitialized = checkMandatoryFieldsExistInMDC(); + + if (myLogger.isDebugEnabled() && !"".equalsIgnoreCase(filedNameThatHasNotBeenInitialized)) { + myLogger.debug(MarkerFactory.getMarker(LogMarkers.DEBUG_MARKER.text()), + String.format(missingLogFieldsMsg, filedNameThatHasNotBeenInitialized, originMsg)); + } + } + + @VisibleForTesting + String checkMandatoryFieldsExistInMDC() { + // this method returns a String of uninitialised fields + StringBuilder missingFields = new StringBuilder(); + getMandatoryFields().forEach(field -> { + if (ecompLogFieldsHandler.isMDCParamEmpty(field)) { + missingFields.append(field).append(" "); + } + }); + return missingFields.toString(); + } + + public abstract List getMandatoryFields(); + + protected String convertExceptionStackToString(Exception ex) { + StringBuilder stackTrack = new StringBuilder(); + Arrays.asList(ex.getStackTrace()).forEach(item -> stackTrack.append(item.toString()).append("\n")); + return stackTrack.toString(); + } + + @Override + public void log(LogLevel logLevel, String message) { + log(logLevel, message, (Object) null); + } + + @Override + public void log(Marker marker, LogLevel logLevel, String message) { + log(marker, logLevel, message, (Object) null); + } + + @Override + public void log(LogLevel logLevel, String message, Object...params) { + validateMandatoryFields(message); + + switch(logLevel) { + case ERROR: + case FATAL: //TODO check how to log "FATAL" word + myLogger.error(myMarker, message, params); + break; + case WARN: + myLogger.warn(myMarker, message, params); + break; + case INFO: + myLogger.info(myMarker, message, params); + break; + case DEBUG: + myLogger.debug(myMarker, message, params); + break; + case TRACE: + myLogger.trace(myMarker, message, params); + break; + default: + break; + } + } + + @Override + public void log(LogLevel logLevel, String message, Throwable throwable) { + validateMandatoryFields(message); + + switch(logLevel) { + case ERROR: + case FATAL: //TODO check how to log "FATAL" word + myLogger.error(myMarker, createErrorMessage(message, throwable)); + break; + case WARN: + myLogger.warn(myMarker, createErrorMessage(message, throwable)); + break; + case INFO: + myLogger.info(myMarker, createErrorMessage(message, throwable)); + break; + case DEBUG: + myLogger.debug(myMarker, message, throwable); + break; + case TRACE: + myLogger.trace(myMarker, message, throwable); + break; + default: + break; + } + } + + @Override + public void log(Marker marker, LogLevel logLevel, String message, Object...params) { + validateMandatoryFields(message); + + switch(logLevel) { + case ERROR: + case FATAL: //TODO check how to log "FATAL" word + myLogger.error(marker, message, params); + break; + case WARN: + myLogger.warn(marker, message, params); + break; + case INFO: + myLogger.info(marker, message, params); + break; + case DEBUG: + myLogger.debug(marker, message, params); + break; + case TRACE: + myLogger.trace(marker, message, params); + break; + default: + break; + } + } + + protected String createErrorMessage(String message, Throwable throwable) { + return String.format("%s: %s", message, throwable.getLocalizedMessage()); + } + + + @Override + public ILogger clear() { + ecompLogFieldsHandler.clear(); + return this; + } + + @Override + public ILogger setKeyRequestId(String keyRequestId) { + ecompLogFieldsHandler.setKeyRequestId(keyRequestId); + return this; + } + + + @Override + public ILogger setKeyInvocationId(String keyInvocationId) { + ecompLogFieldsHandler.setKeyInvocationId(keyInvocationId); + return this; + } + + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerDebug.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerDebug.java new file mode 100644 index 0000000..402fc4d --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerDebug.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.elements; + +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.onap.sdc.security.logging.api.ILogFieldsHandler; +import org.onap.sdc.security.logging.enums.LogLevel; +import org.onap.sdc.security.logging.enums.LogMarkers; +import org.slf4j.Logger; +import org.slf4j.MarkerFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class LoggerDebug extends LoggerBase { + + private static ArrayList mandatoryFields = new ArrayList<>(Arrays.asList(ONAPLogConstants.MDCs.REQUEST_ID)); + + LoggerDebug(ILogFieldsHandler ecompMdcWrapper, Logger logger) { + super(ecompMdcWrapper, MarkerFactory.getMarker(LogMarkers.DEBUG_MARKER.text()), logger); + } + + @Override + public LoggerDebug clear() { + //nothing to clean up + return this; + } + + @Override + public void log(LogLevel logLevel, String message, Object...params){ + setKeyRequestIdIfNotSetYet(); + setKeyInvocationIdIfNotSetYet(); + super.log(logLevel, message, params); + } + + @Override + public void log(LogLevel logLevel, String message, Throwable throwable){ + setKeyRequestIdIfNotSetYet(); + super.log(logLevel, message, throwable); + } + + @Override + public void log(LogLevel logLevel, String message){ + setKeyRequestIdIfNotSetYet(); + super.log(logLevel, message); + } + + @Override + public LoggerDebug startTimer() { + return this; + } + + @Override + public List getMandatoryFields() { + return mandatoryFields; + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerError.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerError.java new file mode 100644 index 0000000..a22d1d6 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerError.java @@ -0,0 +1,163 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.elements; + +import org.apache.commons.lang3.StringUtils; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.onap.sdc.security.logging.api.ILogConfiguration; +import org.onap.sdc.security.logging.api.ILogFieldsHandler; +import org.onap.sdc.security.logging.enums.EcompErrorSevirity; +import org.onap.sdc.security.logging.enums.EcompLoggerErrorCode; +import org.onap.sdc.security.logging.enums.LogLevel; +import org.onap.sdc.security.logging.enums.LogMarkers; +import org.slf4j.Logger; +import org.slf4j.MarkerFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class LoggerError extends LoggerBase { + private static ArrayList mandatoryFields = new ArrayList<>(Arrays.asList( + ONAPLogConstants.MDCs.REQUEST_ID, + ONAPLogConstants.MDCs.SERVICE_NAME, + ILogConfiguration.MDC_ERROR_CATEGORY, + ILogConfiguration.MDC_ERROR_CODE)); + + public static final String defaultServiceName = "SDC catalog"; + + LoggerError(ILogFieldsHandler ecompMdcWrapper, Logger logger) { + super(ecompMdcWrapper, MarkerFactory.getMarker(LogMarkers.ERROR_MARKER.text()), logger); + } + + @Override + public List getMandatoryFields() { + return Collections.unmodifiableList(mandatoryFields); + } + + @Override + public LoggerError setKeyRequestId(String keyRequestId) { + return (LoggerError) super.setKeyRequestId(keyRequestId); + } + + @Override + public LoggerError startTimer() { + return this; + } + + @Override + public LoggerError clear() { + ecompLogFieldsHandler.removeErrorCategory(); + ecompLogFieldsHandler.removeErrorDescription(); + ecompLogFieldsHandler.removeErrorCode(); + return this; + } + + public void log(LogLevel logLevel, + EcompLoggerErrorCode errorCodeEnum, + String serviceName, + String targetEntity, + String message, Object...params) { + fillFieldsBeforeLogging(logLevel, errorCodeEnum, serviceName, targetEntity, null); + super.log(logLevel, message, params); + } + + public void log(LogLevel logLevel, + EcompLoggerErrorCode errorCodeEnum, + String serviceName, + ErrorLogOptionalData errorLogOptionalData, + String description, + Object...params) { + fillFieldsBeforeLogging(logLevel, errorCodeEnum, serviceName, + errorLogOptionalData.getTargetEntity(), errorLogOptionalData.getTargetServiceName()); + super.log(logLevel, description, params); + } + + private void fillFieldsBeforeLogging(LogLevel logLevel, EcompLoggerErrorCode errorCodeEnum, String serviceName, String targetEntity, String targetServiceName) { + clear(); + ecompLogFieldsHandler.setErrorCode(errorCodeEnum.getErrorCode()); + ecompLogFieldsHandler.setErrorCategory(logLevel.name()); + + ecompLogFieldsHandler.setTargetEntity(targetEntity); + ecompLogFieldsHandler.setTargetServiceName(targetServiceName); + + if (StringUtils.isEmpty(ecompLogFieldsHandler.getServiceName())) { + ecompLogFieldsHandler.setServiceName(serviceName); + } + + setKeyRequestIdIfNotSetYet(); + } + + public void log(EcompErrorSevirity errorSeverity, + EcompLoggerErrorCode errorCodeEnum, + String serviceName, + String targetEntity, + String message, Object... params) { + log(convertFromSeverityErrorLevel(errorSeverity), errorCodeEnum, serviceName, targetEntity, message, params); + } + + public void log(LogLevel logLevel, + EcompLoggerErrorCode errorCodeEnum, + String serviceName, + String message, Object...params) { + log(logLevel, errorCodeEnum, serviceName, (String)null, message, params); + } + + public void log(LogLevel logLevel, + EcompLoggerErrorCode errorCodeEnum, + String serviceName, + String message) { + log(logLevel, errorCodeEnum, serviceName, message); + } + + @Override + public void log(LogLevel logLevel, String message, Object...params) { + log(logLevel, EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, defaultServiceName, (String)null, message, params); + } + + public void log(LogLevel logLevel, String message, Throwable throwable) { + log(logLevel, createErrorMessage(message, throwable)); + } + + public void log(LogLevel logLevel, String message) { + log(logLevel, EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, defaultServiceName, (String)null, message); + } + + public void logInfo(LogLevel logLevel, String message, Object... params) { + log(logLevel, EcompLoggerErrorCode.SUCCESS, defaultServiceName, (String)null, message, params); + } + + private LogLevel convertFromSeverityErrorLevel(EcompErrorSevirity severityLevel) { + switch(severityLevel) { + case INFO: + return LogLevel.INFO; + case FATAL: + return LogLevel.FATAL; + case ERROR: + return LogLevel.ERROR; + case WARN: + return LogLevel.WARN; + } + return LogLevel.ERROR; + } + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerFactory.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerFactory.java new file mode 100644 index 0000000..fe67de1 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerFactory.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.elements; + +import org.slf4j.Logger; + +public class LoggerFactory { + + private LoggerFactory() { + } + + @SuppressWarnings("unchecked") + public static V getLogger(Class type, Logger logger) { + + if (type.getName().equals(LoggerAudit.class.getName())) { + return (V) new LoggerAudit(new LogFieldsMdcHandler(), logger); + } + + if (type.getName().equals(LoggerDebug.class.getName())) { + return (V) new LoggerDebug(new LogFieldsMdcHandler(), logger); + } + + if (type.getName().equals(LoggerMetric.class.getName())) { + return (V) new LoggerMetric(new LogFieldsMdcHandler(), logger); + } + + if (type.getName().equals(LoggerError.class.getName())) { + return (V) new LoggerError(new LogFieldsMdcHandler(), logger); + } + + return null; + } + + @SuppressWarnings("unchecked") + public static V getMdcLogger(Class type, Logger logger) { + + if (type.getName().equals(LoggerAudit.class.getName())) { + return (V) new LoggerAudit(LogFieldsMdcHandler.getInstance(), logger); + } + + if (type.getName().equals(LoggerDebug.class.getName())) { + return (V) new LoggerDebug(LogFieldsMdcHandler.getInstance(), logger); + } + + if (type.getName().equals(LoggerMetric.class.getName())) { + return (V) new LoggerMetric(LogFieldsMdcHandler.getInstance(), logger); + } + + if (type.getName().equals(LoggerError.class.getName())) { + return (V) new LoggerError(LogFieldsMdcHandler.getInstance(), logger); + } + + if (type.getName().equals(LoggerSupportability.class.getName())) { + return (V) new LoggerSupportability(LogFieldsMdcHandler.getInstance(), logger); + } + + return null; + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerMetric.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerMetric.java new file mode 100644 index 0000000..3f5ce5c --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerMetric.java @@ -0,0 +1,234 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.elements; + +import org.onap.sdc.security.logging.api.ILogFieldsHandler; +import org.onap.sdc.security.logging.enums.LogLevel; +import org.onap.sdc.security.logging.enums.LogMarkers; +import org.onap.sdc.security.logging.enums.Severity; +import org.slf4j.Logger; +import org.slf4j.MarkerFactory; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.onap.logging.ref.slf4j.ONAPLogConstants.MDCs.*; +import static org.onap.sdc.security.logging.api.ILogConfiguration.*; + + +public class LoggerMetric extends LoggerBase { + private static ArrayList mandatoryFields = new ArrayList<>(Arrays.asList( + INVOKE_TIMESTAMP, + MDC_END_TIMESTAMP, + REQUEST_ID, + SERVICE_NAME, + PARTNER_NAME, + RESPONSE_CODE, + MDC_SERVICE_INSTANCE_ID, + RESPONSE_DESCRIPTION, + MDC_ELAPSED_TIME, + TARGET_ENTITY, + MDC_SERVER_IP_ADDRESS, + SERVER_FQDN)); + + private static ArrayList optionalFields = new ArrayList<>(Arrays.asList( + MDC_TARGET_VIRTUAL_ENTITY, + TARGET_ENTITY, + TARGET_SERVICE_NAME, + RESPONSE_STATUS_CODE, + INSTANCE_UUID, + RESPONSE_SEVERITY, + MDC_REMOTE_HOST, + CLIENT_IP_ADDRESS, + MDC_CLASS_NAME, + MDC_PROCESS_KEY, + MDC_OPT_FIELD1, + MDC_OPT_FIELD2, + MDC_OPT_FIELD3, + MDC_OPT_FIELD4)); + + LoggerMetric(ILogFieldsHandler ecompMdcWrapper, Logger logger) { + super(ecompMdcWrapper, MarkerFactory.getMarker(LogMarkers.METRIC_MARKER.text()), logger); + //put the remote host and FQDN values from another thread if they are set + ecompMdcWrapper.setServerIPAddressInternally(); + ecompMdcWrapper.setServerFQDNInternally(); + } + + public void log(Response.StatusType statusInfo, + String className, + LogLevel logLevel, + Severity securityLevel, + String message) { + log(statusInfo,className, logLevel, securityLevel, message); + } + + @Override + public void log(LogLevel logLevel, String message) { + setKeyRequestIdIfNotSetYet(); + log(logLevel, message, (Object) null); + } + + @Override + public LoggerMetric startTimer() { + clear(); + ecompLogFieldsHandler.startMetricTimer(); + return this; + } + + public LoggerMetric stopTimer() { + ecompLogFieldsHandler.stopMetricTimer(); + return this; + } + + @Override + public LoggerMetric setKeyRequestId(String keyRequestId) { + return (LoggerMetric) super.setKeyRequestId(keyRequestId); + } + + @Override + public List getMandatoryFields() { + return mandatoryFields; + } + + @Override + public LoggerMetric clear() { + ecompLogFieldsHandler.removeTargetEntity(); + ecompLogFieldsHandler.removeTargetServiceName(); + ecompLogFieldsHandler.removeResponseCode(); + ecompLogFieldsHandler.removeResponseDesc(); + ecompLogFieldsHandler.removeStatusCode(); + return this; + } + + // automatic parameter this is optional + public LoggerMetric setAutoServerFQDN(String serverFQDN) { + ecompLogFieldsHandler.setServerFQDN(serverFQDN); + return this; + } + + // automatic parameter this is optional + public LoggerMetric setAutoServerIPAddress(String serverIPAddress) { + ecompLogFieldsHandler.setServerIPAddress(serverIPAddress); + return this; + } + + public LoggerMetric setInstanceUUID(String instanceUUID) { + ecompLogFieldsHandler.setInstanceUUID(instanceUUID); + return this; + } + + // log optional parameter + public LoggerMetric setOptProcessKey(String processKey) { + ecompLogFieldsHandler.setProcessKey(processKey); + return this; + } + + // log optional parameter + public LoggerMetric setOptAlertSeverity(Severity alertSeverity) { + ecompLogFieldsHandler.setAlertSeverity(alertSeverity); + return this; + } + + // log optional parameter + public LoggerMetric setOptCustomField1(String customField1) { + ecompLogFieldsHandler.setOptCustomField1(customField1); + return this; + } + + // log optional parameter + public LoggerMetric setOptCustomField2(String customField2) { + ecompLogFieldsHandler.setOptCustomField2(customField2); + return this; + } + + // log optional parameter + public LoggerMetric setOptCustomField3(String customField3) { + ecompLogFieldsHandler.setOptCustomField3(customField3); + return this; + } + + // log optional parameter + public LoggerMetric setOptCustomField4(String customField4) { + ecompLogFieldsHandler.setOptCustomField4(customField4); + return this; + } + + public LoggerMetric setRemoteHost(String remoteHost) { + ecompLogFieldsHandler.setRemoteHost(remoteHost); + return this; + } + + public LoggerMetric setServiceName(String serviceName) { + ecompLogFieldsHandler.setServiceName(serviceName); + return this; + } + + public LoggerMetric setStatusCode(String statusCode) { + ecompLogFieldsHandler.setStatusCode(statusCode); + return this; + } + + public LoggerMetric setPartnerName(String partnerName) { + ecompLogFieldsHandler.setPartnerName(partnerName); + return this; + } + + public LoggerMetric setResponseCode(int responseCode) { + ecompLogFieldsHandler.setResponseCode(responseCode); + return this; + } + + public LoggerMetric setResponseDesc(String responseDesc) { + ecompLogFieldsHandler.setResponseDesc(responseDesc); + return this; + } + + public LoggerMetric setOptServiceInstanceId(String serviceInstanceId) { + ecompLogFieldsHandler.setServiceInstanceId(serviceInstanceId); + return this; + } + + public LoggerMetric setOptClassName(String className) { + ecompLogFieldsHandler.setClassName(className); + return this; + } + + public LoggerMetric setTargetEntity(String targetEntity) { + ecompLogFieldsHandler.setTargetEntity(targetEntity); + return this; + } + + public LoggerMetric setTargetServiceName(String targetServiceName) { + ecompLogFieldsHandler.setTargetServiceName(targetServiceName); + return this; + } + + public LoggerMetric setTargetVirtualEntity(String targetVirtualEntity) { + ecompLogFieldsHandler.setTargetVirtualEntity(targetVirtualEntity); + return this; + } + + + + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerSupportability.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerSupportability.java new file mode 100644 index 0000000..c5c0463 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/elements/LoggerSupportability.java @@ -0,0 +1,101 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.elements; + +import org.onap.sdc.security.logging.api.ILogConfiguration; +import org.onap.sdc.security.logging.api.ILogFieldsHandler; +import org.onap.sdc.security.logging.enums.LogLevel; +import org.onap.sdc.security.logging.enums.LogMarkers; +import org.onap.sdc.security.logging.enums.LoggerSupportabilityActions; +import org.onap.sdc.security.logging.enums.StatusCode; +import org.slf4j.Logger; +import org.slf4j.MarkerFactory; + +import java.util.*; + +public class LoggerSupportability extends LoggerBase { + + public LoggerSupportability(ILogFieldsHandler ecompLogFieldsHandler, Logger logger) { + super(ecompLogFieldsHandler, MarkerFactory.getMarker(LogMarkers.SUPPORTABILITY_MARKER.text()), + logger); + } + + public static LoggerSupportability getLogger(String className) { + return LoggerFactory.getMdcLogger(LoggerSupportability.class, + org.slf4j.LoggerFactory.getLogger(className)); + } + + + public void log(LoggerSupportabilityActions action, Map componentMetaData, StatusCode statusCode, String message, Object...params) { + fillFieldsBeforeLogging(action,componentMetaData,statusCode); + super.log(LogLevel.INFO,message, params); + } + + public void log(LoggerSupportabilityActions action, StatusCode statusCode, String message, Object...params) { + log(action, null, statusCode, message, params); + } + + private static ArrayList mandatoryFields = new ArrayList<>(Arrays.asList( + ILogConfiguration.MDC_SUPPORTABLITY_ACTION, + ILogConfiguration.MDC_SUPPORTABLITY_CSAR_UUID, + ILogConfiguration.MDC_SUPPORTABLITY_CSAR_VERSION, + ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_NAME, + ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_UUID, + ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_VERSION, + ILogConfiguration.MDC_SUPPORTABLITY_STATUS_CODE)); + + private void fillFieldsBeforeLogging(LoggerSupportabilityActions action, Map componentMetaData, StatusCode statusCode) { + clear(); + if (componentMetaData!=null){ + ecompLogFieldsHandler.setSupportablityCsarUUID(componentMetaData.get(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_UUID)); + ecompLogFieldsHandler.setSupportablityCsarVersion(componentMetaData.get(ILogConfiguration.MDC_SUPPORTABLITY_CSAR_VERSION)); + ecompLogFieldsHandler.setSupportablityComponentName(componentMetaData.get(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_NAME)); + ecompLogFieldsHandler.setSupportablityComponentUUID(componentMetaData.get(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_UUID)); + ecompLogFieldsHandler.setSupportablityComponentVersion(componentMetaData.get(ILogConfiguration.MDC_SUPPORTABLITY_COMPONENT_VERSION)); + } + ecompLogFieldsHandler.setSupportablityAction(action.getName()); + ecompLogFieldsHandler.setSupportablityStatusCode(statusCode.getStatusCodeEnum()); + } + + @Override + public LoggerSupportability clear(){ + LogFieldsMdcHandler.getInstance().removeSupportablityAction(); + LogFieldsMdcHandler.getInstance().removeSupportablityCsarUUID(); + LogFieldsMdcHandler.getInstance().removeSupportablityCsarVersion(); + LogFieldsMdcHandler.getInstance().removeSupportablityComponentName(); + LogFieldsMdcHandler.getInstance().removeSupportablityComponentUUID(); + LogFieldsMdcHandler.getInstance().removeSupportablityComponentVersion(); + LogFieldsMdcHandler.getInstance().removeSupportablityStatusCode(); + return this; + } + + + @Override + public List getMandatoryFields() { + return Collections.unmodifiableList(mandatoryFields); + } + + @Override + public LoggerSupportability startTimer() { + return this; + } + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompErrorSevirity.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompErrorSevirity.java new file mode 100644 index 0000000..72a9754 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompErrorSevirity.java @@ -0,0 +1,24 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security.logging.enums; + +public enum EcompErrorSevirity { + INFO, WARN, ERROR, FATAL; +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompHeadersConstants.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompHeadersConstants.java new file mode 100644 index 0000000..d4fd02b --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompHeadersConstants.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.enums; + +public final class EcompHeadersConstants { + + public static final String USER_ID_HEADER = "USER_ID"; + public static final String USER_AGENT_HEADER = "User-Agent"; + public static final String X_ECOMP_REQUEST_ID_HEADER = "X-ECOMP-RequestID"; + public static final String X_ECOMP_INSTANCE_ID_HEADER = "X-ECOMP-InstanceID"; + public static final String X_ECOMP_SERVICE_ID_HEADER = "X-ECOMP-ServiceID"; + public static final String X_REQUEST_ID = "X-RequestID"; + public static final String X_TRANSACTION_ID_HEADER = "X-TransactionId"; + public static final String PartnerName_Unknown = "UNKNOWN"; + + private EcompHeadersConstants(){} +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompLoggerErrorCode.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompLoggerErrorCode.java new file mode 100644 index 0000000..1bc1461 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/EcompLoggerErrorCode.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.enums; + +import java.util.Arrays; +import java.util.Optional; + +public enum EcompLoggerErrorCode { + SUCCESS(0), + PERMISSION_ERROR(100), + AVAILABILITY_TIMEOUTS_ERROR(200), + DATA_ERROR(300), + SCHEMA_ERROR(400), + BUSINESS_PROCESS_ERROR(500), + UNKNOWN_ERROR(900); + + private int errorCode; + + EcompLoggerErrorCode(int errorCode) { + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } + + public static EcompLoggerErrorCode getByValue(String ecompErrorCode) { + String errorPrefix = parseCode(ecompErrorCode); + Optional optionalCode = Arrays.stream(values()).filter(v->isCode(v, errorPrefix)).findFirst(); + return optionalCode.orElse(UNKNOWN_ERROR); + } + + private static boolean isCode(EcompLoggerErrorCode ecompLoggerErrorCode, String errorPrefix) { + return String.valueOf(ecompLoggerErrorCode.getErrorCode()).contains(errorPrefix); + } + + private static String parseCode(String errorCode) { + try { + return errorCode.substring("E_".length(), 3); + } catch (StringIndexOutOfBoundsException ex) { + return UNKNOWN_ERROR.name(); + } + } + + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LogLevel.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LogLevel.java new file mode 100644 index 0000000..0252f44 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LogLevel.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security.logging.enums; + +public enum LogLevel { + INFO, + WARN, + DEBUG, + TRACE, + ERROR, + FATAL +} + diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LogMarkers.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LogMarkers.java new file mode 100644 index 0000000..74b4baf --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LogMarkers.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.enums; + +public enum LogMarkers { + DEBUG_MARKER("DEBUG_MARKER"), + ERROR_MARKER("ERROR_MARKER"), + METRIC_MARKER("METRICS"), + SUPPORTABILITY_MARKER("SUPPORTABILITY_MARKER"); + + private String text; + + LogMarkers (String text){ + this.text = text; + } + + public String text(){ + return text; + } + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LoggerSupportabilityActions.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LoggerSupportabilityActions.java new file mode 100644 index 0000000..7bb29b5 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/LoggerSupportabilityActions.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.enums; + +public enum LoggerSupportabilityActions { + IMPORT_CSAR("CREATE RESOURCE FROM CSAR"), + CREATE_RESOURCE_FROM_YAML("CREATE RESOURCE FROM YAML"), + CREATE_RI_AND_RELATIONS("CREATE RI AND RELATIONS"), + CREATE_NODES_AND_CVFCS("ADD NODES AND CVFCS"), + CREATE_ARTIFACTS("ADD ARTIFACTS"), + CREATE_SERVICE("CREATE SERVICE"), + CREATE_RESOURCE("CREATE RESOURCE"), + CREATE_PROPERTIES("ADD PROPERTIES"), + CREATE_INPUTS("ADD INPUTS"), + CREATE_POLICIES("ADD POLICIES"), + CREATE_RELATIONS("ADD RELATIONS"), + CREATE_CAPABILITY_REQUIREMENTS("CREATE CAPABILITY REQUIREMENTS"), + MERGE("MERGE"), + PROPERTY_ASSIGNMENT("PROPERTY ASSIGNMENT"), + CREATE_INSTANCE("CREATE INSTANCE"), + CREATE_RELATION("ADD RELATION"), + CREATE_GROUP_POLICY("ADD GROUP POLICY"), + CREATE_GROUPS("ADD GROUPS"), + UPDATE_PROPERTY_IN_GROUP_POLICY("UPDATE PROPERTY IN GROUP POLICY"), + UPDATE_CAPABILITY("UPDATE CAPABILITY"), + PROPERTY("ADD PROPERTY"), + UPLOAD_DOWNLOAD_ARTIFACT("UPLOAD/DOWNLOAD ARTIFACT"), + LIFECYCLE("LIFECYCLE"), + DISTRIBUTION("DISTRIBUTION"), + UPDATE_CATALOG("UPDATE CATALOG"), + ARCHIVE("ARCHIVE"), + TENANT_ISOLATION("TENANT ISOLATION"), + DOWNLOAD_ARTIFACTS("DOWNLOAD ARTIFACTS"), + UPDATE_HEAT("UPDATE HEAT"), + PARAMETERS("PARAMETERS"), + CHANGELIFECYCLESTATE("CHANGE LIFECYCLE STATE"), + VALIDATE_NAME("VALIDATE COMPONENT NAME"), + DELETE_COMPONENT_INSTANCE_ARTIFACT("DELETE COMPONENT INSTANCE ARTIFACT"), + DELETE_SERVICE("DELETE SERVICE"), + DELETE_RESOURCE("DELETE RESOURCE"), + UPDATE_RESOURCE("UPDATE RESOURCE"), + UPDATE_COMPONENT_INSTANCE("UPDATE COMPONENT INSTANCE"), + DELETE_COMPONENT_INSTANCE("DELETE COMPONENT INSTANCE"), + UPDATE_PROPERTIES("UPDATE PROPERTIES"), + RESTORE_FROM_ARCHIVE("RESTORE FROM ARCHIVE"), + UPDATE_INPUTS("UPDATE INPUTS"), + DELETE_INPUTS("DELETE INPUTS"), + ASSOCIATE_RI_TO_RI("ASSOCIATE RI TO RI"), + UN_ASSOCIATE_RI_TO_RI("UN ASSOCIATE RI TO RI"), + UPDATE_ARTIFACT("UPDATE ARTIFACT"), + GENERATE_CSAR("GENERATE CSAR"), + GENERATE_TOSCA("GENERATE TOSCA"), + UPDATE_GROUP_MEMBERS("UPDATE GROUP MEMBERS"), + UPDATE_INSTANCE_CAPABILITY_PROPERTY("UPDATE INSTANCE CAPABILITY PROPERTY"), + UPDATE_POLICY_TARGET("UPDATE POLICY TARGET"), + UPDATE_POLICIES_PROPERTIES("UPDATE POLICIES PROPERTIES"); + private String name; + + LoggerSupportabilityActions(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/Severity.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/Severity.java new file mode 100644 index 0000000..5f6b95b --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/Severity.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.enums; + +public enum Severity { + OK(0), + WARNING(1), + CRITICAL(2), + DOWN(3), + UNREACHABLE(4); + + int severityType; + + Severity(int serveryType) { + this.severityType = serveryType; + } + + public int getSeverityType() { + return severityType; + } +} + diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/StatusCode.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/StatusCode.java new file mode 100644 index 0000000..8dd6205 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/enums/StatusCode.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.enums; + +public enum StatusCode { + ERROR("ERROR"), + STARTED("STARTED"), + COMPLETE("COMPLETE"), + INPROGRESS("INPROGRESS"); + + String statusCode; + + StatusCode(String statusCode) { + this.statusCode = statusCode; + } + + public String getStatusCodeEnum() { + return statusCode; + } +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/Logger.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/Logger.java new file mode 100644 index 0000000..f1f3237 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/Logger.java @@ -0,0 +1,676 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.wrappers; + +import com.google.common.annotations.VisibleForTesting; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.onap.sdc.security.logging.elements.*; +import org.onap.sdc.security.logging.enums.EcompErrorSevirity; +import org.onap.sdc.security.logging.enums.EcompLoggerErrorCode; +import org.onap.sdc.security.logging.enums.LogLevel; +import org.slf4j.Marker; + +import java.util.UUID; + + +/** + * This class wraps {@link org.slf4j.Logger} object and provides mandatory information required by Ecomp logging rules. + * Note: All deprecated methods are supported to be compatible to the legacy code + * and have not be used by the new code + */ +public class Logger implements org.slf4j.Logger { + private final LoggerDebug debug; + private final LoggerError error; + private final LoggerMetric metric; + private final org.slf4j.Logger logger; + + @VisibleForTesting + public Logger(org.slf4j.Logger logger) { + this.logger = logger; + this.debug = LoggerFactory.getMdcLogger(LoggerDebug.class, logger); + this.error = LoggerFactory.getMdcLogger(LoggerError.class, logger); + this.metric = LoggerFactory.getMdcLogger(LoggerMetric.class, logger); + + } + + private Logger(String className) { + this(org.slf4j.LoggerFactory.getLogger(className)); + } + + public static Logger getLogger(String className) { + return new Logger(className); + } + + public static Logger getLogger(Class clazz) { + return new Logger(clazz.getName()); + } + + + public boolean isDebugEnabled() { + return logger.isDebugEnabled(); + } + + @Override + public String getName() { + return logger.getName(); + } + + public boolean isTraceEnabled() { + return logger.isTraceEnabled(); + } + + public boolean isErrorEnabled() { return logger.isErrorEnabled(); } + + public boolean isWarnEnabled() { return logger.isWarnEnabled(); } + + @Override + @Deprecated /** Please use method {@link #warn(EcompLoggerErrorCode, String, String)} **/ + public void warn(String msg) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, msg); + } + } + + @Override + @Deprecated /** Please use method {@link #warn(EcompLoggerErrorCode, String, String)} **/ + public void warn(String msg, Object o) { + + if (isWarnEnabled()) { + error.log(LogLevel.WARN, msg, o); + } + } + + public boolean isInfoEnabled() { return logger.isInfoEnabled(); } + + @Override + public void info(String msg) { + if (isInfoEnabled()) { + debug.log(LogLevel.INFO, msg); + } + } + + @Override + public void info(String msg, Object o) { + if (isInfoEnabled()) { + debug.log(LogLevel.INFO, msg, o); + } + } + + @Override + public void info(String msg, Object o, Object o1) { + if (isInfoEnabled()) { + debug.log(LogLevel.INFO, msg, o, o1); + } + } + + public void debug(String msg, Object... params) { + if (isDebugEnabled()) { + debug.log(LogLevel.DEBUG, msg, params); + } + } + + public void metric(String msg, Object... params) { + metric.log(LogLevel.INFO, msg, params); + } + + public void invoke(String remoteHost, String targetEntity, String targetServiceName, String msg, Object... params) { + + String invocationId = UUID.randomUUID().toString(); + metric.startTimer() + .stopTimer() + .setRemoteHost(remoteHost) + .setOptCustomField2(invocationId) + .setTargetServiceName(targetServiceName) + .setTargetEntity(targetEntity) + .setStatusCode(ONAPLogConstants.ResponseStatus.INPROGRESS.name()); + //(MarkerFactory.getMarker("INVOKE"), LogLevel.INFO, msg, params); + metric.log(ONAPLogConstants.Markers.INVOKE, LogLevel.INFO, msg, params); + } + +// public void invoke(HttpResponse response, String targetServiceName, String targenEntity, String msg, Object... params) { +// +// String invocationId = UUID.randomUUID().toString(); +// metric.startTimer() +// .stopTimer() +// .setRemoteHost(response.getResponse()) +// .setOptCustomField2(invocationId) +// .setTargetServiceName(targetServiceName) +// .setTargetEntity(targenEntity) +// .setStatusCode("1234"); +// //(MarkerFactory.getMarker("INVOKE"), LogLevel.INFO, msg, params); +// metric.log(MarkerFactory.getMarker("INVOKE"), LogLevel.INFO, msg, params); +// } + + public void invokeReturn(ONAPLogConstants.ResponseStatus responseStatus, String msg, Object... params) { + //String invocationId = UUID.randomUUID().toString(); + try { + metric.startTimer() + .stopTimer() + .setStatusCode(responseStatus.name()); + } catch (Exception e) { + e.printStackTrace(); + } + + metric.log(ONAPLogConstants.Markers.INVOKE_RETURN, LogLevel.INFO, msg, params); + } + + public void invokeReturn(String msg, Object... params) { + //String invocationId = UUID.randomUUID().toString(); + + metric.log(ONAPLogConstants.Markers.INVOKE_RETURN, LogLevel.INFO, msg, params); + } + + public void invokeSynchronous(String msg, Object... params) { + metric.log(ONAPLogConstants.Markers.INVOKE_SYNCHRONOUS, LogLevel.INFO, msg, params); + } + + @Override + public void debug(String msg, Throwable throwable) { + if (isDebugEnabled()) { + debug.log(LogLevel.DEBUG, msg, throwable); + } + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return false; + } + + @Override + public void debug(Marker marker, String msg) { + if (isDebugEnabled()) { + debug.log(LogLevel.DEBUG, msg); + } + } + + @Override + public void debug(Marker marker, String msg, Object o) { + if (isDebugEnabled()) { + debug.log(LogLevel.DEBUG, msg, o); + } + } + + @Override + public void debug(Marker marker, String msg, Object o, Object o1) { + if (isDebugEnabled()) { + debug.log(LogLevel.DEBUG, msg, o, o1); + } + } + + @Override + public void debug(Marker marker, String msg, Object... objects) { + if (isDebugEnabled()) { + debug.log(LogLevel.DEBUG, msg, objects); + } + } + + @Override + public void debug(Marker marker, String msg, Throwable throwable) { + if (isDebugEnabled()) { + debug.log(LogLevel.DEBUG, msg, throwable); + } + } + + public void debug(String message) { + if (isDebugEnabled()) { + debug.log(LogLevel.DEBUG, message); + } + } + + @Override + public void debug(String msg, Object o) { + if (isDebugEnabled()) { + debug.log(LogLevel.DEBUG, msg, o); + } + } + + @Override + public void debug(String msg, Object o, Object o1) { + if (isDebugEnabled()) { + debug.log(LogLevel.DEBUG, msg, o, o1); + } + } + + public void trace(String message, Object... params) { + if (isTraceEnabled()) { + debug.log(LogLevel.TRACE, message, params); + } + } + + @Override + public void trace(String msg, Throwable throwable) { + if (isTraceEnabled()) { + debug.log(LogLevel.TRACE, msg, throwable); + } + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return false; + } + + @Override + public void trace(Marker marker, String msg) { + if (isTraceEnabled()) { + debug.log(LogLevel.TRACE, msg); + } + } + + @Override + public void trace(Marker marker, String msg, Object o) { + if (isTraceEnabled()) { + debug.log(LogLevel.TRACE, msg, o); + } + } + + @Override + public void trace(Marker marker, String msg, Object o, Object o1) { + if (isTraceEnabled()) { + debug.log(LogLevel.TRACE, msg, o, o1); + } + } + + @Override + public void trace(Marker marker, String msg, Object... objects) { + if (isTraceEnabled()) { + debug.log(LogLevel.TRACE, msg, objects); + } + } + + @Override + public void trace(Marker marker, String msg, Throwable throwable) { + if (isTraceEnabled()) { + debug.log(LogLevel.TRACE, msg, throwable); + } + } + + public void trace(String msg) { + if (isTraceEnabled()) { + debug.log(LogLevel.TRACE, msg); + } + } + + @Override + public void trace(String msg, Object o) { + if (isTraceEnabled()) { + debug.log(LogLevel.TRACE, msg, o); + } + } + + @Override + public void trace(String msg, Object o, Object o1) { + if (isTraceEnabled()) { + debug.log(LogLevel.TRACE, msg, o, o1); + } + } + + public void info(String msg, Object... params) { + if (isInfoEnabled()) { + debug.log(LogLevel.INFO, msg, params); + } + } + + @Override + public void info(String msg, Throwable throwable) { + if (isInfoEnabled()) { + debug.log(LogLevel.INFO, msg, throwable); + } + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return false; + } + + @Override + public void info(Marker marker, String msg) { + if (isInfoEnabled()) { + debug.log(LogLevel.INFO, msg); + } + } + + @Override + public void info(Marker marker, String msg, Object o) { + if (isInfoEnabled()) { + debug.log(LogLevel.INFO, msg, o); + } + } + + @Override + public void info(Marker marker, String msg, Object o, Object o1) { + if (isInfoEnabled()) { + debug.log(LogLevel.INFO, msg, o, o1); + } + } + + @Override + public void info(Marker marker, String msg, Object... objects) { + if (isInfoEnabled()) { + debug.log(LogLevel.INFO, msg, objects); + } + } + + @Override + public void info(Marker marker, String msg, Throwable throwable) { + if (isInfoEnabled()) { + debug.log(LogLevel.INFO, msg, throwable); + } + } + + @Deprecated /** Please use method {@link #warn(EcompLoggerErrorCode, String, String)} **/ + public void warn(String msg, Object... params){ + if (isWarnEnabled()) { + error.log(LogLevel.WARN, msg, params); + } + } + + @Override + @Deprecated /** Please use method {@link #warn(EcompLoggerErrorCode, String, String)} **/ + public void warn(String msg, Object o, Object o1) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, msg, o, o1); + } + } + + @Override + @Deprecated /** Please use method {@link #warn(EcompLoggerErrorCode, String, String)} **/ + public void warn(String msg, Throwable throwable) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, msg, throwable); + } + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return false; + } + + @Override + @Deprecated /** Please use method {@link #warn(EcompLoggerErrorCode, String, String)} **/ + public void warn(Marker marker, String msg) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, msg); + } + } + + @Override + @Deprecated /** Please use method {@link #warn(EcompLoggerErrorCode, String, String)} **/ + public void warn(Marker marker, String msg, Object o) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, msg, o); + } + } + + @Override + @Deprecated /** Please use method {@link #warn(EcompLoggerErrorCode, String, String)} **/ + public void warn(Marker marker, String msg, Object o, Object o1) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, msg, o, o1); + } + } + + @Override + @Deprecated /** Please use method {@link #warn(EcompLoggerErrorCode, String, String)} **/ + public void warn(Marker marker, String msg, Object... objects) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, msg, objects); + } + } + + @Override + @Deprecated /** Please use method {@link #warn(EcompLoggerErrorCode, String, String)} **/ + public void warn(Marker marker, String msg, Throwable throwable) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, msg, throwable); + } + } + + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, String)} **/ + public void error(String msg, Object... params){ + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, msg, params); + } + } + + @Override + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, String)} **/ + public void error(String msg, Throwable throwable) { + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, msg, throwable); + } + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return false; + } + + @Override + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, String)} **/ + public void error(Marker marker, String msg) { + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, msg); + } + } + + @Override + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, String)} **/ + public void error(Marker marker, String msg, Object o) { + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, msg, o); + } + } + + @Override + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, String)} **/ + public void error(Marker marker, String msg, Object o, Object o1) { + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, msg, o, o1); + } + } + + @Override + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, String)} **/ + public void error(Marker marker, String msg, Object... params) { + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, msg, params); + } + } + + @Override + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, String)} **/ + public void error(Marker marker, String msg, Throwable throwable) { + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, msg, throwable); + } + } + + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, String)} **/ + public void error(String msg){ + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, msg); + } + } + + @Override + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, String)} **/ + public void error(String msg, Object o) { + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, msg, o); + } + } + + @Override + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, String)} **/ + public void error(String msg, Object o, Object o1) { + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, msg, o, o1); + } + } + + /** + * Writes out ERROR logging level message to the application error log + * @param errorLevel code representing the error severity level + * @param serviceName name of the API invoked at the logging component + * @param targetEntity name of the ECOMP component or sub-component, or external entity at which the error occurred or null + * @param errorDescription a human readable description of the error condition + * @param params optional parameters of a given error description + */ + public void error(EcompErrorSevirity errorLevel, + EcompLoggerErrorCode errorCodeEnum, + String serviceName, + String targetEntity, + String errorDescription, Object...params) { + if (isErrorEnabled()) { + error.log(errorLevel, errorCodeEnum, serviceName, targetEntity, errorDescription, params); + } + } + + /** + * Writes out ERROR logging level message to the application error log + * @param errorCodeEnum code representing the error condition + * @param serviceName name of the API invoked at the logging component + * @param targetEntity name of the ECOMP component or sub-component, or external entity at which the error occurred or null + * @param errorDescription a human readable description of the error condition + * @param params optional parameters of a given error description + */ + @Deprecated /** Please use method {@link #error(EcompLoggerErrorCode, String, ErrorLogOptionalData, String, Object...)} **/ + public void error(EcompLoggerErrorCode errorCodeEnum, + String serviceName, + String targetEntity, + String errorDescription, Object...params) { + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, errorCodeEnum, serviceName, targetEntity, errorDescription, params); + } + } + + /* Writes out ERROR logging level message to the application error LOG + * @param errorCodeEnum code representing the error condition + * @param errorDescription a human readable description of the error condition + * @param params optional parameters of a given error description + */ + + public void error(EcompLoggerErrorCode errorCodeEnum, String serviceName, + String errorDescription, Object...params) { + error(errorCodeEnum, serviceName, (String)null, errorDescription, params); + } + + /** + * Writes out ERROR logging level message to the application error log + * @param errorCodeEnum code representing the error condition + * @param serviceName name of the API invoked at the logging component + * @param errorLogOptionalData elements that contans all relevant data of the error + * @param errorDescription a human readable description of the error condition + * @param params optional parameters of a given error description + */ + public void error(EcompLoggerErrorCode errorCodeEnum, + String serviceName, + ErrorLogOptionalData errorLogOptionalData, + String errorDescription, + Object...params) { + if (isErrorEnabled()) { + error.log(LogLevel.ERROR, errorCodeEnum, serviceName, errorLogOptionalData, errorDescription, params); + } + } + + /** + * Writes out WARN logging level message to the application error log + * @param errorCodeEnum code representing the error condition + * @param serviceName name of the API invoked at the logging component + * @param targetEntity name of the ECOMP component or sub-component, or external entity at which the error occurred or null + * @param errorDescription a human readable description of the error condition + * @param params optional parameters of a given error description + */ + public void warn(EcompLoggerErrorCode errorCodeEnum, + String serviceName, + String targetEntity, + String errorDescription, Object...params) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, errorCodeEnum, serviceName, targetEntity, errorDescription, params); + } + } + + /** + * Writes out WARN logging level message to the application error log + * @param errorCodeEnum code representing the error condition + * @param serviceName name of the API invoked at the logging component + * @param errorLogOptionalData elements that contans all relevant data of the error + * @param description a human readable description of the error condition + * @param params optional parameters of a given error description + */ + public void warn(EcompLoggerErrorCode errorCodeEnum, + String serviceName, + ErrorLogOptionalData errorLogOptionalData, + String description, Object...params) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, errorCodeEnum, serviceName, errorLogOptionalData, description, params); + } + } + + /** + * Writes out WARN logging level message to the application error log + * @param errorCodeEnum code representing the error condition + * @param serviceName name of the API invoked at the logging component + * @param errorDescription a human readable description of the error condition + * @param params optional parameters of a given error description + */ + public void warn(EcompLoggerErrorCode errorCodeEnum, + String serviceName, + String errorDescription, Object...params) { + if (isWarnEnabled()) { + error.log(LogLevel.WARN, errorCodeEnum, serviceName, (String)null, errorDescription, params); + } + } + + /** + * Writes out FATAL logging level message to the application error log + * @param errorCodeEnum code representing the error condition + * @param serviceName name of the API invoked at the logging component + * @param targetEntity name of the ECOMP component or sub-component, or external entity at which the error occurred or null + * @param errorDescription a human readable description of the error condition + * @param params optional parameters of a given error description + */ + public void fatal(EcompLoggerErrorCode errorCodeEnum, + String serviceName, + String targetEntity, + String errorDescription, Object...params) { + if (isErrorEnabled()) { + error.log(LogLevel.FATAL, errorCodeEnum, serviceName, targetEntity, errorDescription, params); + } + } + + /** + * Writes out FATAL logging level message to the application error log + * @param errorCodeEnum code representing the error condition + * @param serviceName name of the API invoked at the logging component + * @param errorLogOptionalData elements that contans all relevant data of the error + * @param description a human readable description of the error condition + * @param params optional parameters of a given error description + */ + public void fatal(EcompLoggerErrorCode errorCodeEnum, String serviceName, + ErrorLogOptionalData errorLogOptionalData, + String description, Object...params) { + if (isErrorEnabled()) { + error.log(LogLevel.FATAL, errorCodeEnum, serviceName, errorLogOptionalData, description, params); + } + } +} + diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcAudit.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcAudit.java new file mode 100644 index 0000000..8d24105 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcAudit.java @@ -0,0 +1,167 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.wrappers; + +import org.apache.commons.lang3.StringUtils; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.onap.sdc.security.logging.elements.LoggerAudit; +import org.onap.sdc.security.logging.elements.LoggerBase; +import org.onap.sdc.security.logging.elements.LoggerFactory; +import org.onap.sdc.security.logging.enums.*; +import org.slf4j.MDC; +import org.slf4j.Marker; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.core.Response; +import java.util.UUID; + +public class LoggerSdcAudit extends LoggerSdcUtilBase { + + private static String AUDIT_ON = "auditOn"; + private String className; + private final LoggerAudit ecompLoggerAudit; + + public LoggerSdcAudit(Class clazz) { + this.className = clazz.getName(); + ecompLoggerAudit = LoggerFactory.getMdcLogger(LoggerAudit.class, org.slf4j.LoggerFactory.getLogger(clazz)); + } + + public void startLog(ContainerRequestContext requestContext) { + ecompLoggerAudit.clear() + .startTimer() + .setPartnerName(getPartnerName( + requestContext.getHeaderString("user-agent"), + requestContext.getHeaderString("USER_ID"), + getUrl(requestContext), + requestContext.getHeaderString("X-ONAP-PartnerName"))) + .setServiceName(getServiceName(requestContext)) + .setKeyRequestId(LoggerBase.generateKeyRequestId()) + .setKeyInvocationId(UUID.randomUUID().toString()); + MDC.put(AUDIT_ON, "true"); + } + + public void startAuditFetchLog(String partnerName, String serviceName) { + ecompLoggerAudit.clear() + .startTimer() + .setPartnerName(partnerName) + .setServiceName(serviceName) + .setOptClassName(serviceName); + MDC.put(AUDIT_ON, "true"); + } + + public static boolean isFlowBeingTakenCare() { + String auditOn = MDC.get(AUDIT_ON); + return !StringUtils.isEmpty(auditOn) && "true".equals(auditOn); + } + + //this function clears the MDC data that relevant for this class + public void clearMyData(){ + ecompLoggerAudit.clear(); + } + + public void logExit(String remoteAddress, + ContainerRequestContext requestContext, + Response.StatusType statusInfo, + LogLevel logLevel, + Severity securityLevel, + String message, + Marker marker) { + + try { + + String msg = ecompLoggerAudit.getAuditMessage() == null ? + message : ecompLoggerAudit.getAuditMessage(); + ecompLoggerAudit.stopTimer() + .setRemoteHost(remoteAddress) + .setResponseCode(convertHttpCodeToErrorCode(statusInfo.getStatusCode())) + .setStatusCodeByResponseCode(Integer.toString(statusInfo.getStatusCode())) + .setResponseDesc(statusInfo.getReasonPhrase()) + .setInstanceUUID(requestContext.getHeaderString(EcompHeadersConstants.X_ECOMP_INSTANCE_ID_HEADER)) + .setOptServiceInstanceId(requestContext.getHeaderString(EcompHeadersConstants.X_ECOMP_SERVICE_ID_HEADER)) + .setOptClassName(className) + .setOptAlertSeverity(securityLevel) + .log(marker, logLevel, msg); + } + catch (Exception e) { + log.warn("Failed to write to Audit Log. Original Message: {}", message, e); + } + finally { + MDC.put(AUDIT_ON,"false"); + } + } + + public void logEntry(String remoteAddress, + ContainerRequestContext requestContext, + LogLevel logLevel, + Severity securityLevel, + String message, + Marker marker) { + + try { + + String msg = ecompLoggerAudit.getAuditMessage() == null ? + message : ecompLoggerAudit.getAuditMessage(); + ecompLoggerAudit.stopTimer() + .setRemoteHost(remoteAddress) + .setResponseCode(EcompLoggerErrorCode.SUCCESS) + .setStatusCode(ONAPLogConstants.ResponseStatus.INPROGRESS.name()) + .setResponseDesc("") + .setInstanceUUID(requestContext.getHeaderString(EcompHeadersConstants.X_ECOMP_INSTANCE_ID_HEADER)) + .setOptServiceInstanceId(requestContext.getHeaderString(EcompHeadersConstants.X_ECOMP_SERVICE_ID_HEADER)) + .setOptClassName(className) + .setOptAlertSeverity(securityLevel) + .log(marker, logLevel, msg); + } + catch (Exception e) { + log.warn("Failed to write to Audit Log. Original Message: {}", message, e); + } + finally { + MDC.put(AUDIT_ON,"false"); + } + } + + public void logEntry(LogLevel logLevel, + Severity securityLevel, + String message, + Marker marker, + String requestId) { + + try { + + String msg = ecompLoggerAudit.getAuditMessage() == null ? + message : ecompLoggerAudit.getAuditMessage(); + ecompLoggerAudit.stopTimer() + .setKeyRequestId(requestId) + .setResponseCode(EcompLoggerErrorCode.SUCCESS) + .setStatusCode(ONAPLogConstants.ResponseStatus.COMPLETE.name()) + .setResponseDesc("") + .setOptAlertSeverity(securityLevel) + .log(marker, logLevel, msg); + } + catch (Exception e) { + log.warn("Failed to write to Audit Log. Original Message: {}", message, e); + } + finally { + MDC.put(AUDIT_ON,"false"); + } + } + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcMetrics.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcMetrics.java new file mode 100644 index 0000000..a0416bf --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcMetrics.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security.logging.wrappers; + + +import org.apache.commons.lang3.StringUtils; +import org.onap.sdc.security.logging.elements.LoggerFactory; +import org.onap.sdc.security.logging.elements.LoggerMetric; +import org.slf4j.MDC; + +public class LoggerSdcMetrics extends LoggerSdcUtilBase { + + private static String METRICS_ON = "metricsOn"; + private String className; + private final LoggerMetric ecompLoggerMetrics; + + public LoggerSdcMetrics(Class clazz) { + this.className = clazz.getName(); + ecompLoggerMetrics = LoggerFactory.getMdcLogger(LoggerMetric.class, org.slf4j.LoggerFactory.getLogger(clazz)); + } + + public void startMetricsFetchLog(String partnerName, String serviceName) { + ecompLoggerMetrics.clear() + .startTimer() + .setPartnerName(partnerName) + .setServiceName(serviceName) + .setOptClassName(serviceName); + MDC.put(METRICS_ON, "true"); + } + + public static boolean isFlowBeingTakenCare() { + String auditOn = MDC.get(METRICS_ON); + return !StringUtils.isEmpty(auditOn) && "true".equals(auditOn); + } + + //this function clears the MDC data that relevant for this class + public void clearMyData(){ + ecompLoggerMetrics.clear(); + } + +} + diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcUtilBase.java b/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcUtilBase.java new file mode 100644 index 0000000..b61259b --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/logging/wrappers/LoggerSdcUtilBase.java @@ -0,0 +1,210 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.logging.wrappers; + +import org.apache.commons.lang3.StringUtils; +import org.onap.sdc.security.logging.enums.EcompLoggerErrorCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.container.ContainerRequestContext; +import java.util.List; +import java.util.StringTokenizer; + +import static java.net.HttpURLConnection.*; + + +public class LoggerSdcUtilBase { + + protected static Logger log = LoggerFactory.getLogger(LoggerSdcUtilBase.class.getName()); + + String getRequestIDfromHeaders(List requestHeader) { + // this method gets list of type object. + // toString method returns the RequestId with brackets. + String requestHeaderString = requestHeader.toString(); + return requestHeaderString.replace("[","").replace("]",""); + } + + + + // this method translates http error code to ECOMP Logger Error code + // this is a naive translation and is not a result of any documented format ECOMP specification + protected EcompLoggerErrorCode convertHttpCodeToErrorCode(int httpResponseCode) { + if (isSuccessError(httpResponseCode)) { + return EcompLoggerErrorCode.SUCCESS; + } + + if (isSchemaError(httpResponseCode)) { + return EcompLoggerErrorCode.SCHEMA_ERROR; + } + if (isDataError(httpResponseCode)) { + return EcompLoggerErrorCode.DATA_ERROR; + } + if (isPermissionsError(httpResponseCode)) { + return EcompLoggerErrorCode.PERMISSION_ERROR; + } + if (isTimeoutOrAvailabilityError(httpResponseCode)) { + return EcompLoggerErrorCode.AVAILABILITY_TIMEOUTS_ERROR; + } + if (isBusinessProcessError(httpResponseCode)) { + return EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR; + } + return EcompLoggerErrorCode.UNKNOWN_ERROR; + } + + private boolean isTimeoutOrAvailabilityError(int httpResponseCode) { + + switch (httpResponseCode) { + case HTTP_BAD_REQUEST: + case HTTP_UNAUTHORIZED: + case HTTP_NOT_FOUND: + case HTTP_CLIENT_TIMEOUT: + case HTTP_GONE: + return true; + default: + return false; + } + + } + + private boolean isPermissionsError(int httpResponseCode) { + + switch (httpResponseCode) { + case HTTP_PAYMENT_REQUIRED: + case HTTP_FORBIDDEN: + case HTTP_BAD_METHOD: + case HTTP_PROXY_AUTH: + return true; + } + + return false; + } + + private boolean isDataError(int httpResponseCode) { + + switch (httpResponseCode) { + case HTTP_NOT_ACCEPTABLE: + case HTTP_LENGTH_REQUIRED: + case HTTP_PRECON_FAILED: + case HTTP_REQ_TOO_LONG: + case HTTP_ENTITY_TOO_LARGE: + case HTTP_UNSUPPORTED_TYPE: + return true; + } + + return false; + } + + private boolean isSchemaError(int httpResponseCode) { + return HTTP_CONFLICT == httpResponseCode; + } + + private boolean isSuccessError(int httpResponseCode) { + return httpResponseCode < 399; + } + + private boolean isBusinessProcessError(int httpResponseCode) { + return httpResponseCode > 499; + } + + protected String getPartnerName(String userAgent, String userId, String url, String xOnapPartnerName) { + + //On called side (receiver) If the API call is authenticated, then log the userid/mechid (fully qualified if that is what was provided) + if (isFound(userId)) { + return userId; + } + + String urlUser = getUserIdFromUrl(url); + if (isFound(urlUser)) { + return urlUser; + } + + //Otherwise, if X-ONAP-PartnerName was provided, then log that + if (isFound(xOnapPartnerName)){ + return xOnapPartnerName; + } + + //Otherwise, for an HTTP API call, log the part of the URI specifying the agent that the caller used to make the call + String userAgentName = getUserIdFromUserAgent(userAgent); + if (isFound(userAgentName)) { + return userAgentName; + } + + return "UNKNOWN"; + } + + private String getUserIdFromUserAgent(String userAgent) { + if (userAgent != null && userAgent.length() > 0) { + if (userAgent.toLowerCase().contains("firefox")) { + return "fireFox_FE"; + } + + if (userAgent.toLowerCase().contains("msie")) { + return "explorer_FE"; + } + + if (userAgent.toLowerCase().contains("chrome")) { + return "chrome_FE"; + } + + return userAgent; + } + return null; + } + + private String getUserIdFromUrl(String url) { + if (url != null && url.toLowerCase().contains("user")) { + StringTokenizer st = new StringTokenizer(url, "/"); + while (st.hasMoreElements()) { + if ("user".equalsIgnoreCase(st.nextToken())) { + return st.nextToken(); + } + } + } + return null; + } + + protected String getUrl(ContainerRequestContext requestContext) { + String url = ""; + + try { + if (requestContext.getUriInfo() != null && requestContext.getUriInfo().getRequestUri() != null) { + url = requestContext.getUriInfo().getRequestUri().toURL().toString(); + } + } catch (Exception ex) { + log.error("failed to get url from request context ", ex); + } + + return url; + } + + protected String getServiceName(ContainerRequestContext requestContext) { + return (requestContext.getUriInfo().getRequestUri().toString()) + .replace(requestContext.getUriInfo().getBaseUri().toString(), "/"); + } + + private boolean isFound(String value) { + if (StringUtils.isNotEmpty(value)) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/utils/RestUtils.java b/security-util-lib/src/main/java/org/onap/sdc/security/utils/RestUtils.java new file mode 100644 index 0000000..2803720 --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/utils/RestUtils.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security.utils; + +import com.google.common.annotations.VisibleForTesting; +import fj.data.Either; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHeaders; +import org.onap.sdc.security.SecurityUtil; + +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.Properties; + +public class RestUtils { + + public static void addBasicAuthHeader(Properties headers, String username, String password) { + headers.setProperty(HttpHeaders.AUTHORIZATION, getAuthHeaderValue(username,password)); + } + + private static String getAuthHeaderValue(String username, String password) { + byte[] credentials = Base64.encodeBase64((username + ":" + password).getBytes(StandardCharsets.UTF_8)); + return "Basic " + new String(credentials, StandardCharsets.UTF_8); + } + + public static void addBasicAuthHeaderWithEncryptedPassword(Map headers, String username, String password) { + String decryptedPassword = decryptPassword(password); + headers.put(HttpHeaders.AUTHORIZATION, getAuthHeaderValue(username,decryptedPassword)); + } + + @VisibleForTesting + public static String decryptPassword(String password) { + validate(password); + Either passkey = SecurityUtil.INSTANCE.decrypt(password); + if(passkey.isLeft()) { + return passkey.left().value(); + } + else { + throw new IllegalArgumentException(passkey.right().value()); + } + + } + + private static void validate(String str) { + if(StringUtils.isEmpty(str)) { + throw new IllegalArgumentException("BasicAuthorization username and/or password cannot be empty"); + } + } + +} diff --git a/security-util-lib/src/main/java/org/onap/sdc/security/utils/SecurityLogsUtils.java b/security-util-lib/src/main/java/org/onap/sdc/security/utils/SecurityLogsUtils.java new file mode 100644 index 0000000..6f34a9e --- /dev/null +++ b/security-util-lib/src/main/java/org/onap/sdc/security/utils/SecurityLogsUtils.java @@ -0,0 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.sdc.security.utils; + +import org.onap.sdc.security.logging.elements.ErrorLogOptionalData; + +public class SecurityLogsUtils { + public static String PORTAL_TARGET_ENTITY = "PORTAL"; + + public static ErrorLogOptionalData fullOptionalData(String targetEntity, String targetServiceName) { + return ErrorLogOptionalData.newBuilder().targetEntity(targetEntity) + .targetServiceName(targetServiceName).build(); + } +} diff --git a/security-util-lib/src/main/resources/key.properties b/security-util-lib/src/main/resources/key.properties new file mode 100644 index 0000000..0315075 --- /dev/null +++ b/security-util-lib/src/main/resources/key.properties @@ -0,0 +1,41 @@ +### +# ============LICENSE_START========================================== +# ONAP Portal SDK +# =================================================================== +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the “License”); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# +### + +# Properties read by the ECOMP Framework library (epsdk-fw) + +cipher.enc.key = AGLDdG4D04BKm2IxIWEr8o== \ No newline at end of file diff --git a/security-util-lib/src/test/java/org/onap/sdc/security/AuthenticationCookieUtilsTest.java b/security-util-lib/src/test/java/org/onap/sdc/security/AuthenticationCookieUtilsTest.java new file mode 100644 index 0000000..fdd354e --- /dev/null +++ b/security-util-lib/src/test/java/org/onap/sdc/security/AuthenticationCookieUtilsTest.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import org.junit.Test; +import org.onap.sdc.security.filters.SampleFilter; + +import javax.servlet.http.Cookie; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertTrue; + +public class AuthenticationCookieUtilsTest { + + private SampleFilter sessionValidationFilter = new SampleFilter(); + private ISessionValidationFilterConfiguration filterCfg = sessionValidationFilter.getFilterConfiguration(); + + @Test + public void validateThatCookieCurrentSessionTimeIncreased() throws IOException, CipherUtilException, InterruptedException { + // original cookie, pojo and servlet cookie + AuthenticationCookie authenticationCookieOriginal = new AuthenticationCookie("kuku"); + Cookie cookieWithOriginalTime = new Cookie(filterCfg.getCookieName(), AuthenticationCookieUtils.getEncryptedCookie(authenticationCookieOriginal,filterCfg )); + // cookie with increased time, pojo and servlet cookie + TimeUnit.SECONDS.sleep(1); + Cookie cookieWithIncreasedTime = AuthenticationCookieUtils.updateSessionTime(cookieWithOriginalTime, filterCfg); + AuthenticationCookie authenticationCookieIncreasedTime = AuthenticationCookieUtils.getAuthenticationCookie(cookieWithIncreasedTime, filterCfg); + // validation + long currentSessionTimeOriginal = authenticationCookieOriginal.getCurrentSessionTime(); + long currentSessionTimeIncreased = authenticationCookieIncreasedTime.getCurrentSessionTime(); + assertTrue(currentSessionTimeOriginal < currentSessionTimeIncreased); + } + + @Test + public void validateSerializationEncriptionDeserializationDecryption() throws IOException, CipherUtilException { + // original cookie, pojo and servlet cookie + AuthenticationCookie authenticationCookieOriginal = new AuthenticationCookie("kuku"); + Cookie cookieWithOriginalTime = new Cookie(filterCfg.getCookieName(), AuthenticationCookieUtils.getEncryptedCookie(authenticationCookieOriginal,filterCfg )); + // cookie with increased time, pojo and servlet cookie + AuthenticationCookie decriptedAndDeserializedAuthenticationCookie = AuthenticationCookieUtils.getAuthenticationCookie(cookieWithOriginalTime,filterCfg); + assertTrue(authenticationCookieOriginal.equals(decriptedAndDeserializedAuthenticationCookie)); + } + + + +// @Test +// public void getEncryptedCookie() { +// } +// +// @Test +// public void getAuthenticationCookie() { +// } +// +// @Test +// public void isSessionExpired() { +// } +} \ No newline at end of file diff --git a/security-util-lib/src/test/java/org/onap/sdc/security/CipherUtilTest.java b/security-util-lib/src/test/java/org/onap/sdc/security/CipherUtilTest.java new file mode 100644 index 0000000..3f60a9f --- /dev/null +++ b/security-util-lib/src/test/java/org/onap/sdc/security/CipherUtilTest.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.RandomStringUtils; +import org.junit.Test; + +import java.util.Random; + +import static org.apache.commons.codec.binary.Base64.encodeBase64String; +import static org.junit.Assert.*; + +public class CipherUtilTest { + + private static final String KEY = "AGLDdG4D04BKm2IxIWEr8o=="; + private static final String DATA = "data"; + + @Test + public void encryptDecryptPKC() throws CipherUtilException { + String generatedKey = RandomStringUtils.randomAlphabetic(16); + String base64Key = Base64.encodeBase64String(generatedKey.getBytes()); + String encrypted = CipherUtil.encryptPKC(DATA, base64Key); + assertNotEquals(DATA, encrypted); + String decrypted = CipherUtil.decryptPKC(encrypted, base64Key); + assertEquals(decrypted, DATA); + } + + @Test + public void encryptInvalidKey() { + try { + CipherUtil.encryptPKC(DATA, "invalidKey"); + fail(); + } catch (CipherUtilException ex) { + assertTrue(ex.getMessage().contains("Invalid AES key length")); + } + } + + @Test + public void decryptInvalidKey() { + try { + CipherUtil.decryptPKC(DATA, "invalidKey"); + fail(); + } catch (CipherUtilException ex) { + assertTrue(ex.getMessage().contains("length")); + } + } + + @Test + public void decryptInvalidData() { + try { + CipherUtil.decryptPKC(DATA, KEY); + fail(); + } catch (CipherUtilException ex) { + assertTrue(ex.getMessage().contains("Wrong IV length")); + } + } +} diff --git a/security-util-lib/src/test/java/org/onap/sdc/security/PasswordsTest.java b/security-util-lib/src/test/java/org/onap/sdc/security/PasswordsTest.java new file mode 100644 index 0000000..f8c8452 --- /dev/null +++ b/security-util-lib/src/test/java/org/onap/sdc/security/PasswordsTest.java @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class PasswordsTest { + + @Test + public void hashPassword() throws Exception { + String hash = Passwords.hashPassword("hello1234"); + assertTrue(Passwords.isExpectedPassword("hello1234", hash)); + + //test different salt-> result in different hash + String hash2 = Passwords.hashPassword("hello1234"); + assertFalse(hash.equals(hash2)); + + String hash3 = Passwords.hashPassword(""); + assertTrue(Passwords.isExpectedPassword("", hash3)); + + String hash4 = Passwords.hashPassword(null); + assertTrue(hash4 == null); + } + + @Test + public void isExpectedPassword() throws Exception { + //region isExpectedPassword(String password, String salt, String hash) + assertTrue(Passwords.isExpectedPassword(null, null, null)); + //valid hash + assertTrue(Passwords.isExpectedPassword("hello1234", "e0277df331f4ff8f74752ac4a8fbe03b", "6dfbad308cdf53c9ff2ee2dca811ee92f1b359586b33027580e2ff92578edbd0")); + //invalid salt + assertFalse(Passwords.isExpectedPassword("hello1234", "c0000df331f4ff8f74752ac4a00be03c", "6dfbad308cdf53c9ff2ee2dca811ee92f1b359586b33027580e2ff92578edbd0")); + assertFalse(Passwords.isExpectedPassword("hello1234", null, "6dfbad308cdf53c9ff2ee2dca811ee92f1b359586b33027580e2ff92578edbd0")); + //exacly 1 param uninitialized + assertFalse(Passwords.isExpectedPassword("hello1234", "", null)); + assertFalse(Passwords.isExpectedPassword(null, "", "hello1234")); + //no salt & no hash + assertFalse(Passwords.isExpectedPassword("hello1234", null, "hello1234")); + //endregion + + //region isExpectedPassword(String password, String expectedHash) + assertTrue(Passwords.isExpectedPassword(null, null)); + //valid hash + assertTrue(Passwords.isExpectedPassword("hello1234", "e0277df331f4ff8f74752ac4a8fbe03b:6dfbad308cdf53c9ff2ee2dca811ee92f1b359586b33027580e2ff92578edbd0")); + //invalid salt + assertFalse(Passwords.isExpectedPassword("hello1234", "c0000df331f4ff8f74752ac4a00be03c:6dfbad308cdf53c9ff2ee2dca811ee92f1b359586b33027580e2ff92578edbd0")); + //exacly 1 param uninitialized + assertFalse(Passwords.isExpectedPassword("hello1234", null)); + assertFalse(Passwords.isExpectedPassword(null, "hello1234")); + //no salt & no hash + assertFalse(Passwords.isExpectedPassword("hello1234", "hello1234")); + //endregion + } + + @Test + public void hashtest() { + String password = "123456"; + String hash = Passwords.hashPassword(password); + assertTrue(Passwords.isExpectedPassword(password, hash)); + password = "1sdfgsgd23456"; + hash = Passwords.hashPassword(password); + assertTrue(Passwords.isExpectedPassword(password, hash)); + password = "1sdfgsgd2345((*&%$%6"; + hash = Passwords.hashPassword(password); + assertTrue(Passwords.isExpectedPassword(password, hash)); + password = ""; + hash = Passwords.hashPassword(password); + assertTrue(Passwords.isExpectedPassword(password, hash)); + password = " "; + hash = Passwords.hashPassword(password); + assertTrue(Passwords.isExpectedPassword(password, hash)); + } + + +} \ No newline at end of file diff --git a/security-util-lib/src/test/java/org/onap/sdc/security/RepresentationUtilsTest.java b/security-util-lib/src/test/java/org/onap/sdc/security/RepresentationUtilsTest.java new file mode 100644 index 0000000..26c392e --- /dev/null +++ b/security-util-lib/src/test/java/org/onap/sdc/security/RepresentationUtilsTest.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import org.junit.Test; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertTrue; + +public class RepresentationUtilsTest { + + private static AuthenticationCookie originalCookie = new AuthenticationCookie("kuku"); + + @Test + public void representationE2EwithRoleNull() throws IOException { + originalCookie.setRoles(null); + String jsonStr = RepresentationUtils.toRepresentation(originalCookie); + AuthenticationCookie cookieFromJson = RepresentationUtils.fromRepresentation(jsonStr, AuthenticationCookie.class); + assertTrue(originalCookie.equals(cookieFromJson)); + } + + @Test + public void representationE2EwithRoleNotNull() throws IOException { + Set roles = new HashSet(); + roles.add("Designer"); + roles.add("Admin"); + roles.add("Tester"); + originalCookie.setRoles(roles); + String jsonStr = RepresentationUtils.toRepresentation(originalCookie); + AuthenticationCookie cookieFromJson = RepresentationUtils.fromRepresentation(jsonStr, AuthenticationCookie.class); + assertTrue(originalCookie.equals(cookieFromJson)); + } +} diff --git a/security-util-lib/src/test/java/org/onap/sdc/security/RestUtilsTest.java b/security-util-lib/src/test/java/org/onap/sdc/security/RestUtilsTest.java new file mode 100644 index 0000000..bc0ea6f --- /dev/null +++ b/security-util-lib/src/test/java/org/onap/sdc/security/RestUtilsTest.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import org.apache.http.HttpHeaders; +import org.junit.Test; +import org.onap.sdc.security.utils.RestUtils; +import static org.junit.Assert.*; + +import java.util.Properties; + + +public class RestUtilsTest { + + @Test + public void addBasicAuthHeaderTest() { + Properties headers = new Properties(); + String encryptedPassword = SecurityUtil.INSTANCE.encrypt("password").left().value(); + RestUtils.addBasicAuthHeader(headers, "userName",encryptedPassword); + String authHeader = headers.getProperty(HttpHeaders.AUTHORIZATION); + assertNotNull(authHeader); + assertTrue(authHeader.startsWith("Basic")); + } + + @Test + public void decryptPasswordSuccessTest() { + String decryptedPassword = "password"; + String encryptedPassword = SecurityUtil.INSTANCE.encrypt(decryptedPassword).left().value(); + String resultPassword = RestUtils.decryptPassword(encryptedPassword); + assertEquals(decryptedPassword, resultPassword); + } + + @Test(expected = IllegalArgumentException.class) + public void decryptEmptyPasswordTest() { + RestUtils.decryptPassword(""); + } + + @Test(expected = IllegalArgumentException.class) + public void decryptInvalidPasswordTest() { + RestUtils.decryptPassword("enc:9aS3AHtN_pR8QUGu-LPzHC7L8HO43WqOFx2s6nvrYrS"); + } +} diff --git a/security-util-lib/src/test/java/org/onap/sdc/security/SecurityUtilTest.java b/security-util-lib/src/test/java/org/onap/sdc/security/SecurityUtilTest.java new file mode 100644 index 0000000..f0a21f0 --- /dev/null +++ b/security-util-lib/src/test/java/org/onap/sdc/security/SecurityUtilTest.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security; + +import org.junit.Test; + +import java.util.Base64; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +public class SecurityUtilTest { + + @Test + public void encryptDecryptAES128() { + String data = "decrypt SUCCESS!!"; + String encrypted = SecurityUtil.INSTANCE.encrypt(data).left().value(); + assertNotEquals( data, encrypted ); + byte[] decryptMsg = Base64.getDecoder().decode(encrypted); + assertEquals( SecurityUtil.INSTANCE.decrypt( decryptMsg , false ).left().value() ,data ); + assertEquals( SecurityUtil.INSTANCE.decrypt( encrypted.getBytes() , true ).left().value() ,data ); + } + + @Test + public void obfuscateKey() { + String key = "abcdefghij123456"; + String expectedkey = "********ij123456"; + String obfuscated = SecurityUtil.INSTANCE.obfuscateKey( key ); + System.out.println( obfuscated ); + assertEquals( obfuscated , expectedkey ); + } +} \ No newline at end of file diff --git a/security-util-lib/src/test/java/org/onap/sdc/security/filters/RestrictionAccessFilterTest.java b/security-util-lib/src/test/java/org/onap/sdc/security/filters/RestrictionAccessFilterTest.java new file mode 100644 index 0000000..20f0d05 --- /dev/null +++ b/security-util-lib/src/test/java/org/onap/sdc/security/filters/RestrictionAccessFilterTest.java @@ -0,0 +1,207 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.filters; + +import org.apache.http.impl.client.CloseableHttpClient; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.sdc.security.*; + +import javax.servlet.http.Cookie; +import java.io.IOException; +import java.security.InvalidParameterException; +import java.util.HashSet; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +@RunWith(MockitoJUnitRunner.class) +public class RestrictionAccessFilterTest { + + private static final String jsonResponseFromPortal = "{\"orgId\":null,\"managerId\":null,\"firstName\":\"NAME\",\"middleInitial\":null,\"lastName\":\"FAMILY\",\"phone\":null,\"email\":\"abc123@test.com\",\"hrid\":null,\"orgUserId\":\"abc123\",\"orgCode\":null,\"orgManagerUserId\":null,\"jobTitle\":null," + + "\"loginId\":\"abc123\",\"active\":true,\"roles\":[%s]}"; + private static final String rolesJson = "{\"id\":\"1234\",\"name\":\"designer\",\"roleFunctions\":[\"read\",\"write\"]}"; + + private static final String userId = "abc123"; + + @Mock + private CloseableHttpClient httpClient; + @Mock + private ISessionValidationFilterConfiguration configuration; + @Mock + private ISessionValidationCookieConfiguration cookieConfig; + @Mock + private IUsersThreadLocalHolder threadLocalUtils; + @Mock + private AuthenticationCookie authenticationCookie; + @Mock + private PortalClient portalClient; + + private RestrictionAccessFilter filter; + + @Before + public void setUp() { + mockCreateFilter(configuration, threadLocalUtils, portalClient); + assertNotNull(filter); + } + + private void mockCreateFilter(ISessionValidationFilterConfiguration sessionConfig, IUsersThreadLocalHolder threadLocalUtils, PortalClient portalClient) { + filter = new RestrictionAccessFilter(sessionConfig, threadLocalUtils, portalClient); + } + +// @Test(expected = InvalidParameterException.class) +// public void filterConfigurationObjectCreationFailedWhenPropertyIsNotSet() { +// when(configuration.getAuthCookie()).thenReturn(cookieConfig); +// when(cookieConfig.getRedirectURL()).thenReturn("does_not_exist"); +// filter = new RestrictionAccessFilter(configuration, portalClient, threadLocalUtils); +// } + + @Test (expected = RedirectException.class) + public void authorizeUserOnSessionExpirationWhenUsersDifferent() throws RedirectException { + Cookie[] cookies = new Cookie [1] ; + cookies[0] = new Cookie(RestrictionAccessFilter.CSP_USER_ID, "user1"); + filter.authorizeUserOnSessionExpiration(authenticationCookie, cookies); + } + + @Test (expected = RedirectException.class) + public void authorizeUserOnSessionExpirationWhenUserRolesDifferent() throws RedirectException, IOException { + when(authenticationCookie.getUserID()).thenReturn(userId); + RestrictionAccessFilter spyFilter2 = spy(filter); + HashSet roles = new HashSet<>(); + roles.add("b"); + Cookie[] cookies = new Cookie [] {new Cookie(RestrictionAccessFilter.CSP_USER_ID, userId)}; + when(authenticationCookie.getRoles()).thenReturn(roles); + spyFilter2.authorizeUserOnSessionExpiration(authenticationCookie, cookies); + } + + @Test (expected = RedirectException.class) + public void authorizeUserOnSessionExpirationWhenUserRolesDisappearInCookie() throws RedirectException, IOException { + when(authenticationCookie.getUserID()).thenReturn(userId); + RestrictionAccessFilter spyFilter2 = spy(filter); + HashSet roles = new HashSet<>(); + Cookie[] cookies = new Cookie [] {new Cookie(RestrictionAccessFilter.CSP_USER_ID, userId)}; + when(authenticationCookie.getRoles()).thenReturn(roles); + spyFilter2.authorizeUserOnSessionExpiration(authenticationCookie, cookies); + } + + @Test (expected = RedirectException.class) + public void authorizeUserOnSessionExpirationWhenUserRolesRetrievedFromPortalAndMatch() throws RedirectException, IOException { + when(authenticationCookie.getUserID()).thenReturn(userId); + PortalClient spyFilter = spy(portalClient); + RestrictionAccessFilter spyFilter2 = spy(filter); + HashSet roles = new HashSet<>(); + roles.add("DESIGNER"); + + when(authenticationCookie.getRoles()).thenReturn(roles); + Cookie[] cookies = new Cookie [] {new Cookie(RestrictionAccessFilter.CSP_USER_ID, userId)}; + spyFilter2.authorizeUserOnSessionExpiration(authenticationCookie, cookies); + + } + + @Test (expected = RedirectException.class) + public void authorizeUserOnSessionExpirationWhenUserRolesRetrievedFromPortalAndEmpty() throws RedirectException, IOException { + HashSet roles = new HashSet<>(); + roles.add("b"); + when(authenticationCookie.getUserID()).thenReturn(userId); + when(authenticationCookie.getRoles()).thenReturn(roles); + PortalClient spyFilter = spy(portalClient); + RestrictionAccessFilter spyFilter2 = spy(filter); + + Cookie[] cookies = new Cookie [] {new Cookie(RestrictionAccessFilter.CSP_USER_ID, userId)}; + spyFilter2.authorizeUserOnSessionExpiration(authenticationCookie, cookies); + } + + @Test (expected = RedirectException.class) + public void authorizeUserOnSessionExpirationWhenUserRolesCantBeRetrievedFromPortal() throws RedirectException, IOException { + HashSet roles = new HashSet<>(); + roles.add("b"); + when(authenticationCookie.getUserID()).thenReturn(userId); + when(authenticationCookie.getRoles()).thenReturn(roles); + RestrictionAccessFilter spyFilter2 = spy(filter); + + Cookie[] cookies = new Cookie [] {new Cookie(RestrictionAccessFilter.CSP_USER_ID, userId)}; + spyFilter2.authorizeUserOnSessionExpiration(authenticationCookie, cookies); + } + +// @Test (expected = RedirectException.class) +// public void authorizeUserOnSessionExpirationWhenHttpRequestFailed() throws RedirectException, IOException, RestrictionAccessFilterException { +// HashSet roles = new HashSet<>(); +// roles.add("b"); +// when(authenticationCookie.getUserID()).thenReturn(userId); +// when(authenticationCookie.getRoles()).thenReturn(roles); +//// PortalClient spyFilter = spy(portalClient); +// RestrictionAccessFilter spyFilter2 = spy(filter); +//// when(spyFilter.fetchUserRolesFromPortal()*/ +// doThrow(IOException.class).when(portalClient).fetchUserRolesFromPortal(eq(userId)); +// Cookie[] cookies = new Cookie [] {new Cookie(RestrictionAccessFilter.CSP_USER_ID, userId)}; +// spyFilter2.authorizeUserOnSessionExpiration(authenticationCookie, cookies); +// } + + @Test (expected = RedirectException.class) + public void authorizeUserOnSessionExpirationWhenCspUserCookieIsNull() throws RedirectException, IOException { + when(authenticationCookie.getUserID()).thenReturn(userId); + + Cookie[] cookies = new Cookie [] {new Cookie(RestrictionAccessFilter.CSP_USER_ID, null)}; + filter.authorizeUserOnSessionExpiration(authenticationCookie, cookies); + } + + @Test (expected = RedirectException.class) + public void authorizeUserOnSessionExpirationWhenCookieNotFound() throws RedirectException, IOException { + assertNotNull(filter); + Cookie[] cookies = new Cookie [] {new Cookie("someCookie", userId)}; + filter.authorizeUserOnSessionExpiration(authenticationCookie, cookies); + } + + @Test + public void getCspUserIdWhenMoreThanOneUserIdExists() throws RedirectException { + Cookie[] cookies = new Cookie [] { + new Cookie(RestrictionAccessFilter.CSP_USER_ID, userId), + new Cookie(RestrictionAccessFilter.CSP_USER_ID, "other")}; + assertEquals(userId, filter.getCookieValue(cookies, RestrictionAccessFilter.CSP_USER_ID)); + } + + @Test() + public void getCspUserIdWhenUserIdIsNull() throws RedirectException { + Cookie[] cookies = new Cookie [] {new Cookie(RestrictionAccessFilter.CSP_USER_ID, null)} ; + assertNull(filter.getCookieValue(cookies, RestrictionAccessFilter.CSP_USER_ID)); + } + + @Test(expected=RedirectException.class) + public void getCspUserIdWhenUserIdCookieNotFound() throws RedirectException { + Cookie[] cookies = new Cookie [] {new Cookie("someName", "someValue")} ; + filter.getCookieValue(cookies, RestrictionAccessFilter.CSP_USER_ID); + } + + @Test(expected=RedirectException.class) + public void getCspUserIdWhenNoCookiesFound() throws RedirectException { + Cookie[] cookies = new Cookie [] {}; + filter.getCookieValue(cookies, RestrictionAccessFilter.CSP_USER_ID); + } + + @Test(expected=RedirectException.class) + public void getCspUserIdWhenCookiesNull() throws RedirectException { + filter.getCookieValue(null, RestrictionAccessFilter.CSP_USER_ID); + } + + +} diff --git a/security-util-lib/src/test/java/org/onap/sdc/security/filters/SessionValidationFilterTest.java b/security-util-lib/src/test/java/org/onap/sdc/security/filters/SessionValidationFilterTest.java new file mode 100644 index 0000000..9c5fd89 --- /dev/null +++ b/security-util-lib/src/test/java/org/onap/sdc/security/filters/SessionValidationFilterTest.java @@ -0,0 +1,237 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.sdc.security.filters; + +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.sdc.security.AuthenticationCookie; +import org.onap.sdc.security.AuthenticationCookieUtils; +import org.onap.sdc.security.CipherUtilException; +import org.onap.sdc.security.RepresentationUtils; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class SessionValidationFilterTest { + + @Mock + private HttpServletRequest request; + @Spy + private HttpServletResponse response; + @Mock + private FilterChain filterChain; + @Mock + private FilterConfig filterConfig; + + // implementation of SessionValidationFilter + @InjectMocks + @Spy + private SampleFilter sessionValidationFilter = new SampleFilter(); + + @Before + public void setUpClass() throws ServletException { + sessionValidationFilter.init(filterConfig); + } + + @Test + public void excludedUrlHealthcheck() throws IOException, ServletException { + when(request.getPathInfo()).thenReturn("/healthCheck"); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(filterChain, times(1)).doFilter(request, response); + } + + @Test + public void excludedUrlUpload() throws IOException, ServletException { + when(request.getPathInfo()).thenReturn("/upload/123"); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(filterChain, times(1)).doFilter(request, response); + } + + // case when url pattern in web.xml is forward slash (/) + @Test + public void pathInfoIsNull() throws IOException, ServletException { + when(request.getServletPath()).thenReturn("/upload/2"); + when(request.getPathInfo()).thenReturn(null); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(filterChain, times(1)).doFilter(request, response); + } + + @Test + public void noCookiesInRequest() throws IOException, ServletException { + when(request.getPathInfo()).thenReturn("/resource"); + when(request.getCookies()).thenReturn(new Cookie[0]); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(sessionValidationFilter, times(1)).handleRedirectException(response); + } + + @Test + public void nullCookiesInRequest() throws IOException, ServletException { + when(request.getPathInfo()).thenReturn("/resource"); + when(request.getCookies()).thenReturn(null); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(sessionValidationFilter, times(1)).handleRedirectException(response); + } + + @Test + public void noCookiesWithCorrectNameInRequest() throws IOException, ServletException { + when(request.getPathInfo()).thenReturn("/resource"); + String newNameNotContainsRealName = sessionValidationFilter.getFilterConfiguration().getCookieName().substring(1); + Cookie cookie = new Cookie("fake" + newNameNotContainsRealName + "fake2", RepresentationUtils.toRepresentation(new AuthenticationCookie("kuku"))); + when(request.getCookies()).thenReturn(new Cookie[]{cookie}); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(sessionValidationFilter, times(1)).handleRedirectException(response); + } + + @Test + public void cookieMaxSessionTimedOutAndUserIsNotAuthorized() throws IOException, ServletException, CipherUtilException { + when(request.getPathInfo()).thenReturn("/resource"); + AuthenticationCookie authenticationCookie = new AuthenticationCookie(SampleFilter.FAILED_ON_USER_AUTH); + // set max session time to timout value + long maxSessionTimeOut = sessionValidationFilter.getFilterConfiguration().getMaxSessionTimeOut(); + long startTime = authenticationCookie.getMaxSessionTime(); + long timeout = startTime - maxSessionTimeOut - 1000l; + authenticationCookie.setMaxSessionTime(timeout); + Cookie cookie = new Cookie(sessionValidationFilter.getFilterConfiguration().getCookieName(), AuthenticationCookieUtils.getEncryptedCookie(authenticationCookie, sessionValidationFilter.getFilterConfiguration())); + + when(request.getCookies()).thenReturn(new Cookie[]{cookie}); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(sessionValidationFilter, times(1)).handleRedirectException(response); + } + + @Test + public void cookieMaxSessionTimedOutAndUserIsAuthorized() throws IOException, ServletException, CipherUtilException { + when(request.getPathInfo()).thenReturn("/resource"); + AuthenticationCookie authenticationCookie = new AuthenticationCookie("userId"); + // set max session time to timout value + long maxSessionTimeOut = sessionValidationFilter.getFilterConfiguration().getMaxSessionTimeOut(); + long startTime = authenticationCookie.getMaxSessionTime(); + long timeout = startTime - maxSessionTimeOut - 1000l; + authenticationCookie.setMaxSessionTime(timeout); + Cookie cookie = new Cookie(sessionValidationFilter.getFilterConfiguration().getCookieName(), AuthenticationCookieUtils.getEncryptedCookie(authenticationCookie, sessionValidationFilter.getFilterConfiguration())); + + when(request.getCookies()).thenReturn(new Cookie[]{cookie}); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(filterChain, times(1)).doFilter(request, response); + } + + @Test + public void cookieSessionIdleAndUserIsNotAuthorized() throws IOException, ServletException, CipherUtilException { + when(request.getPathInfo()).thenReturn("/resource"); + AuthenticationCookie authenticationCookie = new AuthenticationCookie(SampleFilter.FAILED_ON_USER_AUTH); + // set session time to timout to idle + long idleSessionTimeOut = sessionValidationFilter.getFilterConfiguration().getSessionIdleTimeOut(); + long sessionStartTime = authenticationCookie.getCurrentSessionTime(); + long timeout = sessionStartTime - idleSessionTimeOut - 2000; + authenticationCookie.setCurrentSessionTime(timeout); + Cookie cookie = new Cookie(sessionValidationFilter.getFilterConfiguration().getCookieName(), AuthenticationCookieUtils.getEncryptedCookie(authenticationCookie, sessionValidationFilter.getFilterConfiguration())); + + when(request.getCookies()).thenReturn(new Cookie[]{cookie}); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(sessionValidationFilter, times(1)).handleRedirectException(response); + } + + @Test + public void cookieSessionIdleAndUserIsAuthorized() throws IOException, ServletException, CipherUtilException { + when(request.getPathInfo()).thenReturn("/resource"); + AuthenticationCookie authenticationCookie = new AuthenticationCookie("kuku"); + // set session time to timout to idle + long idleSessionTimeOut = sessionValidationFilter.getFilterConfiguration().getSessionIdleTimeOut(); + long sessionStartTime = authenticationCookie.getCurrentSessionTime(); + long timeout = sessionStartTime - idleSessionTimeOut - 2000; + authenticationCookie.setCurrentSessionTime(timeout); + Cookie cookie = new Cookie(sessionValidationFilter.getFilterConfiguration().getCookieName(), AuthenticationCookieUtils.getEncryptedCookie(authenticationCookie, sessionValidationFilter.getFilterConfiguration())); + + when(request.getCookies()).thenReturn(new Cookie[]{cookie}); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(filterChain, times(1)).doFilter(request, response); + } + + @Test + public void cookieSessionIsNotExpiredRoleAssignmentDone() throws IOException, ServletException, CipherUtilException { + when(request.getPathInfo()).thenReturn("/resource"); + AuthenticationCookie authenticationCookie = new AuthenticationCookie(SampleFilter.FAILED_ON_ROLE); + Cookie cookie = new Cookie(sessionValidationFilter.getFilterConfiguration().getCookieName(), AuthenticationCookieUtils.getEncryptedCookie(authenticationCookie, sessionValidationFilter.getFilterConfiguration())); + + when(request.getCookies()).thenReturn(new Cookie[]{cookie}); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(sessionValidationFilter, times(0)).handleRedirectException(response); + } + + + @Test + public void requestThatPassFilter() throws IOException, ServletException, CipherUtilException { + when(request.getPathInfo()).thenReturn("/resource"); + + AuthenticationCookie authenticationCookie = new AuthenticationCookie("kuku"); + Cookie cookie = new Cookie(sessionValidationFilter.getFilterConfiguration().getCookieName(), AuthenticationCookieUtils.getEncryptedCookie(authenticationCookie, sessionValidationFilter.getFilterConfiguration())); + + when(request.getCookies()).thenReturn(new Cookie[]{cookie}); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(filterChain, times(1)).doFilter(request, response); + } + +// test validate contains + @Test + public void requestThatPassFilterWithCookieNameAsPartOfOtherString() throws IOException, ServletException, CipherUtilException { + when(request.getPathInfo()).thenReturn("/resource"); + + AuthenticationCookie authenticationCookie = new AuthenticationCookie("kuku"); + Cookie cookie = new Cookie("some" +sessionValidationFilter.getFilterConfiguration().getCookieName() + "Thing", AuthenticationCookieUtils.getEncryptedCookie(authenticationCookie, sessionValidationFilter.getFilterConfiguration())); + + when(request.getCookies()).thenReturn(new Cookie[]{cookie}); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(filterChain, times(1)).doFilter(request, response); + } + + @Test + public void w_requestThatThrowCipherUtilException() throws IOException, ServletException, CipherUtilException { + when(request.getPathInfo()).thenReturn("/resource"); + + AuthenticationCookie authenticationCookie = new AuthenticationCookie("kuku"); + Cookie cookie = new Cookie(sessionValidationFilter.getFilterConfiguration().getCookieName(), AuthenticationCookieUtils.getEncryptedCookie(authenticationCookie, sessionValidationFilter.getFilterConfiguration())); + + when(request.getCookies()).thenReturn(new Cookie[]{cookie}); + String oldKey = sessionValidationFilter.getFilterConfiguration().getSecurityKey(); + sessionValidationFilter.setSecurityKey(""); + sessionValidationFilter.doFilter(request, response, filterChain); + Mockito.verify(sessionValidationFilter, times(1)).handleRedirectException(response); + sessionValidationFilter.setSecurityKey(oldKey); + } + +} \ No newline at end of file -- cgit 1.2.3-korg