Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (C) 2014 Philip Helger (www.helger.com) philip[at]helger[dot]com Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 
 package com.helger.appbasics.security.login;
 
 import java.util.Map;
 import java.util.Set;
 
 
 
This class manages all logged-in users.

Author(s):
Philip Helger
 
 public final class LoggedInUserManager extends GlobalSingleton implements ICurrentUserIDProvider
 {
  
This class manages the user ID of the current session. This is an internal class and should not be used from the outside!

Author(s):
Philip Helger
 
   public static final class SessionUserHolder extends SessionWebSingleton implements ISessionWebScopeActivationHandler
   {
     private static final long serialVersionUID = 2322897734799334L;
 
     private transient IUser m_aUser;
     private String m_sUserID;
     private transient LoggedInUserManager m_aOwningMgr;
 
     @Deprecated
     public SessionUserHolder ()
     {}

    

Returns:
The instance of the current session. If none exists, an instance is created. Never null.
 
     @Nonnull
     static SessionUserHolder getInstance ()
     {
       return getSessionSingleton (SessionUserHolder.class);
     }

    

Returns:
The instance of the current session. If none exists, null is returned.
 
    @Nullable
    {
    }
    @Nullable
    {
      return getSingletonIfInstantiated (aScopeSessionUserHolder.class);
    }
    private void readObject (@Nonnull final ObjectInputStream aOISthrows IOExceptionClassNotFoundException
    {
      aOIS.defaultReadObject ();
      // Resolve user ID
      if ( != null)
      {
         = AccessManager.getInstance ().getUserOfID ();
        if ( == null)
          throw new IllegalStateException ("Failed to resolve user with ID '" +  + "'");
      }
      // Resolve manager
       = LoggedInUserManager.getInstance ();
    }
    public void onSessionDidActivate (@Nonnull final ISessionWebScope aSessionScope)
    {
      // Finally remember that the user is logged in
      .internalSessionActivateUser (aSessionScope);
    }
    boolean hasUser ()
    {
      return  != null;
    }
    @Nullable
    String getUserID ()
    {
      return ;
    }
    void setUser (@Nonnull final LoggedInUserManager aOwningMgr, @Nonnull final IUser aUser)
    {
      ValueEnforcer.notNull (aOwningMgr"OwningMgr");
      ValueEnforcer.notNull (aUser"User");
      if ( != null)
        throw new IllegalStateException ("Session already has a user!");
       = aOwningMgr;
       = aUser;
       = aUser.getID ();
    }
    void _reset ()
    {
      // Reset to avoid access while or after logout
       = null;
       = null;
       = null;
    }
    @Override
    protected void onDestroy (@Nonnull final IScope aScopeInDestruction)
    {
      // Called when the session is destroyed
      // -> Ensure the user is logged out!
      // Remember stuff
      final LoggedInUserManager aOwningMgr = ;
      final String sUserID = ;
      _reset ();
      // Finally logout the user
      if (aOwningMgr != null)
        aOwningMgr.logoutUser (sUserID);
    }
    @Override
    public String toString ()
    {
      return ToStringGenerator.getDerived (super.toString ()).append ("userID").toString ();
    }
  }
  public static final boolean DEFAULT_LOGOUT_ALREADY_LOGGED_IN_USER = false;
  private static final Logger s_aLogger = LoggerFactory.getLogger (LoggedInUserManager.class);
  private final ReadWriteLock m_aRWLock = new ReentrantReadWriteLock ();
  // Set of logged in user IDs
  @GuardedBy ("m_aRWLock")
  private final Map <StringLoginInfom_aLoggedInUsers = new HashMap <StringLoginInfo> ();
  public LoggedInUserManager ()
  {
    // Ensure that all objects of a user are unlocked upon logout
  }

  

Returns:
The global instance of this class. Never null.
  public static LoggedInUserManager getInstance ()
  {
    return getGlobalSingleton (LoggedInUserManager.class);
  }

  

Returns:
The user login callback list. Never null.
  @ReturnsMutableObject (reason = "design")
  {
    return ;
  }

  

Returns:
The user logout callback list. Never null.
  @ReturnsMutableObject (reason = "design")
  {
    return ;
  }
  public boolean isLogoutAlreadyLoggedInUser ()
  {
    .readLock ().lock ();
    try
    {
      return ;
    }
    finally
    {
      .readLock ().unlock ();
    }
  }
  public void setLogoutAlreadyLoggedInUser (final boolean bLogoutAlreadyLoggedInUser)
  {
    .writeLock ().lock ();
    try
    {
       = bLogoutAlreadyLoggedInUser;
    }
    finally
    {
      .writeLock ().unlock ();
    }
  }

  
Login the passed user without much ado.

Parameters:
sLoginName Login name of the user to log-in. May be null.
sPlainTextPassword Plain text password to use. May be null.
Returns:
Never null login status.
  public ELoginResult loginUser (@Nullable final String sLoginName, @Nullable final String sPlainTextPassword)
  {
    return loginUser (sLoginNamesPlainTextPassword, (Collection <String>) null);
  }

  
Login the passed user and require a set of certain roles, the used needs to have to login here.

Parameters:
sLoginName Login name of the user to log-in. May be null.
sPlainTextPassword Plain text password to use. May be null.
aRequiredRoleIDs A set of required role IDs, the user needs to have. May be null.
Returns:
Never null login status.
  public ELoginResult loginUser (@Nullable final String sLoginName,
                                 @Nullable final String sPlainTextPassword,
                                 @Nullable final Collection <StringaRequiredRoleIDs)
  {
    // Try to resolve the user
    final IUser aUser = AccessManager.getInstance ().getUserOfLoginName (sLoginName);
    if (aUser == null)
    {
      AuditUtils.onAuditExecuteFailure ("login"sLoginName"no-such-loginname");
      return .;
    }
    return loginUser (aUsersPlainTextPasswordaRequiredRoleIDs);
  }
  private ELoginResult _onLoginError (@Nonnull @Nonempty final String sUserID, @Nonnull final ELoginResult eLoginResult)
  {
    for (final IUserLoginCallback aUserLoginCallback : .getAllCallbacks ())
      try
      {
        aUserLoginCallback.onUserLoginError (sUserIDeLoginResult);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserLoginError callback on " +
                         aUserLoginCallback +
                         "(" +
                         sUserID +
                         "," +
                         eLoginResult.toString () +
                         ")"t);
      }
    return eLoginResult;
  }
  final void internalSessionActivateUser (@Nonnull final IUser aUser, @Nonnull final ISessionScope aSessionScope)
  {
    ValueEnforcer.notNull (aUser"User");
    ValueEnforcer.notNull (aSessionScope"SessionScope");
    .writeLock ().lock ();
    try
    {
      final LoginInfo aInfo = new LoginInfo (aUseraSessionScope);
      .put (aUser.getID (), aInfo);
    }
    finally
    {
      .writeLock ().unlock ();
    }
  }

  
Login the passed user and require a set of certain roles, the used needs to have to login here.

Parameters:
aUser The user to log-in. May be null. When the user is null the login must fail.
sPlainTextPassword Plain text password to use. May be null.
aRequiredRoleIDs A set of required role IDs, the user needs to have. May be null.
Returns:
Never null login status.
  public ELoginResult loginUser (@Nullable final IUser aUser,
                                 @Nullable final String sPlainTextPassword,
                                 @Nullable final Collection <StringaRequiredRoleIDs)
  {
    if (aUser == null)
      return .;
    final String sUserID = aUser.getID ();
    // Deleted user?
    if (aUser.isDeleted ())
    {
      AuditUtils.onAuditExecuteFailure ("login"sUserID"user-is-deleted");
      return _onLoginError (sUserID.);
    }
    // Disabled user?
    if (aUser.isDisabled ())
    {
      AuditUtils.onAuditExecuteFailure ("login"sUserID"user-is-disabled");
      return _onLoginError (sUserID.);
    }
    final AccessManager aAccessMgr = AccessManager.getInstance ();
    // Are all roles present?
    if (!aAccessMgr.hasUserAllRoles (sUserIDaRequiredRoleIDs))
    {
      AuditUtils.onAuditExecuteFailure ("login",
                                        sUserID,
                                        "user-is-missing-required-roles",
                                        StringHelper.getToString (aRequiredRoleIDs));
      return _onLoginError (sUserID.);
    }
    // Check the password
    if (!aAccessMgr.areUserIDAndPasswordValid (sUserIDsPlainTextPassword))
    {
      AuditUtils.onAuditExecuteFailure ("login"sUserID"invalid-password");
      return _onLoginError (sUserID.);
    }
    boolean bLoggedOutUser = false;
    LoginInfo aInfo;
    .writeLock ().lock ();
    try
    {
      if (.containsKey (sUserID))
      {
        // The user is already logged in
        if (isLogoutAlreadyLoggedInUser ())
        {
          // Explicitly log out
          logoutUser (sUserID);
          // Just a short check
          if (.containsKey (sUserID))
            throw new IllegalStateException ("Failed to logout '" + sUserID + "'");
          AuditUtils.onAuditExecuteSuccess ("logout-in-login"sUserID);
          bLoggedOutUser = true;
        }
        else
        {
          AuditUtils.onAuditExecuteFailure ("login"sUserID"user-already-logged-in");
          return _onLoginError (sUserID.);
        }
      }
      final SessionUserHolder aSUH = SessionUserHolder.getInstance ();
      if (aSUH.hasUser ())
      {
        // This session already has a user
        .warn ("The session user holder already has the user ID '" +
                        aSUH.getUserID () +
                        "' so the new ID '" +
                        sUserID +
                        "' will not be set!");
        AuditUtils.onAuditExecuteFailure ("login"sUserID"session-already-has-user");
        return _onLoginError (sUserID.);
      }
      aInfo = new LoginInfo (aUser, ScopeManager.getSessionScope ());
      .put (sUserIDaInfo);
      aSUH.setUser (thisaUser);
    }
    finally
    {
      .writeLock ().unlock ();
    }
    .info ("Logged in user '" + sUserID + "' with login name '" + aUser.getLoginName () + "'");
    AuditUtils.onAuditExecuteSuccess ("login"sUserIDaUser.getLoginName ());
    // Execute callback as the very last action
    for (final IUserLoginCallback aUserLoginCallback : .getAllCallbacks ())
      try
      {
        aUserLoginCallback.onUserLogin (aInfo);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserLogin callback on " +
                             aUserLoginCallback.toString () +
                             "(" +
                             aInfo.toString () +
                             ")",
                         t);
      }
    return bLoggedOutUser ? . : .;
  }

  
