Skip to content

Commit 5fb4f71

Browse files
committed
Improve JSON formatting in error messages
1 parent f518558 commit 5fb4f71

File tree

5 files changed

+34
-24
lines changed

5 files changed

+34
-24
lines changed

src/main/java/org/openpodcastapi/opa/auth/ApiAuthController.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class ApiAuthController {
2828
private final AuthenticationManager authenticationManager;
2929

3030
@PostMapping("/api/auth/login")
31-
public ResponseEntity<DTOs.LoginSuccessResponse> login(@RequestBody @NotNull DTOs.LoginRequest loginRequest) {
31+
public ResponseEntity<AuthDTO.LoginSuccessResponse> login(@RequestBody @NotNull AuthDTO.LoginRequest loginRequest) {
3232
// Set the authentication using the provided details
3333
Authentication authentication = authenticationManager.authenticate(
3434
new UsernamePasswordAuthenticationToken(loginRequest.username(), loginRequest.password())
@@ -45,13 +45,13 @@ public ResponseEntity<DTOs.LoginSuccessResponse> login(@RequestBody @NotNull DTO
4545
String refreshToken = tokenService.generateRefreshToken(user);
4646

4747
// Format the tokens and expiration time into a DTO
48-
DTOs.LoginSuccessResponse response = new DTOs.LoginSuccessResponse(accessToken, refreshToken, String.valueOf(jwtService.getExpirationTime()));
48+
AuthDTO.LoginSuccessResponse response = new AuthDTO.LoginSuccessResponse(accessToken, refreshToken, String.valueOf(jwtService.getExpirationTime()));
4949

5050
return ResponseEntity.ok(response);
5151
}
5252

5353
@PostMapping("/api/auth/refresh")
54-
public ResponseEntity<DTOs.RefreshTokenResponse> getRefreshToken(@RequestBody @NotNull DTOs.RefreshTokenRequest refreshTokenRequest) {
54+
public ResponseEntity<AuthDTO.RefreshTokenResponse> getRefreshToken(@RequestBody @NotNull AuthDTO.RefreshTokenRequest refreshTokenRequest) {
5555
User targetUser = userRepository.findByUsername(refreshTokenRequest.username()).orElseThrow(() -> new EntityNotFoundException("No user with username " + refreshTokenRequest.username() + " found"));
5656

5757
// Validate the existing refresh token
@@ -61,7 +61,7 @@ public ResponseEntity<DTOs.RefreshTokenResponse> getRefreshToken(@RequestBody @N
6161
String newAccessToken = tokenService.generateAccessToken(user);
6262

6363
// Format the token and expiration time into a DTO
64-
DTOs.RefreshTokenResponse response = new DTOs.RefreshTokenResponse(newAccessToken, String.valueOf(jwtService.getExpirationTime()));
64+
AuthDTO.RefreshTokenResponse response = new AuthDTO.RefreshTokenResponse(newAccessToken, String.valueOf(jwtService.getExpirationTime()));
6565

6666
return ResponseEntity.ok(response);
6767
}

src/main/java/org/openpodcastapi/opa/auth/DTOs.java renamed to src/main/java/org/openpodcastapi/opa/auth/AuthDTO.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import jakarta.validation.constraints.NotNull;
55

6-
/// All DTOs for auth methods
7-
public class DTOs {
6+
/// All data transfer objects for auth methods
7+
public class AuthDTO {
88
/// A DTO representing an API login request
99
///
1010
/// @param username the user's username
@@ -46,4 +46,14 @@ public record RefreshTokenResponse(
4646
@JsonProperty(value = "expiresIn", required = true) @NotNull String expiresIn
4747
) {
4848
}
49+
50+
/// Displays an auth error
51+
///
52+
/// @param error the error message
53+
/// @param message an additional description of the error
54+
public record ErrorMessageDTO(
55+
@JsonProperty(value = "error", required = true) @NotNull String error,
56+
@JsonProperty(value = "message", required = true) @NotNull String message
57+
) {
58+
}
4959
}

src/main/java/org/openpodcastapi/opa/auth/JwtAccessDeniedHandler.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import jakarta.servlet.http.HttpServletRequest;
44
import jakarta.servlet.http.HttpServletResponse;
5+
import org.openpodcastapi.opa.util.JSONFormatter;
56
import org.springframework.http.HttpStatus;
67
import org.springframework.security.access.AccessDeniedException;
78
import org.springframework.security.web.access.AccessDeniedHandler;
@@ -11,7 +12,6 @@
1112

1213
@Component
1314
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
14-
1515
@Override
1616
public void handle(HttpServletRequest request,
1717
HttpServletResponse response,
@@ -23,13 +23,8 @@ public void handle(HttpServletRequest request,
2323
// Set content type to JSON
2424
response.setContentType("application/json");
2525

26-
String body = """
27-
{
28-
"error": "Forbidden",
29-
"message": "You do not have permission to access this resource."
30-
}
31-
""";
26+
AuthDTO.ErrorMessageDTO message = new AuthDTO.ErrorMessageDTO("Forbidden", "You do not have permission to access this resource");
3227

33-
response.getWriter().write(body);
28+
response.getWriter().write(JSONFormatter.parseDataToJSON(message));
3429
}
3530
}

src/main/java/org/openpodcastapi/opa/auth/JwtAuthenticationEntryPoint.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import jakarta.servlet.http.HttpServletRequest;
44
import jakarta.servlet.http.HttpServletResponse;
5-
import lombok.extern.log4j.Log4j2;
5+
import org.openpodcastapi.opa.util.JSONFormatter;
66
import org.springframework.http.HttpStatus;
77
import org.springframework.security.core.AuthenticationException;
88
import org.springframework.security.web.AuthenticationEntryPoint;
@@ -11,7 +11,6 @@
1111
import java.io.IOException;
1212

1313
@Component
14-
@Log4j2
1514
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
1615
/// Returns a 401 when a request is made without a valid bearer token
1716
@Override
@@ -22,14 +21,8 @@ public void commence(HttpServletRequest request, HttpServletResponse response, A
2221
// Set content type to JSON
2322
response.setContentType("application/json");
2423

25-
// Return a simple JSON error message
26-
String body = """
27-
{
28-
"error": "Unauthorized",
29-
"message": "You need to log in to access this resource."
30-
}
31-
""";
24+
AuthDTO.ErrorMessageDTO message = new AuthDTO.ErrorMessageDTO("Access denied", "You need to log in to access this resource");
3225

33-
response.getWriter().write(body);
26+
response.getWriter().write(JSONFormatter.parseDataToJSON(message));
3427
}
3528
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.openpodcastapi.opa.util;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
6+
public class JSONFormatter {
7+
public static String parseDataToJSON(Object item) throws JsonProcessingException {
8+
ObjectMapper objectMapper = new ObjectMapper();
9+
10+
return objectMapper.writeValueAsString(item);
11+
}
12+
}

0 commit comments

Comments
 (0)