From 017ef0afcacab15ace118037dd11f46e6f7e6f11 Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 30 May 2024 20:00:56 +0200 Subject: [PATCH] Added statistics endpoint - Added onlineTime statistic - Added lastLogin tracking and endpoint --- .../sharepulse/SharepulseApplication.java | 5 ++ .../sharepulse/db/repo/UserRepository.java | 9 +++- .../java/de/w665/sharepulse/model/User.java | 5 ++ .../rest/mappings/Administration.java | 50 +++++++++++++++++++ .../service/AuthenticationService.java | 1 + 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/main/java/de/w665/sharepulse/rest/mappings/Administration.java diff --git a/src/main/java/de/w665/sharepulse/SharepulseApplication.java b/src/main/java/de/w665/sharepulse/SharepulseApplication.java index 2c4ac58..2f2af61 100644 --- a/src/main/java/de/w665/sharepulse/SharepulseApplication.java +++ b/src/main/java/de/w665/sharepulse/SharepulseApplication.java @@ -3,10 +3,15 @@ package de.w665.sharepulse; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import java.util.Date; + @SpringBootApplication public class SharepulseApplication { + public static Date startTime; + public static void main(String[] args) { + startTime = new Date(); SpringApplication.run(SharepulseApplication.class, args); } diff --git a/src/main/java/de/w665/sharepulse/db/repo/UserRepository.java b/src/main/java/de/w665/sharepulse/db/repo/UserRepository.java index 9113567..5aaf6db 100644 --- a/src/main/java/de/w665/sharepulse/db/repo/UserRepository.java +++ b/src/main/java/de/w665/sharepulse/db/repo/UserRepository.java @@ -1,7 +1,5 @@ package de.w665.sharepulse.db.repo; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.rethinkdb.RethinkDB; import com.rethinkdb.net.Connection; import de.w665.sharepulse.db.RethinkDBConfig; @@ -35,6 +33,13 @@ public class UserRepository { } } + public void updateLastLoginForUser(String username, Date lastLogin) { + r.db(config.getDatabase()).table("users") + .filter(r.hashMap("username", username)) + .update(r.hashMap("lastLogin", lastLogin.getTime())) + .run(connection); + } + public void insertUser(User user) { r.db(config.getDatabase()).table("users").insert(user).run(connection); } diff --git a/src/main/java/de/w665/sharepulse/model/User.java b/src/main/java/de/w665/sharepulse/model/User.java index e0d821d..ec38466 100644 --- a/src/main/java/de/w665/sharepulse/model/User.java +++ b/src/main/java/de/w665/sharepulse/model/User.java @@ -1,10 +1,13 @@ package de.w665.sharepulse.model; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import java.util.Date; + @Getter @Setter @NoArgsConstructor @@ -14,4 +17,6 @@ public class User { private String password; private String email; private String role; + @JsonFormat(timezone = "ETC") + private Date lastLogin; } diff --git a/src/main/java/de/w665/sharepulse/rest/mappings/Administration.java b/src/main/java/de/w665/sharepulse/rest/mappings/Administration.java new file mode 100644 index 0000000..96b637d --- /dev/null +++ b/src/main/java/de/w665/sharepulse/rest/mappings/Administration.java @@ -0,0 +1,50 @@ +package de.w665.sharepulse.rest.mappings; + +import de.w665.sharepulse.SharepulseApplication; +import de.w665.sharepulse.db.repo.UserRepository; +import de.w665.sharepulse.model.User; +import de.w665.sharepulse.rest.SecureApiRestController; +import de.w665.sharepulse.service.AuthenticationService; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@RestController +public class Administration extends SecureApiRestController { + + private final UserRepository userRepository; + private final AuthenticationService authenticationService; + + public Administration(UserRepository userRepository, AuthenticationService authenticationService) { + this.userRepository = userRepository; + this.authenticationService = authenticationService; + } + + @GetMapping("/statistics") + public ResponseEntity getStatistics(HttpServletRequest request) { + + String token = request.getHeader("Authorization"); + token = token.substring(7); + String username = authenticationService.getClaimValue(token, "username", String.class); + Optional optionalUser = userRepository.retrieveUserByUsername(username); + if(optionalUser.isEmpty()) { + return ResponseEntity.badRequest().body("User not found"); + } + User user = optionalUser.get(); + + // If role filtering is required later, add here + + Map response = new HashMap<>(); + response.put("applicationOnlineTime", System.currentTimeMillis() - SharepulseApplication.startTime.getTime()); + response.put("lastUserLogin", user.getLastLogin()); + log.debug("Received statistics request"); + return ResponseEntity.ok(response); + } +} diff --git a/src/main/java/de/w665/sharepulse/service/AuthenticationService.java b/src/main/java/de/w665/sharepulse/service/AuthenticationService.java index 1ec2a62..e44949c 100644 --- a/src/main/java/de/w665/sharepulse/service/AuthenticationService.java +++ b/src/main/java/de/w665/sharepulse/service/AuthenticationService.java @@ -46,6 +46,7 @@ public class AuthenticationService { } Optional user = userRepository.retrieveUserByUsername(username); if (user.isPresent() && passwordEncoder.matches(password, user.get().getPassword())) { + userRepository.updateLastLoginForUser(user.get().getUsername(), new Date()); return generateToken(user.get()); } return null;