diff --git a/pom.xml b/pom.xml
index c06b865..3e4f30a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,10 +40,15 @@
org.springframework.boot
spring-boot-starter-data-jpa
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+ 3.4.5
+
com.github.Podzilla
podzilla-utils-lib
- v1.1.5
+ v1.1.6
org.springframework.boot
@@ -107,6 +112,10 @@
jakarta.validation-api
3.0.2
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
org.mockito
mockito-core
diff --git a/src/main/java/com/podzilla/auth/controller/AdminController.java b/src/main/java/com/podzilla/auth/controller/AdminController.java
index 0976764..fbefc3e 100644
--- a/src/main/java/com/podzilla/auth/controller/AdminController.java
+++ b/src/main/java/com/podzilla/auth/controller/AdminController.java
@@ -1,5 +1,6 @@
package com.podzilla.auth.controller;
+import com.podzilla.auth.dto.AddCourierRequest;
import com.podzilla.auth.model.User;
import com.podzilla.auth.service.AdminService;
import io.swagger.v3.oas.annotations.Operation;
@@ -8,12 +9,15 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.PostMapping;
+
import java.util.List;
import java.util.UUID;
@@ -71,4 +75,18 @@ public void deleteUser(
LOGGER.debug("Admin requested to delete user with userId={}", userId);
adminService.deleteUser(userId);
}
+
+ @PostMapping("/courier")
+ @Operation(summary = "Add a new courier",
+ description = "Allows an admin to add a new courier to the system.")
+ @ApiResponse(responseCode = "200",
+ description = "Courier added successfully")
+ public void addCourier(
+ @Parameter(description = "Courier details")
+ @RequestBody final AddCourierRequest addCourierRequest) {
+
+ LOGGER.debug("Admin requested to add a new courier with details={}",
+ addCourierRequest);
+ adminService.addCourier(addCourierRequest);
+ }
}
diff --git a/src/main/java/com/podzilla/auth/controller/AuthenticationController.java b/src/main/java/com/podzilla/auth/controller/AuthenticationController.java
index 0d1c85f..a4cd768 100644
--- a/src/main/java/com/podzilla/auth/controller/AuthenticationController.java
+++ b/src/main/java/com/podzilla/auth/controller/AuthenticationController.java
@@ -7,6 +7,7 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -43,7 +44,7 @@ public AuthenticationController(
description = "User logged in successfully"
)
public ResponseEntity> login(
- @RequestBody final LoginRequest loginRequest,
+ @Valid @RequestBody final LoginRequest loginRequest,
final HttpServletResponse response) {
String email = authenticationService.login(loginRequest, response);
LOGGER.info("User {} logged in", email);
@@ -62,7 +63,7 @@ public ResponseEntity> login(
description = "User registered successfully"
)
public ResponseEntity> registerUser(
- @RequestBody final SignupRequest signupRequest) {
+ @Valid @RequestBody final SignupRequest signupRequest) {
authenticationService.registerAccount(signupRequest);
LOGGER.info("User {} registered", signupRequest.getEmail());
return new ResponseEntity<>("Account registered.",
diff --git a/src/main/java/com/podzilla/auth/controller/UserController.java b/src/main/java/com/podzilla/auth/controller/UserController.java
index eea7dc5..d642efc 100644
--- a/src/main/java/com/podzilla/auth/controller/UserController.java
+++ b/src/main/java/com/podzilla/auth/controller/UserController.java
@@ -1,19 +1,18 @@
package com.podzilla.auth.controller;
+import com.podzilla.auth.dto.UpdateRequest;
+import com.podzilla.auth.dto.UserDetailsRequest;
import com.podzilla.auth.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
-import java.util.UUID;
-
@RestController
@RequestMapping("/user")
public class UserController {
@@ -27,14 +26,24 @@ public UserController(final UserService userService) {
this.userService = userService;
}
- @PutMapping("/update/{userId}")
+ @PutMapping("/update")
@Operation(summary = "Update user name",
description = "Allows user to update their name.")
@ApiResponse(responseCode = "200",
description = "User profile updated successfully")
- public void updateProfile(@PathVariable final UUID userId,
- @Valid @RequestBody final String name) {
- LOGGER.debug("Received updateProfile request for userId={}", userId);
- userService.updateUserProfile(userId, name);
+ public void updateProfile(@RequestBody final UpdateRequest
+ updateRequest) {
+ LOGGER.debug("Received updateProfile request");
+ userService.updateUserProfile(updateRequest);
+ }
+
+ @GetMapping("/details")
+ @Operation(summary = "Get user details",
+ description = "Fetches the details of the current user.")
+ @ApiResponse(responseCode = "200",
+ description = "User details fetched successfully")
+ public UserDetailsRequest getUserDetails() {
+ LOGGER.debug("Received getUserDetails request");
+ return userService.getUserDetails();
}
}
diff --git a/src/main/java/com/podzilla/auth/dto/AddCourierRequest.java b/src/main/java/com/podzilla/auth/dto/AddCourierRequest.java
new file mode 100644
index 0000000..0336544
--- /dev/null
+++ b/src/main/java/com/podzilla/auth/dto/AddCourierRequest.java
@@ -0,0 +1,21 @@
+package com.podzilla.auth.dto;
+
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+@Data
+public class AddCourierRequest {
+ @NotBlank(message = "Name is required")
+ private String name;
+
+ @Email
+ @NotBlank(message = "Email is required")
+ private String email;
+
+ @NotBlank(message = "Password is required")
+ private String password;
+
+ @NotBlank(message = "Mobile number is required")
+ private String mobileNumber;
+}
diff --git a/src/main/java/com/podzilla/auth/dto/CustomUserDetails.java b/src/main/java/com/podzilla/auth/dto/CustomUserDetails.java
index 1337bd7..4803fba 100644
--- a/src/main/java/com/podzilla/auth/dto/CustomUserDetails.java
+++ b/src/main/java/com/podzilla/auth/dto/CustomUserDetails.java
@@ -11,6 +11,7 @@
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Set;
+import java.util.UUID;
@JsonIgnoreProperties(ignoreUnknown = true)
@Builder
@@ -21,6 +22,8 @@ public class CustomUserDetails implements UserDetails {
private String username;
+ private UUID id;
+
@JsonIgnore
private String password;
diff --git a/src/main/java/com/podzilla/auth/dto/LoginRequest.java b/src/main/java/com/podzilla/auth/dto/LoginRequest.java
index dce141e..1030318 100644
--- a/src/main/java/com/podzilla/auth/dto/LoginRequest.java
+++ b/src/main/java/com/podzilla/auth/dto/LoginRequest.java
@@ -1,9 +1,16 @@
package com.podzilla.auth.dto;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class LoginRequest {
+
+ @Email
+ @NotBlank(message = "Email is required")
private String email;
+
+ @NotBlank(message = "Password is required")
private String password;
}
diff --git a/src/main/java/com/podzilla/auth/dto/SignupRequest.java b/src/main/java/com/podzilla/auth/dto/SignupRequest.java
index 5749166..380f4ff 100644
--- a/src/main/java/com/podzilla/auth/dto/SignupRequest.java
+++ b/src/main/java/com/podzilla/auth/dto/SignupRequest.java
@@ -1,10 +1,26 @@
package com.podzilla.auth.dto;
+import com.podzilla.mq.events.DeliveryAddress;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class SignupRequest {
+ @NotBlank(message = "Name is required")
private String name;
+
+ @Email
+ @NotBlank(message = "Email is required")
private String email;
+
+ @NotBlank(message = "Password is required")
private String password;
+
+ @NotBlank(message = "Mobile number is required")
+ private String mobileNumber;
+
+ @Valid
+ private DeliveryAddress address;
}
diff --git a/src/main/java/com/podzilla/auth/dto/UpdateRequest.java b/src/main/java/com/podzilla/auth/dto/UpdateRequest.java
new file mode 100644
index 0000000..9258d09
--- /dev/null
+++ b/src/main/java/com/podzilla/auth/dto/UpdateRequest.java
@@ -0,0 +1,11 @@
+package com.podzilla.auth.dto;
+
+import com.podzilla.mq.events.DeliveryAddress;
+import lombok.Data;
+
+@Data
+public class UpdateRequest {
+ private String name;
+ private DeliveryAddress address;
+ private String mobileNumber;
+}
diff --git a/src/main/java/com/podzilla/auth/dto/UserDetailsRequest.java b/src/main/java/com/podzilla/auth/dto/UserDetailsRequest.java
new file mode 100644
index 0000000..6f75b6f
--- /dev/null
+++ b/src/main/java/com/podzilla/auth/dto/UserDetailsRequest.java
@@ -0,0 +1,18 @@
+package com.podzilla.auth.dto;
+
+import com.podzilla.mq.events.DeliveryAddress;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class UserDetailsRequest {
+ private String email;
+ private String name;
+ private String mobileNumber;
+ private DeliveryAddress address;
+}
diff --git a/src/main/java/com/podzilla/auth/exception/GlobalExceptionHandler.java b/src/main/java/com/podzilla/auth/exception/GlobalExceptionHandler.java
index 19eb55d..bbef77c 100644
--- a/src/main/java/com/podzilla/auth/exception/GlobalExceptionHandler.java
+++ b/src/main/java/com/podzilla/auth/exception/GlobalExceptionHandler.java
@@ -1,16 +1,41 @@
package com.podzilla.auth.exception;
+import io.micrometer.common.lang.NonNull;
+import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
+ @Override // Good practice to use @Override
+ protected ResponseEntity