Manually log out the specified user

Parameters:
sUserID The user ID to log out
Returns:
com.helger.commons.state.EChange if something changed
  public EChange logoutUser (@Nullable final String sUserID)
  {
    .writeLock ().lock ();
    LoginInfo aInfo;
    try
    {
      aInfo = .remove (sUserID);
      if (aInfo == null)
      {
        AuditUtils.onAuditExecuteSuccess ("logout"sUserID"user-not-logged-in");
        return .;
      }
      // Ensure that the SessionUser is empty. This is only relevant if user is
      // manually logged out without destructing the underlying session
      final SessionUserHolder aSUH = SessionUserHolder.getInstanceIfInstantiatedInScope (aInfo.getSessionScope ());
      if (aSUH != null)
        aSUH._reset ();
      // Set logout time - in case somebody has a strong reference to the
      // LoginInfo object
      aInfo.setLogoutDTNow ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
    .info ("Logged out user '" +
                    sUserID +
                    "' after " +
                    new Period (aInfo.getLoginDT (), aInfo.getLogoutDT ()).toString ());
    AuditUtils.onAuditExecuteSuccess ("logout"sUserID);
    // Execute callback as the very last action
    for (final IUserLogoutCallback aUserLogoutCallback : .getAllCallbacks ())
      try
      {
        aUserLogoutCallback.onUserLogout (aInfo);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserLogout callback on " +
                             aUserLogoutCallback.toString () +
                             "(" +
                             aInfo.toString () +
                             ")",
                         t);
      }
    return .;
  }

  
