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

com.github.lontime.extpac4j.impl.HeaderSimpleSessionStore Maven / Gradle / Ivy

The newest version!
package com.github.lontime.extpac4j.impl;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.lontime.base.commonj.utils.UuidHelper;
import com.github.lontime.shaded.com.github.benmanes.caffeine.cache.Cache;
import com.github.lontime.shaded.com.github.benmanes.caffeine.cache.Caffeine;
import org.pac4j.core.context.JEEContext;
import org.pac4j.core.context.session.SessionStore;

/**
 * LocalJEESessionStore.
 * @author lontime
 * @since 1.0
 */
public class HeaderSimpleSessionStore implements SessionStore {

    public static final HeaderSimpleSessionStore INSTANCE = new HeaderSimpleSessionStore();

    private static final int MAP_SIZE = 16;

    public static final String DEFAULT_HEADER_NAME = "X-Token";

    protected Cache> cache;

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    protected String headerName;

    public HeaderSimpleSessionStore(String headerName, Duration ttl) {
        this.headerName = headerName == null ? DEFAULT_HEADER_NAME : headerName;
        this.cache = Caffeine.newBuilder().expireAfterAccess(ttl).build();
    }

    public HeaderSimpleSessionStore(String headerName) {
        this(headerName, Duration.ofMinutes(5));
    }

    public HeaderSimpleSessionStore() {
        this(null);
    }

    protected boolean check(JEEContext context) {
        return false;
    }

    @Override
    public String getOrCreateSessionId(JEEContext context) {
        final Optional sessionIdOptional = getSessionId(context);
        if (sessionIdOptional.isPresent()) {
            return sessionIdOptional.get();
        }
        final String sessionId = UuidHelper.fastUUID();
        context.setRequestAttribute(headerName, sessionId);
        return sessionId;
    }

    @Override
    public Optional get(JEEContext context, String key) {
        if (check(context)) {
            return Optional.empty();
        }
        final Optional sessionId = getSessionId(context);
        if (!sessionId.isPresent()) {
            return Optional.empty();
        }
        final Map map = cache.getIfPresent(sessionId.get());
        if (map != null && map.containsKey(key)) {
            return Optional.of(map.get(key));
        }
        return Optional.empty();
    }

    @Override
    public void set(JEEContext context, String key, Object value) {
        if (check(context)) {
            return;
        }
        cache.get(getOrCreateSessionId(context),
                k -> new HashMap<>(MAP_SIZE)).put(key, value);
    }

    @Override
    public boolean destroySession(JEEContext context) {
        if (check(context)) {
            return true;
        }
        final Optional sessionId = getSessionId(context);
        if (!sessionId.isPresent()) {
            return true;
        }
        final String id = sessionId.get();
        cache.invalidate(id);
        cleanup(id);
        return true;
    }

    @Override
    public Optional getTrackableSession(JEEContext context) {
        return Optional.empty();
    }

    @Override
    public Optional> buildFromTrackableSession(JEEContext context, Object trackableSession) {
        return Optional.empty();
    }

    @Override
    public boolean renewSession(JEEContext context) {
        return false;
    }

    protected Optional getSessionId(JEEContext context) {
        final String token = context.getNativeRequest().getHeader(headerName);
        if (token != null) {
            return Optional.of(token);
        }
        return context.getRequestAttribute(headerName);
    }

    protected void cleanup(String id) {

    }

}