From 19cee924372467aa80a20f0a29312a3bb2dc0bde Mon Sep 17 00:00:00 2001 From: Youssef Date: Fri, 3 Jul 2026 17:18:14 +0200 Subject: [PATCH] feat: add active user session tracking and visualization in admin dashboard --- .../astalange/web/config/SecurityConfig.java | 17 +++++ .../web/controller/SessionController.java | 37 +++++++++++ .../resources/templates/admin/sessions.html | 65 +++++++++++++++++++ .../templates/fragments/sidebar.html | 1 + 4 files changed, 120 insertions(+) create mode 100644 as-talange-web/src/main/java/com/astalange/web/controller/SessionController.java create mode 100644 as-talange-web/src/main/resources/templates/admin/sessions.html diff --git a/as-talange-web/src/main/java/com/astalange/web/config/SecurityConfig.java b/as-talange-web/src/main/java/com/astalange/web/config/SecurityConfig.java index 0872131..d3135db 100644 --- a/as-talange-web/src/main/java/com/astalange/web/config/SecurityConfig.java +++ b/as-talange-web/src/main/java/com/astalange/web/config/SecurityConfig.java @@ -10,6 +10,9 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.crypto.argon2.Argon2PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.core.session.SessionRegistry; +import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.web.session.HttpSessionEventPublisher; @Configuration @EnableWebSecurity @@ -41,6 +44,10 @@ public class SecurityConfig { .logout(logout -> logout .logoutSuccessUrl("/login?logout") .permitAll() + ) + .sessionManagement(session -> session + .maximumSessions(100) + .sessionRegistry(sessionRegistry()) ); return http.build(); } @@ -57,4 +64,14 @@ public class SecurityConfig { authProvider.setPasswordEncoder(passwordEncoder()); return authProvider; } + + @Bean + public SessionRegistry sessionRegistry() { + return new SessionRegistryImpl(); + } + + @Bean + public HttpSessionEventPublisher httpSessionEventPublisher() { + return new HttpSessionEventPublisher(); + } } diff --git a/as-talange-web/src/main/java/com/astalange/web/controller/SessionController.java b/as-talange-web/src/main/java/com/astalange/web/controller/SessionController.java new file mode 100644 index 0000000..dc478a2 --- /dev/null +++ b/as-talange-web/src/main/java/com/astalange/web/controller/SessionController.java @@ -0,0 +1,37 @@ +package com.astalange.web.controller; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.session.SessionRegistry; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.util.List; +import java.util.stream.Collectors; + +@Controller +@RequestMapping("/admin/sessions") +public class SessionController { + + private final SessionRegistry sessionRegistry; + + public SessionController(SessionRegistry sessionRegistry) { + this.sessionRegistry = sessionRegistry; + } + + @GetMapping + @PreAuthorize("hasRole('ADMIN')") + public String viewSessions(Model model) { + List principals = sessionRegistry.getAllPrincipals(); + List activeUsers = principals.stream() + .filter(principal -> principal instanceof UserDetails) + .map(principal -> ((UserDetails) principal).getUsername()) + .collect(Collectors.toList()); + + model.addAttribute("activeUsers", activeUsers); + model.addAttribute("activeCount", activeUsers.size()); + return "admin/sessions"; + } +} diff --git a/as-talange-web/src/main/resources/templates/admin/sessions.html b/as-talange-web/src/main/resources/templates/admin/sessions.html new file mode 100644 index 0000000..dd5e52c --- /dev/null +++ b/as-talange-web/src/main/resources/templates/admin/sessions.html @@ -0,0 +1,65 @@ + + + + + Utilisateurs Connectés - AS Talange + + + + + + + + +
+ + +
+ +
+

Utilisateurs Connectés

+
+ + +
+
+

+ Sessions Actives (0) +

+ +
+ +
+ + + + + + + + + + + + + + + + +
Nom d'utilisateurStatut
Aucun utilisateur connecté pour le moment.
+
+ U +
+ username +
+ En ligne +
+
+
+
+ + diff --git a/as-talange-web/src/main/resources/templates/fragments/sidebar.html b/as-talange-web/src/main/resources/templates/fragments/sidebar.html index b15769c..e40bf20 100644 --- a/as-talange-web/src/main/resources/templates/fragments/sidebar.html +++ b/as-talange-web/src/main/resources/templates/fragments/sidebar.html @@ -44,6 +44,7 @@
Administration
Utilisateurs Logs Paiements + Utilisateurs Connectés