summaryrefslogtreecommitdiff
path: root/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java')
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java354
1 files changed, 354 insertions, 0 deletions
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
new file mode 100644
index 00000000..980d77ba
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/AbstractController.java
@@ -0,0 +1,354 @@
+/*******************************************************************************
+ *******************************************************************************/
+package at.gv.egiz.eaaf.core.impl.idp.controller;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.naming.ConfigurationException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+import at.gv.egiz.components.eventlog.api.EventConstants;
+import at.gv.egiz.eaaf.core.api.IRequest;
+import at.gv.egiz.eaaf.core.api.IRequestStorage;
+import at.gv.egiz.eaaf.core.api.IStatusMessager;
+import at.gv.egiz.eaaf.core.api.data.EAAFConstants;
+import at.gv.egiz.eaaf.core.api.data.ExceptionContainer;
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.gui.IGUIBuilderConfigurationFactory;
+import at.gv.egiz.eaaf.core.api.gui.IGUIFormBuilder;
+import at.gv.egiz.eaaf.core.api.gui.ModifyableGuiBuilderConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.api.logging.IRevisionLogger;
+import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger;
+import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
+import at.gv.egiz.eaaf.core.exceptions.AuthnRequestValidatorException;
+import at.gv.egiz.eaaf.core.exceptions.EAAFException;
+import at.gv.egiz.eaaf.core.exceptions.GUIBuildException;
+import at.gv.egiz.eaaf.core.exceptions.InvalidProtocolRequestException;
+import at.gv.egiz.eaaf.core.exceptions.ProcessExecutionException;
+import at.gv.egiz.eaaf.core.exceptions.ProtocolNotActiveException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.utils.HTTPUtils;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
+import at.gv.egiz.eaaf.core.impl.utils.ServletUtils;
+
+
+/**
+ * @author tlenz
+ *
+ */
+public abstract class AbstractController {
+
+ private static final Logger log = LoggerFactory.getLogger(AbstractController.class);
+
+ @Autowired(required=true) protected ApplicationContext applicationContext;
+ @Autowired(required=true) protected IConfiguration authConfig;
+ @Autowired(required=true) protected ITransactionStorage transactionStorage;
+ @Autowired(required=true) protected IRequestStorage requestStorage;
+ @Autowired(required=true) protected IGUIFormBuilder guiBuilder;
+ @Autowired(required=true) protected IGUIBuilderConfigurationFactory guiConfigFactory;
+ @Autowired(required=true) protected IStatusMessager statusMessager;
+
+ @Autowired protected IStatisticLogger statisticLogger;
+ @Autowired protected IRevisionLogger revisionsLogger;
+
+
+
+
+
+ @ExceptionHandler({EAAFException.class})
+ public void MOAIDExceptionHandler(HttpServletRequest req, HttpServletResponse resp, Exception e) throws IOException {
+ log.error(e.getMessage() , e);
+ internalMOAIDExceptionHandler(req, resp, e, true);
+
+ }
+
+ @ExceptionHandler({Exception.class})
+ public void GenericExceptionHandler(HttpServletResponse resp, Exception exception) throws IOException {
+ log.error("Internel Server Error." , exception);
+ resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error!" +
+ "(Errorcode=9199"
+ +" | Description="
+ + StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(exception.getMessage()))
+ + ")");
+ return;
+
+ }
+
+ @ExceptionHandler({IOException.class})
+ public void IOExceptionHandler(HttpServletResponse resp, Throwable exception) {
+ log.error("Internel Server Error." , exception);
+ resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
+ resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+
+ }
+
+ protected void handleError(String errorMessage, Throwable exceptionThrown,
+ HttpServletRequest req, HttpServletResponse resp, IRequest pendingReq) throws IOException {
+
+ String pendingRequestID = null;
+ if (pendingReq != null)
+ pendingRequestID = pendingReq.getPendingRequestId();
+
+ Throwable loggedException = null;
+ Throwable extractedException = extractOriginalExceptionFromProcessException(exceptionThrown);
+
+ //extract pendingRequestID and originalException if it was a TaskExecutionException
+ if (extractedException instanceof TaskExecutionException) {
+ //set original exception
+ loggedException = ((TaskExecutionException) extractedException).getOriginalException();
+
+ //use TaskExecutionException directly, if no Original Exeception is included
+ if (loggedException == null)
+ loggedException = exceptionThrown;
+
+ //set pending-request ID if it is set
+ String reqID = ((TaskExecutionException) extractedException).getPendingRequestID();
+ if (StringUtils.isNotEmpty(reqID))
+ pendingRequestID = reqID;
+
+ } else
+ loggedException = exceptionThrown;
+
+ try {
+ //switch to protocol-finalize method to generate a protocol-specific error message
+
+ //log error directly in debug mode
+ if (log.isDebugEnabled())
+ log.warn(loggedException.getMessage(), loggedException);
+
+
+ //put exception into transaction store for redirect
+ String key = Random.nextLongRandom();
+ if (pendingReq != null) {
+ revisionsLogger.logEvent(pendingReq, EventConstants.TRANSACTION_ERROR);
+ transactionStorage.put(key,
+ new ExceptionContainer(pendingReq, loggedException), -1);
+
+ } else {
+ transactionStorage.put(key,
+ new ExceptionContainer(null, loggedException), -1);
+
+ }
+
+ //build up redirect URL
+ String redirectURL = null;
+ redirectURL = ServletUtils.getBaseUrl(req);
+ redirectURL += "/"+AbstractAuthProtocolModulController.ENDPOINT_ERRORHANDLING
+ + "?" + EAAFConstants.PARAM_HTTP_ERROR_CODE + "=" + key;
+
+// //only add pending-request Id if it exists
+// if (StringUtils.isNotEmpty(pendingRequestID))
+// redirectURL += "&" + EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID + "=" + pendingRequestID;
+
+ resp.setContentType("text/html");
+ resp.setStatus(302);
+
+ resp.addHeader("Location", redirectURL);
+ log.debug("REDIRECT TO: " + redirectURL);
+
+ return;
+
+ } catch (Exception e) {
+ log.warn("Default error-handling FAILED. Exception can not be stored ....", e);
+ log.info("Switch to generic generic backup error-handling ... ");
+ handleErrorNoRedirect(loggedException, req, resp, true);
+
+ }
+
+ }
+
+ /**
+ * Handles all exceptions with no pending request.
+ * Therefore, the error is written to the users browser
+ *
+ * @param throwable
+ * @param req
+ * @param resp
+ * @throws IOException
+ */
+ protected void handleErrorNoRedirect(Throwable throwable, HttpServletRequest req,
+ HttpServletResponse resp, boolean writeExceptionToStatisticLog) throws IOException {
+
+ //log Exception into statistic database
+ if (writeExceptionToStatisticLog)
+ statisticLogger.logErrorOperation(throwable);
+
+ //write errror to console
+ logExceptionToTechnicalLog(throwable);
+
+ //return error to Web browser
+ if (throwable instanceof EAAFException || throwable instanceof ProcessExecutionException)
+ internalMOAIDExceptionHandler(req, resp, (Exception)throwable, false);
+
+ else {
+ //write generic message for general exceptions
+ String msg = statusMessager.getMessage(IStatusMessager.CODES_INTERNAL_ERROR_GENERIC, null);
+ writeHTMLErrorResponse(req, resp, msg, "9199", (Exception) throwable);
+
+ }
+
+ }
+
+ /**
+ * Write a Exception to the MOA-ID-Auth internal technical log
+ *
+ * @param loggedException Exception to log
+ */
+ protected void logExceptionToTechnicalLog(Throwable loggedException) {
+ if (!( loggedException instanceof EAAFException
+ || loggedException instanceof ProcessExecutionException )) {
+ log.error("Receive an internal error: Message=" + loggedException.getMessage(), loggedException);
+
+ } else {
+ if (log.isDebugEnabled() || log.isTraceEnabled()) {
+ log.warn(loggedException.getMessage(), loggedException);
+
+ } else {
+ log.warn(loggedException.getMessage());
+
+ }
+ }
+ }
+
+ private void writeBadRequestErrorResponse(HttpServletRequest req, HttpServletResponse resp, EAAFException e) throws IOException {
+ String code = statusMessager.mapInternalErrorToExternalError(((InvalidProtocolRequestException)e).getErrorId());
+ String descr = StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(e.getMessage()));
+ resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Protocol validation FAILED!" +
+ "(Errorcode=" + code +
+ " | Description=" + descr + ")");
+
+ }
+
+ private void writeHTMLErrorResponse(HttpServletRequest req, HttpServletResponse httpResp, String msg, String errorCode, Exception error) throws IOException {
+
+ try {
+ IGUIBuilderConfiguration config
+ = guiConfigFactory.getDefaultErrorGUI(HTTPUtils.extractAuthURLFromRequest(req));
+
+// HTTPUtils.extractAuthURLFromRequest(req),
+// DefaultGUIFormBuilderConfiguration.VIEW_ERRORMESSAGE,
+// null);
+
+ //add errorcode and errormessage
+ if (config instanceof ModifyableGuiBuilderConfiguration) {
+ ((ModifyableGuiBuilderConfiguration)config).putCustomParameter("errorMsg", msg);
+ ((ModifyableGuiBuilderConfiguration)config).putCustomParameter("errorCode", errorCode);
+
+ //add stacktrace if debug is enabled
+ if (log.isTraceEnabled()) {
+ ((ModifyableGuiBuilderConfiguration)config).putCustomParameter("stacktrace", getStacktraceFromException(error));
+
+ }
+
+ } else
+ log.info("Can not ADD error message, because 'GUIBuilderConfiguration' is not modifieable ");
+
+
+
+ guiBuilder.build(httpResp, config, "Error-Message");
+
+ } catch (GUIBuildException e) {
+ log.warn("Can not build error-message GUI.", e);
+ GenericExceptionHandler(httpResp, e);
+
+ }
+
+ }
+
+ private void writeHTMLErrorResponse(HttpServletRequest req, HttpServletResponse httpResp, Exception error) throws IOException {
+ writeHTMLErrorResponse(req, httpResp,
+ error.getMessage(),
+ statusMessager.getResponseErrorCode(error),
+ error);
+ }
+
+
+ private String getStacktraceFromException(Exception ex) {
+ StringWriter errors = new StringWriter();
+ ex.printStackTrace(new PrintWriter(errors));
+ return errors.toString();
+
+ }
+
+ /**
+ * Extracts a TaskExecutionException of a ProcessExecutionExeception Stacktrace.
+ *
+ * @param exception
+ * @return Return the latest TaskExecutionExecption if exists, otherwise the latest ProcessExecutionException
+ */
+ private Throwable extractOriginalExceptionFromProcessException(Throwable exception) {
+ Throwable exholder = exception;
+ TaskExecutionException taskExc = null;
+
+ while(exholder != null
+ && exholder instanceof ProcessExecutionException) {
+ ProcessExecutionException procExc = (ProcessExecutionException) exholder;
+ if (procExc.getCause() != null &&
+ procExc.getCause() instanceof TaskExecutionException) {
+ taskExc = (TaskExecutionException) procExc.getCause();
+ exholder = taskExc.getOriginalException();
+
+ } else
+ break;
+
+ }
+
+ if (taskExc == null)
+ return exholder;
+
+ else
+ return taskExc;
+ }
+
+ private void internalMOAIDExceptionHandler(HttpServletRequest req, HttpServletResponse resp, Exception e, boolean writeExceptionToStatisicLog) throws IOException {
+ if (e instanceof ProtocolNotActiveException) {
+ resp.getWriter().write(e.getMessage());
+ resp.setContentType(EAAFConstants.CONTENTTYPE_HTML_UTF8);
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN,
+ StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(e.getMessage())));
+
+ } else if (e instanceof AuthnRequestValidatorException) {
+ AuthnRequestValidatorException ex = (AuthnRequestValidatorException)e;
+ //log Error Message
+ if (writeExceptionToStatisicLog)
+ statisticLogger.logErrorOperation(ex, ex.getErrorRequest());
+
+ //write error message
+ writeBadRequestErrorResponse(req, resp, (EAAFException) e);
+
+ } else if (e instanceof InvalidProtocolRequestException) {
+ //send error response
+ writeBadRequestErrorResponse(req, resp, (EAAFException) e);
+
+ } else if (e instanceof ConfigurationException) {
+ //send HTML formated error message
+ writeHTMLErrorResponse(req, resp, (EAAFException) e);
+
+ } else if (e instanceof EAAFException) {
+ //send HTML formated error message
+ writeHTMLErrorResponse(req, resp, e);
+
+ } else if (e instanceof ProcessExecutionException) {
+ //send HTML formated error message
+ writeHTMLErrorResponse(req, resp, e);
+
+ }
+
+ }
+
+}