Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix/http status codes for errors #21

Merged
merged 12 commits into from
Nov 22, 2024
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v1.0.10](https://github.com/in2workspace/in2-verifier-api/releases/tag/v1.0.9)
## [v1.0.11](https://github.com/in2workspace/in2-verifier-api/releases/tag/v1.0.11)
### Fixed
- Unauthorized Http response code for failed validation of VP token

## [v1.0.10](https://github.com/in2workspace/in2-verifier-api/releases/tag/v1.0.10)
### Fixed
- Add an error page for errors during the client authentication request.

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {
}

group = 'es.in2'
version = '1.0.10'
version = '1.0.11'

java {
toolchain {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package es.in2.vcverifier.exception;

public class InvalidVPtokenException extends RuntimeException {

public InvalidVPtokenException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package es.in2.vcverifier.exception.handler;

import es.in2.vcverifier.exception.CredentialRevokedException;
import es.in2.vcverifier.exception.MismatchOrganizationIdentifierException;
import es.in2.vcverifier.exception.QRCodeGenerationException;
import es.in2.vcverifier.exception.ResourceNotFoundException;
import es.in2.vcverifier.exception.*;
import es.in2.vcverifier.model.GlobalErrorMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -52,11 +49,19 @@ public GlobalErrorMessage handleException(MismatchOrganizationIdentifierExceptio
log.error("The organization identifier of the cert does not match the organization identifier from the credential payload: ", ex);
return new GlobalErrorMessage("","","");
}

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public GlobalErrorMessage handleException(Exception ex) {
log.error("An unexpected error occurred: ", ex);
return new GlobalErrorMessage("","","");
}

@ExceptionHandler(InvalidVPtokenException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public GlobalErrorMessage handleException(InvalidVPtokenException ex) {
log.error("VP token is not valid: ", ex);
return new GlobalErrorMessage("VP token is not valid", ex.getMessage(),"");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.nimbusds.jwt.SignedJWT;
import es.in2.vcverifier.config.CacheStore;
import es.in2.vcverifier.exception.InvalidCredentialTypeException;
import es.in2.vcverifier.exception.InvalidVPtokenException;
import es.in2.vcverifier.exception.UnsupportedGrantTypeException;
import es.in2.vcverifier.model.AuthorizationCodeData;
import es.in2.vcverifier.model.credentials.machine.LEARCredentialMachine;
Expand Down Expand Up @@ -124,7 +125,7 @@ private Authentication handleM2MGrant(MultiValueMap<String, String> parameters)
isValid = vpService.validateVerifiablePresentation(vpToken);
if (!isValid) {
log.error("CustomTokenRequestConverter -- handleM2MGrant -- VP Token is invalid");
throw new IllegalArgumentException("Invalid VP Token");
throw new InvalidVPtokenException("Invalid VP Token");
}
log.info("VP Token validated successfully");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import es.in2.vcverifier.config.CacheStore;
import es.in2.vcverifier.config.properties.SecurityProperties;
import es.in2.vcverifier.exception.InvalidVPtokenException;
import es.in2.vcverifier.model.AuthorizationCodeData;
import es.in2.vcverifier.service.AuthorizationResponseProcessorService;
import es.in2.vcverifier.service.VpService;
Expand Down Expand Up @@ -62,7 +63,7 @@ public void processAuthResponse(String state, String vpToken){
boolean isValid = vpService.validateVerifiablePresentation(decodedVpToken);
if (!isValid) {
log.error("VP Token is invalid");
throw new IllegalArgumentException("Invalid VP Token");
throw new InvalidVPtokenException("Invalid VP Token");
}
log.info("VP Token validated successfully");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package es.in2.vcverifier.exception.handler;

import es.in2.vcverifier.exception.*;
import es.in2.vcverifier.model.GlobalErrorMessage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.NoSuchElementException;

import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest
class GlobalExceptionHandlerTest {

private GlobalExceptionHandler globalExceptionHandler;

@BeforeEach
void setUp() {
globalExceptionHandler = new GlobalExceptionHandler();
}

@Test
void testHandleResourceNotFoundException() {
ResourceNotFoundException exception = new ResourceNotFoundException("Resource not found");

GlobalErrorMessage response = globalExceptionHandler.handleResourceNotFoundException(exception);

assertEquals("", response.title());
assertEquals("", response.message());
assertEquals("", response.path());
}

@Test
void testHandleNoSuchElementException() {
NoSuchElementException exception = new NoSuchElementException("Element not found");

GlobalErrorMessage response = globalExceptionHandler.handleNoSuchElementException(exception);

assertEquals("", response.title());
assertEquals("", response.message());
assertEquals("", response.path());
}

@Test
void testHandleQRCodeGenerationException() {
QRCodeGenerationException exception = new QRCodeGenerationException("QR Code Generation Failed");

GlobalErrorMessage response = globalExceptionHandler.handleQRCodeGenerationException(exception);

assertEquals("QR Code Generation Failed", response.title());
assertEquals("", response.message());
assertEquals("", response.path());
}

@Test
void testHandleCredentialRevokedException() {
CredentialRevokedException exception = new CredentialRevokedException("Credential revoked");

GlobalErrorMessage response = globalExceptionHandler.handleException(exception);

assertEquals("Verifiable presentation failed", response.title());
assertEquals("", response.message());
assertEquals("", response.path());
}

@Test
void testHandleMismatchOrganizationIdentifierException() {
MismatchOrganizationIdentifierException exception = new MismatchOrganizationIdentifierException("Mismatch org identifier");

GlobalErrorMessage response = globalExceptionHandler.handleException(exception);

assertEquals("", response.title());
assertEquals("", response.message());
assertEquals("", response.path());
}

@Test
void testHandleGenericException() {
Exception exception = new Exception("Generic error");

GlobalErrorMessage response = globalExceptionHandler.handleException(exception);

assertEquals("", response.title());
assertEquals("", response.message());
assertEquals("", response.path());
}

@Test
void testHandleInvalidVPtokenException() {
InvalidVPtokenException exception = new InvalidVPtokenException("Invalid VP token");

GlobalErrorMessage response = globalExceptionHandler.handleException(exception);

assertEquals("VP token is not valid", response.title());
assertEquals("Invalid VP token", response.message());
assertEquals("", response.path());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.nimbusds.jwt.SignedJWT;
import es.in2.vcverifier.config.CacheStore;
import es.in2.vcverifier.exception.InvalidCredentialTypeException;
import es.in2.vcverifier.exception.InvalidVPtokenException;
import es.in2.vcverifier.exception.UnsupportedGrantTypeException;
import es.in2.vcverifier.model.AuthorizationCodeData;
import es.in2.vcverifier.model.credentials.machine.LEARCredentialMachine;
Expand Down Expand Up @@ -192,7 +193,7 @@ void convert_clientCredentialsGrant_shouldReturnIllegalArgumentException_Invalid
when(clientAssertionValidationService.validateClientAssertionJWTClaims(anyString(), any())).thenReturn(true);
when(vpService.validateVerifiablePresentation(anyString())).thenReturn(false);

assertThrows(IllegalArgumentException.class, () ->
assertThrows(InvalidVPtokenException.class, () ->
customTokenRequestConverter.convert(mockRequest));
}

Expand Down