package org.ovirt.engine.core; import java.io.IOException; import java.net.MalformedURLException; import java.util.Locale; import java.util.Map; import javax.ejb.EJB; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.aaa.SsoOAuthServiceUtils; import org.ovirt.engine.core.aaa.filters.FiltersHelper; import org.ovirt.engine.core.branding.BrandingManager; import org.ovirt.engine.core.common.config.ConfigCommon; import org.ovirt.engine.core.common.interfaces.BackendLocal; import org.ovirt.engine.core.common.queries.ConfigurationValues; import org.ovirt.engine.core.common.queries.GetConfigurationValueParameters; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.utils.EngineLocalConfig; import org.ovirt.engine.core.utils.servlet.LocaleFilter; import org.ovirt.engine.core.utils.servlet.UnsupportedLocaleHelper; import org.ovirt.engine.core.uutils.net.URLBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This Servlet serves the welcome page to allow users to select either web admin or user portal. */ public class WelcomeServlet extends HttpServlet { /** * Generated UID. */ private static final long serialVersionUID = 8289914264581273721L; /** * The request attribute keys describing the available locales. */ private static final String LOCALE_KEYS = "localeKeys"; /** * The request attribute containing the section map. */ private static final String SECTIONS = "sections"; /** * The request attribute containing the version. */ private static final String VERSION = "version"; /** * Back-end bean for database access. */ private transient BackendLocal backend; /** * The branding manager. */ private transient BrandingManager brandingManager; private static final Logger log = LoggerFactory.getLogger(WelcomeServlet.class); private static String identityScope = "ovirt-ext=auth:identity"; private String engineUri; /** * Setter for the {@code BackendLocal} bean. * * @param backendLocal The bean */ @EJB(beanInterface = BackendLocal.class, mappedName = "java:global/engine/bll/Backend!org.ovirt.engine.core.common.interfaces.BackendLocal") public void setBackend(final BackendLocal backendLocal) { this.backend = backendLocal; } @Override public void init() { init(BrandingManager.getInstance(), EngineLocalConfig.getInstance().getProperty(WelcomeUtils.ENGINE_URI)); } /** * Init with the branding manager as a parameter. * * @param brandingManager The branding manager. */ void init(final BrandingManager brandingManager, String engineUri) { this.brandingManager = brandingManager; this.engineUri = engineUri; } @Override protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { log.debug("Entered WelcomeServlet"); String reauthenticate = (String) request.getSession(true).getAttribute(WelcomeUtils.REAUTHENTICATE); if (StringUtils.isEmpty(reauthenticate)) { Map<String, Object> deployedResponse = isSsoWebappDeployed(); if (deployedResponse.containsKey(WelcomeUtils.ERROR)) { request.getSession(true).setAttribute(WelcomeUtils.ERROR, deployedResponse.get(WelcomeUtils.ERROR)); request.getSession(true).setAttribute(WelcomeUtils.ERROR_CODE, deployedResponse.get(WelcomeUtils.ERROR_CODE)); } } String authCode = (String) request.getSession(true).getAttribute(WelcomeUtils.AUTH_CODE); String token = (String) request.getSession(true).getAttribute(WelcomeUtils.TOKEN); String error = (String) request.getSession(true).getAttribute(WelcomeUtils.ERROR); if (StringUtils.isNotEmpty(token) && !isSessionValid(request, token)) { request.getSession(true).removeAttribute(WelcomeUtils.TOKEN); request.getSession(true).removeAttribute(WelcomeUtils.SSO_USER); request.getSession(true).removeAttribute(WelcomeUtils.CAPABILITY_CREDENTIALS_CHANGE); token = ""; } if (authCode == null && StringUtils.isEmpty(error) && StringUtils.isEmpty(reauthenticate)) { if (StringUtils.isNotEmpty(request.getParameter(WelcomeUtils.ERROR_CODE)) && !WelcomeUtils.ERR_OVIRT_CODE_NOT_AUTHENTICATED.equals(request.getParameter(WelcomeUtils.ERROR_CODE))) { request.getSession(true).setAttribute(WelcomeUtils.ERROR, request.getParameter(WelcomeUtils.ERROR)); request.getSession(true).setAttribute(WelcomeUtils.ERROR_CODE, request.getParameter(WelcomeUtils.ERROR_CODE)); } String url = WelcomeUtils.getLoginUrl(engineUri, identityScope); log.debug("redirecting to {}", url); response.sendRedirect(url); } else { request.getSession(true).removeAttribute(WelcomeUtils.REAUTHENTICATE); log.debug("Displaying Welcome Page"); try { setUserNameForMenu(request, token); } catch (Exception ex) { log.debug("Unable to set request attributed for user menu", ex); log.error("Unable to set request attributed for user menu: {}", ex.getMessage()); } request.setAttribute(LOCALE_KEYS, UnsupportedLocaleHelper.getDisplayedLocales(LocaleFilter.getLocaleKeys())); String oVirtVersion = backend.runPublicQuery(VdcQueryType.GetConfigurationValue, new GetConfigurationValueParameters(ConfigurationValues.ProductRPMVersion, ConfigCommon.defaultConfigurationVersion)).getReturnValue(); request.setAttribute("sso_credential_change_url", getCredentialsChangeUrl(request)); request.setAttribute(VERSION, oVirtVersion != null ? oVirtVersion : "myVersion"); request.setAttribute(SECTIONS, brandingManager .getWelcomeSections((Locale) request.getAttribute(LocaleFilter.LOCALE))); log.debug("Including to ovirt-engine.jsp"); RequestDispatcher dispatcher = request.getRequestDispatcher(WelcomeUtils.WELCOME_PAGE_JSP_URI); response.setContentType("text/html;charset=UTF-8"); if (dispatcher != null) { dispatcher.include(request, response); } } log.debug("Exiting WelcomeServlet"); } private void setUserNameForMenu(HttpServletRequest request, String token) { try { log.debug("setting request attributes for User Menu"); if (StringUtils.isNotEmpty(token)) { Map<String, Object> userInfoMap = SsoOAuthServiceUtils.getTokenInfo(token); String username = getCurrentSsoSessionUser(request, userInfoMap); if (StringUtils.isNotEmpty(username)) { request.getSession(true).setAttribute(WelcomeUtils.SSO_USER, username); request.getSession(true).setAttribute(WelcomeUtils.CAPABILITY_CREDENTIALS_CHANGE, getChangePasswordEnabled(userInfoMap)); } } } catch (Exception e) { log.error("Unable to get session user", e); } finally { request.getSession(true).removeAttribute(WelcomeUtils.AUTH_CODE); } } public String getCredentialsChangeUrl(HttpServletRequest request) throws MalformedURLException { return new URLBuilder(FiltersHelper.getEngineSsoUrl(request), WelcomeUtils.CREDENTIALS_CHANGE_FORM_URI).build(); } public String getCurrentSsoSessionUser(HttpServletRequest request, Map<String, Object> userInfoMap) { String username = null; if (userInfoMap.containsKey(WelcomeUtils.ERROR)) { request.getSession(true).setAttribute(WelcomeUtils.ERROR, userInfoMap.get(WelcomeUtils.ERROR)); request.getSession(true).setAttribute(WelcomeUtils.ERROR_CODE, userInfoMap.get(WelcomeUtils.ERROR_CODE)); } else { username = (String) userInfoMap.get(WelcomeUtils.JSON_USER_ID); log.debug("Got current user {} for session", username); } return username; } public boolean getChangePasswordEnabled(Map<String, Object> userInfoMap) { return (boolean) ((Map<String, Object>) userInfoMap.get("ovirt")).get(WelcomeUtils.CAPABILITY_CREDENTIALS_CHANGE); } public Map<String, Object> isSsoWebappDeployed() { return SsoOAuthServiceUtils.isSsoDeployed(); } public boolean isSessionValid(HttpServletRequest request, String token) { boolean isValid = false; if (StringUtils.isNotEmpty(token)) { Map<String, Object> response = SsoOAuthServiceUtils.getTokenInfo(token, "ovirt-ext=token-info:validate"); isValid = !response.containsKey(WelcomeUtils.ERROR); if (response.containsKey(WelcomeUtils.ERROR) && !WelcomeUtils.ERR_CODE_INVALID_GRANT.equals(response.get(WelcomeUtils.ERROR_CODE))) { request.getSession(true).setAttribute(WelcomeUtils.ERROR, response.get(WelcomeUtils.ERROR)); request.getSession(true).setAttribute(WelcomeUtils.ERROR_CODE, response.get(WelcomeUtils.ERROR_CODE)); log.error("Session not valid session id = " + token, response.get(WelcomeUtils.ERROR)); } } return isValid; } }