<commit_before>/*
 * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
 *
 * Copyright (c) 2014, Gluu
 */

package org.xdi.oxauth.service;

import com.unboundid.ldap.sdk.Filter;
import com.unboundid.util.StaticUtils;
import org.apache.commons.lang.StringUtils;
import org.gluu.site.ldap.persistence.LdapEntryManager;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.contexts.Lifecycle;
import org.jboss.seam.log.Log;
import org.xdi.oxauth.model.common.Prompt;
import org.xdi.oxauth.model.common.SessionId;
import org.xdi.oxauth.model.common.SessionIdState;
import org.xdi.oxauth.model.config.ConfigurationFactory;
import org.xdi.oxauth.model.util.Util;
import org.xdi.util.StringHelper;

import javax.faces.context.FacesContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author <NAME>
 * @author <NAME>
 * @version 0.9, 20/12/2012
 */

@Scope(ScopeType.STATELESS)
@Name("sessionIdService")
@AutoCreate
public class SessionIdService {

    private static final String SESSION_ID_COOKIE_NAME = "session_id";
    private static final String STORED_ORIGIN_PARAMETERS = "stored_origin_parameters";

    @Logger
    private Log log;

    @In
    private LdapEntryManager ldapEntryManager;

    public static SessionIdService instance() {
        if (!Contexts.isEventContextActive() && !Contexts.isApplicationContextActive()) {
            Lifecycle.beginCall();
        }
        return (SessionIdService) Component.getInstance(SessionIdService.class);
    }

