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

pl.edu.icm.unity.saml.slo.LogoutContextsStore Maven / Gradle / Ivy

There is a newer version: 4.0.4
Show newest version
/*
 * Copyright (c) 2014 ICM Uniwersytet Warszawski All rights reserved.
 * See LICENCE.txt file for licensing information.
 */
package pl.edu.icm.unity.saml.slo;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;

import pl.edu.icm.unity.base.utils.Log;

/**
 * In memory storage of logout contexts. Ensures that the contexts are expired after some time.
 * Thread safe.
 * @author K. Benedyczak
 */
@Component
public class LogoutContextsStore
{
	private static final Logger log = Log.getLogger(Log.U_SERVER_SAML, LogoutContextsStore.class);
	public static final long MAX_AGE = 180000;
	public static final long CLEANUP_EVERY = 30000;
	
	private Map intContexts = new HashMap(64);
	private Map extContexts = new HashMap(64);
	private Map plainExtContexts = 
			new HashMap(64);
	private long lastCleanup;
	
	public synchronized SAMLInternalLogoutContext getInternalContext(String id)
	{
		cleanup();
		return intContexts.get(id);
	}

	public synchronized SAMLExternalLogoutContext getSAMLExternalContext(String id)
	{
		cleanup();
		return extContexts.get(id);
	}

	public synchronized PlainExternalLogoutContext getPlainExternalContext(String id)
	{
		cleanup();
		return plainExtContexts.get(id);
	}
	
	public synchronized void removeInternalContext(String key)
	{
		intContexts.remove(key);
	}

	public synchronized void removeSAMLExternalContext(String key)
	{
		extContexts.remove(key);
	}

	public synchronized void removePlainExternalContext(String key)
	{
		plainExtContexts.remove(key);
	}

	/**
	 * The identifier of the context must be provided. Useful for logouts started with SAML.
	 * @param context
	 */
	public synchronized void addInternalContext(String key, SAMLInternalLogoutContext context)
	{
		cleanup();
		intContexts.put(key, context);
	}
	
	/**
	 * Adds a new external logout context, the key is returned and set as internal relay state.
	 * @param key
	 * @param context
	 */
	public synchronized String addSAMLExternalContext(SAMLExternalLogoutContext context)
	{
		cleanup();
		String key = UUID.randomUUID().toString();
		extContexts.put(key, context);
		context.setInternalRelayState(key);
		return key;
	}

	public synchronized String addPlainExternalContext(PlainExternalLogoutContext context)
	{
		cleanup();
		String key = UUID.randomUUID().toString();
		plainExtContexts.put(key, context);
		return key;
	}
	
	private void cleanup()
	{
		if (lastCleanup + CLEANUP_EVERY > System.currentTimeMillis())
			return;
		log.debug("Running SAML logout contexts expiration task");
		lastCleanup = System.currentTimeMillis();
		cleanup(extContexts);
		cleanup(intContexts);
	}
	
	private void cleanup(Map contexts)
	{
		Iterator mapIt = contexts.values().iterator();
		while (mapIt.hasNext())
		{
			AbstractSAMLLogoutContext ctx = mapIt.next();
			if (ctx.getCreationTs().getTime() + MAX_AGE < lastCleanup)
			{
				if (log.isDebugEnabled())
					log.debug("Expiring stale SAML logout context " + ctx + ", is " + 
						((lastCleanup - ctx.getCreationTs().getTime())/1000) + "s old");
				mapIt.remove();
			}
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy