Untitled
unknown
java
2 years ago
11 kB
6
Indexable
package com.fontana.backend.session.service; import com.fontana.backend.exception.customExceptions.NotFoundException; import com.fontana.backend.exception.customExceptions.RoleNotAllowedException; import com.fontana.backend.exception.customExceptions.SessionNotModifiedException; import com.fontana.backend.role.entity.RoleType; import com.fontana.backend.session.dto.*; import com.fontana.backend.session.entity.Session; import com.fontana.backend.session.mapper.SessionMapper; import com.fontana.backend.session.repository.SessionRepository; import com.fontana.backend.user.entity.User; import com.fontana.backend.user.repository.UserRepository; import com.fontana.backend.utils.AuthUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import static com.fontana.backend.config.RestEndpoints.SESSION; @Service @RequiredArgsConstructor @Slf4j public class SessionServiceImpl implements SessionService { @Value("${session.not-found-msg}") private String notFoundMsg; @Value("${session.busy-msg}") private String sessionBusyMsg; @Value("${session.not-allowed-to-close-msg}") private String notAllowedToCloseMsg; @Value("${session.already-closed}") private String sessionAlreadyClosedMsg; @Value("${session.role-not-allowed-msg}") private String roleNotAllowedMsg; @Value("${user.not-found-msg}") private String userNotFoundMsg; @Value("${cache.active-session}") private String activeSessionLabel; @Value("${session.expiration-delay}") private String expirationDelay; private final SessionRepository sessionRepository; private final UserRepository userRepository; private final SessionMapper sessionMapper; private final AuthUtils authUtils; private final CacheManager cacheManager; @Scheduled(fixedRate = 15000) public void autoCloseSession() { Session session = getActiveSession(); if (session != null && session.getExpirationTime().isBefore(LocalDateTime.now())) { Session updated = buildUpdatedSession(session, null, false, true); sessionRepository.save(updated); Objects.requireNonNull(cacheManager.getCache(activeSessionLabel)).clear(); log.info("(SESSION SCHEDULER) Auto closed session due to no activity: " + session); return; } log.info("(SESSION SCHEDULER) AutoCloseSession scheduler invoked with no action."); } @Override public List<SessionResponseDTO> findAll(String watcher) { if (watcher != null) { User user = userRepository.findByUsername(watcher).orElseThrow( () -> new NotFoundException(userNotFoundMsg)); if (!user.getRole().getName().equals(RoleType.ADMIN.name())) { throw new RoleNotAllowedException(roleNotAllowedMsg); } log.info("Filtered sessions: " + filterSessionsInReversedOrder(user).size()); return filterSessionsInReversedOrder(user).stream() .map(sessionMapper::map) .toList(); } return sessionRepository.findAll().stream() .map(sessionMapper::map) .toList(); } @Override public SessionResponseDTO findById(Integer id) { Session session = sessionRepository.findById(id).orElseThrow( () -> new NotFoundException(notFoundMsg.concat(" " + id))); return sessionMapper.map(session); } @Override public ResponseEntity<?> add(SessionRequestDTO sessionRequestDTO) { Session activeSession = getActiveSession(); String authority = authUtils.extractAuthenticatedAuthority(); if (authority.equals(RoleType.VIEWER.name())) { return ResponseEntity.status(HttpStatus.FORBIDDEN).body(buildRoleNotAllowedResponse()); } if (activeSession != null && authority.equals(RoleType.ADMIN.name())) { Session updated = buildUpdatedSession(activeSession, null, true, false); log.info("Session force-closed by admin: " + updated); sessionRepository.save(updated); } if (activeSession != null && !authority.equals(RoleType.ADMIN.name())) { SessionBusyResponse response = buildSessionBusyResponse(sessionBusyMsg, activeSession); return ResponseEntity.status(HttpStatus.FORBIDDEN).body(response); } Session saved = sessionRepository.save(sessionMapper.map(sessionRequestDTO)); Objects.requireNonNull(cacheManager.getCache(activeSessionLabel)).put("id", saved.getId()); log.info("(OPEN) activeSession: " + saved); return buildAddSessionResponse(saved); } @Override public ResponseEntity<?> updateCloseSession(SessionCloseRequest sessionCloseRequest) { Session activeSession = getActiveSession(); log.info("(CLOSE) active session: " + activeSession); String authority = authUtils.extractAuthenticatedAuthority(); log.info("Request:" + sessionCloseRequest); if (activeSession == null) { throw new SessionNotModifiedException(sessionAlreadyClosedMsg); } String currentPrincipalName = authUtils.getAuthentication().getPrincipal().toString(); if (activeSession.getUsername().equals(currentPrincipalName) || authority.equals(RoleType.ADMIN.name())) { Session updated = buildUpdatedSession( activeSession, sessionCloseRequest, false, false); log.info("Updated:" + updated); sessionRepository.save(updated); Objects.requireNonNull(cacheManager.getCache(activeSessionLabel)).clear(); return ResponseEntity.ok().build(); } else { throw new SessionNotModifiedException(notAllowedToCloseMsg); } } @Override public boolean checkIsActive(String username) { Session session = getActiveSession(); log.info(String.valueOf(session)); if (session == null) { throw new NotFoundException(notFoundMsg); } return session.getClosedTime() == null; } public void updateExpirationTime() { Session session = getActiveSession(); if (session != null) { session.setExpirationTime(LocalDateTime.now().plusMinutes(Integer.parseInt(expirationDelay))); sessionRepository.save(session); } } public Session getActiveSession() { Cache cache = cacheManager.getCache(activeSessionLabel); Cache.ValueWrapper valueWrapper = cache.get("id"); if (valueWrapper != null && valueWrapper.get() != null) { log.info("Active session id: " + valueWrapper.get()); return sessionRepository.findById((int) valueWrapper.get()).orElse(null); } return null; } private ResponseEntity<?> buildAddSessionResponse(Session saved) { HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.LOCATION, SESSION.concat("/").concat(saved.getId().toString())); Map<String, LocalDateTime> response = new HashMap<>(); response.put("expirationTime", saved.getExpirationTime()); return ResponseEntity.status(HttpStatus.OK).headers(headers).body(response); } /** * Filters and retrieves a list of closed sessions in reversed order of opening time, * where the session's opening time is after the user's last role change. * * @param user for whom to filter sessions. * @return A list of SessionResponseDTO objects representing the filtered sessions. */ public List<Session> filterSessionsInReversedOrder(User user) { Pageable pageable = PageRequest.of(0, 21, Sort.by(Sort.Direction.DESC, "id")); return sessionRepository.findAllInReversedOrderAfterDate(user.getLastRoleChange(), pageable).stream() .filter(session -> !session.getUsername().equals(authUtils.getAuthentication().getPrincipal())) .filter(session -> session.getClosedTime() != null) .filter(session -> session.getWatchers().stream() .noneMatch(watcher -> watcher.getWatcher().equals(user.getUsername()))) .toList(); } private Session buildUpdatedSession( Session activeSession, SessionCloseRequest request, boolean isForcedToClose, boolean isAutoClosed) { return Session.builder() .id(activeSession.getId()) .username(activeSession.getUsername()) .openedTime(activeSession.getOpenedTime()) .closedTime(request != null ? request.getClosedTime() : LocalDateTime.now()) .expirationTime(request != null ? request.getClosedTime() : LocalDateTime.now()) .logs(activeSession.getLogs()) .isForcedToClose(isForcedToClose) .isAutoClosed(isAutoClosed) .build(); } private SessionBusyResponse buildSessionBusyResponse(String message, Session activeSession) { return SessionBusyResponse.builder() .message(message) .activeUserName(activeSession.getUsername()) .activeSessionStartTime(activeSession.getOpenedTime()) .intercepted(LocalDateTime.now()) .build(); } private SessionRoleNotAllowedResponse buildRoleNotAllowedResponse() { return SessionRoleNotAllowedResponse.builder() .message(roleNotAllowedMsg) .intercepted(LocalDateTime.now()) .build(); } }
Editor is loading...