From 21a8761f684745bb300e075c7e98ad897ace9eed Mon Sep 17 00:00:00 2001 From: st782s Date: Tue, 30 Jan 2018 17:29:36 -0500 Subject: Security/ Package Name changes Issue-ID: PORTAL-174, PORTAL-157, PORTAL-156, PORTAL-148, PORTAL-145, PORTAL-140, PORTAL-133, PORTAL-121, PORTAL-111, PORTAL-88 Includes security fixes, Role Centralization, replace certain ECOMP occurrences etc Change-Id: I3c8b706709c6b92e646e3cbe50c2d660e8a46ef4 Signed-off-by: st782s --- .../onap/portalapp/service/AdminAuthExtension.java | 53 ++++ .../onap/portalapp/service/EPProfileService.java | 54 ++++ .../portalapp/service/EPProfileServiceImpl.java | 89 +++++++ .../service/RemoteWebServiceCallService.java | 72 +++++ .../service/sessionmgt/CoreTimeoutHandler.java | 183 +++++++++++++ .../service/sessionmgt/ManageService.java | 125 +++++++++ .../service/sessionmgt/SessionCommunication.java | 290 +++++++++++++++++++++ .../service/sessionmgt/TimeoutHandler.java | 269 +++++++++++++++++++ 8 files changed, 1135 insertions(+) create mode 100644 ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/AdminAuthExtension.java create mode 100644 ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/EPProfileService.java create mode 100644 ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/EPProfileServiceImpl.java create mode 100644 ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/RemoteWebServiceCallService.java create mode 100644 ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/CoreTimeoutHandler.java create mode 100644 ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/ManageService.java create mode 100644 ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/SessionCommunication.java create mode 100644 ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/TimeoutHandler.java (limited to 'ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service') diff --git a/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/AdminAuthExtension.java b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/AdminAuthExtension.java new file mode 100644 index 00000000..7f401ff6 --- /dev/null +++ b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/AdminAuthExtension.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.service; + +import org.onap.portalapp.portal.domain.EPUser; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + + +@Service("adminAuthExtension") +@Transactional +public class AdminAuthExtension { + + public void saveUserExtension(EPUser user){ + //app's developer implement their own logic here, like updating app's related tables + } + +} diff --git a/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/EPProfileService.java b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/EPProfileService.java new file mode 100644 index 00000000..a08e2748 --- /dev/null +++ b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/EPProfileService.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.service; + +import java.util.List; + +import org.onap.portalapp.portal.domain.EPUser; +import org.onap.portalsdk.core.domain.Profile; + + +public interface EPProfileService { + List findAll(); + + Profile getProfile(int id); + + EPUser getUser(String id); + + void saveUser(EPUser user); +} diff --git a/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/EPProfileServiceImpl.java b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/EPProfileServiceImpl.java new file mode 100644 index 00000000..35090d94 --- /dev/null +++ b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/EPProfileServiceImpl.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.service; + +import java.util.List; + +import org.onap.portalapp.portal.domain.EPUser; +import org.onap.portalapp.portal.logging.aop.EPMetricsLog; +import org.onap.portalsdk.core.dao.ProfileDao; +import org.onap.portalsdk.core.domain.Profile; +import org.onap.portalsdk.core.service.DataAccessService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("epProfileService") +@Transactional +@org.springframework.context.annotation.Configuration +@EnableAspectJAutoProxy +@EPMetricsLog +public class EPProfileServiceImpl implements EPProfileService { + + @Autowired + private ProfileDao profileDao; + + @Autowired + private DataAccessService dataAccessService; + + @SuppressWarnings("unchecked") + public List findAll() { + return getDataAccessService().getList(Profile.class, null); + } + + public EPUser getUser(String userId) { + return (EPUser) getDataAccessService().getDomainObject(EPUser.class, Long.parseLong(userId), null); + } + + public void saveUser(EPUser user) { + getDataAccessService().saveDomainObject(user, null); + } + + public Profile getProfile(int id) { + return profileDao.getProfile(id); + } + + public DataAccessService getDataAccessService() { + return dataAccessService; + } + + public void setDataAccessService(DataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } +} diff --git a/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/RemoteWebServiceCallService.java b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/RemoteWebServiceCallService.java new file mode 100644 index 00000000..91b9e0cf --- /dev/null +++ b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/RemoteWebServiceCallService.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.service; + +public interface RemoteWebServiceCallService { + + /** + * Answers whether the specified credentials match application information + * in the database. + * + * @param secretKey + * Key used to decrypt passwords; ignored if null. + * @param requestUebKey + * UEB key that identifies the application + * @param requestUserName + * User name for the application + * @param requestPassword + * Password for the application + * @return True if the UEB key and the credentials match the database + * entries; else false. + * @throws Exception + * If decryption fails. + */ + public boolean verifyRESTCredential(String secretKey, String requestUebKey, String requestUserName, + String requestPassword) throws Exception; + + /** + * + * @param requestUebKey + * UEB key + * @return boolean + * @throws Exception + * on error + */ + public boolean verifyAppKeyCredential(String requestUebKey) throws Exception; + +} diff --git a/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/CoreTimeoutHandler.java b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/CoreTimeoutHandler.java new file mode 100644 index 00000000..03bc7296 --- /dev/null +++ b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/CoreTimeoutHandler.java @@ -0,0 +1,183 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.service.sessionmgt; + +import java.util.Calendar; +import java.util.Hashtable; +import java.util.Map; + +import javax.servlet.http.HttpSession; + +import org.onap.portalapp.portal.logging.aop.EPMetricsLog; +import org.onap.portalsdk.core.domain.sessionmgt.TimeoutVO; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.onboarding.util.PortalApiConstants; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Service +@org.springframework.context.annotation.Configuration +@EnableAspectJAutoProxy +@EPMetricsLog +public class CoreTimeoutHandler { + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CoreTimeoutHandler.class); + + public static final Map sessionMap = new Hashtable(); + public static final Integer repeatInterval = 15 * 60; // 15 minutes + ObjectMapper mapper = new ObjectMapper(); + + public static void sessionCreated(String portalJSessionId, String jSessionId, HttpSession session) { + + storeMaxInactiveTime(session); + + // this key is a combination of portal jsession id and app session id + session.setAttribute(PortalApiConstants.PORTAL_JSESSION_ID, jSessionKey(jSessionId, portalJSessionId)); + sessionMap.put((String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID), session); + + } + + protected static void storeMaxInactiveTime(HttpSession session) { + + if (session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME) == null) + session.setAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME, session.getMaxInactiveInterval()); + } + + public static void sessionDestroyed(HttpSession session) { + + try { + sessionMap.remove((String) session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID)); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "sessionDestroyed failed on session " + session.getId(), e); + } + + } + + public String gatherSessionExtenstions() { + + Map sessionTimeoutMap = new Hashtable(); + String jsonMap = ""; + + for (String jSessionKey : sessionMap.keySet()) { + + try { + // get the expirytime in seconds + HttpSession session = sessionMap.get(jSessionKey); + + Long lastAccessedTimeMilliSec = session.getLastAccessedTime(); + Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L; + // Long currentTimeMilliSec = Calendar.getInstance().getTimeInMillis() ; + // (maxIntervalMilliSec - (currentTimeMilliSec - lastAccessedTimeMilliSec) + ; + Calendar instance = Calendar.getInstance(); + instance.setTimeInMillis(session.getLastAccessedTime()); + logger.info(EELFLoggerDelegate.errorLogger, + "gatherSessionExtenstions: Session Management: Last Accessed time for " + jSessionKey + ": " + + instance.getTime()); + + Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; + + sessionTimeoutMap.put(portalJSessionId(jSessionKey), + new TimeoutVO(jSessionId(jSessionKey), sessionTimOutMilliSec)); + + jsonMap = mapper.writeValueAsString(sessionTimeoutMap); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "gatherSessionExtenstions failed", e); + } + } + + return jsonMap; + + } + + public void updateSessionExtensions(String sessionTimeoutMapStr) throws Exception { + + Map sessionTimeoutMap; + try { + TypeReference> typeRef = new TypeReference>() { + }; + + sessionTimeoutMap = mapper.readValue(sessionTimeoutMapStr, typeRef); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "updateSessionExtensions failed 1", e); + return; + } + for (String jPortalSessionId : sessionTimeoutMap.keySet()) { + try { + + TimeoutVO extendedTimeoutVO = mapper + .readValue(mapper.writeValueAsString(sessionTimeoutMap.get(jPortalSessionId)), TimeoutVO.class); + HttpSession session = sessionMap.get(jSessionKey(extendedTimeoutVO.getjSessionId(), jPortalSessionId)); + + if (session == null) { + continue; + } + + Long lastAccessedTimeMilliSec = session.getLastAccessedTime(); + Long maxIntervalMilliSec = session.getMaxInactiveInterval() * 1000L; + Long sessionTimOutMilliSec = maxIntervalMilliSec + lastAccessedTimeMilliSec; + + Long maxTimeoutTimeMilliSec = extendedTimeoutVO.getSessionTimOutMilliSec(); + if (maxTimeoutTimeMilliSec > sessionTimOutMilliSec) { + logger.debug(EELFLoggerDelegate.debugLogger, + "updateSessionExtensions: Session Management: updated session max idle time"); + session.setMaxInactiveInterval((int) (maxTimeoutTimeMilliSec - lastAccessedTimeMilliSec) / 1000); + } + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, + "updateSessionExtensions failed", e); + } + + } + + } + + protected static String jSessionKey(String jSessionId, String portalJSessionId) { + return portalJSessionId + "-" + jSessionId; + } + + protected String portalJSessionId(String jSessionKey) { + return jSessionKey.split("-")[0]; + } + + protected String jSessionId(String jSessionKey) { + return jSessionKey.split("-")[1]; + } + +} diff --git a/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/ManageService.java b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/ManageService.java new file mode 100644 index 00000000..3c08f910 --- /dev/null +++ b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/ManageService.java @@ -0,0 +1,125 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.service.sessionmgt; + +import java.text.ParseException; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.onap.portalapp.portal.logging.aop.EPMetricsLog; +import org.onap.portalapp.portal.service.EPAppService; +import org.onap.portalapp.portal.transport.OnboardingApp; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.onboarding.listener.PortalTimeoutHandler; +import org.onap.portalsdk.core.util.SystemProperties; +import org.quartz.CronExpression; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +@Service("manageService") +@org.springframework.context.annotation.Configuration +@EnableAspectJAutoProxy +@EPMetricsLog +public class ManageService implements PortalTimeoutHandler.SessionCommInf { + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ManageService.class); + + @Autowired + private EPAppService appService; + + @Autowired + private SessionCommunication sessionCommunication; + + public Integer fetchSessionSlotCheckInterval(String... params) { + + String defaultCronExpressionStr = "0 0/5 * * * ? *"; + String cronExpressionStr = SystemProperties.getProperty(SystemProperties.SESSIONTIMEOUT_FEED_CRON); + + if (cronExpressionStr == null) { + cronExpressionStr = defaultCronExpressionStr; + } + + CronExpression cal = null; + try { + cal = new CronExpression(cronExpressionStr); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + final Date nowTime = Calendar.getInstance().getTime(); + Date nextTime = cal.getNextValidTimeAfter(nowTime); + Date nextNextTime = cal.getNextValidTimeAfter(nextTime); + + final int timeDiff = (int)(nextNextTime.getTime()-nextTime.getTime()); + logger.debug(EELFLoggerDelegate.debugLogger, "Time interval between subsequent session checks " + timeDiff); + + return timeDiff; + } + + public void extendSessionTimeOuts(String... params) { + try { + String sessionMap = params[3]; + + logger.debug(EELFLoggerDelegate.debugLogger, "Extending the App sessions for last minute request: " + sessionMap); + + if (StringUtils.isEmpty(sessionMap)) { + logger.error(EELFLoggerDelegate.errorLogger, "extendSessionTimeOuts: Skipping session updates since the portal session value is empty."); + } else { + List appList = appService.getEnabledNonOpenOnboardingApps(); + for (OnboardingApp onApp : appList) { + sessionCommunication.pingSession(onApp, sessionMap); + } + updateSessionExtensions(sessionMap); + sessionCommunication.clear(false); + } + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "extendSessionTimeOuts failed", e); + } + } + + public String gatherSessionExtenstions() { + return PortalTimeoutHandler.gatherSessionExtensions(); + } + + public void updateSessionExtensions(String sessionTimeoutMapStr) throws Exception { + PortalTimeoutHandler.updateSessionExtensions(sessionTimeoutMapStr); + } + +} diff --git a/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/SessionCommunication.java b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/SessionCommunication.java new file mode 100644 index 00000000..ee525796 --- /dev/null +++ b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/SessionCommunication.java @@ -0,0 +1,290 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.service.sessionmgt; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.UUID; + +import javax.servlet.http.HttpServletResponse; + +import org.onap.portalapp.portal.logging.aop.EPAuditLog; +import org.onap.portalapp.portal.logging.aop.EPMetricsLog; +import org.onap.portalapp.portal.logging.format.EPAppMessagesEnum; +import org.onap.portalapp.portal.logging.logic.EPLogUtil; +import org.onap.portalapp.portal.transport.OnboardingApp; +import org.onap.portalapp.portal.utils.EPCommonSystemProperties; +import org.onap.portalapp.portal.utils.EcompPortalUtils; +import org.onap.portalsdk.core.exception.UrlAccessRestrictedException; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.slf4j.MDC; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import com.att.eelf.configuration.Configuration; + +@Service("sessionCommunication") +@org.springframework.context.annotation.Configuration +@EnableAspectJAutoProxy +public class SessionCommunication { + EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SessionCommunication.class); + + @EPAuditLog + public String sendGet(OnboardingApp app) throws Exception { + String appResponse = ""; + String appName = ""; + int responseCode = 0; + if (app != null && app.name != null && app.name != "") { + try { + appName = app.name; + String url = app.restUrl + "/sessionTimeOuts"; + String encriptedPwdDB = app.appPassword; + String appUserName = app.username; + + setLocalMDCContext(app, "/sessionTimeOuts", url); + + URL obj = new URL(url); + + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // optional default is GET + con.setRequestMethod("GET"); + con.setConnectTimeout(3000); + con.setReadTimeout(8000); + // add request header + con.setRequestProperty("username", appUserName); + con.setRequestProperty("password", encriptedPwdDB); + + // con.set + responseCode = con.getResponseCode(); + logger.debug(EELFLoggerDelegate.debugLogger, "Response Code : " + responseCode); + + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + + in.close(); + appResponse = response.toString(); + } catch (UrlAccessRestrictedException e) { + responseCode = HttpServletResponse.SC_UNAUTHORIZED; + logger.error(EELFLoggerDelegate.errorLogger, String.format( + "SessionCommunication.sendGet received an un-authorized exception. AppName: %s", appName)); + EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeRestApiAuthenticationError, e); + } catch (Exception e) { + responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; + String message = String.format( + "SessionCommunication.sendGet encountered an Exception. AppName: %s, Details: %s", appName, + e.toString()); + EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeHttpConnectionError, e); + logger.error(EELFLoggerDelegate.errorLogger, message, e); + } finally { + EcompPortalUtils.setExternalAppResponseCode(responseCode); + } + } else { + logger.error(EELFLoggerDelegate.errorLogger, "SessionCommunication sendGet: app is null"); + } + return appResponse; + } + + @EPAuditLog + public Boolean pingSession(OnboardingApp app, String sessionTimeoutMap) throws Exception { + String appName = ""; + int responseCode = 0; + try { + if (app == null) + throw new Exception("SessionCommunication.pingSession: app is null"); + if (app != null && app.name != null && app.name != "") { + appName = app.name; + } + String url = app.restUrl + "/updateSessionTimeOuts"; + String encriptedPwdDB = app.appPassword; + String appUserName = app.username; + + setLocalMDCContext(app, "/updateSessionTimeOuts", url); + + URL obj = new URL(url); + + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // optional default is GET + con.setRequestMethod("POST"); + con.setConnectTimeout(3000); + con.setReadTimeout(15000); + + // add request header + con.setRequestProperty("username", appUserName); + con.setRequestProperty("password", encriptedPwdDB); + + con.setRequestProperty("sessionMap", sessionTimeoutMap); + con.setDoInput(true); + con.setDoOutput(true); + con.getOutputStream().write(sessionTimeoutMap.getBytes()); + con.getOutputStream().flush(); + con.getOutputStream().close(); + + responseCode = con.getResponseCode(); + logger.debug(EELFLoggerDelegate.debugLogger, "Response Code : " + responseCode); + } catch (UrlAccessRestrictedException e) { + responseCode = HttpServletResponse.SC_UNAUTHORIZED; + String message = String.format( + "SessionCommunication.pingSession received an un-authorized exception. AppName: %s", appName); + logger.error(EELFLoggerDelegate.errorLogger, message); + EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeRestApiAuthenticationError, e); + } catch (Exception e) { + responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; + String message = String.format( + "SessionCommunication.pingSession encountered an Exception. AppName: %s, Details: %s", appName, e.toString()); + EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeHttpConnectionError, e); + logger.error(EELFLoggerDelegate.errorLogger, message, e); + } finally { + EcompPortalUtils.setExternalAppResponseCode(responseCode); + } + + return true; + } + + @EPAuditLog + public Boolean timeoutSession(OnboardingApp app, String portalJSessionId) throws Exception { + String appName = "Unknwon"; + int responseCode = 0; + if (app != null && app.name != null && app.name != "") { + try { + appName = app.name; + String url = app.restUrl + "/timeoutSession" + "?portalJSessionId=" + portalJSessionId; + + String encriptedPwdDB = app.appPassword; + String appUserName = app.username; + // String decreptedPwd = CipherUtil.decrypt(encriptedPwdDB, + // SystemProperties.getProperty(SystemProperties.Decryption_Key)); + + setLocalMDCContext(app, "/timeoutSession", url); + + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // optional default is GET + con.setRequestMethod("POST"); + con.setConnectTimeout(3000); + con.setReadTimeout(15000); + + // add request header + con.setRequestProperty("username", appUserName); + con.setRequestProperty("password", encriptedPwdDB); + + // con.setRequestProperty("portalJSessionId", portalJSessionId); + con.setDoInput(true); + con.setDoOutput(true); + con.getOutputStream().flush(); + con.getOutputStream().close(); + + responseCode = con.getResponseCode(); + logger.debug(EELFLoggerDelegate.debugLogger, "Response Code : " + responseCode); + } catch (UrlAccessRestrictedException e) { + responseCode = HttpServletResponse.SC_UNAUTHORIZED; + String message = String.format( + "SessionCommunication.timeoutSession received an un-authorized exception. AppName: %s", + appName); + logger.error(EELFLoggerDelegate.errorLogger, message); + EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeRestApiAuthenticationError, e); + } catch (Exception e) { + responseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; + String message = String.format( + "SessionCommunication.timeoutSession encountered an Exception. AppName: %s, Details: %s", + appName, e.toString()); + EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeHttpConnectionError, e); + logger.error(EELFLoggerDelegate.errorLogger, message, e); + } finally { + EcompPortalUtils.setExternalAppResponseCode(responseCode); + } + } else { + logger.error(EELFLoggerDelegate.errorLogger, "SessionCommunication pingSession: app is null"); + } + return true; + } + + @EPMetricsLog + private void setLocalMDCContext(OnboardingApp app, String restPath, String url) { + setRequestId(); + MDC.put(EPCommonSystemProperties.PROTOCOL, EPCommonSystemProperties.HTTP); + if (url != null && url.contains("https")) { + MDC.put(EPCommonSystemProperties.PROTOCOL, EPCommonSystemProperties.HTTPS); + } + MDC.put(EPCommonSystemProperties.FULL_URL, url); + MDC.put(EPCommonSystemProperties.TARGET_ENTITY, app.myLoginsAppName); + MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, restPath); + } + + /** + * Generates request id, service name fields and loads them into MDC, as these + * values could be empty as these session timeout requests are generated at + * scheduled intervals using quartz scheduler. + */ + @EPMetricsLog + public void setRequestId() { + String requestId = MDC.get(Configuration.MDC_KEY_REQUEST_ID); + if (StringUtils.isEmpty(requestId)) { + MDC.put(Configuration.MDC_KEY_REQUEST_ID, UUID.randomUUID().toString()); + } + + MDC.put(Configuration.MDC_SERVICE_NAME, "/quartz/keepSessionAlive"); + MDC.put(EPCommonSystemProperties.PARTNER_NAME, EPCommonSystemProperties.ECOMP_PORTAL_BE); + } + + /** + * Remove the values from MDC as these requests are executed at regular + * intervals based on quartz rather incoming REST API requests. + * + * @param bAll + */ + @EPMetricsLog + public void clear(Boolean bAll) { + MDC.remove(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE); + if (bAll) { + MDC.remove(Configuration.MDC_KEY_REQUEST_ID); + MDC.remove(Configuration.MDC_SERVICE_NAME); + MDC.remove(EPCommonSystemProperties.PARTNER_NAME); + } + } +} diff --git a/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/TimeoutHandler.java b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/TimeoutHandler.java new file mode 100644 index 00000000..e795e98a --- /dev/null +++ b/ecomp-portal-BE-common/src/main/java/org/onap/portalapp/service/sessionmgt/TimeoutHandler.java @@ -0,0 +1,269 @@ +/*- + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 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============================================ + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.portalapp.service.sessionmgt; + +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpSession; + +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.PersistJobDataAfterExecution; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.scheduling.quartz.QuartzJobBean; +import org.onap.portalapp.portal.logging.aop.EPMetricsLog; +import org.onap.portalapp.portal.logging.format.EPAppMessagesEnum; +import org.onap.portalapp.portal.logging.logic.EPLogUtil; +import org.onap.portalapp.portal.service.EPAppService; +import org.onap.portalapp.portal.transport.OnboardingApp; +import org.onap.portalapp.portal.utils.EcompPortalUtils; +import org.onap.portalsdk.core.domain.sessionmgt.TimeoutVO; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.onboarding.util.PortalApiConstants; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Executed periodically by Quartz to discover remote application sessions and + * update timeouts suitably. + */ +@PersistJobDataAfterExecution +@DisallowConcurrentExecution +@org.springframework.context.annotation.Configuration +@EnableAspectJAutoProxy +@EPMetricsLog +public class TimeoutHandler extends QuartzJobBean { + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(TimeoutHandler.class); + + private ObjectMapper mapper = new ObjectMapper(); + + /** + * Supports static call {@link #timeoutSessions(HttpSession)} + */ + private static List onboardedAppList = null; + + @Autowired + private SessionCommunication sessionCommunication; + + @Override + protected void executeInternal(JobExecutionContext context) throws JobExecutionException { + try { + //Create a request id if there is none available, + //and which will internally be used when making + //session extended timeout calls to the partner applications. + if (getSessionCommunication()!=null) { + getSessionCommunication().setRequestId(); + } + logger.info(EELFLoggerDelegate.debugLogger, "Quartz Cronjob for Session Management begins"); + + ManageService manageService = (ManageService) applicationContext.getBean("manageService"); + EPAppService appService = (EPAppService) applicationContext.getBean("epAppService"); + + List appList = appService.getEnabledNonOpenOnboardingApps(); + onboardedAppList = appList; + TypeReference> typeRef = new TypeReference>() { + }; + String portalJsonSessionStr; + Map portalSessionTimeoutMap = null; + + portalJsonSessionStr = manageService.gatherSessionExtenstions(); + if (portalJsonSessionStr == null || portalJsonSessionStr == "") { + logger.error(EELFLoggerDelegate.errorLogger, "Session Management: Portal session information is empty."); + return; + } + + try { + portalSessionTimeoutMap = mapper.readValue(portalJsonSessionStr, typeRef); + } catch (JsonMappingException | JsonParseException je) { + EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeInvalidJsonInput, je); + logger.error(EELFLoggerDelegate.errorLogger, "Session Management: JSON Mapping Exception occurred while gathering the Session", je); + return; + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "Session Management: Error while gather Session from portal", e); + return; + } + + Map> appSessionTimeOutMap = new Hashtable>(); + // determine the Max TimeOut Time for each of the managed sessions + for (OnboardingApp app : appList) { + if (app.restUrl == null) { + logger.info(EELFLoggerDelegate.debugLogger, "Session Management: null restUrl, not fetching from app " + app.name); + continue; + } + logger.info(EELFLoggerDelegate.debugLogger, "Session Management: Calling App " + app.name + " at URL " + app.restUrl); + String jsonSessionStr = fetchAppSessions(app); + logger.info(EELFLoggerDelegate.debugLogger, "Session Management: App " + app.name + " returned " + jsonSessionStr); + if (jsonSessionStr == null || jsonSessionStr.isEmpty()) + continue; + + try { + Map sessionTimeoutMap = mapper.readValue(jsonSessionStr, typeRef); + appSessionTimeOutMap.put(app.id, sessionTimeoutMap); + for (String portalJSessionId : sessionTimeoutMap.keySet()) { + final TimeoutVO maxTimeoutVO = portalSessionTimeoutMap.get(portalJSessionId); + final TimeoutVO compareTimeoutVO = sessionTimeoutMap.get(portalJSessionId); + if (maxTimeoutVO != null && compareTimeoutVO != null) { + if (maxTimeoutVO.compareTo(compareTimeoutVO) < 0) + portalSessionTimeoutMap.get(portalJSessionId) + .setSessionTimOutMilliSec(compareTimeoutVO.getSessionTimOutMilliSec()); + } + } + } catch (JsonParseException | JsonMappingException e) { + EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeInvalidJsonInput, e); + logger.error(EELFLoggerDelegate.errorLogger, + "JSON Mapping/Processing Exception occurred while mapping/parsing the jsonSessionStr", e); + continue; + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while mapping/parsing the jsonSessionStr", e); + continue; + } + + } + + // post the updated session timeouts back to the Apps + for (OnboardingApp app : appList) { + if (app.restUrl == null) { + logger.warn(EELFLoggerDelegate.errorLogger, "Session Management: null restUrl, not posting back to app " + app.name); + continue; + } + + Map sessionTimeoutMap = appSessionTimeOutMap.get(app.id); + if (sessionTimeoutMap == null || sessionTimeoutMap.isEmpty()) + continue; + + for (String portalJSessionId : sessionTimeoutMap.keySet()) { + try { + final TimeoutVO maxTimeoutVO = portalSessionTimeoutMap.get(portalJSessionId); + final TimeoutVO setTimeoutVO = sessionTimeoutMap.get(portalJSessionId); + if (maxTimeoutVO == null || setTimeoutVO == null) { + String message = String.format( + "Session Management: Failed to update the session timeouts for the app: %s and the sessionId: %s.", + app.name, portalJSessionId); + logger.warn(EELFLoggerDelegate.errorLogger, message); + continue; + } + setTimeoutVO.setSessionTimOutMilliSec(maxTimeoutVO.getSessionTimOutMilliSec()); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "Session Management: error while updating the session timeout map", e); + continue; + } + } + logger.info(EELFLoggerDelegate.debugLogger, "Session Management: Updating App " + app.restUrl); + String sessionTimeoutMapStr = ""; + try { + sessionTimeoutMapStr = mapper.writeValueAsString(sessionTimeoutMap); + } catch (JsonProcessingException je) { + logger.error(EELFLoggerDelegate.errorLogger, "executeInternal failed while processing sessionTimeOutMap object to a String", je); + EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeInvalidJsonInput, je); + } + pingAppSessions(app, sessionTimeoutMapStr); + } + String portalSessionTimeoutMapStr = ""; + try { + portalSessionTimeoutMapStr = mapper.writeValueAsString(portalSessionTimeoutMap); + } catch (JsonProcessingException je) { + logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while processing portalSessionTimeOutMap object to a String", je); + EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeInvalidJsonInput, je); + } + manageService.updateSessionExtensions(portalSessionTimeoutMapStr); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "************************ Session Management: error in managing session timeouts", e); + } finally { + getSessionCommunication().clear(true); + } + } + + private String fetchAppSessions(OnboardingApp app) throws Exception { + String jsonSessionValue = getSessionCommunication().sendGet(app); + getSessionCommunication().clear(false); + return jsonSessionValue; + } + + private void pingAppSessions(OnboardingApp app, String sessionTimeoutMapStr) throws Exception { + getSessionCommunication().pingSession(app, sessionTimeoutMapStr); + getSessionCommunication().clear(false); + } + + public void timeoutSessions(HttpSession session) throws Exception { + String portalJSessionId = portalJSessionId(session); + if (onboardedAppList == null) + return; + + for (OnboardingApp app : onboardedAppList) { + getSessionCommunication().timeoutSession(app, portalJSessionId); + getSessionCommunication().clear(false); + } + } + + protected static String portalJSessionId(HttpSession session) { + final Object attribute = session.getAttribute(PortalApiConstants.PORTAL_JSESSION_ID); + if (attribute == null) + return ""; + String jSessionKey = (String) attribute; + return jSessionKey.split("-")[0]; + } + + private static ApplicationContext applicationContext; + + public static void setApplicationContext(ApplicationContext _applicationContext) { + applicationContext = _applicationContext; + } + + public SessionCommunication getSessionCommunication() { + if(sessionCommunication == null){ + if (applicationContext != null) + sessionCommunication = (SessionCommunication)applicationContext.getBean("sessionCommunication"); + } + + return sessionCommunication; + } + + public void setSessionCommunication(SessionCommunication sessionCommunication) { + this.sessionCommunication = sessionCommunication; + } + +} \ No newline at end of file -- cgit 1.2.3-korg