From d840b05da2322bae2e8bf27a3667bfec3c58b2e4 Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 28 Oct 2025 18:01:21 +0100 Subject: [PATCH] Enhanced OAuth2 API Tester tool, updated validation and improved CORS configuration: - Improved OAuth2 Tester UI/UX: added support for multiple HTTP methods, query parameters, request body validation, collapsible result sections, and dynamic input handling. - Enhanced `UserController` with validation annotations for `UserDTO` in API requests. - Updated `UserDTO` to include stricter validation constraints (`@NotNull`, `@NotBlank`, `@Email`). - Adjusted CORS configuration to allow all origins for OAuth endpoints. --- .../java/de/avatic/lcc/config/CorsConfig.java | 2 +- .../lcc/controller/users/UserController.java | 3 +- .../java/de/avatic/lcc/dto/users/UserDTO.java | 10 +- tools/oauth2-tester/index.html | 387 ++++++++++++++---- 4 files changed, 323 insertions(+), 79 deletions(-) diff --git a/src/main/java/de/avatic/lcc/config/CorsConfig.java b/src/main/java/de/avatic/lcc/config/CorsConfig.java index 102fff3..f4d7ea7 100644 --- a/src/main/java/de/avatic/lcc/config/CorsConfig.java +++ b/src/main/java/de/avatic/lcc/config/CorsConfig.java @@ -67,7 +67,7 @@ public class CorsConfig implements WebMvcConfigurer { // OAuth endpoints registry.addMapping("/oauth/**") - .allowedOriginPatterns(allowedCors) + .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true); diff --git a/src/main/java/de/avatic/lcc/controller/users/UserController.java b/src/main/java/de/avatic/lcc/controller/users/UserController.java index 4ffe3e4..77026c7 100644 --- a/src/main/java/de/avatic/lcc/controller/users/UserController.java +++ b/src/main/java/de/avatic/lcc/controller/users/UserController.java @@ -4,6 +4,7 @@ package de.avatic.lcc.controller.users; import de.avatic.lcc.dto.users.UserDTO; import de.avatic.lcc.repositories.pagination.SearchQueryResult; import de.avatic.lcc.service.users.UserService; +import jakarta.validation.Valid; import jakarta.validation.constraints.Min; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -60,7 +61,7 @@ public class UserController { */ @PutMapping({"/", ""}) @PreAuthorize("hasRole('RIGHT-MANAGEMENT')") - public ResponseEntity updateUser(@RequestParam UserDTO user) { + public ResponseEntity updateUser(@Valid @RequestBody UserDTO user) { userService.updateUser(user); return ResponseEntity.ok().build(); } diff --git a/src/main/java/de/avatic/lcc/dto/users/UserDTO.java b/src/main/java/de/avatic/lcc/dto/users/UserDTO.java index c645b9d..e9029cf 100644 --- a/src/main/java/de/avatic/lcc/dto/users/UserDTO.java +++ b/src/main/java/de/avatic/lcc/dto/users/UserDTO.java @@ -2,28 +2,36 @@ package de.avatic.lcc.dto.users; import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; import java.util.List; public class UserDTO { + @NotNull @JsonProperty("firstname") private String firstName; + @NotNull @JsonProperty("lastname") private String lastName; + @Email @JsonProperty("mail") private String email; + @NotNull @JsonProperty("workday_id") private String workdayId; @JsonProperty("is_active") private boolean isActive; + @NotNull + @Size(min = 1) @JsonProperty("groups") - private List groups; + private List<@NotBlank String> groups; public String getFirstName() { return firstName; diff --git a/tools/oauth2-tester/index.html b/tools/oauth2-tester/index.html index d1c8e98..a94962f 100644 --- a/tools/oauth2-tester/index.html +++ b/tools/oauth2-tester/index.html @@ -57,7 +57,7 @@ font-size: 14px; } - input { + input, textarea { width: 100%; padding: 12px; border: 2px solid #e0e0e0; @@ -67,6 +67,12 @@ transition: border-color 0.3s; } + textarea { + min-height: 100px; + resize: vertical; + font-family: 'Courier New', monospace; + } + select { width: 100%; padding: 12px; @@ -80,11 +86,23 @@ } input:focus, - select:focus { + select:focus, + textarea:focus { outline: none; border-color: #667eea; } + .method-selector { + display: grid; + grid-template-columns: 120px 1fr; + gap: 10px; + align-items: start; + } + + .method-select { + width: 100%; + } + button { width: 100%; padding: 14px; @@ -158,7 +176,7 @@ .result-box { background: #f8f9fa; - border: 1px solid #e0e0e0; + border: none; border-radius: 6px; padding: 15px; max-height: 400px; @@ -175,14 +193,14 @@ } .error { - color: #d32f2f; - background: #ffebee; - border-color: #ef9a9a; + color: #333; + background-color: #f8f9fa; + border-color: #BC2B72; } .success { - color: #388e3c; - background: #e8f5e9; + color: #333; + background-color: #f8f9fa; border-color: #81c784; } @@ -222,8 +240,8 @@ } .status-error { - background: #ffebee; - color: #d32f2f; + background-color: #BC2B72; + color: #ffffff; } .error-summary { @@ -240,83 +258,195 @@ } .error-summary strong { - color: #002F54; font-weight: 600; } .details-button { - width: 100%; + display: none; + } + + .result-box-header { + display: flex; + justify-content: space-between; + align-items: center; padding: 10px; + background: #e9ecef; + border-radius: 6px 6px 0 0; + cursor: pointer; + user-select: none; + margin: -15px -15px 10px -15px; + } + + .result-box-header:hover { + background: #dee2e6; + } + + .result-box-title { + font-weight: 500; + color: #333; + font-size: 14px; + } + + .toggle-icon { + font-size: 18px; + color: #666; + transition: transform 0.3s; + } + + .toggle-icon.collapsed { + transform: rotate(-90deg); + } + + .section-divider { + border-top: 2px solid #e0e0e0; + margin: 30px 0; + } + + .section-title { + font-size: 18px; + color: #333; + margin-bottom: 15px; + font-weight: 600; + } + + .params-section { + background: #f8f9fa; + padding: 15px; + border-radius: 6px; + margin-bottom: 20px; + } + + .param-row { + display: grid; + grid-template-columns: 1fr 1fr auto; + gap: 10px; + margin-bottom: 10px; + } + + .param-input { + padding: 8px; + border: 1px solid #e0e0e0; + border-radius: 4px; + font-size: 13px; + } + + .param-remove { + padding: 8px 12px; + background-color: #BC2B72; + color: #ffffff; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 13px; + } + + .param-remove:hover { + background-color: #a02460; + } + + .param-add { + padding: 8px 16px; background-color: #002F54; color: #ffffff; border: none; - border-radius: 6px; - font-size: 14px; - font-weight: 500; - font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; + border-radius: 4px; cursor: pointer; - margin-bottom: 15px; - transition: opacity 0.3s; + font-size: 13px; + font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; + width: auto; + margin-top: 5px; } - .details-button:hover { - opacity: 0.8; + .param-add:hover { + background-color: #001a30; + } + + .body-section { + display: none; + } + + .body-section.active { + display: block; + } + + .helper-text { + font-size: 12px; + color: #666; + margin-top: 5px; }

OAuth2 API Tester

-

Teste deine OAuth2 Client Credentials API-Integration

- +

Testen Sie APIs mit OAuth2-Authentifizierung

+
-

Hinweis

-

Diese Anwendung verwendet den OAuth2 Client Credentials Flow. Stelle sicher, dass deine API diesen Flow unterstützt und CORS für diese Domain aktiviert ist.

+

Funktionen:

+

+ • Unterstützt alle HTTP-Methoden (GET, POST, PUT, DELETE, PATCH)
+ • Query-Parameter für alle Methoden
+ • Request-Body für POST, PUT und PATCH
+ • OAuth2 Client Credentials Flow +

+ +
OAuth2 Konfiguration
+
- - + +
- +
- +
+
+ + +
API Request Konfiguration
+
- - + +
+ + +
+
+ + +
+ +
+
+ +
+
+ + +
+ + +
Geben Sie valides JSON ein
@@ -333,8 +463,11 @@
-
+

             
@@ -342,14 +475,100 @@