diff --git a/src/main/java/de/w665/sharepulse/db/repo/UserLoginRepository.java b/src/main/java/de/w665/sharepulse/db/repo/UserLoginRepository.java index f616fca..30f1107 100644 --- a/src/main/java/de/w665/sharepulse/db/repo/UserLoginRepository.java +++ b/src/main/java/de/w665/sharepulse/db/repo/UserLoginRepository.java @@ -1,19 +1,40 @@ package de.w665.sharepulse.db.repo; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import com.rethinkdb.RethinkDB; import com.rethinkdb.net.Connection; +import com.rethinkdb.net.Result; import de.w665.sharepulse.db.RethinkDBConfig; import de.w665.sharepulse.db.RethinkDBConnector; +import de.w665.sharepulse.model.FileUpload; +import de.w665.sharepulse.model.User; import de.w665.sharepulse.model.UserLogin; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; + +import java.lang.reflect.Type; +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j @Repository public class UserLoginRepository { private final RethinkDB r; private final Connection connection; private final RethinkDBConfig config; private final String TABLE_NAME = "user_logins"; + + private final Gson gson = new Gson(); + private final ObjectMapper mapper = new ObjectMapper(); + + @Autowired public UserLoginRepository(RethinkDBConnector connector, RethinkDBConfig config) { this.r = connector.getR(); @@ -22,6 +43,39 @@ public class UserLoginRepository { } public void insertUserLogin(UserLogin userLogin) { + String uuid = r.uuid().run(connection, String.class).first(); + userLogin.setId(uuid); r.db(config.getDatabase()).table(TABLE_NAME).insert(userLogin).run(connection); } + + public List getRecentUserLoginsForUser(String userId, int limit) throws JsonProcessingException { + Result rawResult = r.db("sharepulse").table(TABLE_NAME) + .filter(r.hashMap("userId", userId)) + .orderBy(r.desc("sort")) + .limit(limit) + .run(connection); + + String jsonString = mapper.writeValueAsString(rawResult.single()); + Type listType = new TypeToken>() {}.getType(); + return gson.fromJson(jsonString, listType); + } + + private UserLogin convertToUserLogin(Object obj) { + ObjectMapper mapper = new ObjectMapper(); + return mapper.convertValue(obj, UserLogin.class); + } + + /*public List getRecentUserLoginsForUser(String userId, int limit) { + Result results = r.db(config.getDatabase()).table(TABLE_NAME) + .filter(r.hashMap("userId", userId)) + .orderBy(r.desc("loginTime")) + .limit(limit) + .run(connection); + List objectList = results.toList(); + List obj = (List) objectList.get(0); + System.out.println(obj.getFirst()); + UserLogin userLogin = (UserLogin) obj.getFirst(); + System.out.println(userLogin.toString()); + return null; + }*/ } 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 94d2f25..0ac22ac 100644 --- a/src/main/java/de/w665/sharepulse/db/repo/UserRepository.java +++ b/src/main/java/de/w665/sharepulse/db/repo/UserRepository.java @@ -49,7 +49,7 @@ public class UserRepository { // If username is changed, this method must be used. Else the user will not be found public void updateUser(User user, String originalUsername) { - // TODO: Refactor this to use the userID instead of the username + // TODO: Refactor this to use the userID instead of the username (remove this and use method above) r.db(config.getDatabase()).table("users") .filter(r.hashMap("username", originalUsername)) .update(user) @@ -57,6 +57,9 @@ public class UserRepository { } public void insertUser(User user) { + String optionalUuid = r.uuid().run(connection, String.class).first(); + user.setId(optionalUuid); + System.out.println(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 124fb89..0bb9576 100644 --- a/src/main/java/de/w665/sharepulse/model/User.java +++ b/src/main/java/de/w665/sharepulse/model/User.java @@ -1,15 +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 lombok.*; import java.util.Date; @Getter @Setter +@ToString @NoArgsConstructor @AllArgsConstructor public class User { @@ -18,6 +16,4 @@ 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/model/UserLogin.java b/src/main/java/de/w665/sharepulse/model/UserLogin.java index 5aba29b..2e1f261 100644 --- a/src/main/java/de/w665/sharepulse/model/UserLogin.java +++ b/src/main/java/de/w665/sharepulse/model/UserLogin.java @@ -1,5 +1,6 @@ package de.w665.sharepulse.model; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -12,7 +13,10 @@ import java.util.Date; @NoArgsConstructor @AllArgsConstructor public class UserLogin { + String id; String userId; + @JsonFormat(timezone = "ETC") Date loginTime; String loginIp; + int sort; } diff --git a/src/main/java/de/w665/sharepulse/rest/mappings/Administration.java b/src/main/java/de/w665/sharepulse/rest/mappings/Administration.java index 378107e..9fb374e 100644 --- a/src/main/java/de/w665/sharepulse/rest/mappings/Administration.java +++ b/src/main/java/de/w665/sharepulse/rest/mappings/Administration.java @@ -1,6 +1,8 @@ package de.w665.sharepulse.rest.mappings; +import com.fasterxml.jackson.core.JsonProcessingException; import de.w665.sharepulse.SharepulseApplication; +import de.w665.sharepulse.db.repo.UserLoginRepository; import de.w665.sharepulse.db.repo.UserRepository; import de.w665.sharepulse.model.FileUpload; import de.w665.sharepulse.model.User; @@ -25,11 +27,13 @@ public class Administration extends SecureApiRestController { private final UserRepository userRepository; private final AuthenticationService authenticationService; private final FileCleanupService fileCleanupService; + private final UserLoginRepository userLoginRepository; - public Administration(UserRepository userRepository, AuthenticationService authenticationService, FileCleanupService fileCleanupService) { + public Administration(UserRepository userRepository, AuthenticationService authenticationService, FileCleanupService fileCleanupService, UserLoginRepository userLoginRepository) { this.userRepository = userRepository; this.authenticationService = authenticationService; this.fileCleanupService = fileCleanupService; + this.userLoginRepository = userLoginRepository; } @GetMapping("/statistics") @@ -50,7 +54,11 @@ public class Administration extends SecureApiRestController { Map response = new HashMap<>(); response.put("applicationOnlineTime", System.currentTimeMillis() - SharepulseApplication.startTime.getTime()); - response.put("lastUserLogin", user.getLastLogin()); + try { + response.put("lastUserLogin", userLoginRepository.getRecentUserLoginsForUser(user.getId(), 2)); + } catch (JsonProcessingException e) { + response.put("lastUserLogin", "Error retrieving last user login"); + } 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 92d4b9c..11bc828 100644 --- a/src/main/java/de/w665/sharepulse/service/AuthenticationService.java +++ b/src/main/java/de/w665/sharepulse/service/AuthenticationService.java @@ -21,6 +21,8 @@ import java.util.Optional; @Service public class AuthenticationService { + static int count = 0; + private final UserRepository userRepository; private final UserLoginRepository userLoginRepository; @@ -51,7 +53,8 @@ public class AuthenticationService { Optional optionalUser = userRepository.retrieveUserByUsername(username); if (optionalUser.isPresent() && passwordEncoder.matches(password, optionalUser.get().getPassword())) { User user = optionalUser.get(); - userLoginRepository.insertUserLogin(new UserLogin(user.getId(), new Date(), remoteAddr)); + + userLoginRepository.insertUserLogin(new UserLogin("", user.getId(), new Date(), remoteAddr, count++)); userRepository.updateLastLoginForUser(user.getUsername(), new Date()); return generateToken(user); }