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.user;
 
 import java.util.List;
 import java.util.Map;
 
 
 
This class manages the available users.

Author(s):
Philip Helger
 
 public class UserManager extends AbstractSimpleDAO implements IUserManagerIReloadableDAO
 {
   public static final boolean DEFAULT_CREATE_DEFAULTS = true;
 
   private static final Logger s_aLogger = LoggerFactory.getLogger (UserManager.class);
   private static final ReadWriteLock s_aRWLock = new ReentrantReadWriteLock ();
 
   @GuardedBy ("s_aRWLock")
   private static boolean s_bCreateDefaults = ;
 
   @GuardedBy ("m_aRWLock")
   private final Map <StringUserm_aUsers = new HashMap <StringUser> ();
 
 
   public static boolean isCreateDefaults ()
   {
     .readLock ().lock ();
     try
     {
       return ;
     }
     finally
     {
       .readLock ().unlock ();
     }
   }
 
   public static void setCreateDefaults (final boolean bCreateDefaults)
   {
     .writeLock ().lock ();
     try
     {
        = bCreateDefaults;
     }
     finally
     {
       .writeLock ().unlock ();
     }
  }
  public UserManager (@Nonnull @Nonempty final String sFilenamethrows DAOException
  {
    super (sFilename);
    initialRead ();
  }
  public void reload () throws DAOException
  {
    .writeLock ().lock ();
    try
    {
      .clear ();
      initialRead ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
  }
  protected EChange onInit ()
  {
    if (!isCreateDefaults ())
      return .;
    // Create Administrator
                        .,
                        .,
                        GlobalPasswordSettings.createUserDefaultPasswordHash (.),
                        .,
                        (Stringnull,
                        (Localenull,
                        (Map <StringString>) null,
                        false));
    // Create regular user
                        .,
                        .,
                        GlobalPasswordSettings.createUserDefaultPasswordHash (.),
                        .,
                        (Stringnull,
                        (Localenull,
                        (Map <StringString>) null,
                        false));
    // Create guest user
                        .,
                        .,
                        GlobalPasswordSettings.createUserDefaultPasswordHash (.),
                        .,
                        (Stringnull,
                        (Localenull,
                        (Map <StringString>) null,
                        false));
    return .;
  }
  protected EChange onRead (@Nonnull final IMicroDocument aDoc)
  {
    for (final IMicroElement eUser : aDoc.getDocumentElement ().getAllChildElements ())
      _addUser (MicroTypeConverter.convertToNative (eUserUser.class));
    return .;
  }
  {
    final IMicroDocument aDoc = new MicroDocument ();
    final IMicroElement eRoot = aDoc.appendElement ("users");
    for (final User aUser : ContainerHelper.getSortedByKey ().values ())
      eRoot.appendChild (MicroTypeConverter.convertToMicroElement (aUser"user"));
    return aDoc;
  }
  @ReturnsMutableObject (reason = "design")
  {
    return ;
  }
  private void _addUser (@Nonnull final User aUser)
  {
    final String sUserID = aUser.getID ();
    if (.containsKey (sUserID))
      throw new IllegalArgumentException ("User ID " + sUserID + " is already in use!");
    .put (sUserIDaUser);
  }
  public IUser createNewUser (@Nonnull @Nonempty final String sLoginName,
                              @Nullable final String sEmailAddress,
                              @Nonnull final String sPlainTextPassword,
                              @Nullable final String sFirstName,
                              @Nullable final String sLastName,
                              @Nullable final Locale aDesiredLocale,
                              @Nullable final Map <String, ?> aCustomAttrs,
                              final boolean bDisabled)
  {
    ValueEnforcer.notEmpty (sLoginName"LoginName");
    ValueEnforcer.notNull (sPlainTextPassword"PlainTextPassword");
    if (getUserOfLoginName (sLoginName) != null)
    {
      // Another user with this login name already exists
      AuditUtils.onAuditCreateFailure (."login-name-already-in-use"sLoginName);
      return null;
    }
    // Create user
    final User aUser = new User (sLoginName,
                                 sEmailAddress,
                                 GlobalPasswordSettings.createUserDefaultPasswordHash (sPlainTextPassword),
                                 sFirstName,
                                 sLastName,
                                 aDesiredLocale,
                                 aCustomAttrs,
                                 bDisabled);
    .writeLock ().lock ();
    try
    {
      _addUser (aUser);
      markAsChanged ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
                                     aUser.getID (),
                                     sLoginName,
                                     sEmailAddress,
                                     sFirstName,
                                     sLastName,
                                     StringHelper.getToString (aDesiredLocale),
                                     StringHelper.getToString (aCustomAttrs),
                                     Boolean.toString (bDisabled));
    // Execute callback as the very last action
    for (final IUserModificationCallback aUserCallback : .getAllCallbacks ())
      try
      {
        aUserCallback.onUserCreated (aUserfalse);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserCreated callback on " + aUser.toString (), t);
      }
    return aUser;
  }
  public IUser createPredefinedUser (@Nonnull @Nonempty final String sID,
                                     @Nonnull @Nonempty final String sLoginName,
                                     @Nullable final String sEmailAddress,
                                     @Nonnull final String sPlainTextPassword,
                                     @Nullable final String sFirstName,
                                     @Nullable final String sLastName,
                                     @Nullable final Locale aDesiredLocale,
                                     @Nullable final Map <String, ?> aCustomAttrs,
                                     final boolean bDisabled)
  {
    ValueEnforcer.notEmpty (sLoginName"LoginName");
    ValueEnforcer.notNull (sPlainTextPassword"PlainTextPassword");
    if (getUserOfLoginName (sLoginName) != null)
    {
      // Another user with this login name already exists
      AuditUtils.onAuditCreateFailure (."login-name-already-in-use"sLoginName"predefined-user");
      return null;
    }
    // Create user
    final User aUser = new User (sID,
                                 sLoginName,
                                 sEmailAddress,
                                 GlobalPasswordSettings.createUserDefaultPasswordHash (sPlainTextPassword),
                                 sFirstName,
                                 sLastName,
                                 aDesiredLocale,
                                 aCustomAttrs,
                                 bDisabled);
    .writeLock ().lock ();
    try
    {
      _addUser (aUser);
      markAsChanged ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
                                     aUser.getID (),
                                     "predefined-user",
                                     sLoginName,
                                     sEmailAddress,
                                     sFirstName,
                                     sLastName,
                                     StringHelper.getToString (aDesiredLocale),
                                     StringHelper.getToString (aCustomAttrs),
                                     Boolean.toString (bDisabled));
    // Execute callback as the very last action
    for (final IUserModificationCallback aUserCallback : .getAllCallbacks ())
      try
      {
        aUserCallback.onUserCreated (aUsertrue);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserCreated callback on " + aUser.toString (), t);
      }
    return aUser;
  }
  public boolean containsUserWithID (@Nullable final String sUserID)
  {
    .readLock ().lock ();
    try
    {
      return .containsKey (sUserID);
    }
    finally
    {
      .readLock ().unlock ();
    }
  }
  public User getUserOfID (@Nullable final String sUserID)
  {
    if (StringHelper.hasNoText (sUserID))
      return null;
    .readLock ().lock ();
    try
    {
      return .get (sUserID);
    }
    finally
    {
      .readLock ().unlock ();
    }
  }
  public IUser getUserOfLoginName (@Nullable final String sLoginName)
  {
    if (StringHelper.hasNoText (sLoginName))
      return null;
    .readLock ().lock ();
    try
    {
      for (final User aUser : .values ())
        if (aUser.getLoginName ().equals (sLoginName))
          return aUser;
      return null;
    }
    finally
    {
      .readLock ().unlock ();
    }
  }
  public IUser getUserOfEmailAddress (@Nullable final String sEmailAddress)
  {
    if (StringHelper.hasNoText (sEmailAddress))
      return null;
    .readLock ().lock ();
    try
    {
      for (final User aUser : .values ())
        if (sEmailAddress.equals (aUser.getEmailAddress ()))
          return aUser;
      return null;
    }
    finally
    {
      .readLock ().unlock ();
    }
  }
  public List <UsergetAllUsers ()
  {
    .readLock ().lock ();
    try
    {
      return ContainerHelper.newList (.values ());
    }
    finally
    {
      .readLock ().unlock ();
    }
  }
  public List <UsergetAllActiveUsers ()
  {
    .readLock ().lock ();
    try
    {
      final List <Userret = new ArrayList <User> ();
      for (final User aUser : .values ())
        if (!aUser.isDeleted () && aUser.isEnabled ())
          ret.add (aUser);
      return ret;
    }
    finally
    {
      .readLock ().unlock ();
    }
  }
  public List <UsergetAllDisabledUsers ()
  {
    .readLock ().lock ();
    try
    {
      final List <Userret = new ArrayList <User> ();
      for (final User aUser : .values ())
        if (!aUser.isDeleted () && aUser.isDisabled ())
          ret.add (aUser);
      return ret;
    }
    finally
    {
      .readLock ().unlock ();
    }
  }
  public List <UsergetAllNotDeletedUsers ()
  {
    .readLock ().lock ();
    try
    {
      final List <Userret = new ArrayList <User> ();
      for (final User aUser : .values ())
        if (!aUser.isDeleted ())
          ret.add (aUser);
      return ret;
    }
    finally
    {
      .readLock ().unlock ();
    }
  }
  public List <UsergetAllDeletedUsers ()
  {
    .readLock ().lock ();
    try
    {
      final List <Userret = new ArrayList <User> ();
      for (final User aUser : .values ())
        if (aUser.isDeleted ())
          ret.add (aUser);
      return ret;
    }
    finally
    {
      .readLock ().unlock ();
    }
  }
  public EChange setUserData (@Nullable final String sUserID,
                              @Nonnull @Nonempty final String sNewLoginName,
                              @Nullable final String sNewEmailAddress,
                              @Nullable final String sNewFirstName,
                              @Nullable final String sNewLastName,
                              @Nullable final Locale aNewDesiredLocale,
                              @Nullable final Map <String, ?> aNewCustomAttrs,
                              final boolean bNewDisabled)
  {
    // Resolve user
    final User aUser = getUserOfID (sUserID);
    if (aUser == null)
    {
      AuditUtils.onAuditModifyFailure (.sUserID"no-such-user-id");
      return .;
    }
    .writeLock ().lock ();
    try
    {
      EChange eChange = aUser.setLoginName (sNewLoginName);
      eChange = eChange.or (aUser.setEmailAddress (sNewEmailAddress));
      eChange = eChange.or (aUser.setFirstName (sNewFirstName));
      eChange = eChange.or (aUser.setLastName (sNewLastName));
      eChange = eChange.or (aUser.setDesiredLocale (aNewDesiredLocale));
      eChange = eChange.or (aUser.setAttributes (aNewCustomAttrs));
      eChange = eChange.or (aUser.setDisabled (bNewDisabled));
      if (eChange.isUnchanged ())
        return .;
      aUser.updateLastModified ();
      markAsChanged ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
                                     "all",
                                     aUser.getID (),
                                     sNewLoginName,
                                     sNewEmailAddress,
                                     sNewFirstName,
                                     sNewLastName,
                                     StringHelper.getToString (aNewDesiredLocale),
                                     StringHelper.getToString (aNewCustomAttrs),
                                     Boolean.toString (bNewDisabled));
    // Execute callback as the very last action
    for (final IUserModificationCallback aUserCallback : .getAllCallbacks ())
      try
      {
        aUserCallback.onUserUpdated (aUser);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserUpdated callback on " + aUser.toString (), t);
      }
    return .;
  }
  public EChange setUserPassword (@Nullable final String sUserID, @Nonnull final String sNewPlainTextPassword)
  {
    // Resolve user
    final User aUser = getUserOfID (sUserID);
    if (aUser == null)
    {
      AuditUtils.onAuditModifyFailure (.sUserID"no-such-user-id""password");
      return .;
    }
    final PasswordHash aPasswordHash = GlobalPasswordSettings.createUserDefaultPasswordHash (sNewPlainTextPassword);
    .writeLock ().lock ();
    try
    {
      final EChange eChange = aUser.setPasswordHash (aPasswordHash);
      if (eChange.isUnchanged ())
        return .;
      aUser.updateLastModified ();
      markAsChanged ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
    AuditUtils.onAuditModifySuccess (."password"sUserID);
    // Execute callback as the very last action
    for (final IUserModificationCallback aUserCallback : .getAllCallbacks ())
      try
      {
        aUserCallback.onUserPasswordChanged (aUser);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserPasswordChanged callback on " + aUser.toString (), t);
      }
    return .;
  }
  public EChange updateUserLastLogin (@Nullable final String sUserID)
  {
    // Resolve user
    final User aUser = getUserOfID (sUserID);
    if (aUser == null)
    {
      AuditUtils.onAuditModifyFailure (.sUserID"no-such-user-id""update-last-login");
      return .;
    }
    .writeLock ().lock ();
    try
    {
      aUser.onSuccessfulLogin ();
      markAsChanged ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
    AuditUtils.onAuditModifySuccess (."update-last-login"sUserID);
    return .;
  }
  public EChange updateUserLastFailedLogin (@Nullable final String sUserID)
  {
    // Resolve user
    final User aUser = getUserOfID (sUserID);
    if (aUser == null)
    {
      AuditUtils.onAuditModifyFailure (.sUserID"no-such-user-id""update-last-failed-login");
      return .;
    }
    .writeLock ().lock ();
    try
    {
      aUser.onFailedLogin ();
      markAsChanged ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
    AuditUtils.onAuditModifySuccess (."update-last-failed-login"sUserID);
    // Execute callback as the very last action
    for (final IUserModificationCallback aUserCallback : .getAllCallbacks ())
      try
      {
        aUserCallback.onUserLastFailedLoginUpdated (aUser);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserLastFailedLoginUpdated callback on " + aUser.toString (), t);
      }
    return .;
  }
  public EChange deleteUser (@Nullable final String sUserID)
  {
    final User aUser = getUserOfID (sUserID);
    if (aUser == null)
    {
      AuditUtils.onAuditDeleteFailure (.sUserID"no-such-user-id");
      return .;
    }
    .writeLock ().lock ();
    try
    {
      if (aUser.setDeleted (true).isUnchanged ())
        return .;
      markAsChanged ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
    AuditUtils.onAuditDeleteSuccess (.sUserID);
    // Execute callback as the very last action
    for (final IUserModificationCallback aUserCallback : .getAllCallbacks ())
      try
      {
        aUserCallback.onUserDeleted (aUser);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserDeleted callback on " + aUser.toString (), t);
      }
    return .;
  }
  public EChange undeleteUser (@Nullable final String sUserID)
  {
    final User aUser = getUserOfID (sUserID);
    if (aUser == null)
    {
      AuditUtils.onAuditUndeleteFailure (.sUserID"no-such-user-id");
      return .;
    }
    .writeLock ().lock ();
    try
    {
      if (aUser.setDeleted (false).isUnchanged ())
        return .;
      markAsChanged ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
    AuditUtils.onAuditUndeleteSuccess (.sUserID);
    // Execute callback as the very last action
    for (final IUserModificationCallback aUserCallback : .getAllCallbacks ())
      try
      {
        aUserCallback.onUserUndeleted (aUser);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserUndeleted callback on " + aUser.toString (), t);
      }
    return .;
  }
  public EChange disableUser (@Nullable final String sUserID)
  {
    final User aUser = getUserOfID (sUserID);
    if (aUser == null)
    {
      AuditUtils.onAuditModifyFailure (.sUserID"no-such-user-id""disable");
      return .;
    }
    .writeLock ().lock ();
    try
    {
      if (aUser.setDisabled (true).isUnchanged ())
        return .;
      markAsChanged ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
    AuditUtils.onAuditModifySuccess (."disable"sUserID);
    // Execute callback as the very last action
    for (final IUserModificationCallback aUserCallback : .getAllCallbacks ())
      try
      {
        aUserCallback.onUserEnabled (aUserfalse);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserEnabled callback on " + aUser.toString (), t);
      }
    return .;
  }
  public EChange enableUser (@Nullable final String sUserID)
  {
    final User aUser = getUserOfID (sUserID);
    if (aUser == null)
    {
      AuditUtils.onAuditModifyFailure (.sUserID"no-such-user-id""enable");
      return .;
    }
    .writeLock ().lock ();
    try
    {
      if (aUser.setDisabled (false).isUnchanged ())
        return .;
      markAsChanged ();
    }
    finally
    {
      .writeLock ().unlock ();
    }
    AuditUtils.onAuditModifySuccess (."enable"sUserID);
    // Execute callback as the very last action
    for (final IUserModificationCallback aUserCallback : .getAllCallbacks ())
      try
      {
        aUserCallback.onUserEnabled (aUsertrue);
      }
      catch (final Throwable t)
      {
        .error ("Failed to invoke onUserEnabled callback on " + aUser.toString (), t);
      }
    return .;
  }
  public boolean areUserIDAndPasswordValid (@Nullable final String sUserID, @Nullable final String sPlainTextPassword)
  {
    // No password is not allowed
    if (sPlainTextPassword == null)
      return false;
    // Is there such a user?
    final IUser aUser = getUserOfID (sUserID);
    if (aUser == null)
      return false;
    // Now compare the hashes
    final String sPasswordHashAlgorithm = aUser.getPasswordHash ().getAlgorithmName ();
    final PasswordHash aPasswordHash = GlobalPasswordSettings.createUserPasswordHash (sPasswordHashAlgorithm,
                                                                                      sPlainTextPassword);
    return aUser.getPasswordHash ().equals (aPasswordHash);
  }
New to GrepCode? Check out our FAQ X