package org.jboss.resteasy.skeleton.key.as7; import org.apache.catalina.Session; import org.apache.catalina.SessionEvent; import org.apache.catalina.SessionListener; import org.apache.catalina.realm.GenericPrincipal; import org.jboss.resteasy.skeleton.key.as7.i18n.LogMessages; import org.jboss.resteasy.skeleton.key.as7.i18n.Messages; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * Manages relationship to users and sessions so that forced admin logout can be implemented * * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ public class UserSessionManagement implements SessionListener { protected ConcurrentHashMap<String, Map<String, Session>> userSessionMap = new ConcurrentHashMap<String, Map<String, Session>>(); protected void login(Session session, String username) { Map<String, Session> map = userSessionMap.get(username); if (map == null) { final Map<String, Session> value = new HashMap<String, Session>(); map = userSessionMap.putIfAbsent(username, value); if (map == null) { map = value; } } synchronized (map) { map.put(session.getId(), session); } session.addSessionListener(this); } public void logoutAll() { List<String> users = new ArrayList<String>(); users.addAll(userSessionMap.keySet()); for (String user : users) logout(user); } public void logoutAllBut(String but) { List<String> users = new ArrayList<String>(); users.addAll(userSessionMap.keySet()); for (String user : users) { if (!but.equals(user)) logout(user); } } public void logout(String user) { LogMessages.LOGGER.debug(Messages.MESSAGES.logoutUser(user)); Map<String, Session> map = userSessionMap.remove(user); if (map == null) { LogMessages.LOGGER.debug(Messages.MESSAGES.noSessionForUser(user)); return; } LogMessages.LOGGER.debug(Messages.MESSAGES.foundSessionForUser()); synchronized (map) { for (Session session : map.values()) { LogMessages.LOGGER.debug(Messages.MESSAGES.invalidatingSessionForUser(user)); session.setPrincipal(null); session.setAuthType(null); session.getSession().invalidate(); } } } public void sessionEvent(SessionEvent event) { // We only care about session destroyed events if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType()) && (!Session.SESSION_PASSIVATED_EVENT.equals(event.getType()))) return; // Look up the single session id associated with this session (if any) Session session = event.getSession(); GenericPrincipal principal = (GenericPrincipal) session.getPrincipal(); if (principal == null) return; session.setPrincipal(null); session.setAuthType(null); String username = principal.getUserPrincipal().getName(); Map<String, Session> map = userSessionMap.get(username); if (map == null) return; synchronized (map) { map.remove(session.getId()); if (map.isEmpty()) userSessionMap.remove(username); } } }