mirror of
https://gitea.gofwd.group/Forward_Group/ballistic-builder-spring.git
synced 2026-01-20 16:51:03 -05:00
new admin-user api
This commit is contained in:
@@ -13,4 +13,6 @@ public interface UserRepository extends JpaRepository<User, Integer> {
|
||||
boolean existsByEmailIgnoreCaseAndDeletedAtIsNull(String email);
|
||||
|
||||
Optional<User> findByUuid(UUID uuid);
|
||||
|
||||
boolean existsByRole(String role);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package group.goforward.ballistic.services.admin;
|
||||
|
||||
import group.goforward.ballistic.model.User;
|
||||
import group.goforward.ballistic.repos.UserRepository;
|
||||
import group.goforward.ballistic.web.dto.admin.AdminUserDto;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class AdminUserService {
|
||||
|
||||
private static final Set<String> ALLOWED_ROLES = Set.of("USER", "ADMIN");
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public AdminUserService(UserRepository userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
public List<AdminUserDto> getAllUsersForAdmin() {
|
||||
return userRepository.findAll()
|
||||
.stream()
|
||||
.map(AdminUserDto::fromUser)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public AdminUserDto updateUserRole(UUID userUuid, String newRole, Authentication auth) {
|
||||
if (newRole == null || !ALLOWED_ROLES.contains(newRole.toUpperCase())) {
|
||||
throw new IllegalArgumentException("Invalid role: " + newRole);
|
||||
}
|
||||
|
||||
User user = userRepository.findByUuid(userUuid)
|
||||
.orElseThrow(() -> new IllegalArgumentException("User not found"));
|
||||
|
||||
// Optional safety: do not allow demoting yourself (you can loosen this later)
|
||||
String currentEmail = auth != null ? auth.getName() : null;
|
||||
boolean isSelf = currentEmail != null
|
||||
&& currentEmail.equalsIgnoreCase(user.getEmail());
|
||||
|
||||
if (isSelf && !"ADMIN".equalsIgnoreCase(newRole)) {
|
||||
throw new IllegalStateException("You cannot change your own role to non-admin.");
|
||||
}
|
||||
|
||||
user.setRole(newRole.toUpperCase());
|
||||
// updatedAt will be handled by your entity / DB defaults
|
||||
|
||||
return AdminUserDto.fromUser(user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package group.goforward.ballistic.web.admin;
|
||||
|
||||
import group.goforward.ballistic.services.admin.AdminUserService;
|
||||
import group.goforward.ballistic.web.dto.admin.AdminUserDto;
|
||||
import group.goforward.ballistic.web.dto.admin.UpdateUserRoleRequest;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/users")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public class AdminUserController {
|
||||
|
||||
private final AdminUserService adminUserService;
|
||||
|
||||
public AdminUserController(AdminUserService adminUserService) {
|
||||
this.adminUserService = adminUserService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public List<AdminUserDto> listUsers() {
|
||||
return adminUserService.getAllUsersForAdmin();
|
||||
}
|
||||
|
||||
@PatchMapping("/{uuid}/role")
|
||||
public AdminUserDto updateRole(
|
||||
@PathVariable("uuid") UUID uuid,
|
||||
@RequestBody UpdateUserRoleRequest request,
|
||||
Authentication auth
|
||||
) {
|
||||
return adminUserService.updateUserRole(uuid, request.getRole(), auth);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package group.goforward.ballistic.web.dto.admin;
|
||||
|
||||
import group.goforward.ballistic.model.User;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AdminUserDto {
|
||||
|
||||
// We'll expose the UUID as the "id" used by the frontend
|
||||
private UUID id;
|
||||
private String email;
|
||||
private String displayName;
|
||||
private String role;
|
||||
private OffsetDateTime createdAt;
|
||||
private OffsetDateTime updatedAt;
|
||||
private OffsetDateTime lastLoginAt;
|
||||
|
||||
public AdminUserDto(UUID id,
|
||||
String email,
|
||||
String displayName,
|
||||
String role,
|
||||
OffsetDateTime createdAt,
|
||||
OffsetDateTime updatedAt,
|
||||
OffsetDateTime lastLoginAt) {
|
||||
this.id = id;
|
||||
this.email = email;
|
||||
this.displayName = displayName;
|
||||
this.role = role;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
this.lastLoginAt = lastLoginAt;
|
||||
}
|
||||
|
||||
public static AdminUserDto fromUser(User user) {
|
||||
return new AdminUserDto(
|
||||
user.getUuid(), // use UUID here (stable id)
|
||||
user.getEmail(),
|
||||
user.getDisplayName(),
|
||||
user.getRole(), // String: "USER" / "ADMIN"
|
||||
user.getCreatedAt(),
|
||||
user.getUpdatedAt(),
|
||||
user.getLastLoginAt()
|
||||
);
|
||||
}
|
||||
|
||||
// Getters (and setters if you want Jackson to use them)
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public OffsetDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public OffsetDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public OffsetDateTime getLastLoginAt() {
|
||||
return lastLoginAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package group.goforward.ballistic.web.dto.admin;
|
||||
|
||||
public class UpdateUserRoleRequest {
|
||||
|
||||
private String role;
|
||||
|
||||
public UpdateUserRoleRequest() {
|
||||
}
|
||||
|
||||
public UpdateUserRoleRequest(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,10 @@ spring.datasource.driver-class-name=org.postgresql.Driver
|
||||
security.jwt.secret=ballistic-test-secret-key-1234567890-ABCDEFGHIJKLNMOPQRST
|
||||
security.jwt.access-token-minutes=2880
|
||||
|
||||
# Temp disabling logging to find what I fucked up
|
||||
spring.jpa.show-sql=false
|
||||
logging.level.org.hibernate.SQL=warn
|
||||
# Logging
|
||||
|
||||
spring.jpa.show-sql=true
|
||||
logging.level.org.hibernate.SQL=INFO
|
||||
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=warn
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user