/* * ============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============================================ * * */ package org.onap.portalapp.service; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import org.onap.portalsdk.core.auth.LoginStrategy; import org.onap.portalsdk.core.domain.App; import org.onap.portalsdk.core.domain.Role; import org.onap.portalsdk.core.domain.RoleFunction; import org.onap.portalsdk.core.domain.User; import org.onap.portalsdk.core.domain.UserApp; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.onboarding.client.AppContextManager; import org.onap.portalsdk.core.onboarding.crossapi.IPortalRestAPIService; import org.onap.portalsdk.core.onboarding.crossapi.IPortalRestCentralService; import org.onap.portalsdk.core.onboarding.exception.CipherUtilException; import org.onap.portalsdk.core.onboarding.exception.PortalAPIException; import org.onap.portalsdk.core.onboarding.listener.PortalTimeoutHandler; import org.onap.portalsdk.core.onboarding.util.CipherUtil; import org.onap.portalsdk.core.onboarding.util.PortalApiConstants; import org.onap.portalsdk.core.onboarding.util.PortalApiProperties; import org.onap.portalsdk.core.restful.domain.EcompRole; import org.onap.portalsdk.core.restful.domain.EcompRoleFunction; import org.onap.portalsdk.core.restful.domain.EcompUser; import org.onap.portalsdk.core.service.AppService; import org.onap.portalsdk.core.service.RestApiRequestBuilder; import org.onap.portalsdk.core.service.RoleService; import org.onap.portalsdk.core.service.UserProfileService; import org.onap.portalsdk.core.service.UserService; import org.onap.portalsdk.core.service.WebServiceCallService; import org.onap.portalsdk.core.util.JSONUtil; import org.onap.portalsdk.core.util.SystemProperties; import org.onap.portalsdk.core.web.support.UserUtils; import org.slf4j.MDC; import org.springframework.context.ApplicationContext; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; /** * Implements the REST API interface to answer requests made by Portal app about * users and active sessions. * * Since an instance of this class will be instantiated by the OnBoarding * servlet from the ecompFW library, we cannot use Spring injections here. This * 'injection' is done indirectly using AppContextManager class. * */ public class OnBoardingApiServiceImpl implements IPortalRestAPIService, IPortalRestCentralService { private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(OnBoardingApiServiceImpl.class); private RoleService roleService; private UserProfileService userProfileService; private IAdminAuthExtension adminAuthExtensionServiceImpl; private LoginStrategy loginStrategy; private UserService userService; private RestApiRequestBuilder restApiRequestBuilder; private AppService appServiceImpl; private static final String isAccessCentralized = PortalApiProperties .getProperty(PortalApiConstants.ROLE_ACCESS_CENTRALIZED); private static final String isCentralized = "remote"; private static String portalApiVersion = "/v3"; public OnBoardingApiServiceImpl() { // Defend against null-pointer exception during server startup // that was caused by a spurious Spring annotation on this class. ApplicationContext appContext = AppContextManager.getAppContext(); if (appContext == null) throw new RuntimeException("OnBoardingApiServiceImpl ctor failed to get appContext"); roleService = appContext.getBean(RoleService.class); userProfileService = appContext.getBean(UserProfileService.class); loginStrategy = appContext.getBean(LoginStrategy.class); // initialize the base class definition for Admin Auth Extension adminAuthExtensionServiceImpl = appContext.getBean(IAdminAuthExtension.class); userService = appContext.getBean(UserService.class); appServiceImpl = appContext.getBean(AppService.class); if(isCentralized.equals(isAccessCentralized)){ restApiRequestBuilder = appContext.getBean(RestApiRequestBuilder.class); } } @SuppressWarnings("unchecked") private void setCurrentAttributes(User user, EcompUser userJson) { user.setEmail(userJson.getEmail()); user.setFirstName(userJson.getFirstName()); user.setHrid(userJson.getHrid()); user.setJobTitle(userJson.getJobTitle()); user.setLastName(userJson.getLastName()); user.setLoginId(userJson.getLoginId()); user.setOrgManagerUserId(userJson.getOrgManagerUserId()); user.setMiddleInitial(userJson.getMiddleInitial()); user.setOrgCode(userJson.getOrgCode()); user.setOrgId(userJson.getOrgId()); user.setPhone(userJson.getPhone()); user.setOrgUserId(userJson.getOrgUserId()); user.setActive(userJson.isActive()); // user.setRoles(new TreeSet(userJson.getRoles())); } @Override public void pushUser(EcompUser userJson) throws PortalAPIException { if (logger.isDebugEnabled()) logger.debug(EELFLoggerDelegate.debugLogger, "pushUser was invoked: {}", userJson); User user = new User(); String response = ""; try { // Set input attributes to the object obout to be saved setCurrentAttributes(user, userJson); user.setRoles(new TreeSet()); user.setUserApps(new TreeSet()); user.setPseudoRoles(new TreeSet()); User domainUser = userProfileService.getUserByLoginId(user.getLoginId()); if (domainUser != null) { JSONUtil.mapToDomainUser(domainUser, user); userProfileService.saveUser(domainUser); } else { userProfileService.saveUser(user); } logger.debug(EELFLoggerDelegate.debugLogger, "push user success."); // After successful creation, call admin auth extension Set ecompRoles = userJson.getRoles(); SortedSet roles = new TreeSet<>(); Iterator roleIter = ecompRoles.iterator(); ObjectMapper mapper = new ObjectMapper(); while (roleIter.hasNext()) { Object nextValue = roleIter.next(); EcompRole epRole = mapper.convertValue(nextValue, EcompRole.class); roles.add(convertToRole(epRole)); } user.setRoles(roles); if (adminAuthExtensionServiceImpl != null) { try { adminAuthExtensionServiceImpl.saveUserExtension(user); } catch (Exception ex) { logger.error("pushUser: saveUserExtension failed", ex); } } response = "push user success."; response = JSONUtil.convertResponseToJSON(response); } catch (Exception e) { response = "OnboardingApiService.pushUser failed"; logger.error(EELFLoggerDelegate.errorLogger, response, e); throw new PortalAPIException(response, e); } finally { MDC.remove(SystemProperties.MDC_TIMER); } } public Role convertToRole(EcompRole epRole) { Role role = new Role(); role.setId(epRole.getId()); role.setName(epRole.getName()); role.setActive(true); Set ecompRolefunctions = new TreeSet<>(); @SuppressWarnings("unchecked") Set rolefunctions = epRole.getRoleFunctions(); ObjectMapper mapper = new ObjectMapper(); Iterator roleFnIter = rolefunctions.iterator(); while (roleFnIter.hasNext()) { Object nextValue = roleFnIter.next(); EcompRoleFunction epRoleFunction = mapper.convertValue(nextValue, EcompRoleFunction.class); ecompRolefunctions.add(convertToRoleFunction(epRoleFunction)); } role.setRoleFunctions(ecompRolefunctions); return role; } public RoleFunction convertToRoleFunction(EcompRoleFunction rolefun) { RoleFunction roleFunction = new RoleFunction(); roleFunction.setName(rolefun.getName()); roleFunction.setCode(rolefun.getCode()); roleFunction.setType(rolefun.getType()); roleFunction.setAction(rolefun.getAction()); return roleFunction; } @Override public void editUser(String loginId, EcompUser userJson) throws PortalAPIException { if (logger.isDebugEnabled()) logger.debug(EELFLoggerDelegate.debugLogger, "OnboardingApi editUser was invoked with loginID {}, JSON {}", loginId, userJson); User editUser = new User(); String response = ""; try { setCurrentAttributes(editUser, userJson); if (editUser.getOrgUserId() != null) { editUser.setLoginId(editUser.getOrgUserId()); } User domainUser = userProfileService.getUserByLoginId(loginId); if (domainUser != null) domainUser = JSONUtil.mapToDomainUser(domainUser, editUser); else domainUser = editUser; userProfileService.saveUser(domainUser); logger.debug(EELFLoggerDelegate.debugLogger, "edit user success."); Set ecompRoles = userJson.getRoles(); SortedSet roles = new TreeSet<>(); Iterator roleIter = ecompRoles.iterator(); ObjectMapper mapper = new ObjectMapper(); while (roleIter.hasNext()) { Object nextValue = roleIter.next(); EcompRole epRole = mapper.convertValue(nextValue, EcompRole.class); roles.add(convertToRole(epRole)); } domainUser.setRoles(roles); // After successful edit, call the admin auth extension if (adminAuthExtensionServiceImpl != null) { try { adminAuthExtensionServiceImpl.editUserExtension(domainUser); } catch (Exception ex) { logger.error("editUser: editUserExtension failed", ex); } } response = "edit user success."; response = JSONUtil.convertResponseToJSON(response); } catch (Exception e) { response = "OnboardingApiService.editUser failed"; logger.error(EELFLoggerDelegate.errorLogger, response, e); throw new PortalAPIException(response, e); } finally { MDC.remove(SystemProperties.MDC_TIMER); } // return response; } @Override public EcompUser getUser(String loginId) throws PortalAPIException { try { if (logger.isDebugEnabled()) logger.debug(EELFLoggerDelegate.debugLogger, "## REST API ## loginId: {}", loginId); User user = null; if (isCentralized.equals(isAccessCentralized)) { String responseString = restApiRequestBuilder.getViaREST(portalApiVersion+"/user/" + loginId, true, loginId); user = userService.userMapper(responseString); } else{ user = userProfileService.getUserByLoginId(loginId); user.getRoles().removeIf(role -> (role.getActive() == false)); } if (user == null) { logger.info(EELFLoggerDelegate.debugLogger, "User + " + loginId + " doesn't exist"); return null; // Unfortunately, Portal is not ready to accept proper error // response yet .. // commenting throw clauses until portal is ready // throw new PortalAPIException("User + " + loginId + " doesn't // exist"); } else return UserUtils.convertToEcompUser(user); } catch (Exception e) { String response = "OnboardingApiService.getUser failed"; logger.error(EELFLoggerDelegate.errorLogger, response, e); return null; // Unfortunately, Portal is not ready to accept proper error response // yet .. commenting throw clauses until portal is ready // throw new PortalAPIException(response, e); } } @Override public List getUsers() throws PortalAPIException { String users_List = ""; try { if (isCentralized.equals(isAccessCentralized)) { List UsersList = new ArrayList<>(); List finalUsersList = new ArrayList<>(); users_List = restApiRequestBuilder.getViaREST(portalApiVersion + "/users", true, null); ObjectMapper mapper = new ObjectMapper(); UsersList = mapper.readValue(users_List, TypeFactory.defaultInstance().constructCollectionType(List.class, EcompUser.class)); for (EcompUser userString : UsersList) { EcompUser ecompUser = mapper.convertValue(userString, EcompUser.class); finalUsersList.add(ecompUser); } return UsersList; } else { List users = userProfileService.findAllActive(); List ecompUsers = new ArrayList<>(); for (User user : users) ecompUsers.add(UserUtils.convertToEcompUser(user)); return ecompUsers; } } catch (Exception e) { String response = "OnboardingApiService.getUsers failed"; logger.error(EELFLoggerDelegate.errorLogger, response, e); if (users_List.equals("")) { throw new PortalAPIException("Application is Inactive"); } else { throw new PortalAPIException(response, e); } } } @Override public List getAvailableRoles(String requestedLoginId) throws PortalAPIException { try { List roles = roleService.getActiveRoles(requestedLoginId); List ecompRoles = new ArrayList<>(); for (Role role : roles) ecompRoles.add(UserUtils.convertToEcompRole(role)); return ecompRoles; } catch (Exception e) { String response = "OnboardingApiService.getAvailableRoles failed"; logger.error(EELFLoggerDelegate.errorLogger, response, e); throw new PortalAPIException(response, e); } } @Override public void pushUserRole(String loginId, List rolesJson) throws PortalAPIException { String response = ""; try { if (logger.isDebugEnabled()) logger.debug(EELFLoggerDelegate.debugLogger, "## REST API ## loginId: {}, roles Json {}", loginId, rolesJson); User user = userProfileService.getUserByLoginId(loginId); /* * List ecompRoles = mapper.readValue(rolesJson, * TypeFactory.defaultInstance().constructCollectionType(List.class, * EcompRole.class)); */ SortedSet roles = new TreeSet<>(); for (EcompRole role : rolesJson) { roles.add(roleService.getRole(loginId,role.getId())); } // Replace existing roles with new ones replaceExistingRoles(roles, user); logger.debug(EELFLoggerDelegate.debugLogger, "push user role success."); // After successful creation, call admin auth extension if (adminAuthExtensionServiceImpl != null) { try { adminAuthExtensionServiceImpl.saveUserRoleExtension(roles, user); } catch (Exception ex) { logger.error("pushUserRole: saveUserRoleExtension failed", ex); } } response = "push user role success."; response = JSONUtil.convertResponseToJSON(response); } catch (Exception e) { response = "OnboardingApiService.pushUserRole failed"; logger.error(EELFLoggerDelegate.errorLogger, response, e); throw new PortalAPIException(response, e); } finally { MDC.remove(SystemProperties.MDC_TIMER); } } @Override public List getUserRoles(String loginId) throws PortalAPIException { if (logger.isDebugEnabled()) logger.debug(EELFLoggerDelegate.debugLogger, "## REST API ## loginId: {}", loginId); List ecompRoles = new ArrayList<>(); try { if (isCentralized.equals(isAccessCentralized)) { User user = null; String responseString = restApiRequestBuilder.getViaREST(portalApiVersion+"/user/" + loginId, true, loginId); user = userService.userMapper(responseString); SortedSet currentRoles = null; if (user != null) { currentRoles = user.getRoles(); if (currentRoles != null) for (Role role : currentRoles) ecompRoles.add(UserUtils.convertToEcompRole(role)); } } else { User user = userProfileService.getUserByLoginId(loginId); SortedSet currentRoles = null; if (user != null) { currentRoles = user.getRoles(); currentRoles.removeIf(role -> (role.getActive() == false)); if (currentRoles != null) for (Role role : currentRoles) ecompRoles.add(UserUtils.convertToEcompRole(role)); } } return ecompRoles; } catch (Exception e) { String response = "OnboardingApiService.getUserRoles failed"; logger.error(EELFLoggerDelegate.errorLogger, response, e); throw new PortalAPIException(response, e); } } @SuppressWarnings("unchecked") private void replaceExistingRoles(SortedSet roles, User user) { // 1. remove existing roles Set userApps = user.getUserApps(); Iterator appsItr = userApps.iterator(); while (appsItr.hasNext()) { UserApp tempUserApp = appsItr.next(); boolean roleFound = false; for (Role role : roles) { if (tempUserApp.getRole().getId().equals(role.getId())) { roleFound = true; break; } } if (!roleFound) appsItr.remove(); } user.setUserApps(userApps); userProfileService.saveUser(user); // 2. add new roles user.setRoles(roles); userProfileService.saveUser(user); } @Override public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException { WebServiceCallService securityService = AppContextManager.getAppContext().getBean(WebServiceCallService.class); try { String appUser = request.getHeader("username"); String password = request.getHeader("password"); // System.out.println("username = " + appUser); // System.out.println("password = " + password); boolean flag = securityService.verifyRESTCredential(null, appUser, password); // System.out.println("username = " + appUser); // System.out.println("password = " + password); return flag; } catch (Exception e) { String response = "OnboardingApiService.isAppAuthenticated failed"; logger.error(EELFLoggerDelegate.errorLogger, response, e); throw new PortalAPIException(response, e); } } public String getSessionTimeOuts() throws Exception { return PortalTimeoutHandler.gatherSessionExtensions(); } public void updateSessionTimeOuts(String sessionMap) throws Exception { PortalTimeoutHandler.updateSessionExtensions(sessionMap); } @Override public String getUserId(HttpServletRequest request) throws PortalAPIException { return loginStrategy.getUserId(request); } @Override public Map getAppCredentials() throws PortalAPIException{ Map credentialsMap = new HashMap<>(); String appName = null; String appUserName = null; String decryptedPwd = null; App app = appServiceImpl.getDefaultApp(); if (app != null) { appName = app.getName(); appUserName = app.getUsername(); try { decryptedPwd = CipherUtil.decryptPKC(app.getAppPassword(), SystemProperties.getProperty(SystemProperties.Decryption_Key)); } catch (CipherUtilException e) { logger.error(EELFLoggerDelegate.errorLogger, "getAppCredentials failed", e); } } else { logger.warn(EELFLoggerDelegate.errorLogger, "getAppCredentials: Unable to locate the app information from the database."); appUserName = "unknown"; appName = SystemProperties.SDK_NAME; } credentialsMap.put("username", appUserName); credentialsMap.put("password", decryptedPwd); credentialsMap.put("appName", appName); return credentialsMap; } @Override public Map getCredentials() throws PortalAPIException{ return getAppCredentials(); } }