2019-09-27 06:37:55 +00:00
|
|
|
package org.ros.chatto.service;
|
|
|
|
|
2019-11-16 09:09:01 +00:00
|
|
|
import java.time.Duration;
|
2019-11-12 05:26:50 +00:00
|
|
|
import java.time.Instant;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
2019-10-02 16:25:46 +00:00
|
|
|
import java.util.List;
|
2019-11-12 05:26:50 +00:00
|
|
|
import java.util.Map;
|
2020-05-27 10:46:04 +00:00
|
|
|
import java.util.Optional;
|
2020-01-31 04:46:13 +00:00
|
|
|
import java.util.Set;
|
|
|
|
import java.util.stream.Collectors;
|
2019-10-02 16:25:46 +00:00
|
|
|
|
2019-11-12 05:26:50 +00:00
|
|
|
import org.ros.chatto.dto.ActiveUserDTO;
|
2019-10-02 16:25:46 +00:00
|
|
|
import org.ros.chatto.dto.UserRegistrationDTO;
|
2020-01-25 14:53:05 +00:00
|
|
|
import org.ros.chatto.logged.TokenCacheUtil;
|
2019-09-27 06:37:55 +00:00
|
|
|
import org.ros.chatto.model.ChatUser;
|
|
|
|
import org.ros.chatto.model.Role;
|
|
|
|
import org.ros.chatto.model.UserRole;
|
2019-11-12 05:26:50 +00:00
|
|
|
import org.ros.chatto.model.UserSession;
|
2019-12-10 14:43:31 +00:00
|
|
|
import org.ros.chatto.repository.RoleRepository;
|
2019-09-27 06:37:55 +00:00
|
|
|
import org.ros.chatto.repository.UserRepository;
|
|
|
|
import org.ros.chatto.repository.UserRoleRepository;
|
2019-11-12 05:26:50 +00:00
|
|
|
import org.ros.chatto.repository.UserSessionRepository;
|
2020-01-25 14:53:05 +00:00
|
|
|
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
2019-09-27 06:37:55 +00:00
|
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
|
|
import org.springframework.stereotype.Service;
|
2019-11-28 05:38:50 +00:00
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
2019-09-27 06:37:55 +00:00
|
|
|
|
2019-12-12 06:48:19 +00:00
|
|
|
import lombok.RequiredArgsConstructor;
|
2020-01-25 14:53:05 +00:00
|
|
|
import lombok.extern.slf4j.Slf4j;
|
2019-12-12 06:48:19 +00:00
|
|
|
|
2019-11-28 05:38:50 +00:00
|
|
|
@Transactional
|
2019-09-27 06:37:55 +00:00
|
|
|
@Service
|
2019-12-12 06:48:19 +00:00
|
|
|
@RequiredArgsConstructor
|
2020-01-25 14:53:05 +00:00
|
|
|
@Slf4j
|
2019-11-13 15:04:31 +00:00
|
|
|
public class UserServiceImpl implements UserService {
|
2019-12-10 14:43:31 +00:00
|
|
|
private final UserRepository userRepository;
|
2019-11-13 15:04:31 +00:00
|
|
|
|
2019-12-10 14:43:31 +00:00
|
|
|
private final UserRoleRepository userRoleRepository;
|
2019-11-13 15:04:31 +00:00
|
|
|
|
2019-12-10 14:43:31 +00:00
|
|
|
private final PasswordEncoder passwordEncoder;
|
2019-12-09 15:32:25 +00:00
|
|
|
|
2019-12-10 14:43:31 +00:00
|
|
|
private final RoleRepository roleRepository;
|
2019-11-13 15:04:31 +00:00
|
|
|
|
2019-12-10 14:43:31 +00:00
|
|
|
private final UserSessionRepository userSessionRepository;
|
|
|
|
|
2020-01-25 14:53:05 +00:00
|
|
|
private final UserTokenService userTokenService;
|
|
|
|
|
2019-09-27 06:37:55 +00:00
|
|
|
@Override
|
2020-01-31 04:46:13 +00:00
|
|
|
public ChatUser createUser(final UserRegistrationDTO userRegistrationDTO) {
|
2019-12-12 05:22:32 +00:00
|
|
|
final ChatUser user = new ChatUser();
|
2019-10-02 16:25:46 +00:00
|
|
|
user.setUserName(userRegistrationDTO.getUserName());
|
2020-05-27 10:46:04 +00:00
|
|
|
user.setPassword(
|
|
|
|
passwordEncoder.encode(userRegistrationDTO.getPassword()));
|
2019-12-12 05:22:32 +00:00
|
|
|
final ChatUser changedUser = userRepository.save(user);
|
|
|
|
final UserRole userRole = new UserRole();
|
|
|
|
final Role role = roleRepository.findByName("USER");
|
2019-09-27 06:37:55 +00:00
|
|
|
userRole.setRole(role);
|
|
|
|
userRole.setUser(changedUser);
|
2020-01-31 04:46:13 +00:00
|
|
|
return userRoleRepository.save(userRole).getUser();
|
2019-09-27 06:37:55 +00:00
|
|
|
}
|
|
|
|
|
2019-10-02 16:25:46 +00:00
|
|
|
@Override
|
2019-11-28 05:38:50 +00:00
|
|
|
@Transactional(readOnly = true)
|
2019-12-12 05:22:32 +00:00
|
|
|
public List<String> findAllOtherUsers(final String userName) {
|
2019-11-28 05:38:50 +00:00
|
|
|
return userRepository.findAllOtherUserNames(userName);
|
2019-10-02 16:25:46 +00:00
|
|
|
}
|
|
|
|
|
2019-11-28 05:38:50 +00:00
|
|
|
@Transactional(readOnly = true)
|
2019-10-22 12:12:18 +00:00
|
|
|
@Override
|
|
|
|
public List<String> getAllRegularUsers() {
|
|
|
|
return userRoleRepository.getAllRegularUser();
|
|
|
|
}
|
|
|
|
|
2019-11-28 05:38:50 +00:00
|
|
|
@Transactional(readOnly = true)
|
2019-12-12 05:22:32 +00:00
|
|
|
public List<ActiveUserDTO> getOtherActiveUsers(final String userName) {
|
|
|
|
final List<String> userList = findAllOtherUsers(userName);
|
2019-12-09 15:32:25 +00:00
|
|
|
|
2020-05-27 10:46:04 +00:00
|
|
|
final List<UserSession> userSessionsList = userSessionRepository
|
|
|
|
.findAllUserSessions();
|
|
|
|
final Map<String, UserSession> lastActiveMap = convertToMap(
|
|
|
|
userSessionsList);
|
2019-12-09 15:32:25 +00:00
|
|
|
|
2019-12-12 05:22:32 +00:00
|
|
|
final List<ActiveUserDTO> activeUserDTOs = new ArrayList<ActiveUserDTO>();
|
2019-11-12 05:26:50 +00:00
|
|
|
userList.forEach(u -> {
|
2019-12-12 05:22:32 +00:00
|
|
|
final ActiveUserDTO activeUserDTO = new ActiveUserDTO();
|
|
|
|
final UserSession us = lastActiveMap.get(u);
|
2019-12-09 15:32:25 +00:00
|
|
|
|
2019-11-12 05:26:50 +00:00
|
|
|
activeUserDTO.setUserName(u);
|
|
|
|
activeUserDTO.setOnline(false);
|
2019-11-16 08:45:30 +00:00
|
|
|
activeUserDTO.setLastActive(null);
|
2019-12-09 15:32:25 +00:00
|
|
|
if (us != null) {
|
2019-11-16 08:45:30 +00:00
|
|
|
activeUserDTO.setOnline(us.isOnline());
|
2020-02-01 09:04:42 +00:00
|
|
|
activeUserDTO.setLastActive(us.getTimeStamp());
|
2019-11-12 05:26:50 +00:00
|
|
|
}
|
2019-12-09 15:32:25 +00:00
|
|
|
|
2019-11-12 05:26:50 +00:00
|
|
|
activeUserDTOs.add(activeUserDTO);
|
|
|
|
});
|
2019-12-09 15:32:25 +00:00
|
|
|
|
2019-11-12 05:26:50 +00:00
|
|
|
return activeUserDTOs;
|
|
|
|
}
|
|
|
|
|
2019-11-28 05:38:50 +00:00
|
|
|
@Transactional(readOnly = true)
|
2019-11-12 05:26:50 +00:00
|
|
|
@Override
|
2020-05-27 10:46:04 +00:00
|
|
|
public Optional<ChatUser> getUser(final String userName) {
|
2019-11-12 05:26:50 +00:00
|
|
|
return userRepository.findByUserName(userName);
|
|
|
|
}
|
2019-11-13 15:04:31 +00:00
|
|
|
|
2020-05-27 10:46:04 +00:00
|
|
|
private Map<String, UserSession> convertToMap(
|
|
|
|
final List<UserSession> userSessionList) {
|
2019-12-12 05:22:32 +00:00
|
|
|
final Map<String, UserSession> userMap = new HashMap<>();
|
2019-11-12 05:26:50 +00:00
|
|
|
userSessionList.forEach(us -> {
|
2019-11-16 08:45:30 +00:00
|
|
|
userMap.put(us.getUser().getUserName(), us);
|
2019-11-12 05:26:50 +00:00
|
|
|
});
|
|
|
|
return userMap;
|
|
|
|
}
|
2019-11-13 15:04:31 +00:00
|
|
|
|
2019-12-12 05:22:32 +00:00
|
|
|
private String toLastActiveString(final Instant lastActive) {
|
2019-11-13 15:04:31 +00:00
|
|
|
if (lastActive == null)
|
|
|
|
return null;
|
2019-12-12 05:22:32 +00:00
|
|
|
final Duration duration = Duration.between(lastActive, Instant.now());
|
|
|
|
final long hours = duration.toHours();
|
|
|
|
final long minutes = duration.toMinutes();
|
|
|
|
final long days = duration.toDays();
|
2020-05-27 10:46:04 +00:00
|
|
|
if (minutes < 60) {
|
2019-11-13 15:04:31 +00:00
|
|
|
return String.format("%d minutes ago", minutes);
|
2020-05-27 10:46:04 +00:00
|
|
|
} else {
|
|
|
|
if (hours < 24) {
|
2019-11-13 15:04:31 +00:00
|
|
|
return String.format("%d hours ago", hours);
|
2020-05-27 10:46:04 +00:00
|
|
|
} else {
|
|
|
|
if (days < 30) {
|
2019-11-13 15:04:31 +00:00
|
|
|
return String.format("%d days ago", days);
|
2020-05-27 10:46:04 +00:00
|
|
|
} else if (days < 366) {
|
|
|
|
return String.format("%d months ago", days / 30);
|
|
|
|
} else {
|
|
|
|
return String.format("%d years ago", days / 365);
|
2019-11-13 15:04:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-12-09 15:32:25 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
@Transactional(readOnly = true)
|
2020-01-31 04:46:13 +00:00
|
|
|
public ChatUser getUserWithRole(final String userName) {
|
|
|
|
return userRepository.findByUserNameWithRole(userName);
|
2019-12-09 15:32:25 +00:00
|
|
|
}
|
2020-01-25 14:53:05 +00:00
|
|
|
|
|
|
|
@Override
|
2020-05-27 10:46:04 +00:00
|
|
|
public void incrementUserSession(final String userName) {
|
|
|
|
final Optional<ChatUser> chatUser = getUser(userName);
|
|
|
|
final Instant instant = Instant.now();
|
2020-01-25 14:53:05 +00:00
|
|
|
|
2020-05-27 10:46:04 +00:00
|
|
|
chatUser.ifPresent(cu -> {
|
|
|
|
UserSession userSession = userSessionRepository
|
|
|
|
.findByUserName(userName);
|
2020-01-25 14:53:05 +00:00
|
|
|
|
2020-05-27 10:46:04 +00:00
|
|
|
if (userSession == null) {
|
|
|
|
userSession = new UserSession();
|
|
|
|
}
|
|
|
|
userSession.setUser(cu);
|
|
|
|
userSession.setTimeStamp(instant);
|
|
|
|
userSession.setOnline(true);
|
|
|
|
userSession.setNumSessions(userSession.getNumSessions() + 1);
|
|
|
|
userSessionRepository.save(userSession);
|
|
|
|
});
|
2020-01-25 14:53:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-05-27 10:46:04 +00:00
|
|
|
public UserSession decrementUserSession(final String userName) {
|
|
|
|
final UserSession userSession = userSessionRepository
|
|
|
|
.findByUserName(userName);
|
|
|
|
final Instant instant = Instant.now();
|
2020-01-25 14:53:05 +00:00
|
|
|
|
|
|
|
if (userSession == null) {
|
|
|
|
log.error("User session is somehow null for user: " + userName);
|
2020-05-27 10:46:04 +00:00
|
|
|
throw new InternalAuthenticationServiceException(
|
|
|
|
"User session not found");
|
2020-01-25 14:53:05 +00:00
|
|
|
}
|
|
|
|
|
2020-05-27 10:46:04 +00:00
|
|
|
final ChatUser chatUser = userSession.getUser();
|
2020-01-25 14:53:05 +00:00
|
|
|
|
|
|
|
int numSessions = userSession.getNumSessions();
|
|
|
|
|
|
|
|
if (--numSessions == 0) {
|
|
|
|
log.info("Num sessions is 0 so setting user to offline");
|
2020-05-27 10:46:04 +00:00
|
|
|
log.info("Deleting token and evicting cache for user: "
|
|
|
|
+ chatUser.getUserName());
|
2020-01-25 14:53:05 +00:00
|
|
|
userSession.setOnline(false);
|
|
|
|
userTokenService.deleteToken(chatUser.getUserName());
|
|
|
|
TokenCacheUtil.evictSingleTokenValue(chatUser.getUserName());
|
|
|
|
}
|
|
|
|
|
|
|
|
userSession.setNumSessions(numSessions);
|
2020-01-31 04:46:13 +00:00
|
|
|
userSession.setTimeStamp(instant);
|
2020-01-25 14:53:05 +00:00
|
|
|
return userSessionRepository.save(userSession);
|
|
|
|
}
|
2020-01-31 04:46:13 +00:00
|
|
|
|
|
|
|
@Override
|
2020-05-27 10:46:04 +00:00
|
|
|
public Set<Role> getRoles(final ChatUser user) {
|
|
|
|
return user.getUserRoles().stream().map(ur -> ur.getRole())
|
|
|
|
.collect(Collectors.toSet());
|
2020-01-31 04:46:13 +00:00
|
|
|
}
|
2019-09-27 06:37:55 +00:00
|
|
|
}
|