Added UserLogin tracking
- Added UserLoginRepository - Added latest UserLogin statistics - Added entity - Fixed user generator - Added user UUID tracking
This commit is contained in:
parent
d50d6de466
commit
348bf8050c
@ -1,19 +1,40 @@
|
|||||||
package de.w665.sharepulse.db.repo;
|
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.RethinkDB;
|
||||||
import com.rethinkdb.net.Connection;
|
import com.rethinkdb.net.Connection;
|
||||||
|
import com.rethinkdb.net.Result;
|
||||||
import de.w665.sharepulse.db.RethinkDBConfig;
|
import de.w665.sharepulse.db.RethinkDBConfig;
|
||||||
import de.w665.sharepulse.db.RethinkDBConnector;
|
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 de.w665.sharepulse.model.UserLogin;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Repository
|
@Repository
|
||||||
public class UserLoginRepository {
|
public class UserLoginRepository {
|
||||||
private final RethinkDB r;
|
private final RethinkDB r;
|
||||||
private final Connection connection;
|
private final Connection connection;
|
||||||
private final RethinkDBConfig config;
|
private final RethinkDBConfig config;
|
||||||
private final String TABLE_NAME = "user_logins";
|
private final String TABLE_NAME = "user_logins";
|
||||||
|
|
||||||
|
private final Gson gson = new Gson();
|
||||||
|
private final ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public UserLoginRepository(RethinkDBConnector connector, RethinkDBConfig config) {
|
public UserLoginRepository(RethinkDBConnector connector, RethinkDBConfig config) {
|
||||||
this.r = connector.getR();
|
this.r = connector.getR();
|
||||||
@ -22,6 +43,39 @@ public class UserLoginRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void insertUserLogin(UserLogin userLogin) {
|
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);
|
r.db(config.getDatabase()).table(TABLE_NAME).insert(userLogin).run(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<UserLogin> getRecentUserLoginsForUser(String userId, int limit) throws JsonProcessingException {
|
||||||
|
Result<Object> 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<List<UserLogin>>() {}.getType();
|
||||||
|
return gson.fromJson(jsonString, listType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserLogin convertToUserLogin(Object obj) {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
return mapper.convertValue(obj, UserLogin.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public List<UserLogin> getRecentUserLoginsForUser(String userId, int limit) {
|
||||||
|
Result<Object> results = r.db(config.getDatabase()).table(TABLE_NAME)
|
||||||
|
.filter(r.hashMap("userId", userId))
|
||||||
|
.orderBy(r.desc("loginTime"))
|
||||||
|
.limit(limit)
|
||||||
|
.run(connection);
|
||||||
|
List<Object> objectList = results.toList();
|
||||||
|
List<Object> obj = (List) objectList.get(0);
|
||||||
|
System.out.println(obj.getFirst());
|
||||||
|
UserLogin userLogin = (UserLogin) obj.getFirst();
|
||||||
|
System.out.println(userLogin.toString());
|
||||||
|
return null;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ public class UserRepository {
|
|||||||
|
|
||||||
// If username is changed, this method must be used. Else the user will not be found
|
// If username is changed, this method must be used. Else the user will not be found
|
||||||
public void updateUser(User user, String originalUsername) {
|
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")
|
r.db(config.getDatabase()).table("users")
|
||||||
.filter(r.hashMap("username", originalUsername))
|
.filter(r.hashMap("username", originalUsername))
|
||||||
.update(user)
|
.update(user)
|
||||||
@ -57,6 +57,9 @@ public class UserRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void insertUser(User user) {
|
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);
|
r.db(config.getDatabase()).table("users").insert(user).run(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package de.w665.sharepulse.model;
|
package de.w665.sharepulse.model;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.*;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@ToString
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class User {
|
public class User {
|
||||||
@ -18,6 +16,4 @@ public class User {
|
|||||||
private String password;
|
private String password;
|
||||||
private String email;
|
private String email;
|
||||||
private String role;
|
private String role;
|
||||||
@JsonFormat(timezone = "ETC")
|
|
||||||
private Date lastLogin;
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.w665.sharepulse.model;
|
package de.w665.sharepulse.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -12,7 +13,10 @@ import java.util.Date;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class UserLogin {
|
public class UserLogin {
|
||||||
|
String id;
|
||||||
String userId;
|
String userId;
|
||||||
|
@JsonFormat(timezone = "ETC")
|
||||||
Date loginTime;
|
Date loginTime;
|
||||||
String loginIp;
|
String loginIp;
|
||||||
|
int sort;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package de.w665.sharepulse.rest.mappings;
|
package de.w665.sharepulse.rest.mappings;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import de.w665.sharepulse.SharepulseApplication;
|
import de.w665.sharepulse.SharepulseApplication;
|
||||||
|
import de.w665.sharepulse.db.repo.UserLoginRepository;
|
||||||
import de.w665.sharepulse.db.repo.UserRepository;
|
import de.w665.sharepulse.db.repo.UserRepository;
|
||||||
import de.w665.sharepulse.model.FileUpload;
|
import de.w665.sharepulse.model.FileUpload;
|
||||||
import de.w665.sharepulse.model.User;
|
import de.w665.sharepulse.model.User;
|
||||||
@ -25,11 +27,13 @@ public class Administration extends SecureApiRestController {
|
|||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final AuthenticationService authenticationService;
|
private final AuthenticationService authenticationService;
|
||||||
private final FileCleanupService fileCleanupService;
|
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.userRepository = userRepository;
|
||||||
this.authenticationService = authenticationService;
|
this.authenticationService = authenticationService;
|
||||||
this.fileCleanupService = fileCleanupService;
|
this.fileCleanupService = fileCleanupService;
|
||||||
|
this.userLoginRepository = userLoginRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/statistics")
|
@GetMapping("/statistics")
|
||||||
@ -50,7 +54,11 @@ public class Administration extends SecureApiRestController {
|
|||||||
|
|
||||||
Map<String, Object> response = new HashMap<>();
|
Map<String, Object> response = new HashMap<>();
|
||||||
response.put("applicationOnlineTime", System.currentTimeMillis() - SharepulseApplication.startTime.getTime());
|
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");
|
log.debug("Received statistics request");
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ import java.util.Optional;
|
|||||||
@Service
|
@Service
|
||||||
public class AuthenticationService {
|
public class AuthenticationService {
|
||||||
|
|
||||||
|
static int count = 0;
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final UserLoginRepository userLoginRepository;
|
private final UserLoginRepository userLoginRepository;
|
||||||
|
|
||||||
@ -51,7 +53,8 @@ public class AuthenticationService {
|
|||||||
Optional<User> optionalUser = userRepository.retrieveUserByUsername(username);
|
Optional<User> optionalUser = userRepository.retrieveUserByUsername(username);
|
||||||
if (optionalUser.isPresent() && passwordEncoder.matches(password, optionalUser.get().getPassword())) {
|
if (optionalUser.isPresent() && passwordEncoder.matches(password, optionalUser.get().getPassword())) {
|
||||||
User user = optionalUser.get();
|
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());
|
userRepository.updateLastLoginForUser(user.getUsername(), new Date());
|
||||||
return generateToken(user);
|
return generateToken(user);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user