    public String getSessionIdFromCookie(HttpServletRequest request) {
        try {
            final Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals(SESSION_ID_COOKIE_NAME) /*&& cookie.getSecure()*/) {
                        log.trace("Found session_id cookie: '{0}'", cookie.getValue());
                        return cookie.getValue();
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }

    public String getSessionIdFromCookie() {
		try {
		    final HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
		    return getSessionIdFromCookie(request);
		} catch (Exception e) {
		    log.error(e.getMessage(), e);
		}

		return null;
	}

    public String getSessionIdFromOpbsCookie(HttpServletRequest request) {
        try {
            final Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals("opbs") /*&& cookie.getSecure()*/) {
                        log.trace("Found session_id cookie: '{0}'", cookie.getValue());
                        return cookie.getValue();
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return "";
    }

    public void createSessionIdCookie(String sessionId) {
        try {
            final Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
            if (response instanceof HttpServletResponse) {
                final Cookie sessionIdCookie = new Cookie(SESSION_ID_COOKIE_NAME, sessionId);
                sessionIdCookie.setPath("/");

                // ATTENTION : we have to set also HttpOnly flag but it's supported from Servlet 3.0
                // we need to upgrade to Servlet 3.0 and target to Tomcat 7 : http://tomcat.apache.org/whichversion.html
//                sessionIdCookie.setSecure(true);
//                sessionIdCookie.setHttpOnly(true);
                final HttpServletResponse httpResponse = (HttpServletResponse) response;
                httpResponse.addCookie(sessionIdCookie);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public void removeSessionIdCookie() {
        try {
            final FacesContext currentInstance = FacesContext.getCurrentInstance();
            if (currentInstance != null && currentInstance.getExternalContext() != null) {
                final Object response = currentInstance.getExternalContext().getResponse();
                if (response instanceof HttpServletResponse) {
                    removeSessionIdCookie((HttpServletResponse) response);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public void removeSessionIdCookie(HttpServletResponse httpResponse) {
        final Cookie cookie = new Cookie(SESSION_ID_COOKIE_NAME, null); // Not necessary, but saves bandwidth.
        cookie.setPath("/");
        cookie.setMaxAge(0); // Don't set to -1 or it will become a session cookie!
        httpResponse.addCookie(cookie);
    }

    public SessionId getSessionId() {
    	String sessionId = getSessionIdFromCookie();

        if (StringHelper.isNotEmpty(sessionId)) {
            return getSessionId(sessionId);
        }
        
        return null;
    }

    public Map<String, String> getSessionAttributes(SessionId sessionId) {
    	if (sessionId != null) {
    		return sessionId.getSessionAttributes();
    	}
    	
		return null;
    }

    public SessionId generateAuthenticatedSessionId(String userDn) {
    	return generateAuthenticatedSessionId(userDn, "");
    }

    public SessionId generateAuthenticatedSessionId(String userDn, String prompt) {
    	Map<String, String> sessionIdAttributes = new HashMap<String, String>();
    	sessionIdAttributes.put("prompt", prompt);

    	return generateSessionId(userDn, new Date(), SessionIdState.AUTHENTICATED, sessionIdAttributes, true);
    }

    public SessionId generateAuthenticatedSessionId(String userDn, Map<String, String> sessionIdAttributes) {
    	return generateSessionId(userDn, new Date(), SessionIdState.AUTHENTICATED, sessionIdAttributes, true);
    }

	public SessionId generateSessionId(String p_userDn, Date authenticationDate, SessionIdState state, Map<String, String> sessionIdAttributes, boolean persist) {
            final String uuid = UUID.randomUUID().toString();
            final String dn = dn(uuid);

            if (StringUtils.isBlank(dn)) {
        		return null;
        	}

            if (SessionIdState.AUTHENTICATED == state) {
                if (StringUtils.isBlank(p_userDn)) {
            		return null;
            	}
            }

            final SessionId sessionId = new SessionId();
            sessionId.setId(uuid);
            sessionId.setDn(dn);

            if (StringUtils.isNotBlank(p_userDn)) {
            	sessionId.setUserDn(p_userDn);
            }

            if (authenticationDate != null) {
                sessionId.setAuthenticationTime(authenticationDate);
            }
            
        	if (state != null) {
            	sessionId.setState(state);
            }

        	configureOpbsCookie(sessionId);
        	
        	sessionId.setSessionAttributes(sessionIdAttributes);

            boolean persisted = false;
            if (persist) {
            	persisted = persistSessionId(sessionId);
            }

            log.trace("Generated new session, id = '{0}', state = '{1}', persisted = '{2}'", sessionId.getId(), sessionId.getState(), persisted);
            return sessionId;
    }

    public SessionId setSessionIdAuthenticated(SessionId sessionId, String p_userDn) {
       	sessionId.setUserDn(p_userDn);
        sessionId.setAuthenticationTime(new Date());
       	sessionId.setState(SessionIdState.AUTHENTICATED);

    	configureOpbsCookie(sessionId);

        boolean persisted = updateSessionId(sessionId);

        log.trace("Authenticated session, id = '{0}', state = '{1}', persisted = '{2}'", sessionId.getId(), sessionId.getState(), persisted);
        return sessionId;
}

	private void configureOpbsCookie(SessionId sessionId) {
		final int unusedLifetime = ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime();
        FacesContext facesContext = FacesContext.getCurrentInstance();
        if (facesContext != null) {
            Cookie cookie = new Cookie("opbs", sessionId.getId());
            cookie.setMaxAge(unusedLifetime);
            ((HttpServletResponse) facesContext.getExternalContext().getResponse()).addCookie(cookie);
        }
	}

    public boolean persistSessionId(final SessionId sessionId) {
        return persistSessionId(sessionId, false);
    }

	public boolean persistSessionId(final SessionId sessionId, boolean forcePersistence) {
		List<Prompt> prompts = getPromptsFromSessionId(sessionId);

        try {
        	final int unusedLifetime = ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime();
			if ((unusedLifetime > 0 && isPersisted(prompts)) || forcePersistence) {
	            sessionId.setLastUsedAt(new Date());

	            sessionId.setPersisted(true);
	            ldapEntryManager.persist(sessionId);
		        return true;
			}
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return false;
	}

    public boolean updateSessionId(final SessionId sessionId) {
        return updateSessionId(sessionId, true);
    }

	public boolean updateSessionId(final SessionId sessionId, boolean updateLastUsedAt) {
		List<Prompt> prompts = getPromptsFromSessionId(sessionId);

		try {
        	final int unusedLifetime = ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime();
			if (unusedLifetime > 0 && isPersisted(prompts)) {
                if (updateLastUsedAt) {
	                sessionId.setLastUsedAt(new Date());
                }

	            sessionId.setPersisted(true);
	            ldapEntryManager.merge(sessionId);
			}
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }

		return true;
	}

    private static boolean isPersisted(List<Prompt> prompts) {
        if (prompts != null && prompts.contains(Prompt.NONE)) {
            final Boolean persistOnPromptNone = ConfigurationFactory.getConfiguration().getSessionIdPersistOnPromptNone();
            return persistOnPromptNone != null && persistOnPromptNone;
        }
        return true;
    }

    private static String dn(String p_id) {
        final String baseDn = getBaseDn();
        final StringBuilder sb = new StringBuilder();
        if (Util.allNotBlank(p_id, getBaseDn())) {
            sb.append("uniqueIdentifier=").append(p_id).append(",").append(baseDn);
        }
        return sb.toString();
    }

    public SessionId getSessionByDN(String p_dn) {
        try {
            return ldapEntryManager.find(SessionId.class, p_dn);
        } catch (Exception e) {
            log.trace(e.getMessage(), e);
        }
        return null;
    }

    public SessionId getSessionId(String sessionId) {
        if (StringHelper.isEmpty(sessionId)) {
            return null;
        }

        String dn = dn(sessionId);
        boolean contains = containsSessionId(dn);
    	if (!contains) {
    		return null;
    	}

        try {
        	final SessionId entity = getSessionByDN(dn);
            log.trace("Try to get session by id: {0} ...", sessionId);
            if (entity != null) {
                log.trace("Session dn: {0}", entity.getDn());

                if (isSessionValid(entity)) {
                    return entity;
                }
            }
        } catch (Exception ex) {
            log.trace(ex.getMessage(), ex);
        }

        log.trace("Failed to get session by id: {0}", sessionId);
        return null;
    }

    public boolean containsSessionId(String dn) {
        try {
            return ldapEntryManager.contains(SessionId.class, dn);
        } catch (Exception e) {
            log.trace(e.getMessage(), e);
        }

        return false;
    }

    private static String getBaseDn() {
        return ConfigurationFactory.getBaseDn().getSessionId();
    }

    public boolean remove(SessionId p_sessionId) {
        try {
            ldapEntryManager.remove(p_sessionId);
        } catch (Exception e) {
            log.error(e.getMessage(), e);

            return false;
        }
        return true;
    }

    public void remove(List<SessionId> list) {
        for (SessionId id : list) {
            remove(id);
        }
    }

    public void cleanUpSessions() {
        final int interval = ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime();
        final int unauthenticatedInterval = ConfigurationFactory.getConfiguration().getSessionIdUnauthenticatedUnusedLifetime();

        remove(getUnauthenticatedIdsOlderThan(unauthenticatedInterval));
        remove(getIdsOlderThan(interval));
    }

    public List<SessionId> getUnauthenticatedIdsOlderThan(int p_intervalInSeconds) {
        try {
            final long dateInPast = new Date().getTime() - TimeUnit.SECONDS.toMillis(p_intervalInSeconds);
            final Filter filter = Filter.create(String.format("&(lastModifiedTime<=%s)(oxState=unauthenticated)", StaticUtils.encodeGeneralizedTime(new Date(dateInPast))));
            return ldapEntryManager.findEntries(getBaseDn(), SessionId.class, filter);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return Collections.emptyList();
    }


    public List<SessionId> getIdsOlderThan(int p_intervalInSeconds) {
        try {
            final long dateInPast = new Date().getTime() - TimeUnit.SECONDS.toMillis(p_intervalInSeconds);
            final Filter filter = Filter.create(String.format("(lastModifiedTime<=%s)", StaticUtils.encodeGeneralizedTime(new Date(dateInPast))));
            return ldapEntryManager.findEntries(getBaseDn(), SessionId.class, filter);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return Collections.emptyList();
    }

    public boolean isSessionValid(SessionId sessionId) {
        if (sessionId == null) {
            return false;
        }

        final long sessionInterval = TimeUnit.SECONDS.toMillis(ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime());
        final long sessionUnauthenticatedInterval = TimeUnit.SECONDS.toMillis(ConfigurationFactory.getConfiguration().getSessionIdUnauthenticatedUnusedLifetime());

        final long timeSinceLastAccess = System.currentTimeMillis() - sessionId.getLastUsedAt().getTime();
        if (timeSinceLastAccess > sessionInterval) {
            return false;
        }
        if (sessionId.getState() == SessionIdState.UNAUTHENTICATED && timeSinceLastAccess > sessionUnauthenticatedInterval) {
            return false;
        }

        return true;
    }

	private List<Prompt> getPromptsFromSessionId(final SessionId sessionId) {<commit_msg>session is valid if we have -1<commit_after>/*
 * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
 *
 * Copyright (c) 2014, Gluu
 */

package org.xdi.oxauth.service;

import com.unboundid.ldap.sdk.Filter;
import com.unboundid.util.StaticUtils;
import org.apache.commons.lang.StringUtils;
import org.gluu.site.ldap.persistence.LdapEntryManager;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.contexts.Lifecycle;
import org.jboss.seam.log.Log;
import org.xdi.oxauth.model.common.Prompt;
import org.xdi.oxauth.model.common.SessionId;
import org.xdi.oxauth.model.common.SessionIdState;
import org.xdi.oxauth.model.config.ConfigurationFactory;
import org.xdi.oxauth.model.util.Util;
import org.xdi.util.StringHelper;

import javax.faces.context.FacesContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author <NAME>
 * @author <NAME>
 * @version 0.9, 20/12/2012
 */

@Scope(ScopeType.STATELESS)
@Name("sessionIdService")
@AutoCreate
public class SessionIdService {

    private static final String SESSION_ID_COOKIE_NAME = "session_id";
    private static final String STORED_ORIGIN_PARAMETERS = "stored_origin_parameters";

    @Logger
    private Log log;

    @In
    private LdapEntryManager ldapEntryManager;

    public static SessionIdService instance() {
        if (!Contexts.isEventContextActive() && !Contexts.isApplicationContextActive()) {
            Lifecycle.beginCall();
        }
        return (SessionIdService) Component.getInstance(SessionIdService.class);
    }

    public String getSessionIdFromCookie(HttpServletRequest request) {
        try {
            final Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals(SESSION_ID_COOKIE_NAME) /*&& cookie.getSecure()*/) {
                        log.trace("Found session_id cookie: '{0}'", cookie.getValue());
                        return cookie.getValue();
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }

    public String getSessionIdFromCookie() {
		try {
		    final HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
		    return getSessionIdFromCookie(request);
		} catch (Exception e) {
		    log.error(e.getMessage(), e);
		}

		return null;
	}

    public String getSessionIdFromOpbsCookie(HttpServletRequest request) {
        try {
            final Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals("opbs") /*&& cookie.getSecure()*/) {
                        log.trace("Found session_id cookie: '{0}'", cookie.getValue());
                        return cookie.getValue();
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return "";
    }

    public void createSessionIdCookie(String sessionId) {
        try {
            final Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
            if (response instanceof HttpServletResponse) {
                final Cookie sessionIdCookie = new Cookie(SESSION_ID_COOKIE_NAME, sessionId);
                sessionIdCookie.setPath("/");

                // ATTENTION : we have to set also HttpOnly flag but it's supported from Servlet 3.0
                // we need to upgrade to Servlet 3.0 and target to Tomcat 7 : http://tomcat.apache.org/whichversion.html
//                sessionIdCookie.setSecure(true);
//                sessionIdCookie.setHttpOnly(true);
                final HttpServletResponse httpResponse = (HttpServletResponse) response;
                httpResponse.addCookie(sessionIdCookie);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public void removeSessionIdCookie() {
        try {
            final FacesContext currentInstance = FacesContext.getCurrentInstance();
            if (currentInstance != null && currentInstance.getExternalContext() != null) {
                final Object response = currentInstance.getExternalContext().getResponse();
                if (response instanceof HttpServletResponse) {
                    removeSessionIdCookie((HttpServletResponse) response);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public void removeSessionIdCookie(HttpServletResponse httpResponse) {
        final Cookie cookie = new Cookie(SESSION_ID_COOKIE_NAME, null); // Not necessary, but saves bandwidth.
        cookie.setPath("/");
        cookie.setMaxAge(0); // Don't set to -1 or it will become a session cookie!
        httpResponse.addCookie(cookie);
    }

    public SessionId getSessionId() {
    	String sessionId = getSessionIdFromCookie();

        if (StringHelper.isNotEmpty(sessionId)) {
            return getSessionId(sessionId);
        }
        
        return null;
    }

    public Map<String, String> getSessionAttributes(SessionId sessionId) {
    	if (sessionId != null) {
    		return sessionId.getSessionAttributes();
    	}
    	
		return null;
    }

    public SessionId generateAuthenticatedSessionId(String userDn) {
    	return generateAuthenticatedSessionId(userDn, "");
    }

    public SessionId generateAuthenticatedSessionId(String userDn, String prompt) {
    	Map<String, String> sessionIdAttributes = new HashMap<String, String>();
    	sessionIdAttributes.put("prompt", prompt);

    	return generateSessionId(userDn, new Date(), SessionIdState.AUTHENTICATED, sessionIdAttributes, true);
    }

    public SessionId generateAuthenticatedSessionId(String userDn, Map<String, String> sessionIdAttributes) {
    	return generateSessionId(userDn, new Date(), SessionIdState.AUTHENTICATED, sessionIdAttributes, true);
    }

	public SessionId generateSessionId(String p_userDn, Date authenticationDate, SessionIdState state, Map<String, String> sessionIdAttributes, boolean persist) {
            final String uuid = UUID.randomUUID().toString();
            final String dn = dn(uuid);

            if (StringUtils.isBlank(dn)) {
        		return null;
        	}

            if (SessionIdState.AUTHENTICATED == state) {
                if (StringUtils.isBlank(p_userDn)) {
            		return null;
            	}
            }

            final SessionId sessionId = new SessionId();
            sessionId.setId(uuid);
            sessionId.setDn(dn);

            if (StringUtils.isNotBlank(p_userDn)) {
            	sessionId.setUserDn(p_userDn);
            }

            if (authenticationDate != null) {
                sessionId.setAuthenticationTime(authenticationDate);
            }
            
        	if (state != null) {
            	sessionId.setState(state);
            }

        	configureOpbsCookie(sessionId);
        	
        	sessionId.setSessionAttributes(sessionIdAttributes);

            boolean persisted = false;
            if (persist) {
            	persisted = persistSessionId(sessionId);
            }

            log.trace("Generated new session, id = '{0}', state = '{1}', persisted = '{2}'", sessionId.getId(), sessionId.getState(), persisted);
            return sessionId;
    }

    public SessionId setSessionIdAuthenticated(SessionId sessionId, String p_userDn) {
       	sessionId.setUserDn(p_userDn);
        sessionId.setAuthenticationTime(new Date());
       	sessionId.setState(SessionIdState.AUTHENTICATED);

    	configureOpbsCookie(sessionId);

        boolean persisted = updateSessionId(sessionId);

        log.trace("Authenticated session, id = '{0}', state = '{1}', persisted = '{2}'", sessionId.getId(), sessionId.getState(), persisted);
        return sessionId;
}

	private void configureOpbsCookie(SessionId sessionId) {
		final int unusedLifetime = ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime();
        FacesContext facesContext = FacesContext.getCurrentInstance();
        if (facesContext != null) {
            Cookie cookie = new Cookie("opbs", sessionId.getId());
            cookie.setMaxAge(unusedLifetime);
            ((HttpServletResponse) facesContext.getExternalContext().getResponse()).addCookie(cookie);
        }
	}

    public boolean persistSessionId(final SessionId sessionId) {
        return persistSessionId(sessionId, false);
    }

	public boolean persistSessionId(final SessionId sessionId, boolean forcePersistence) {
		List<Prompt> prompts = getPromptsFromSessionId(sessionId);

        try {
        	final int unusedLifetime = ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime();
			if ((unusedLifetime > 0 && isPersisted(prompts)) || forcePersistence) {
	            sessionId.setLastUsedAt(new Date());

	            sessionId.setPersisted(true);
	            ldapEntryManager.persist(sessionId);
		        return true;
			}
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return false;
	}

    public boolean updateSessionId(final SessionId sessionId) {
        return updateSessionId(sessionId, true);
    }

	public boolean updateSessionId(final SessionId sessionId, boolean updateLastUsedAt) {
		List<Prompt> prompts = getPromptsFromSessionId(sessionId);

		try {
        	final int unusedLifetime = ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime();
			if (unusedLifetime > 0 && isPersisted(prompts)) {
                if (updateLastUsedAt) {
	                sessionId.setLastUsedAt(new Date());
                }

	            sessionId.setPersisted(true);
	            ldapEntryManager.merge(sessionId);
			}
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }

		return true;
	}

    private static boolean isPersisted(List<Prompt> prompts) {
        if (prompts != null && prompts.contains(Prompt.NONE)) {
            final Boolean persistOnPromptNone = ConfigurationFactory.getConfiguration().getSessionIdPersistOnPromptNone();
            return persistOnPromptNone != null && persistOnPromptNone;
        }
        return true;
    }

    private static String dn(String p_id) {
        final String baseDn = getBaseDn();
        final StringBuilder sb = new StringBuilder();
        if (Util.allNotBlank(p_id, getBaseDn())) {
            sb.append("uniqueIdentifier=").append(p_id).append(",").append(baseDn);
        }
        return sb.toString();
    }

    public SessionId getSessionByDN(String p_dn) {
        try {
            return ldapEntryManager.find(SessionId.class, p_dn);
        } catch (Exception e) {
            log.trace(e.getMessage(), e);
        }
        return null;
    }

    public SessionId getSessionId(String sessionId) {
        if (StringHelper.isEmpty(sessionId)) {
            return null;
        }

        String dn = dn(sessionId);
        boolean contains = containsSessionId(dn);
    	if (!contains) {
    		return null;
    	}

        try {
        	final SessionId entity = getSessionByDN(dn);
            log.trace("Try to get session by id: {0} ...", sessionId);
            if (entity != null) {
                log.trace("Session dn: {0}", entity.getDn());

                if (isSessionValid(entity)) {
                    return entity;
                }
            }
        } catch (Exception ex) {
            log.trace(ex.getMessage(), ex);
        }

        log.trace("Failed to get session by id: {0}", sessionId);
        return null;
    }

    public boolean containsSessionId(String dn) {
        try {
            return ldapEntryManager.contains(SessionId.class, dn);
        } catch (Exception e) {
            log.trace(e.getMessage(), e);
        }

        return false;
    }

    private static String getBaseDn() {
        return ConfigurationFactory.getBaseDn().getSessionId();
    }

    public boolean remove(SessionId p_sessionId) {
        try {
            ldapEntryManager.remove(p_sessionId);
        } catch (Exception e) {
            log.error(e.getMessage(), e);

            return false;
        }
        return true;
    }

    public void remove(List<SessionId> list) {
        for (SessionId id : list) {
            remove(id);
        }
    }

    public void cleanUpSessions() {
        final int interval = ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime();
        final int unauthenticatedInterval = ConfigurationFactory.getConfiguration().getSessionIdUnauthenticatedUnusedLifetime();

        remove(getUnauthenticatedIdsOlderThan(unauthenticatedInterval));
        remove(getIdsOlderThan(interval));
    }

    public List<SessionId> getUnauthenticatedIdsOlderThan(int p_intervalInSeconds) {
        try {
            final long dateInPast = new Date().getTime() - TimeUnit.SECONDS.toMillis(p_intervalInSeconds);
            final Filter filter = Filter.create(String.format("&(lastModifiedTime<=%s)(oxState=unauthenticated)", StaticUtils.encodeGeneralizedTime(new Date(dateInPast))));
            return ldapEntryManager.findEntries(getBaseDn(), SessionId.class, filter);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return Collections.emptyList();
    }


    public List<SessionId> getIdsOlderThan(int p_intervalInSeconds) {
        try {
            final long dateInPast = new Date().getTime() - TimeUnit.SECONDS.toMillis(p_intervalInSeconds);
            final Filter filter = Filter.create(String.format("(lastModifiedTime<=%s)", StaticUtils.encodeGeneralizedTime(new Date(dateInPast))));
            return ldapEntryManager.findEntries(getBaseDn(), SessionId.class, filter);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return Collections.emptyList();
    }

    public boolean isSessionValid(SessionId sessionId) {
        if (sessionId == null) {
            return false;
        }

        final long sessionInterval = TimeUnit.SECONDS.toMillis(ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime());
        final long sessionUnauthenticatedInterval = TimeUnit.SECONDS.toMillis(ConfigurationFactory.getConfiguration().getSessionIdUnauthenticatedUnusedLifetime());

        final long timeSinceLastAccess = System.currentTimeMillis() - sessionId.getLastUsedAt().getTime();
        if (timeSinceLastAccess > sessionInterval && ConfigurationFactory.getConfiguration().getSessionIdUnusedLifetime() != -1) {
            return false;
        }
        if (sessionId.getState() == SessionIdState.UNAUTHENTICATED && timeSinceLastAccess > sessionUnauthenticatedInterval && ConfigurationFactory.getConfiguration().getSessionIdUnauthenticatedUnusedLifetime() != -1) {
            return false;
        }

        return true;
    }

	private List<Prompt> getPromptsFromSessionId(final SessionId sessionId) {
{'fraction_non_alphanumeric': 0.10327415412324714, 'fraction_numerical': 0.002540846520005146, 'mean_word_length': 2.5771974229176253, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1115355', 'n_tokens_mistral': 8702, 'n_tokens_neox': 8386, 'n_words': 1732}