Skip to content

Commit

Permalink
Exception mapping and frontend preventing access to unauthorized page…
Browse files Browse the repository at this point in the history
…s via URL
  • Loading branch information
AntonioG70 committed Nov 21, 2024
1 parent 103dbd7 commit 817c682
Show file tree
Hide file tree
Showing 25 changed files with 716 additions and 559 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

<source path="client"/>
<source path="api" />
<source path="exceptions"/>
<!-- https://github.com/resty-gwt/resty-gwt/issues/296 -->
<!-- in order to use auto-detection on strings you need to set in your XZY-gwt.xml -->
<set-property name="restygwt.autodetect.plainText" value="true" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import org.glassfish.jersey.servlet.ServletProperties;
import org.springframework.context.annotation.Configuration;

import com.databasepreservation.common.api.exceptions.RestExceptionMapper;
import com.databasepreservation.common.api.utils.CacheFilterFactory;
import com.databasepreservation.common.api.v1.ActivityLogResource;
import com.databasepreservation.common.api.v1.AuthenticationResource;
Expand Down Expand Up @@ -66,7 +65,6 @@ public RestApplicationNoSwagger() {
register(JacksonFeature.class);
register(MoxyXmlFeature.class);
register(MultiPartFeature.class);
register(RestExceptionMapper.class);
register(CacheFilterFactory.class);

register(ActivityLogResource.class);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE file at the root of the source
* tree and available online at
*
* https://github.com/keeps/dbptk-ui
*/
package com.databasepreservation.common.api.exceptions;

import com.databasepreservation.common.exceptions.SavedSearchException;
import com.google.gwt.http.client.Response;
import org.roda.core.data.exceptions.*;

import java.io.Serial;

/**
* @author António Lindo <[email protected]>
*/

public class RESTException extends RuntimeException {
@Serial
private static final long serialVersionUID = 4667937307148805083L;

private Throwable cause;

public RESTException() {
}

public RESTException(Throwable cause) {
super();
this.cause = cause;
}

private static String getCauseMessage(Throwable e) {
StringBuilder message = new StringBuilder();
Throwable cause = e;

while (cause != null) {
message.append(" caused by ").append(cause.getClass().getSimpleName()).append(": ");
if (cause.getMessage() != null) {
message.append(cause.getMessage());
}
cause = cause.getCause();
}
return message.toString();
}

@Override
public synchronized Throwable getCause() {
return cause;
}

public int getStatus() {
if (cause instanceof AuthorizationDeniedException) {
return Response.SC_UNAUTHORIZED;
} else if (cause instanceof NotFoundException) {
return Response.SC_NOT_FOUND;
} else if (cause instanceof AlreadyExistsException) {
return Response.SC_CONFLICT;
} else if (cause instanceof SavedSearchException) {
return Response.SC_BAD_REQUEST;
} else if (cause instanceof GenericException) {
return Response.SC_BAD_REQUEST;
} else if (cause instanceof RequestNotValidException) {
return Response.SC_BAD_REQUEST;
}
return Response.SC_INTERNAL_SERVER_ERROR;
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.databasepreservation.common.api.exceptions;

import java.io.IOException;
import java.util.UUID;

import com.databasepreservation.common.api.exceptions.model.ErrorResponseMessage;
import com.databasepreservation.common.exceptions.AuthorizationException;
import com.databasepreservation.common.exceptions.ViewerException;
import org.roda.core.data.exceptions.AlreadyExistsException;
import org.roda.core.data.exceptions.AuthenticationDeniedException;
import org.roda.core.data.exceptions.AuthorizationDeniedException;
import org.roda.core.data.exceptions.GenericException;
import org.roda.core.data.exceptions.NotFoundException;
import org.roda.core.data.exceptions.RequestNotValidException;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler(value = {RESTException.class})
protected ResponseEntity<Object> handleRestException(RuntimeException ex, WebRequest request) {
String message = "Internal server error";
String details = "";
Object objectDetails = null;
HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
UUID errorID = UUID.randomUUID();
if (ex.getCause() instanceof AuthorizationDeniedException || ex.getCause() instanceof AuthorizationException) {
message = "Forbidden";
details = ex.getCause().getMessage();
httpStatus = HttpStatus.FORBIDDEN;
} else if (ex.getCause() instanceof AuthenticationDeniedException) {
message = "Unauthorized access";
details = ex.getCause().getMessage();
httpStatus = HttpStatus.UNAUTHORIZED;
} else if (ex.getCause() instanceof NotFoundException) {
message = "Resource not found";
details = ex.getCause().getMessage();
httpStatus = HttpStatus.NOT_FOUND;
} else if (ex.getCause() instanceof AlreadyExistsException) {
message = "Resource already exists";
details = ex.getCause().getMessage();
httpStatus = HttpStatus.CONFLICT;
} else if (ex.getCause() instanceof GenericException || ex.getCause() instanceof RequestNotValidException
|| ex.getCause() instanceof IOException || ex.getCause() instanceof ViewerException) {
message = "Request was not valid";
details = ex.getCause().getMessage();
httpStatus = HttpStatus.BAD_REQUEST;
}

String warn = "ERROR_ID: " + errorID + " - " + ex.getClass().getSimpleName() + ": " + ex.getCause().getMessage();
LoggerFactory.getLogger(RestResponseEntityExceptionHandler.class).warn(warn);

ErrorResponseMessage body = new ErrorResponseMessage(httpStatus.value(), errorID.toString(), message, details,
((ServletWebRequest) request).getRequest().getRequestURI(), objectDetails);

HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);

return handleExceptionInternal(ex, body, responseHeaders, httpStatus, request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.databasepreservation.common.api.exceptions.model;

import java.io.Serial;
import java.io.Serializable;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

import com.fasterxml.jackson.annotation.JsonInclude;

public class ErrorResponseMessage implements Serializable {

@Serial
private static final long serialVersionUID = -2206131216992713872L;

private final int status;
private final String errorId;
private final String message;
private final String details;
private final Instant timestamp;
private final String instance;
@JsonInclude(JsonInclude.Include.NON_NULL)
private Object objectDetails;

public ErrorResponseMessage(int status, String errorId, String message, String details, String instance) {
this.status = status;
this.errorId = errorId;
this.message = message;
this.details = details;
this.timestamp = Instant.now().truncatedTo(ChronoUnit.MILLIS);
this.instance = instance;
}

public ErrorResponseMessage(int status, String errorId, String message, String details, String instance, Object objectDetails) {
this.status = status;
this.errorId = errorId;
this.message = message;
this.details = details;
this.timestamp = Instant.now().truncatedTo(ChronoUnit.MILLIS);
this.instance = instance;
this.objectDetails = objectDetails;
}

public int getStatus() {
return status;
}

public String getErrorId() {
return errorId;
}

public String getMessage() {
return message;
}

public String getDetails() {
return details;
}

public Instant getTimestamp() {
return timestamp;
}

public String getInstance() {
return instance;
}

public Object getObjectDetails() {
return objectDetails;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
package com.databasepreservation.common.api.utils;

import com.databasepreservation.common.api.exceptions.RESTException;
import com.databasepreservation.common.client.tools.ViewerCelllUtils;
import java.io.IOException;
import java.math.BigDecimal;
Expand All @@ -19,7 +20,6 @@
import org.apache.commons.lang3.StringUtils;

import com.databasepreservation.common.client.ViewerConstants;
import com.databasepreservation.common.client.exceptions.RESTException;
import com.databasepreservation.common.client.models.status.collection.ColumnStatus;
import com.databasepreservation.common.client.models.status.collection.NestedColumnStatus;
import com.databasepreservation.common.client.models.status.collection.TableStatus;
Expand Down
Loading

0 comments on commit 817c682

Please sign in to comment.