summaryrefslogtreecommitdiff
path: root/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/TicketErrorService.java
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/TicketErrorService.java')
-rw-r--r--eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/TicketErrorService.java234
1 files changed, 234 insertions, 0 deletions
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/TicketErrorService.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/TicketErrorService.java
new file mode 100644
index 00000000..557614e6
--- /dev/null
+++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/TicketErrorService.java
@@ -0,0 +1,234 @@
+package at.gv.egiz.eaaf.core.impl.idp.auth.services;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.PostConstruct;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.CollectionType;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+import at.gv.egiz.eaaf.core.api.IStatusMessenger;
+import at.gv.egiz.eaaf.core.api.data.EaafConstants;
+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.utils.IPendingRequestIdGenerationStrategy;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.data.ErrorConfig;
+import at.gv.egiz.eaaf.core.impl.gui.AbstractGuiFormBuilderConfiguration;
+import at.gv.egiz.eaaf.core.impl.idp.controller.ProtocolFinalizationController;
+import at.gv.egiz.eaaf.core.impl.utils.DefaultYamlMapper;
+import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
+import at.gv.egiz.eaaf.core.impl.utils.ServletUtils;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.var;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public abstract class TicketErrorService implements IErrorService {
+ private static final String CONFIG_PROP_ERROR_HANDLING_CONFIG_PATH = "core.error.handling.config";
+ private static final String TECH_LOG_MSG = "errorCode={0} Message={1}";
+ private static final String TICKET_LOG_MSG = "Ticket={2} errorCode={0} Message={1}";
+
+ private final List<ErrorConfig> errorConfigList = new ArrayList<>();
+
+
+ @Autowired
+ IConfiguration basicConfig;
+
+ @Autowired
+ ResourceLoader resourceLoader;
+
+ @Autowired
+ IPendingRequestIdGenerationStrategy requestIdValidationStragegy;
+
+ @Override
+ public String getExternalCodeFromInternal(String internalCode) {
+ ErrorConfig errorConfig = findByInternalCode(internalCode);
+ return StringUtils.isNotEmpty(errorConfig.getExternalCode())
+ ? errorConfig.getExternalCode()
+ : errorConfig.getUseInternalAsExternal()
+ ? internalCode
+ : IStatusMessenger.CODES_EXTERNAL_ERROR_GENERIC;
+
+ }
+
+ @Override
+ public IHandleData createHandleData(Throwable throwable, boolean supportRedirctToSp) throws EaafException {
+ String internalErrorId = extractInternalErrorCode(throwable);
+ ErrorConfig errorFlowConfig = findByInternalCode(internalErrorId);
+ ActionType errorHandlingFlow = errorFlowConfig.getActionType();
+
+ return HandleData.builder()
+ .throwable(throwable)
+ .internalErrorCode(internalErrorId)
+ .actionType(errorHandlingFlow)
+ .logLevel(LogLevel.fromString(errorFlowConfig.getLogLevel()))
+ .supportTicket(ActionType.TICKET.equals(errorHandlingFlow) ? generateSupportTicket() : null)
+ .errorIdTokenForRedirect(
+ supportRedirctToSp ? requestIdValidationStragegy.generateExternalPendingRequestId() : null)
+ .build();
+
+ }
+
+ @Override
+ public void displayErrorData(ModifyableGuiBuilderConfiguration c, IErrorService.IHandleData errorData,
+ HttpServletRequest httpReq) throws EaafException {
+ if (!(errorData instanceof TicketErrorService.HandleData)) {
+ throw new EaafException(IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC);
+ }
+ var ed = (TicketErrorService.HandleData) errorData;
+
+ // set SupportTicket
+ c.putCustomParameter(AbstractGuiFormBuilderConfiguration.PARAM_GROUP_MSG, PARAM_GUI_TICKET, ed.getSupportTicket());
+
+ // set redirect to SP path
+ if (StringUtils.isNotEmpty(ed.getErrorIdTokenForRedirect())) {
+ c.putCustomParameterWithOutEscaption(
+ AbstractGuiFormBuilderConfiguration.PARAM_GROUP_MSG, PARAM_GUI_REDIRECT,
+ generateRedirect(httpReq, ed.getErrorIdTokenForRedirect()));
+
+ }
+ }
+
+ /**
+ * Generate a application-specific support-ticket.
+ *
+ * @return Support ticket for error screen
+ */
+ protected abstract String generateSupportTicket();
+
+
+ @Nonnull
+ private ErrorConfig findByInternalCode(@Nonnull String seekedInternalCode) {
+ return errorConfigList.stream()
+ .filter(c -> c.getInternalCode() != null && c.getInternalCode().contains(seekedInternalCode))
+ .findFirst()
+ .orElse(
+ errorConfigList.stream()
+ .filter(c -> c.getDefaultConfig() != null && c.getDefaultConfig().equals(true))
+ .findFirst()
+ .orElse(ErrorConfig.builder()
+ .action(ActionType.TICKET.toString())
+ .externalCode(IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC)
+ .logLevel("ERROR")
+ .defaultConfig(true)
+ .build())
+ );
+
+ }
+
+ private String extractInternalErrorCode(Throwable throwable) {
+ Throwable originalException;
+ if (throwable instanceof TaskExecutionException
+ && ((TaskExecutionException) throwable).getOriginalException() != null) {
+ originalException = ((TaskExecutionException) throwable).getOriginalException();
+
+ } else {
+ originalException = throwable;
+
+ }
+
+ if (!(originalException instanceof EaafException)) {
+ return IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC;
+
+ } else {
+ return ((EaafException) originalException).getErrorId();
+
+ }
+ }
+
+ private String generateRedirect(HttpServletRequest httpReq, String errorTokenId) {
+ String redirectUrl = ServletUtils.getBaseUrl(httpReq);
+ redirectUrl += ProtocolFinalizationController.ENDPOINT_ERROR_REDIRECT + "?"
+ + EaafConstants.PARAM_HTTP_ERROR_CODE + "=" + StringEscapeUtils
+ .escapeHtml4(errorTokenId);
+ return redirectUrl;
+
+ }
+
+ @PostConstruct
+ private void initialize() throws EaafException {
+ final String errorConfPath = basicConfig.getBasicConfiguration(CONFIG_PROP_ERROR_HANDLING_CONFIG_PATH);
+ log.info("Initializing error-handling service from configuration: {}", errorConfPath);
+
+ if (StringUtils.isEmpty(errorConfPath)) {
+ log.error("Error: Path to error handling config is not known");
+ throw new EaafException("internal.configuration.00", new Object[]{CONFIG_PROP_ERROR_HANDLING_CONFIG_PATH});
+ }
+
+ try {
+ final byte[] raw = readFromFile(errorConfPath);
+ ObjectMapper mapper = DefaultYamlMapper.getYamlMapper();
+ final TypeFactory typeFactory = mapper.getTypeFactory();
+ final CollectionType javaType = typeFactory.constructCollectionType(List.class, ErrorConfig.class);
+ errorConfigList.addAll(mapper.readValue(raw, javaType));
+
+ log.info("Found #{} configuration-elements for Error Handling", errorConfigList.size());
+
+ } catch (Exception e) {
+ log.error("Error reading Configurations file", e);
+ throw new EaafException("internal.configuration.01",
+ new Object[]{CONFIG_PROP_ERROR_HANDLING_CONFIG_PATH, "Error reading Configurations file"});
+ }
+
+ }
+
+ private byte[] readFromFile(final String filePath) throws URISyntaxException, IOException {
+ final String fullFilePath = FileUtils.makeAbsoluteUrl(filePath, basicConfig.getConfigurationRootDirectory());
+ final Resource ressource = resourceLoader.getResource(fullFilePath);
+ final InputStream is = ressource.getInputStream();
+ final byte[] result = IOUtils.toByteArray(is);
+ is.close();
+ return result;
+ }
+
+ @Builder
+ static class HandleData implements IHandleData {
+
+ @Getter
+ private String errorIdTokenForRedirect;
+
+ @Getter
+ private String supportTicket;
+
+ @Getter
+ private final Throwable throwable;
+
+ @Getter
+ private String internalErrorCode;
+
+ @Getter
+ private ActionType actionType;
+
+ @Getter
+ private LogLevel logLevel;
+
+ public String getPreFormatedErrorMessage() {
+ if (supportTicket != null) {
+ return MessageFormat.format(TICKET_LOG_MSG, internalErrorCode, throwable.getMessage(), supportTicket);
+
+ } else {
+ return MessageFormat.format(TECH_LOG_MSG, internalErrorCode, throwable.getMessage());
+
+ }
+ }
+ }
+
+}