feat: track user login and logout timestamps in session management
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
package com.astalange.web.controller;
|
||||
|
||||
import com.astalange.core.entity.AppUser;
|
||||
import com.astalange.core.entity.Role;
|
||||
import com.astalange.core.repository.AppUserRepository;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.session.SessionRegistry;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
@@ -8,7 +11,9 @@ import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Controller
|
||||
@@ -16,22 +21,73 @@ import java.util.stream.Collectors;
|
||||
public class SessionController {
|
||||
|
||||
private final SessionRegistry sessionRegistry;
|
||||
private final AppUserRepository userRepository;
|
||||
|
||||
public SessionController(SessionRegistry sessionRegistry) {
|
||||
public SessionController(SessionRegistry sessionRegistry, AppUserRepository userRepository) {
|
||||
this.sessionRegistry = sessionRegistry;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
public static class UserSessionDTO {
|
||||
private final Long id;
|
||||
private final String username;
|
||||
private final boolean online;
|
||||
private final LocalDateTime lastLoginAt;
|
||||
private final LocalDateTime lastLogoutAt;
|
||||
private final String roles;
|
||||
|
||||
public UserSessionDTO(Long id, String username, boolean online, LocalDateTime lastLoginAt, LocalDateTime lastLogoutAt, String roles) {
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.online = online;
|
||||
this.lastLoginAt = lastLoginAt;
|
||||
this.lastLogoutAt = lastLogoutAt;
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public Long getId() { return id; }
|
||||
public String getUsername() { return username; }
|
||||
public boolean isOnline() { return online; }
|
||||
public LocalDateTime getLastLoginAt() { return lastLoginAt; }
|
||||
public LocalDateTime getLastLogoutAt() { return lastLogoutAt; }
|
||||
public String getRoles() { return roles; }
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public String viewSessions(Model model) {
|
||||
List<Object> principals = sessionRegistry.getAllPrincipals();
|
||||
List<String> activeUsers = principals.stream()
|
||||
Set<String> activeUsernames = principals.stream()
|
||||
.filter(principal -> principal instanceof UserDetails)
|
||||
.map(principal -> ((UserDetails) principal).getUsername())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
model.addAttribute("activeUsers", activeUsers);
|
||||
model.addAttribute("activeCount", activeUsers.size());
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<AppUser> allUsers = userRepository.findAll();
|
||||
|
||||
List<UserSessionDTO> userSessions = allUsers.stream().map(user -> {
|
||||
boolean isOnline = activeUsernames.contains(user.getUsername());
|
||||
String rolesStr = user.getRoles().stream()
|
||||
.map(Role::getName)
|
||||
.map(r -> r.replace("ROLE_", ""))
|
||||
.collect(Collectors.joining(", "));
|
||||
|
||||
return new UserSessionDTO(
|
||||
user.getId(),
|
||||
user.getUsername(),
|
||||
isOnline,
|
||||
user.getLastLoginAt(),
|
||||
user.getLastLogoutAt(),
|
||||
rolesStr
|
||||
);
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
long activeCount = userSessions.stream().filter(UserSessionDTO::isOnline).count();
|
||||
long offlineCount = userSessions.size() - activeCount;
|
||||
|
||||
model.addAttribute("userSessions", userSessions);
|
||||
model.addAttribute("activeCount", activeCount);
|
||||
model.addAttribute("offlineCount", offlineCount);
|
||||
model.addAttribute("totalCount", userSessions.size());
|
||||
return "admin/sessions";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user