Package org.sonatype.security.usermanagement.xml

Source Code of org.sonatype.security.usermanagement.xml.SecurityXmlUserManager

/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2007-2014 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package org.sonatype.security.usermanagement.xml;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.enterprise.inject.Typed;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.sonatype.configuration.validation.InvalidConfigurationException;
import org.sonatype.security.SecuritySystem;
import org.sonatype.security.authorization.NoSuchRoleException;
import org.sonatype.security.model.CRole;
import org.sonatype.security.model.CUser;
import org.sonatype.security.model.CUserRoleMapping;
import org.sonatype.security.realms.tools.ConfigurationManager;
import org.sonatype.security.realms.tools.ConfigurationManagerAction;
import org.sonatype.security.realms.tools.NoSuchRoleMappingException;
import org.sonatype.security.usermanagement.AbstractUserManager;
import org.sonatype.security.usermanagement.DefaultUser;
import org.sonatype.security.usermanagement.NoSuchUserManagerException;
import org.sonatype.security.usermanagement.RoleIdentifier;
import org.sonatype.security.usermanagement.RoleMappingUserManager;
import org.sonatype.security.usermanagement.User;
import org.sonatype.security.usermanagement.UserManager;
import org.sonatype.security.usermanagement.UserNotFoundException;
import org.sonatype.security.usermanagement.UserSearchCriteria;
import org.sonatype.security.usermanagement.UserStatus;

import com.google.common.base.Throwables;
import org.apache.shiro.authc.credential.PasswordService;
import org.eclipse.sisu.Description;

