All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pl.fhframework.SessionTimeoutManager Maven / Gradle / Ivy

package pl.fhframework;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import pl.fhframework.core.session.ForceLogoutService;
import pl.fhframework.core.session.UserSessionRepository;
import pl.fhframework.event.dto.ForcedLogoutEvent;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ConditionalOnProperty(value = "fh.web.inactive_session_auto_logout")
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class SessionTimeoutManager {
    @Value("${fh.web.inactive_session_auto_logout:false}")
    private boolean active;

    @Value("${fh.web.inactive_session_max_time:10}")
    private int maxInactivityMinutes;

    @Value("${fh.web.inactive_session_counter_id:}")
    private String counterElementId;

    @Autowired
    private ForceLogoutService forceLogoutService;

    @Autowired
    private UserSessionRepository userSessionRepository;

    private Map sessionActivityDictionary = new ConcurrentHashMap<>();

    public Session.TimeoutData keepSessionAlive(String conversationId) {
        if (!active) {
            throw new IllegalStateException("Session timeout management is not enabled.");
        }

        Instant activityLimitDate = sessionActivityDictionary.get(conversationId);
        if (activityLimitDate != null) {
            boolean allowedDuration = Instant.now().isBefore(activityLimitDate);
            if (allowedDuration) {
                activityLimitDate = getInstantMinutesLater();
                sessionActivityDictionary.put(conversationId, activityLimitDate);
            }
            userSessionRepository.onSessionKeepAlive(conversationId);
            return new Session.TimeoutData(activityLimitDate, counterElementId, maxInactivityMinutes);
        } else {
            throw new IllegalStateException("Cannot find session in activity dictionary. Make sure it has been properly initialized.");
        }
    }

    void registerConversation(String conversationId) {
        sessionActivityDictionary.put(conversationId, getInstantMinutesLater());
    }

    private Instant getInstantMinutesLater() {
        return Instant.now().plus(maxInactivityMinutes, ChronoUnit.MINUTES);
    }

    @Scheduled(fixedDelay = 500L)
    public synchronized void serverSideInactiveSessionsLogout() {
        if (active) {
            sessionActivityDictionary.keySet().removeIf(conversationId -> {
                Instant activityLimitDate = sessionActivityDictionary.get(conversationId);
                if (Instant.now().isBefore(activityLimitDate)) {
                    return false;
                } else {
                    forceLogoutService.forceLogout(conversationId, ForcedLogoutEvent.Reason.LOGOUT_TIMEOUT);
                    return true;
                }
            });
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy