/* * Password Management Servlets (PWM) * http://www.pwm-project.org * * Copyright (c) 2006-2009 Novell, Inc. * Copyright (c) 2009-2017 The PWM Project * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package password.pwm.http; import password.pwm.PwmApplication; import password.pwm.PwmConstants; import password.pwm.config.Configuration; import password.pwm.config.PwmSetting; import password.pwm.error.ErrorInformation; import password.pwm.error.PwmUnrecoverableException; import password.pwm.http.servlet.PwmServletDefinition; import password.pwm.i18n.Message; import password.pwm.util.java.JavaHelper; import password.pwm.util.java.JsonUtil; import password.pwm.util.logging.PwmLogger; import password.pwm.ws.server.RestResultBean; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.Serializable; import java.util.Arrays; public class PwmResponse extends PwmHttpResponseWrapper { private static final PwmLogger LOGGER = PwmLogger.forClass(PwmResponse.class); private final PwmRequest pwmRequest; public enum Flag { AlwaysShowMessage, ForceLogout, } public enum RedirectType { Permanent_301(HttpServletResponse.SC_MOVED_PERMANENTLY), Found_302(HttpServletResponse.SC_FOUND), Other_303(303), ; private final int code; RedirectType(final int code) { this.code = code; } public int getCode() { return code; } } public PwmResponse( final HttpServletResponse response, final PwmRequest pwmRequest, final Configuration configuration ) { super(pwmRequest.getHttpServletRequest(), response, configuration); this.pwmRequest = pwmRequest; } public void forwardToJsp( final JspUrl jspURL ) throws ServletException, IOException, PwmUnrecoverableException { if (!pwmRequest.isFlag(PwmRequestFlag.NO_REQ_COUNTER)) { pwmRequest.getPwmSession().getSessionManager().incrementRequestCounterKey(); } preCommitActions(); final HttpServletRequest httpServletRequest = pwmRequest.getHttpServletRequest(); final ServletContext servletContext = httpServletRequest.getSession().getServletContext(); final String url = jspURL.getPath(); try { LOGGER.trace(pwmRequest.getSessionLabel(), "forwarding to " + url); } catch (Exception e) { /* noop, server may not be up enough to do the log output */ } servletContext.getRequestDispatcher(url).forward(httpServletRequest, this.getHttpServletResponse()); } public void forwardToSuccessPage(final Message message, final String... field) throws ServletException, PwmUnrecoverableException, IOException { final String messageStr = Message.getLocalizedMessage(pwmRequest.getLocale(), message, pwmRequest.getConfig(), field); forwardToSuccessPage(messageStr); } public void forwardToSuccessPage(final String message, final Flag... flags) throws ServletException, PwmUnrecoverableException, IOException { final PwmApplication pwmApplication = pwmRequest.getPwmApplication(); final PwmSession pwmSession = pwmRequest.getPwmSession(); this.pwmRequest.setAttribute(PwmRequestAttribute.SuccessMessage, message); final boolean showMessage = !pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.DISPLAY_SUCCESS_PAGES) && !Arrays.asList(flags).contains(Flag.AlwaysShowMessage); if (showMessage) { LOGGER.trace(pwmSession, "skipping success page due to configuration setting."); final String redirectUrl = pwmRequest.getContextPath() + PwmServletDefinition.PublicCommand.servletUrl() + "?processAction=next"; sendRedirect(redirectUrl); return; } try { forwardToJsp(JspUrl.SUCCESS); } catch (PwmUnrecoverableException e) { LOGGER.error("unexpected error sending user to success page: " + e.toString()); } } public void respondWithError( final ErrorInformation errorInformation, final Flag... flags ) throws IOException, ServletException { LOGGER.error(pwmRequest.getSessionLabel(), errorInformation); pwmRequest.setAttribute(PwmRequestAttribute.PwmErrorInfo, errorInformation); if (JavaHelper.enumArrayContainsValue(flags, Flag.ForceLogout)) { LOGGER.debug(pwmRequest, "forcing logout due to error " + errorInformation.toDebugStr()); pwmRequest.getPwmSession().unauthenticateUser(pwmRequest); } if (pwmRequest.isJsonRequest()) { outputJsonResult(RestResultBean.fromError(errorInformation, pwmRequest)); } else if (pwmRequest.isHtmlRequest()) { try { forwardToJsp(JspUrl.ERROR); } catch (PwmUnrecoverableException e) { LOGGER.error("unexpected error sending user to error page: " + e.toString()); } } else { final boolean showDetail = pwmRequest.getPwmApplication().determineIfDetailErrorMsgShown(); final String errorStatusText = showDetail ? errorInformation.toDebugStr() : errorInformation.toUserStr(pwmRequest.getPwmSession(),pwmRequest.getPwmApplication()); getHttpServletResponse().sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorStatusText); } } public void outputJsonResult( final RestResultBean restResultBean ) throws IOException { preCommitActions(); final HttpServletResponse resp = this.getHttpServletResponse(); final String outputString = restResultBean.toJson(); resp.setContentType(PwmConstants.ContentTypeValue.json.getHeaderValue()); resp.getWriter().print(outputString); resp.getWriter().close(); } public void writeEncryptedCookie(final String cookieName, final Serializable cookieValue, final CookiePath path) throws PwmUnrecoverableException { writeEncryptedCookie(cookieName, cookieValue, -1, path); } public void writeEncryptedCookie(final String cookieName, final Serializable cookieValue, final int seconds, final CookiePath path) throws PwmUnrecoverableException { final String jsonValue = JsonUtil.serialize(cookieValue); final String encryptedValue = pwmRequest.getPwmApplication().getSecureService().encryptToString(jsonValue); writeCookie(cookieName, encryptedValue, seconds, path, PwmHttpResponseWrapper.Flag.BypassSanitation); } public void markAsDownload(final PwmConstants.ContentTypeValue contentType, final String filename) { this.setHeader(HttpHeader.ContentDisposition,"attachment; fileName=" + filename); this.setContentType(contentType); } public void sendRedirect(final String url) throws IOException { sendRedirect(url, RedirectType.Found_302); } public void sendRedirect(final String url, final RedirectType redirectType) throws IOException { preCommitActions(); final HttpServletResponse resp = pwmRequest.getPwmResponse().getHttpServletResponse(); resp.setStatus(redirectType.getCode()); // http "other" redirect resp.setHeader(HttpHeader.Location.getHttpName(), url); LOGGER.trace("sending " + redirectType.getCode() + " redirect to " + url); } private void preCommitActions() { if (pwmRequest.getPwmResponse().isCommitted()) { return; } pwmRequest.getPwmApplication().getSessionStateService().saveLoginSessionState(pwmRequest); pwmRequest.getPwmApplication().getSessionStateService().saveSessionBeans(pwmRequest); } }