/**
* A UserManager backed by the security.xml file. This UserManger supports all User CRUD operations.
*
* @author Brian Demers
*/
@Singleton
@Typed(UserManager.class)
@Named("default")
@Description("Default")
public class SecurityXmlUserManager
    extends AbstractUserManager
    implements RoleMappingUserManager
{
  public static final String SOURCE = "default";

  private final ConfigurationManager configuration;

  //private final SecurityConfigurationManager securityConfiguration;

  private final SecuritySystem securitySystem;

  private final PasswordService passwordService;

  @Inject
  public SecurityXmlUserManager(@Named("default") ConfigurationManager configuration,
                                SecuritySystem securitySystem,
                                PasswordService passwordService)
  {
    this.configuration = configuration;
    this.securitySystem = securitySystem;
    this.passwordService = passwordService;
  }

  protected CUser toUser(User user) {
    if (user == null) {
      return null;
    }

    CUser secUser = new CUser();

    secUser.setId(user.getUserId());
    secUser.setFirstName(user.getFirstName());
    secUser.setLastName(user.getLastName());
    secUser.setEmail(user.getEmailAddress());
    secUser.setStatus(user.getStatus().name());
    // secUser.setPassword( password )// DO NOT set the users password!

    return secUser;
  }

  protected User toUser(CUser cUser) {
    if (cUser == null) {
      return null;
    }

    DefaultUser user = new DefaultUser();

    user.setUserId(cUser.getId());
    user.setFirstName(cUser.getFirstName());
    user.setLastName(cUser.getLastName());
    user.setEmailAddress(cUser.getEmail());
    user.setSource(SOURCE);
    user.setStatus(UserStatus.valueOf(cUser.getStatus()));

    try {
      user.setRoles(this.getUsersRoles(cUser.getId(), SOURCE));
    }
    catch (UserNotFoundException e) {
      // We should NEVER get here
      this.log.warn("Could not find user: '" + cUser.getId() + "' of source: '" + SOURCE
          + "' while looking up the users roles.", e);
    }

    return user;
  }

  protected RoleIdentifier toRole(String roleId) {
    if (roleId == null) {
      return null;
    }

    try {
      CRole role = configuration.readRole(roleId);

      RoleIdentifier roleIdentifier = new RoleIdentifier(SOURCE, role.getId());
      return roleIdentifier;
    }
    catch (NoSuchRoleException e) {
      return null;
    }
  }

  public Set<User> listUsers() {
    Set<User> users = new HashSet<User>();

    for (CUser user : configuration.listUsers()) {
      users.add(toUser(user));
    }

    return users;
  }

  public Set<String> listUserIds() {
    Set<String> userIds = new HashSet<String>();

    for (CUser user : configuration.listUsers()) {
      userIds.add(user.getId());
    }

    return userIds;
  }

  public User getUser(String userId)
      throws UserNotFoundException
  {
    User user = toUser(configuration.readUser(userId));
    return user;
  }

  public String getSource() {
    return SOURCE;
  }

  public boolean supportsWrite() {
    return true;
  }

  public User addUser(final User user, String password)
      throws InvalidConfigurationException
  {
    final CUser secUser = this.toUser(user);
    secUser.setPassword(this.hashPassword(password));

    try {
      this.configuration.runWrite(new ConfigurationManagerAction()
      {
        public void run() throws Exception {
          configuration.createUser(secUser, getRoleIdsFromUser(user));
          saveConfiguration();
        }
      });
    }
    catch (Exception e) {
      Throwables.propagateIfPossible(e, InvalidConfigurationException.class);
      throw Throwables.propagate(e);
    }

    // TODO: i am starting to feel we shouldn't return a user.
    return user;
  }

  public void changePassword(final String userId, final String newPassword)
      throws UserNotFoundException, InvalidConfigurationException
  {
    try {
      this.configuration.runWrite(new ConfigurationManagerAction()
      {
        public void run() throws Exception {
          final CUser secUser = configuration.readUser(userId);
          secUser.setPassword(hashPassword(newPassword));
          configuration.updateUser(secUser);
          saveConfiguration();
        }
      });
    }
    catch (Exception e) {
      Throwables.propagateIfPossible(e, UserNotFoundException.class, InvalidConfigurationException.class);
      throw Throwables.propagate(e);
    }
  }

  public User updateUser(final User user)
      throws UserNotFoundException, InvalidConfigurationException
  {
    try {
      this.configuration.runWrite(new ConfigurationManagerAction()
      {
        public void run() throws Exception {
          // we need to pull the users password off off the old user object
          CUser oldSecUser = configuration.readUser(user.getUserId());
          CUser newSecUser = toUser(user);
          newSecUser.setPassword(oldSecUser.getPassword());

          configuration.updateUser(newSecUser, getRoleIdsFromUser(user));
          saveConfiguration();
        }
      });
      return user;
    }
    catch (Exception e) {
      Throwables.propagateIfPossible(e, UserNotFoundException.class, InvalidConfigurationException.class);
      throw Throwables.propagate(e);
    }
  }

  public void deleteUser(final String userId)
      throws UserNotFoundException
  {
    try {
      this.configuration.runWrite(new ConfigurationManagerAction()
      {
        public void run() throws Exception {
          configuration.deleteUser(userId);
          saveConfiguration();
        }
      });
    }
    catch (Exception e) {
      Throwables.propagateIfPossible(e, UserNotFoundException.class);
      throw Throwables.propagate(e);
    }
  }

  public Set<RoleIdentifier> getUsersRoles(final String userId, final String source)
      throws UserNotFoundException
  {
    final Set<RoleIdentifier> roles = new HashSet<RoleIdentifier>();

    try {
      this.configuration.runRead(new ConfigurationManagerAction()
      {
        public void run() throws Exception {
          CUserRoleMapping roleMapping;
          try {
            roleMapping = configuration.readUserRoleMapping(userId, source);
            if (roleMapping != null) {
              for (String roleId : (List<String>) roleMapping.getRoles()) {
                RoleIdentifier role = toRole(roleId);
                if (role != null) {
                  roles.add(role);
                }
              }
            }
          }
          catch (NoSuchRoleMappingException e) {
            log.debug("No user role mapping found for user: " + userId);
          }
        }
      });
    }
    catch (Exception e) {
      Throwables.propagateIfPossible(e, UserNotFoundException.class);
      throw Throwables.propagate(e);
    }

    return roles;
  }

  private void saveConfiguration() {
    this.configuration.save();
  }

  public Set<User> searchUsers(final UserSearchCriteria criteria) {
    final Set<User> users = new HashSet<User>();

    try {
      this.configuration.runRead(new ConfigurationManagerAction()
      {
        public void run() throws Exception {
          users.addAll(filterListInMemeory(listUsers(), criteria));

          // we also need to search through the user role mappings.

          List<CUserRoleMapping> roleMappings = configuration.listUserRoleMappings();
          for (CUserRoleMapping roleMapping : roleMappings) {
            if (!SOURCE.equals(roleMapping.getSource())) {
              if (matchesCriteria(roleMapping.getUserId(), roleMapping.getSource(), roleMapping.getRoles(),
                  criteria)) {
                try {
                  User user = getSecuritySystem().getUser(roleMapping.getUserId(), roleMapping.getSource());
                  users.add(user);
                }
                catch (UserNotFoundException e) {
                  log.debug("User: '" + roleMapping.getUserId() + "' of source: '"
                      + roleMapping.getSource() + "' could not be found.", e);
                }
                catch (NoSuchUserManagerException e) {
                  log.warn("User: '" + roleMapping.getUserId() + "' of source: '"
                      + roleMapping.getSource() + "' could not be found.", e);
                }

              }
            }
          }
        }
      });
    }
    catch (Exception e) {
      throw Throwables.propagate(e);
    }

    return users;
  }

  private SecuritySystem getSecuritySystem() {
    return this.securitySystem;
  }

  private String hashPassword(String clearPassword) {
    // set the password if its not null
    if (clearPassword != null && clearPassword.trim().length() > 0) {
      return this.passwordService.encryptPassword(clearPassword);
    }

    return clearPassword;
  }

  public void setUsersRoles(final String userId, final String userSource, final Set<RoleIdentifier> roleIdentifiers)
      throws UserNotFoundException, InvalidConfigurationException
  {
    try {
      this.configuration.runWrite(new ConfigurationManagerAction()
      {
        public void run() throws Exception {
          // delete if no roleIdentifiers
          if (roleIdentifiers == null || roleIdentifiers.isEmpty()) {
            try {
              configuration.deleteUserRoleMapping(userId, userSource);
            }
            catch (NoSuchRoleMappingException e) {
              log.debug("User role mapping for user: " + userId + " source: " + userSource
                  + " could not be deleted because it does not exist.");
            }
          }
          else {
            CUserRoleMapping roleMapping = new CUserRoleMapping();
            roleMapping.setUserId(userId);
            roleMapping.setSource(userSource);

            for (RoleIdentifier roleIdentifier : roleIdentifiers) {
              // make sure we only save roles that we manage
              // TODO: although we shouldn't need to worry about this.
              if (getSource().equals(roleIdentifier.getSource())) {
                roleMapping.addRole(roleIdentifier.getRoleId());
              }
            }

            // try to update first
            try {
              configuration.updateUserRoleMapping(roleMapping);
            }
            catch (NoSuchRoleMappingException e) {
              // update failed try create
              log.debug("Update of user role mapping for user: " + userId + " source: " + userSource
                  + " did not exist, creating new one.");
              configuration.createUserRoleMapping(roleMapping);
            }
          }

          // save the config
          saveConfiguration();
        }
      });
    }
    catch (Exception e) {
      Throwables.propagateIfPossible(e, UserNotFoundException.class, InvalidConfigurationException.class);
      throw Throwables.propagate(e);
    }
  }

  public String getAuthenticationRealmName() {
    return "XmlAuthenticatingRealm";
  }

  private Set<String> getRoleIdsFromUser(User user) {
    Set<String> roles = new HashSet<String>();
    for (RoleIdentifier roleIdentifier : user.getRoles()) {
      // TODO: should we just grab the Default roles?
      // these users are managed by this realm so they should ONLY have roles from it anyway.
      roles.add(roleIdentifier.getRoleId());
    }
    return roles;
  }
}
TOP

Related Classes of org.sonatype.security.usermanagement.xml.SecurityXmlUserManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.