Manually log out the current user

Returns:
com.helger.commons.state.EChange if something changed
  public EChange logoutCurrentUser ()
  {
    return logoutUser (getCurrentUserID ());
  }

  
Check if the specified user is logged in or not

Parameters:
sUserID The user ID to check. May be null.
Returns:
true if the user is logged in, false otherwise.
  public boolean isUserLoggedIn (@Nullable final String sUserID)
  {
    .readLock ().lock ();
    try
    {
      return .containsKey (sUserID);
    }
    finally
    {
      .readLock ().unlock ();
    }
  }

  

Returns:
A non-null but maybe empty set with all currently logged in user IDs.
  public Set <StringgetAllLoggedInUserIDs ()
  {
    .readLock ().lock ();
    try
    {
      return ContainerHelper.newSet (.keySet ());
    }
    finally
    {
      .readLock ().unlock ();
    }
  }

  
Get the login details of the specified user.

Parameters:
sUserID The user ID to check. May be null.
Returns:
null if the passed user is not logged in.
  public LoginInfo getLoginInfo (@Nullable final String sUserID)
  {
    .readLock ().lock ();
    try
    {
      return .get (sUserID);
    }
    finally
    {
      .readLock ().unlock ();
    }
  }

  

Returns:
A non-null but maybe empty collection with the details of all currently logged in users.
  {
    .readLock ().lock ();
    try
    {
      return ContainerHelper.newList (.values ());
    }
    finally
    {
      .readLock ().unlock ();
    }
  }

  

Returns:
The number of currently logged in users. Always &ge; 0.
  public int getLoggedInUserCount ()
  {
    .readLock ().lock ();
    try
    {
      return .size ();
    }
    finally
    {
      .readLock ().unlock ();
    }
  }

  

Returns:
The ID of the user logged in this session or null if no user is logged in.
  public String getCurrentUserID ()
  {
    final SessionUserHolder aSUH = SessionUserHolder.getInstanceIfInstantiated ();
    return aSUH == null ? null : aSUH.m_sUserID;
  }

  

Returns:
true if a user is currently logged into this session, false otherwise.
  public boolean isUserLoggedInInCurrentSession ()
  {
    return getCurrentUserID () != null;
  }

  

Returns:
The user currently logged in this session or null if no user is logged in.
  public IUser getCurrentUser ()
  {
    final SessionUserHolder aSUH = SessionUserHolder.getInstanceIfInstantiated ();
    return aSUH == null ? null : aSUH.m_aUser;
  }

  

Returns:
true if a user is logged in and is administrator
  public boolean isCurrentUserAdministrator ()
  {
    final IUser aUser = getCurrentUser ();
    return aUser != null && aUser.isAdministrator ();
  }
  public String toString ()
  {
    return ToStringGenerator.getDerived (super.toString ())
                            .append ("loggedInUsers")
                            .append ("userLoginCallbacks")
                            .append ("userLogoutCallbacks")
                            .toString ();
  }
New to GrepCode? Check out our FAQ X