|  | @@ -1,4 +1,4 @@
 | 
	
		
			
				|  |  | -/* Copyright 2004, 2005 Acegi Technology Pty Limited
 | 
	
		
			
				|  |  | +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  |   * Licensed under the Apache License, Version 2.0 (the "License");
 | 
	
		
			
				|  |  |   * you may not use this file except in compliance with the License.
 | 
	
	
		
			
				|  | @@ -18,30 +18,35 @@ package org.acegisecurity.concurrent;
 | 
	
		
			
				|  |  |  import org.acegisecurity.AcegiMessageSource;
 | 
	
		
			
				|  |  |  import org.acegisecurity.Authentication;
 | 
	
		
			
				|  |  |  import org.acegisecurity.AuthenticationException;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.InitializingBean;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  import org.springframework.context.MessageSource;
 | 
	
		
			
				|  |  |  import org.springframework.context.MessageSourceAware;
 | 
	
		
			
				|  |  |  import org.springframework.context.support.MessageSourceAccessor;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  import org.springframework.util.Assert;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * Base implementation of {@link ConcurrentSessionControllerImpl} which
 | 
	
		
			
				|  |  |   * prohibits simultaneous logins.
 | 
	
		
			
				|  |  | + * 
 | 
	
		
			
				|  |  |   * <p>
 | 
	
		
			
				|  |  | - * By default uses {@link SessionRegistryImpl},
 | 
	
		
			
				|  |  | - * although any <code>SessionRegistry</code> may be used.
 | 
	
		
			
				|  |  | + * By default uses {@link SessionRegistryImpl}, although any
 | 
	
		
			
				|  |  | + * <code>SessionRegistry</code> may be used.
 | 
	
		
			
				|  |  |   * </p>
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  |   * @author Ben Alex
 | 
	
		
			
				|  |  |   * @version $Id$
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  | -public class ConcurrentSessionControllerImpl implements ConcurrentSessionController,
 | 
	
		
			
				|  |  | -        InitializingBean, MessageSourceAware {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +public class ConcurrentSessionControllerImpl
 | 
	
		
			
				|  |  | +    implements ConcurrentSessionController, InitializingBean,
 | 
	
		
			
				|  |  | +        MessageSourceAware {
 | 
	
		
			
				|  |  |      //~ Instance fields ========================================================
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
 | 
	
		
			
				|  |  | +    protected MessageSourceAccessor messages = AcegiMessageSource
 | 
	
		
			
				|  |  | +        .getAccessor();
 | 
	
		
			
				|  |  |      private SessionRegistry sessionRegistry = new SessionRegistryImpl();
 | 
	
		
			
				|  |  |      private boolean exceptionIfMaximumExceeded = false;
 | 
	
		
			
				|  |  |      private int maximumSessions = 1;
 | 
	
	
		
			
				|  | @@ -51,7 +56,7 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
 | 
	
		
			
				|  |  |      public void afterPropertiesSet() throws Exception {
 | 
	
		
			
				|  |  |          Assert.notNull(sessionRegistry, "SessionRegistry required");
 | 
	
		
			
				|  |  |          Assert.isTrue(maximumSessions != 0,
 | 
	
		
			
				|  |  | -                "MaximumLogins must be either -1 to allow unlimited logins, or a positive integer to specify a maximum");
 | 
	
		
			
				|  |  | +            "MaximumLogins must be either -1 to allow unlimited logins, or a positive integer to specify a maximum");
 | 
	
		
			
				|  |  |          Assert.notNull(this.messages, "A message source must be set");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -59,21 +64,22 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
 | 
	
		
			
				|  |  |       * Allows subclasses to customise behaviour when too many sessions are
 | 
	
		
			
				|  |  |       * detected.
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  | -     * @param sessionId         the session ID of the present request
 | 
	
		
			
				|  |  | -     * @param sessions          either <code>null</code> or all unexpired sessions
 | 
	
		
			
				|  |  | -     *                          associated with the principal
 | 
	
		
			
				|  |  | +     * @param sessionId the session ID of the present request
 | 
	
		
			
				|  |  | +     * @param sessions either <code>null</code> or all unexpired sessions
 | 
	
		
			
				|  |  | +     *        associated with the principal
 | 
	
		
			
				|  |  |       * @param allowableSessions DOCUMENT ME!
 | 
	
		
			
				|  |  | -     * @param registry          an instance of the <code>SessionRegistry</code> for
 | 
	
		
			
				|  |  | -     *                          subclass use
 | 
	
		
			
				|  |  | +     * @param registry an instance of the <code>SessionRegistry</code> for
 | 
	
		
			
				|  |  | +     *        subclass use
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  |       * @throws ConcurrentLoginException DOCUMENT ME!
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      protected void allowableSessionsExceeded(String sessionId,
 | 
	
		
			
				|  |  | -                                             SessionInformation[] sessions, int allowableSessions,
 | 
	
		
			
				|  |  | -                                             SessionRegistry registry) {
 | 
	
		
			
				|  |  | +        SessionInformation[] sessions, int allowableSessions,
 | 
	
		
			
				|  |  | +        SessionRegistry registry) {
 | 
	
		
			
				|  |  |          if (exceptionIfMaximumExceeded || (sessions == null)) {
 | 
	
		
			
				|  |  |              throw new ConcurrentLoginException(messages.getMessage(
 | 
	
		
			
				|  |  |                      "ConcurrentSessionControllerImpl.exceededAllowed",
 | 
	
		
			
				|  |  | -                    new Object[]{new Integer(allowableSessions)},
 | 
	
		
			
				|  |  | +                    new Object[] {new Integer(allowableSessions)},
 | 
	
		
			
				|  |  |                      "Maximum sessions of {0} for this principal exceeded"));
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -82,8 +88,8 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          for (int i = 0; i < sessions.length; i++) {
 | 
	
		
			
				|  |  |              if ((leastRecentlyUsed == null)
 | 
	
		
			
				|  |  | -                    || sessions[i].getLastRequest()
 | 
	
		
			
				|  |  | -                    .before(leastRecentlyUsed.getLastRequest())) {
 | 
	
		
			
				|  |  | +                || sessions[i].getLastRequest()
 | 
	
		
			
				|  |  | +                              .before(leastRecentlyUsed.getLastRequest())) {
 | 
	
		
			
				|  |  |                  leastRecentlyUsed = sessions[i];
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -92,16 +98,17 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public void checkAuthenticationAllowed(Authentication request)
 | 
	
		
			
				|  |  | -            throws AuthenticationException {
 | 
	
		
			
				|  |  | +        throws AuthenticationException {
 | 
	
		
			
				|  |  |          Assert.notNull(request,
 | 
	
		
			
				|  |  | -                "Authentication request cannot be null (violation of interface contract)");
 | 
	
		
			
				|  |  | +            "Authentication request cannot be null (violation of interface contract)");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          Object principal = SessionRegistryUtils
 | 
	
		
			
				|  |  | -                .obtainPrincipalFromAuthentication(request);
 | 
	
		
			
				|  |  | +            .obtainPrincipalFromAuthentication(request);
 | 
	
		
			
				|  |  |          String sessionId = SessionRegistryUtils
 | 
	
		
			
				|  |  | -                .obtainSessionIdFromAuthentication(request);
 | 
	
		
			
				|  |  | +            .obtainSessionIdFromAuthentication(request);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        SessionInformation[] sessions = sessionRegistry.getAllSessions(principal);
 | 
	
		
			
				|  |  | +        SessionInformation[] sessions = sessionRegistry.getAllSessions(principal,
 | 
	
		
			
				|  |  | +                false);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          int sessionCount = 0;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -111,7 +118,7 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          int allowableSessions = getMaximumSessionsForThisUser(request);
 | 
	
		
			
				|  |  |          Assert.isTrue(allowableSessions != 0,
 | 
	
		
			
				|  |  | -                "getMaximumSessionsForThisUser() must return either -1 to allow unlimited logins, or a positive integer to specify a maximum");
 | 
	
		
			
				|  |  | +            "getMaximumSessionsForThisUser() must return either -1 to allow unlimited logins, or a positive integer to specify a maximum");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if (sessionCount < allowableSessions) {
 | 
	
		
			
				|  |  |              return;
 | 
	
	
		
			
				|  | @@ -124,41 +131,40 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        allowableSessionsExceeded(sessionId, sessions,
 | 
	
		
			
				|  |  | -                allowableSessions, sessionRegistry);
 | 
	
		
			
				|  |  | +        allowableSessionsExceeded(sessionId, sessions, allowableSessions,
 | 
	
		
			
				|  |  | +            sessionRegistry);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  | -     * Method intended for use by subclasses to override the maximum
 | 
	
		
			
				|  |  | -     * number of sessions that are permitted for a particular
 | 
	
		
			
				|  |  | -     * authentication. The default implementation simply returns the
 | 
	
		
			
				|  |  | -     * <code>maximumSessions</code> value for the bean.
 | 
	
		
			
				|  |  | +     * Method intended for use by subclasses to override the maximum number of
 | 
	
		
			
				|  |  | +     * sessions that are permitted for a particular authentication. The
 | 
	
		
			
				|  |  | +     * default implementation simply returns the <code>maximumSessions</code>
 | 
	
		
			
				|  |  | +     * value for the bean.
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  |       * @param authentication to determine the maximum sessions for
 | 
	
		
			
				|  |  | -     * @return either -1 meaning unlimited, or a positive integer to
 | 
	
		
			
				|  |  | -     *         limit (never zero)
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @return either -1 meaning unlimited, or a positive integer to limit
 | 
	
		
			
				|  |  | +     *         (never zero)
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    protected int getMaximumSessionsForThisUser(
 | 
	
		
			
				|  |  | -            Authentication authentication) {
 | 
	
		
			
				|  |  | +    protected int getMaximumSessionsForThisUser(Authentication authentication) {
 | 
	
		
			
				|  |  |          return maximumSessions;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    public void registerSuccessfulAuthentication(
 | 
	
		
			
				|  |  | -            Authentication authentication) {
 | 
	
		
			
				|  |  | +    public void registerSuccessfulAuthentication(Authentication authentication) {
 | 
	
		
			
				|  |  |          Assert.notNull(authentication,
 | 
	
		
			
				|  |  | -                "Authentication cannot be null (violation of interface contract)");
 | 
	
		
			
				|  |  | +            "Authentication cannot be null (violation of interface contract)");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          Object principal = SessionRegistryUtils
 | 
	
		
			
				|  |  | -                .obtainPrincipalFromAuthentication(authentication);
 | 
	
		
			
				|  |  | +            .obtainPrincipalFromAuthentication(authentication);
 | 
	
		
			
				|  |  |          String sessionId = SessionRegistryUtils
 | 
	
		
			
				|  |  | -                .obtainSessionIdFromAuthentication(authentication);
 | 
	
		
			
				|  |  | +            .obtainSessionIdFromAuthentication(authentication);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          sessionRegistry.removeSessionInformation(sessionId);
 | 
	
		
			
				|  |  |          sessionRegistry.registerNewSession(sessionId, principal);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public void setExceptionIfMaximumExceeded(
 | 
	
		
			
				|  |  | -            boolean exceptionIfMaximumExceeded) {
 | 
	
		
			
				|  |  | +        boolean exceptionIfMaximumExceeded) {
 | 
	
		
			
				|  |  |          this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -170,8 +176,7 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
 | 
	
		
			
				|  |  |          this.messages = new MessageSourceAccessor(messageSource);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    public void setSessionRegistry(
 | 
	
		
			
				|  |  | -            SessionRegistry sessionRegistry) {
 | 
	
		
			
				|  |  | +    public void setSessionRegistry(SessionRegistry sessionRegistry) {
 | 
	
		
			
				|  |  |          this.sessionRegistry = sessionRegistry;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |