001/** 002 * Copyright 2005-2018 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.kns.web.struts.action; 017 018import java.io.Serializable; 019import java.util.Enumeration; 020import java.util.HashMap; 021import java.util.Map; 022 023import javax.servlet.http.HttpServletRequest; 024import javax.servlet.http.HttpServletResponse; 025 026import org.apache.log4j.Logger; 027import org.apache.struts.Globals; 028import org.apache.struts.action.Action; 029import org.apache.struts.action.ActionForm; 030import org.apache.struts.action.ActionForward; 031import org.apache.struts.action.ActionMapping; 032import org.kuali.rice.core.api.config.property.ConfigContext; 033import org.kuali.rice.core.api.util.RiceConstants; 034import org.kuali.rice.kns.util.IncidentReportUtils; 035import org.kuali.rice.kns.web.struts.form.KualiExceptionIncidentForm; 036import org.kuali.rice.krad.exception.ExceptionIncident; 037import org.kuali.rice.krad.exception.KualiExceptionIncident; 038import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 039import org.kuali.rice.krad.service.KualiExceptionIncidentService; 040import org.kuali.rice.krad.util.GlobalVariables; 041import org.kuali.rice.krad.util.KRADConstants; 042 043/** 044 * This is the struts action class for handling the exception for Kuali 045 * applications. 046 * 047 * @deprecated KNS Struts deprecated, use KRAD and the Spring MVC framework. 048 */ 049@Deprecated 050public class KualiExceptionHandlerAction extends Action { 051 private static final Logger LOG = Logger 052 .getLogger(KualiExceptionHandlerAction.class); 053 054 private static final String EXCEPTION_TIME_STAMP = "exception-timeStamp"; 055 private static final String EXCEPTION_DOCUMENT_ID = "exception-" + ExceptionIncident.DOCUMENT_ID; 056 private static final String EXCEPTION_USER_EMAIL = "exception-" + ExceptionIncident.USER_EMAIL; 057 private static final String EXCEPTION_USER_NAME = "exception-" + ExceptionIncident.USER_NAME; 058 private static final String EXCEPTION_UUID = "exception-" + ExceptionIncident.UUID; 059 private static final String EXCEPTION_COMPONENT_NAME = "exception-" + ExceptionIncident.COMPONENT_NAME; 060 private static final String EXCEPTION_EXCEPTION_REPORT_SUBJECT = "exception-" + ExceptionIncident.EXCEPTION_REPORT_SUBJECT; 061 private static final String EXCEPTION_EXCEPTION_MESSAGE = "exception-" + ExceptionIncident.EXCEPTION_MESSAGE; 062 private static final String EXCEPTION_STACK_TRACE = "exception-" + ExceptionIncident.STACK_TRACE; 063 064 /** 065 * This overridden method dispatches action to be taken based on 066 * "methodToCall" parameter. The exception is processed when there is no 067 * "methodToCall" specified. 068 * 069 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, 070 * org.apache.struts.action.ActionForm, 071 * javax.servlet.http.HttpServletRequest, 072 * javax.servlet.http.HttpServletResponse) 073 */ 074 public ActionForward execute(ActionMapping mapping, ActionForm form, 075 HttpServletRequest request, HttpServletResponse response) 076 throws Exception { 077 return executeException(mapping, form, request, response); 078 } 079 080 /** 081 * This overridden method processes the exception and post exception (when 082 * user either submit/cancel the exception JSP page). 083 * <ul> 084 * <li>ProcessDefinition application Exception - Exception is stored in Http Request</li> 085 * <li>ProcessDefinition exception incident reporting - No exception, only form data</li> 086 * </ul> 087 * 088 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, 089 * org.apache.struts.action.ActionForm, 090 * javax.servlet.http.HttpServletRequest, 091 * javax.servlet.http.HttpServletResponse) 092 */ 093 public ActionForward executeException(ActionMapping mapping, 094 ActionForm form, HttpServletRequest request, 095 HttpServletResponse response) throws Exception { 096 097 if (LOG.isDebugEnabled()) { 098 String lm = String.format("ENTRY %s%n%s", form.getClass() 099 .getSimpleName(), request.getRequestURI()); 100 LOG.debug(lm); 101 } 102 103 // Get exception thrown 104 Exception e = (Exception) request.getAttribute(Globals.EXCEPTION_KEY); 105 106 // Initialize defined action mapping from struts-config 107 ActionForward returnForward = null; 108 109 // In case there is no exception, either a post back after page was 110 // filled in 111 // or just an error from directly accessing this struts action 112 if (e == null) { 113 if (form instanceof KualiExceptionIncidentForm) { 114 KualiExceptionIncidentForm formObject = (KualiExceptionIncidentForm) form; 115 // Manage conditions: submit or cancel 116 if (!formObject.isCancel()) { 117 // Locate the post exception handler service. The service id 118 // is 119 // defined in the application properties 120 // Only process the post exception handling when the 121 // service 122 // is specified 123 KualiExceptionIncidentService reporterService = KRADServiceLocatorWeb 124 .getKualiExceptionIncidentService(); 125 // An instance of the ExceptionIncident is created by 126 // the 127 // ExceptionIncidentService 128 Map reducedMap = new HashMap(); 129 Enumeration<String> names = request.getParameterNames(); 130 while (names.hasMoreElements()) { 131 String name = names.nextElement(); 132 reducedMap.put(name, request.getParameter(name)); 133 } 134 135 // Sensitive data stored in user session 136 Map<String, Serializable> userSessionMap = GlobalVariables.getUserSession().getObjectMap(); 137 138 // Only display if this is the right exception 139 if(userSessionMap.get("EXCEPTION_TIME_STAMP").toString().equals(reducedMap.get(ExceptionIncident.STACK_TRACE))) { 140 reducedMap.put(ExceptionIncident.DOCUMENT_ID, userSessionMap.get("EXCEPTION_DOCUMENT_ID").toString()); 141 reducedMap.put(ExceptionIncident.USER_EMAIL, userSessionMap.get("EXCEPTION_USER_EMAIL").toString()); 142 reducedMap.put(ExceptionIncident.USER_NAME, userSessionMap.get("EXCEPTION_USER_NAME").toString()); 143 reducedMap.put(ExceptionIncident.UUID, userSessionMap.get("EXCEPTION_UUID").toString()); 144 reducedMap.put(ExceptionIncident.COMPONENT_NAME, userSessionMap.get("EXCEPTION_COMPONENT_NAME").toString()); 145 reducedMap.put(ExceptionIncident.EXCEPTION_REPORT_SUBJECT, userSessionMap.get("EXCEPTION_EXCEPTION_REPORT_SUBJECT").toString()); 146 reducedMap.put(ExceptionIncident.EXCEPTION_MESSAGE, userSessionMap.get("EXCEPTION_EXCEPTION_MESSAGE").toString()); 147 reducedMap.put(ExceptionIncident.STACK_TRACE, userSessionMap.get("EXCEPTION_STACK_TRACE").toString()); 148 149 } else { 150 reducedMap.put(ExceptionIncident.STACK_TRACE,"Not available."); 151 } 152 153 KualiExceptionIncident exceptionIncident = reporterService 154 .getExceptionIncident(reducedMap); 155 156 // Report the incident 157 reporterService.report(exceptionIncident); 158 } else { 159 // Set return after canceling 160 ActionForward cancelForward = mapping 161 .findForward(KRADConstants.MAPPING_CANCEL); 162 if (cancelForward == null) { 163 cancelForward = returnForward; 164 } else { 165 returnForward = cancelForward; 166 } 167 } 168 } 169 } else { 170 // ProcessDefinition the received exception from HTTP request 171 returnForward = processException(mapping, form, request, e); 172 } 173 174 // Not specified, return 175 if (returnForward == null) { 176 returnForward = mapping.findForward(KRADConstants.MAPPING_CLOSE); 177 } 178 179 if (LOG.isDebugEnabled()) { 180 String lm = String.format("EXIT %s", 181 (returnForward == null) ? "null" : returnForward.getPath()); 182 LOG.debug(lm); 183 } 184 185 return returnForward; 186 } 187 188 /** 189 * This method process the caught exception by creating an exception 190 * information properties list and forward these properties to the exception 191 * incident handler JSP. 192 * 193 * @param exception 194 * @param mapping 195 * @param request 196 * @param documentId 197 * Id of the document that Struts threw exception during its 198 * processing. null if not the document processing that caused 199 * the exception 200 * @return 201 * @throws Exception 202 */ 203 @SuppressWarnings("unchecked") 204 protected ActionForward processException(ActionMapping mapping, 205 ActionForm form, HttpServletRequest request, Exception exception) 206 throws Exception { 207 // Only process the exception handling when the service 208 // is specified 209 KualiExceptionIncidentService reporterService = KRADServiceLocatorWeb 210 .getKualiExceptionIncidentService(); 211 // Get exception properties from the Http Request 212 Map<String, String> properties = (Map<String, String>) request 213 .getAttribute(IncidentReportUtils.EXCEPTION_PROPERTIES); 214 215 // Construct the exception incident object 216 KualiExceptionIncident ei = reporterService.getExceptionIncident( 217 exception, properties); 218 219 // Add sensitive data to user session 220 String exceptionTimeStamp = String.valueOf(System.currentTimeMillis()); 221 GlobalVariables.getUserSession().addObject("EXCEPTION_TIME_STAMP", exceptionTimeStamp); 222 GlobalVariables.getUserSession().addObject("EXCEPTION_DOCUMENT_ID", ei.getProperty(ExceptionIncident.DOCUMENT_ID)); 223 GlobalVariables.getUserSession().addObject("EXCEPTION_USER_EMAIL", ei.getProperty(ExceptionIncident.USER_EMAIL)); 224 GlobalVariables.getUserSession().addObject("EXCEPTION_USER_NAME", ei.getProperty(ExceptionIncident.USER_NAME)); 225 GlobalVariables.getUserSession().addObject("EXCEPTION_UUID", ei.getProperty(ExceptionIncident.UUID)); 226 GlobalVariables.getUserSession().addObject("EXCEPTION_COMPONENT_NAME", ei.getProperty(ExceptionIncident.COMPONENT_NAME)); 227 GlobalVariables.getUserSession().addObject("EXCEPTION_EXCEPTION_REPORT_SUBJECT", ei.getProperty(ExceptionIncident.EXCEPTION_REPORT_SUBJECT)); 228 GlobalVariables.getUserSession().addObject("EXCEPTION_EXCEPTION_MESSAGE", ei.getProperty(ExceptionIncident.EXCEPTION_MESSAGE)); 229 GlobalVariables.getUserSession().addObject("EXCEPTION_STACK_TRACE", ei.getProperty(ExceptionIncident.STACK_TRACE)); 230 231 // Hide sensitive data from form in production only 232 if(ConfigContext.getCurrentContextConfig().isProductionEnvironment()) { 233 Map<String, String> prodProperties = ei.toProperties(); 234 prodProperties.put(ExceptionIncident.DOCUMENT_ID, ""); 235 prodProperties.put(ExceptionIncident.USER_EMAIL, ""); 236 prodProperties.put(ExceptionIncident.USER_NAME, ""); 237 prodProperties.put(ExceptionIncident.UUID, ""); 238 prodProperties.put(ExceptionIncident.COMPONENT_NAME, ""); 239 prodProperties.put(ExceptionIncident.EXCEPTION_REPORT_SUBJECT, ""); 240 prodProperties.put(ExceptionIncident.EXCEPTION_MESSAGE, ""); 241 prodProperties.put(ExceptionIncident.STACK_TRACE, exceptionTimeStamp); 242 ei = reporterService.getExceptionIncident( 243 null, prodProperties); 244 } 245 246 // Set full exception properties in Http Request and forward to JSP 247 request.setAttribute(KualiExceptionHandlerAction.class 248 .getSimpleName(), ei.toProperties()); 249 return mapping.findForward(RiceConstants.MAPPING_BASIC); 250 } 251}