/** * Copyright (c) 2009--2016 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.redhat.rhn.frontend.xmlrpc.user; import com.redhat.rhn.FaultException; import com.redhat.rhn.common.conf.UserDefaults; import com.redhat.rhn.common.hibernate.LookupException; import com.redhat.rhn.common.localization.LocalizationService; import com.redhat.rhn.common.security.PermissionException; import com.redhat.rhn.common.util.MethodUtil; import com.redhat.rhn.common.util.StringUtil; import com.redhat.rhn.common.validator.ValidatorError; import com.redhat.rhn.domain.role.Role; import com.redhat.rhn.domain.role.RoleFactory; import com.redhat.rhn.domain.server.ManagedServerGroup; import com.redhat.rhn.domain.server.ServerGroup; import com.redhat.rhn.domain.server.ServerGroupFactory; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.domain.user.UserFactory; import com.redhat.rhn.frontend.action.common.BadParameterException; import com.redhat.rhn.frontend.xmlrpc.BaseHandler; import com.redhat.rhn.frontend.xmlrpc.DeleteUserException; import com.redhat.rhn.frontend.xmlrpc.InvalidOperationException; import com.redhat.rhn.frontend.xmlrpc.InvalidServerGroupException; import com.redhat.rhn.frontend.xmlrpc.LookupServerGroupException; import com.redhat.rhn.frontend.xmlrpc.NoSuchRoleException; import com.redhat.rhn.frontend.xmlrpc.PermissionCheckFailureException; import com.redhat.rhn.frontend.xmlrpc.UserNeverLoggedInException; import com.redhat.rhn.frontend.xmlrpc.UserNotUpdatedException; import com.redhat.rhn.manager.SatManager; import com.redhat.rhn.manager.system.ServerGroupManager; import com.redhat.rhn.manager.user.CreateUserCommand; import com.redhat.rhn.manager.user.DeleteSatAdminException; import com.redhat.rhn.manager.user.UpdateUserCommand; import com.redhat.rhn.manager.user.UserManager; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; /** * UserHandler * Corresponds to User.pm in old perl code. * @version $Rev$ * @xmlrpc.namespace user * @xmlrpc.doc User namespace contains methods to access common user functions * available from the web user interface. */ public class UserHandler extends BaseHandler { /** * Contains a mapping of details key as submitted by the call to the * {@link #setDetails(String, String, Map)} to the internal key used in the command * and domain objects. This is a band-aid to make the external API read correctly * (first_name instead of first_names) without having to refactor the entire code * base to use the singular version (for instance, User still uses first_names and * will be a significant change to refactor that). For more information, see * bugzilla 469957. */ private static final Map<String, String> USER_EDITABLE_DETAILS = new HashMap<String, String>(); static { USER_EDITABLE_DETAILS.put("first_name", "first_names"); USER_EDITABLE_DETAILS.put("first_names", "first_names"); USER_EDITABLE_DETAILS.put("last_name", "last_name"); USER_EDITABLE_DETAILS.put("email", "email"); USER_EDITABLE_DETAILS.put("prefix", "prefix"); USER_EDITABLE_DETAILS.put("password", "password"); } /** * Lists the users in the org. * @param loggedInUser The current user * @return Returns a list of userids and logins * @throws FaultException A FaultException is thrown if the loggedInUser * doesn't have permissions to list the users in their org. * * @xmlrpc.doc Returns a list of users in your organization. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.returntype * #array() * $UserSerializer * #array_end() */ public List listUsers(User loggedInUser) throws FaultException { // Get the logged in user try { List users = UserManager.usersInOrg(loggedInUser); return users; } catch (PermissionException e) { throw new PermissionCheckFailureException(); } } /** * Lists the roles for a user * @param loggedInUser The current user * @param login The login for the user you want to get the roles for * @return Returns a list of roles for the user specified by login * @throws FaultException A FaultException is thrown if the user doesn't have access * to lookup the user corresponding to login or if the user does not exist. * * @xmlrpc.doc Returns a list of the user's roles. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.returntype #array_single("string", "(role label)") */ public Object[] listRoles(User loggedInUser, String login) throws FaultException { // Get the logged in user User target = XmlRpcUserHelper.getInstance().lookupTargetUser(loggedInUser, login); List roles = new ArrayList(); //List of role labels to return //Loop through the target users roles and stick the labels into the ArrayList Set roleObjects = target.getPermanentRoles(); for (Iterator itr = roleObjects.iterator(); itr.hasNext();) { Role r = (Role) itr.next(); roles.add(r.getLabel()); } return roles.toArray(); } /** * Lists all the roles that can be assign by this user. * @param loggedInUser The current user * @return Returns a list of assignable roles for user * @throws FaultException A FaultException is thrown if the logged doesn't have access. * * @xmlrpc.doc Returns a list of user roles that this user can assign to others. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.returntype #array_single("string", "(role label)") */ public Set<String> listAssignableRoles(User loggedInUser) { return getAssignableRoles(loggedInUser); } /** * Gets details for a given user. These details include first names, last name, email, * prefix, last login date, and created on date. * @param loggedInUser The current user * @param login The login for the user you want the details for * @return Returns a Map containing the details for the given user. * @throws FaultException A FaultException is thrown if the user doesn't have access * to lookup the user corresponding to login or if the user does not exist. * * @xmlrpc.doc Returns the details about a given user. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.returntype * #struct("user details") * #prop_desc("string", "first_names", "deprecated, use first_name") * #prop("string", "first_name") * #prop("string", "last_name") * #prop("string", "email") * #prop("int", "org_id") * #prop("string", "org_name") * #prop("string", "prefix") * #prop("string", "last_login_date") * #prop("string", "created_date") * #prop_desc("boolean", "enabled", "true if user is enabled, * false if the user is disabled") * #prop_desc("boolean", "use_pam", "true if user is configured to use * PAM authentication") * #prop_desc("boolean", "read_only", "true if user is readonly") * #prop_desc("boolean", "errata_notification", "true if errata e-mail notification * is enabled for the user") * #struct_end() */ public Map getDetails(User loggedInUser, String login) throws FaultException { User target = XmlRpcUserHelper.getInstance().lookupTargetUser(loggedInUser, login); LocalizationService ls = LocalizationService.getInstance(); Map ret = new HashMap(); ret.put("first_names", StringUtils.defaultString(target.getFirstNames())); ret.put("first_name", StringUtils.defaultString(target.getFirstNames())); ret.put("last_name", StringUtils.defaultString(target.getLastName())); ret.put("email", StringUtils.defaultString(target.getEmail())); ret.put("prefix", StringUtils.defaultString(target.getPrefix())); //Last login date String lastLoggedIn = target.getLastLoggedIn() == null ? "" : ls.formatDate(target.getLastLoggedIn()); ret.put("last_login_date", lastLoggedIn); //Created date String created = target.getCreated() == null ? "" : ls.formatDate(target.getCreated()); ret.put("created_date", created); ret.put("org_id", loggedInUser.getOrg().getId()); ret.put("org_name", loggedInUser.getOrg().getName()); if (target.isDisabled()) { ret.put("enabled", Boolean.FALSE); } else { ret.put("enabled", Boolean.TRUE); } ret.put("use_pam", target.getUsePamAuthentication()); ret.put("read_only", target.isReadOnly()); ret.put("errata_notification", target.getEmailNotify() == 1); return ret; } /** * Sets the details for a given user. Settable details include: first names, * last name, email, prefix, and password. * @param loggedInUser The current user * user. * @param login The login for the user you want to edit * @param details A map containing the new details values * @return Returns 1 if edit was successful, an error is thrown otherwise * @throws FaultException A FaultException is thrown if the user doesn't * have access to lookup the user corresponding to login or if the user * does not exist. * * @xmlrpc.doc Updates the details of a user. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param * #struct("user details") * #prop_desc("string", "first_names", "deprecated, use first_name") * #prop("string", "first_name") * #prop("string", "last_name") * #prop("string", "email") * #prop("string", "prefix") * #prop("string", "password") * #struct_end() * @xmlrpc.returntype #return_int_success() */ public int setDetails(User loggedInUser, String login, Map details) throws FaultException { validateMap(USER_EDITABLE_DETAILS.keySet(), details); // Lookup user handles the logic for making sure that the loggedInUser // has access to the login they are trying to edit. User target = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); UpdateUserCommand uuc = new UpdateUserCommand(target); // Process each entry passed in by the user for (Object userKey : details.keySet()) { // Check to make sure we have an internal key mapping to prevent issues // if the user passes in cruft String internalKey = USER_EDITABLE_DETAILS.get(userKey); if (internalKey != null) { String newValue = StringUtils.defaultString((String) details.get(userKey)); prepareAttributeUpdate(internalKey, uuc, newValue); } } try { uuc.updateUser(); } catch (IllegalArgumentException iae) { throw new UserNotUpdatedException(iae.getMessage()); } // If we made it here without an exception, then we are a.o.k. return 1; } /** * Handles the vagaries related to granting or revoking sat admin role * @param loggedInUser the logged in user * @param login the login of the user who needs to be granted/revoked sat admin role * @param grant true if granting the role to the login, false for revoking... * @return 1 if it success.. Ofcourse error on failure.. */ private int modifySatAdminRole(User loggedInUser, String login, boolean grant) { ensureUserRole(loggedInUser, RoleFactory.SAT_ADMIN); SatManager manager = SatManager.getInstance(); User user = UserFactory.lookupByLogin(login); if (grant) { manager.grantSatAdminRoleTo(user, loggedInUser); } else { manager.revokeSatAdminRoleFrom(user, loggedInUser); } UserManager.storeUser(user); return 1; } /** * Returns all roles that are assignable to a given user * @return all the role labels that are assignable to a user. */ private Set<String> getAssignableRoles(User user) { Set <String> assignableRoles = new LinkedHashSet<String>(); for (Role r : UserManager.listRolesAssignableBy(user)) { assignableRoles.add(r.getLabel()); } return assignableRoles; } /** * Validates that the select roles is among the ones we support. * @param role the role that user wanted to be assigned * @param user the logged in user who wants to assign the given role. */ private void validateRoleInputs(String role, User user) { Set <String> assignableRoles = getAssignableRoles(user); if (!assignableRoles.contains(role)) { String msg = "Role with the label [%s] cannot be " + "assigned/revoked from the user." + " Possible Roles assignable/revokable by this user %s"; throw new NoSuchRoleException(String.format(msg, role, assignableRoles.toString())); } } /** * Adds a role to the given user * @param loggedInUser The current user * @param login The login for the user you would like to add the role to * @param role The role you would like to give the user * @return Returns 1 if successful (exception otherwise) * @throws FaultException A FaultException is thrown if the user doesn't have access * to lookup the user corresponding to login or if the user does not exist. * * @xmlrpc.doc Adds a role to a user. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User login name to update.") * @xmlrpc.param #param_desc("string", "role", "Role label to add. Can be any of: * satellite_admin, org_admin, channel_admin, config_admin, system_group_admin, or * activation_key_admin.") * @xmlrpc.returntype #return_int_success() */ public int addRole(User loggedInUser, String login, String role) throws FaultException { validateRoleInputs(role, loggedInUser); if (RoleFactory.SAT_ADMIN.getLabel().equals(role)) { return modifySatAdminRole(loggedInUser, login, true); } User target = XmlRpcUserHelper.getInstance().lookupTargetUser(loggedInUser, login); // Retrieve the role object corresponding to the role label passed in and // add to user Role r = RoleFactory.lookupByLabel(role); target.addPermanentRole(r); UserManager.storeUser(target); return 1; } /** * Removes a role from the given user * @param loggedInUser The current user * @param login The login for the user you would like to remove the role from * @param role The role you would like to remove from the user * @return Returns 1 if successful (exception otherwise) * @throws FaultException A FaultException is thrown if the user doesn't have access * to lookup the user corresponding to login or if the user does not exist. * * @xmlrpc.doc Remove a role from a user. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User login name to update.") * @xmlrpc.param #param_desc("string", "role", "Role label to remove. Can be any of: * satellite_admin, org_admin, channel_admin, config_admin, system_group_admin, or * activation_key_admin.") * @xmlrpc.returntype #return_int_success() */ public int removeRole(User loggedInUser, String login, String role) throws FaultException { validateRoleInputs(role, loggedInUser); if (RoleFactory.SAT_ADMIN.getLabel().equals(role)) { return modifySatAdminRole(loggedInUser, login, false); } ensureOrgAdmin(loggedInUser); User target = XmlRpcUserHelper.getInstance().lookupTargetUser(loggedInUser, login); /* * Perform some error checking here... we need to make sure that this * isn't the last org_admin in the org trying to remove org_admin * status from himself. */ if (!target.isReadOnly()) { if (role.equals(RoleFactory.ORG_ADMIN.getLabel()) && target.hasRole(RoleFactory.ORG_ADMIN) && target.getOrg().numActiveOrgAdmins() <= 1) { throw new PermissionCheckFailureException(); } } // Retrieve the role object corresponding to the role label passed in and // remove from user Role r = RoleFactory.lookupByLabel(role); target.removePermanentRole(r); UserManager.storeUser(target); return 1; } /** * Creates a new user * @param loggedInUser The current user * @param desiredLogin The login for the new user * @param desiredPassword The password for the new user * @param firstName The first name of the new user * @param lastName The last name of the new user * @param email The email address for the new user * @return Returns 1 if successful (exception otherwise) * @throws FaultException A FaultException is thrown if the loggedInUser doesn't have * permissions to create new users in thier org. * * @xmlrpc.doc Create a new user. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "desiredLogin", "Desired login name, will fail if * already in use.") * @xmlrpc.param #param("string", "desiredPassword") * @xmlrpc.param #param("string", "firstName") * @xmlrpc.param #param("string", "lastName") * @xmlrpc.param #param_desc("string", "email", "User's e-mail address.") * @xmlrpc.returntype #return_int_success() */ public int create(User loggedInUser, String desiredLogin, String desiredPassword, String firstName, String lastName, String email) throws FaultException { // If we didn't get a value for pamAuth, default to no return create(loggedInUser, desiredLogin, desiredPassword, firstName, lastName, email, new Integer(0)); } /** * Creates a new user * @param loggedInUser The current user * @param desiredLogin The login for the new user * @param desiredPassword The password for the new user * @param firstName The first name of the new user * @param lastName The last name of the new user * @param email The email address for the new user * @param usePamAuth Should this user authenticate via PAM? * @return Returns 1 if successful (exception otherwise) * @throws FaultException A FaultException is thrown if the loggedInUser doesn't have * permissions to create new users in thier org. * * @xmlrpc.doc Create a new user. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "desiredLogin", "Desired login name, * will fail if already in use.") * @xmlrpc.param #param("string", "desiredPassword") * @xmlrpc.param #param("string", "firstName") * @xmlrpc.param #param("string", "lastName") * @xmlrpc.param #param_desc("string", "email", "User's e-mail address.") * @xmlrpc.param #param_desc("int", "usePamAuth", "1 if you wish to use PAM * authentication for this user, 0 otherwise.") * @xmlrpc.returntype #return_int_success() */ public int create(User loggedInUser, String desiredLogin, String desiredPassword, String firstName, String lastName, String email, Integer usePamAuth) throws FaultException { //Logged in user must be an org admin and we must be on a sat to do this. ensureOrgAdmin(loggedInUser); ensurePasswordOrPamAuth(usePamAuth, desiredPassword); boolean pamAuth = BooleanUtils.toBoolean( usePamAuth, new Integer(1), new Integer(0)); if (pamAuth) { desiredPassword = getDefaultPasswordForPamAuth(); } CreateUserCommand command = new CreateUserCommand(); command.setUsePamAuthentication(pamAuth); command.setLogin(desiredLogin); command.setPassword(desiredPassword); command.setFirstNames(firstName); command.setLastName(lastName); command.setEmail(email); command.setOrg(loggedInUser.getOrg()); command.setCompany(loggedInUser.getCompany()); //Validate the user to be ValidatorError[] errors = command.validate(); if (errors.length > 0) { StringBuilder errorString = new StringBuilder(); LocalizationService ls = LocalizationService.getInstance(); //Build a sane error message here for (int i = 0; i < errors.length; i++) { ValidatorError err = errors[i]; errorString.append(ls.getMessage(err.getKey(), err.getValues())); if (i != errors.length - 1) { errorString.append(" :: "); } } //Throw a BadParameterException with our message string throw new BadParameterException(errorString.toString()); } command.storeNewUser(); return 1; } /** * Deletes a user * @param loggedInUser The current user * @param login The login for the user you would like to delete * @return Returns 1 if successful (exception otherwise) * @throws FaultException A FaultException is thrown if the user doesn't have access * to lookup the user corresponding to login or if the user does not exist. * * @xmlrpc.doc Delete a user. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User login name to delete.") * @xmlrpc.returntype #return_int_success() */ public int delete(User loggedInUser, String login) throws FaultException { ensureOrgAdmin(loggedInUser); User target = XmlRpcUserHelper.getInstance().lookupTargetUser(loggedInUser, login); try { UserManager.deleteUser(loggedInUser, target.getId()); } catch (DeleteSatAdminException e) { throw new DeleteUserException("user.cannot.delete.last.sat.admin"); } return 1; } /** * Disable a user * @param loggedInUser The current user * @param login The login for the user you would like to disable * @return Returns 1 if successful (exception otherwise) * @throws FaultException A FaultException is thrown if the user doesn't have access * to lookup the user corresponding to login or if the user does not exist. * * @xmlrpc.doc Disable a user. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User login name to disable.") * @xmlrpc.returntype #return_int_success() */ public int disable(User loggedInUser, String login) throws FaultException { ensureOrgAdmin(loggedInUser); User target = XmlRpcUserHelper.getInstance().lookupTargetUser(loggedInUser, login); UserManager.disableUser(loggedInUser, target); return 1; } /** * Enable a user * @param loggedInUser The current user * @param login The login for the user you would like to enable * @return Returns 1 if successful (exception otherwise) * @throws FaultException A FaultException is thrown if the user doesn't have access * to lookup the user corresponding to login or if the user does not exist. * * @xmlrpc.doc Enable a user. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User login name to enable.") * @xmlrpc.returntype #return_int_success() */ public int enable(User loggedInUser, String login) throws FaultException { ensureOrgAdmin(loggedInUser); User target = XmlRpcUserHelper.getInstance().lookupTargetUser(loggedInUser, login); UserManager.enableUser(loggedInUser, target); return 1; } /** * Toggles whether or not a user users pamAuthentication or the basic Satellite db auth. * @param loggedInUser The current user * @param login The login for the user you would like to change * @param val The value you would like to set this to (1 = true, 0 = false) * @return Returns 1 if successful (exception otherwise) * @throws FaultException A FaultException is thrown if the user doesn't have access * to lookup the user corresponding to login or if the user does not exist. * * @xmlrpc.doc Toggles whether or not a user uses PAM authentication or * basic Satellite authentication. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #param("int", "pam_value") * #options() * #item("1 to enable PAM authentication") * #item("0 to disable.") * #options_end() * @xmlrpc.returntype #return_int_success() */ public int usePamAuthentication(User loggedInUser, String login, Integer val) throws FaultException { // Only org admins can use this method. ensureOrgAdmin(loggedInUser); User target = XmlRpcUserHelper.getInstance().lookupTargetUser(loggedInUser, login); if (val.equals(new Integer(1))) { target.setUsePamAuthentication(true); } else { target.setUsePamAuthentication(false); } UserManager.storeUser(target); return 1; } private void ensurePasswordOrPamAuth(Integer usePamAuth, String password) throws FaultException { if (!BooleanUtils.toBoolean(usePamAuth, new Integer(1), new Integer(0)) && StringUtils.isEmpty(password)) { throw new FaultException(-501, "passwordRequiredOrUsePam", "Password is required if not using PAM authentication"); } } private String getDefaultPasswordForPamAuth() { // taken from line 169 of CreateUserAction // this is utter crap. We don't require a password when // we set use pam authentication, yet the password field // in the database is NOT NULL. So we have to create this // stupid HACK! Actually this is beyond HACK. return RandomStringUtils.random(UserDefaults.get().getMinPasswordLength()); } private void prepareAttributeUpdate(String attrName, UpdateUserCommand cmd, String value) { String methodName = StringUtil.beanify("set_" + attrName); Object[] params = {value}; MethodUtil.callMethod(cmd, methodName, params); } /** * Add ServerGroup to the list of Default System groups. The ServerGroup * <strong>MUST</strong> exist otherwise a IllegalArgumentException is * thrown. * @param loggedInUser The current user * in user. * @param login The login for the user whose Default ServerGroup list will * be affected. * @param name name of ServerGroup. * @return Returns 1 if successful (exception otherwise) * * @xmlrpc.doc Add system group to user's list of default system groups. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #param("string", "serverGroupName") * @xmlrpc.returntype #return_int_success() */ public int addDefaultSystemGroup(User loggedInUser, String login, String name) { List<String> ids = new LinkedList<String>(); ids.add(name); return addDefaultSystemGroups(loggedInUser, login, ids); } /** * Add ServerGroups to the list of Default System groups. The ServerGroups * <strong>MUST</strong> exist otherwise a IllegalArgumentException is * thrown. * @param loggedInUser The current user * in user. * @param login The login for the user whose Default ServerGroup list will * be affected. * @param sgNames names of ServerGroups. * @return Returns 1 if successful (exception otherwise) * * @xmlrpc.doc Add system groups to user's list of default system groups. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #array_single("string", "serverGroupName") * @xmlrpc.returntype #return_int_success() */ public int addDefaultSystemGroups(User loggedInUser, String login, List sgNames) { User target = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); if (sgNames == null || sgNames.size() < 1) { throw new IllegalArgumentException("no servergroup names supplied"); } List groups = ServerGroupFactory.listManagedGroups(target.getOrg()); Map groupMap = new HashMap(); // sigh. After looking through all of the apache collections package // I couldn't find anything that would create a map from a list using // a property from the object in the list as the key. This is where // python would be useful. for (Iterator itr = groups.iterator(); itr.hasNext();) { ServerGroup sg = (ServerGroup) itr.next(); groupMap.put(sg.getName(), sg); } // Doing full check of all supplied names, if one is bad // throw an exception, prior to altering the DefaultSystemGroup Set. for (Iterator itr = sgNames.iterator(); itr.hasNext();) { String name = (String)itr.next(); ServerGroup sg = (ServerGroup) groupMap.get(name); if (sg == null) { throw new LookupServerGroupException(name); } } // now for the real reason we're in this method. Set defaults = target.getDefaultSystemGroupIds(); for (Iterator itr = sgNames.iterator(); itr.hasNext();) { ServerGroup sg = (ServerGroup) groupMap.get(itr.next()); if (sg != null) { // not a simple add to the groups. Needs to call // UserManager as DataSource is being used. defaults.add(sg.getId()); } } UserManager.setDefaultSystemGroupIds(target, defaults); UserManager.storeUser(target); return 1; } /** * Remove ServerGroup from the list of Default System groups. The * ServerGroup <strong>MUST</strong> exist otherwise a * IllegalArgumentException is thrown. * @param loggedInUser The current user * in user. * @param login The login for the user whose Default ServerGroup list will * be affected. * @param sgName Name of ServerGroup. * @return Returns 1 if successful (exception otherwise) * * @xmlrpc.doc Remove a system group from user's list of default system groups. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #param("string", "serverGroupName") * @xmlrpc.returntype #return_int_success() */ public int removeDefaultSystemGroup(User loggedInUser, String login, String sgName) { List<String> names = new LinkedList<String>(); names.add(sgName); return removeDefaultSystemGroups(loggedInUser, login, names); } /** * Remove ServerGroups from the list of Default System groups. The * ServerGroups <strong>MUST</strong> exist otherwise a * IllegalArgumentException is thrown. * @param loggedInUser The current user * in user. * @param login The login for the user whose Default ServerGroup list will * be affected. * @param sgNames Names of ServerGroups. * @return Returns 1 if successful (exception otherwise) * * @xmlrpc.doc Remove system groups from a user's list of default system groups. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #array_single("string", "serverGroupName") * @xmlrpc.returntype #return_int_success() */ public int removeDefaultSystemGroups(User loggedInUser, String login, List sgNames) { User target = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); if (sgNames == null || sgNames.size() < 1) { throw new IllegalArgumentException("no servergroup names supplied"); } List groups = ServerGroupFactory.listManagedGroups(target.getOrg()); Map groupMap = new HashMap(); // sigh. After looking through all of the apache collections package // I couldn't find anything that would create a map from a list using // a property from the object in the list as the key. This is where // python would be useful. for (Iterator itr = groups.iterator(); itr.hasNext();) { ServerGroup sg = (ServerGroup) itr.next(); groupMap.put(sg.getName(), sg); } // Doing full check of all supplied names, if one is bad // throw an exception, prior to altering the DefaultSystemGroup Set. for (Iterator itr = sgNames.iterator(); itr.hasNext();) { String name = (String)itr.next(); ServerGroup sg = (ServerGroup) groupMap.get(name); if (sg == null) { throw new LookupServerGroupException(name); } } // now for the real reason we're in this method. Set defaults = target.getDefaultSystemGroupIds(); for (Iterator itr = sgNames.iterator(); itr.hasNext();) { ServerGroup sg = (ServerGroup) groupMap.get(itr.next()); if (sg != null) { // not a simple remove to the groups. Needs to call // UserManager as DataSource is being used. defaults.remove(sg.getId()); } } UserManager.setDefaultSystemGroupIds(target, defaults); UserManager.storeUser(target); return 1; } /** * Returns default system groups for the given login. * @param loggedInUser The current user * in user. * @param login The login for the user whose Default ServerGroup list is * sought. * @return default system groups for the given login * * @xmlrpc.doc Returns a user's list of default system groups. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.returntype * #array() * #struct("system group") * #prop("int", "id") * #prop("string", "name") * #prop("string", "description") * #prop("int", "system_count") * #prop_desc("int", "org_id", "Organization ID for this system group.") * #struct_end() * #array_end() */ public Object[] listDefaultSystemGroups(User loggedInUser, String login) { User target = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); Set<Long> ids = target.getDefaultSystemGroupIds(); List <ServerGroup> sgs = new ArrayList(ids.size()); for (Long id : ids) { sgs.add(ServerGroupFactory.lookupByIdAndOrg(id, target.getOrg())); } return sgs.toArray(); } /** * Returns the ServerGroups that the user can administer. * @param loggedInUser The current user * in user. * @param login The login for the user whose ServerGroups are sought. * @return the ServerGroups that the user can administer. * @throws FaultException A FaultException is thrown if the user doesn't * have access to lookup the user corresponding to login or if the user * does not exist. * * @xmlrpc.doc Returns the system groups that a user can administer. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.returntype * #array() * #struct("system group") * #prop("int", "id") * #prop("string", "name") * #prop("string", "description") * #prop("int", "system_count") * #prop_desc("int", "org_id", "Organization ID for this system group.") * #struct_end() * #array_end() */ public Object[] listAssignedSystemGroups(User loggedInUser, String login) throws FaultException { User target = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); List groups = ServerGroupFactory.listAdministeredServerGroups(target); return groups.toArray(); } /** * Returns the last logged in time of the given user. * @param loggedInUser The current user * in user. * @param login The login of the user. * @return last logged in time * @throws UserNeverLoggedInException if the given user has never logged in. * @deprecated Never returned usable value. * * @xmlrpc.doc Returns the time user last logged in. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.returntype dateTime.iso8601 */ @Deprecated public Date getLoggedInTime(User loggedInUser, String login) throws UserNeverLoggedInException { User target = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); Date d = target.getLastLoggedIn(); if (d != null) { return d; } throw new UserNeverLoggedInException(); } /** * remove system group association from a user * @param loggedInUser The current user * @param login the user's login that we want to remove the association from * @param systemGroupNames list of system group names to remove * @param setDefault if true the default group will be removed from the users's * group defaults * @return 1 on success * * @xmlrpc.doc Remove system groups from a user's list of assigned system groups. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #array_single("string", "serverGroupName") * @xmlrpc.param #param_desc("boolean", "setDefault", "Should system groups also be * removed from the user's list of default system groups.") * @xmlrpc.returntype #return_int_success() */ public int removeAssignedSystemGroups(User loggedInUser, String login, List<String> systemGroupNames, Boolean setDefault) { ensureUserRole(loggedInUser, RoleFactory.ORG_ADMIN); if (setDefault) { removeDefaultSystemGroups(loggedInUser, login, systemGroupNames); } User user = UserManager.lookupUser(loggedInUser, login); ServerGroupManager manager = ServerGroupManager.getInstance(); // Iterate once to lookup the server groups and avoid removing some when // an exception will only be thrown later: List<ManagedServerGroup> groups = new LinkedList<ManagedServerGroup>(); for (String name : systemGroupNames) { ManagedServerGroup sg = null; try { sg = manager.lookup(name, user); } catch (LookupException e) { throw new InvalidServerGroupException(); } groups.add(sg); } for (ManagedServerGroup sg : groups) { UserManager.revokeServerGroupPermission(user, sg.getId().longValue()); } return 1; } /** * remove system group association from a user * @param loggedInUser The current user * @param login the user's login that we want to remove the association from * @param systemGroupName system group name to remove * @param setDefault if true the default group will be removed from the users's * group defaults * @return 1 on success * * @xmlrpc.doc Remove system group from the user's list of assigned system groups. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #param("string", "serverGroupName") * @xmlrpc.param #param_desc("boolean", "setDefault", "Should system group also * be removed from the user's list of default system groups.") * @xmlrpc.returntype #return_int_success() */ public int removeAssignedSystemGroup(User loggedInUser, String login, String systemGroupName, Boolean setDefault) { List groups = new ArrayList(); groups.add(systemGroupName); return removeAssignedSystemGroups(loggedInUser, login, groups, setDefault); } /** * Add to the user's list of assigned system groups. * * @param loggedInUser The current user * @param login User to modify. * @param sgName Server group Name. * @param setDefault True to also add group to the user's default system groups. * @return Returns 1 if successful (exception thrown otherwise) * * @xmlrpc.doc Add system group to user's list of assigned system groups. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #param("string", "serverGroupName") * @xmlrpc.param #param_desc("boolean", "setDefault", "Should system group also be * added to user's list of default system groups.") * @xmlrpc.returntype #return_int_success() */ public int addAssignedSystemGroup(User loggedInUser, String login, String sgName, Boolean setDefault) { List<String> names = new LinkedList<String>(); names.add(sgName); return addAssignedSystemGroups(loggedInUser, login, names, setDefault); } /** * Add to the user's list of assigned system groups. * * @param loggedInUser The current user * @param login User to modify. * @param sgNames List of server group Names. * @param setDefault True to also add groups to the user's default system groups. * @return Returns 1 if successful (exception thrown otherwise) * * @xmlrpc.doc Add system groups to user's list of assigned system groups. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #array_single("string", "serverGroupName") * @xmlrpc.param #param_desc("boolean", "setDefault", "Should system groups also be * added to user's list of default system groups.") * @xmlrpc.returntype #return_int_success() */ public int addAssignedSystemGroups(User loggedInUser, String login, List sgNames, Boolean setDefault) { User targetUser = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); if (sgNames == null || sgNames.size() < 1) { throw new IllegalArgumentException("no servergroup names supplied"); } // Iterate once just to make sure all the server groups exist. Done to // prevent adding a bunch of valid groups and then throwing an exception // when coming across one that doesn't exist. List<ManagedServerGroup> groups = new LinkedList<ManagedServerGroup>(); for (Iterator it = sgNames.iterator(); it.hasNext();) { String serverGroupName = (String)it.next(); // Make sure the server group exists: ServerGroupManager manager = ServerGroupManager.getInstance(); ManagedServerGroup group; try { group = manager.lookup(serverGroupName, loggedInUser); } catch (LookupException e) { throw new InvalidServerGroupException(); } groups.add(group); } // Now do the actual add: for (ManagedServerGroup group : groups) { UserManager.grantServerGroupPermission(targetUser, group.getId()); } // Follow up with a call to addDefaultSystemGroups if setDefault is true: if (setDefault.booleanValue()) { addDefaultSystemGroups(loggedInUser, login, sgNames); } return 1; } /** * Return the current value of the createDefaultSystemGroup settnig * @param loggedInUser The current user * Must be org_admin. * @return Returns 1 if successful (exception otherwise) * * @xmlrpc.doc Returns the current value of the CreateDefaultSystemGroup setting. * If True this will cause there to be a system group created (with the same name * as the user) every time a new user is created, with the user automatically given * permission to that system group and the system group being set as the default * group for the user (so every time the user registers a system it will be * placed in that system group by default). This can be useful if different * users will administer different groups of servers in the same organization. * Can only be called by an org_admin. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.returntype #return_int_success() */ public boolean getCreateDefaultSystemGroup(User loggedInUser) { //Logged in user must be an org admin. ensureOrgAdmin(loggedInUser); return loggedInUser.getOrg().getOrgConfig().isCreateDefaultSg(); } /** * Return the current value of the createDefaultSystemGroup settnig * @param loggedInUser The current user * Must be org_admin. * @param createDefaultSystemGroup The value to set * @return Returns 1 if successful (exception otherwise) * * @xmlrpc.doc Sets the value of the CreateDefaultSystemGroup setting. * If True this will cause there to be a system group created (with the same name * as the user) every time a new user is created, with the user automatically given * permission to that system group and the system group being set as the default * group for the user (so every time the user registers a system it will be * placed in that system group by default). This can be useful if different * users will administer different groups of servers in the same organization. * Can only be called by an org_admin. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("boolean", "createDefaultSystemGruop", * "True if we should automatically create system groups, false otherwise.") * @xmlrpc.returntype #return_int_success() */ public int setCreateDefaultSystemGroup(User loggedInUser, Boolean createDefaultSystemGroup) { //Logged in user must be an org admin. ensureOrgAdmin(loggedInUser); loggedInUser.getOrg().getOrgConfig().setCreateDefaultSg(createDefaultSystemGroup); return 1; } /** * @param loggedInUser The current user * @param login User to modify. * @param readOnly readOnly flag to set * @return 1 (should always succeed) * @xmlrpc.doc Sets whether the target user should have only read-only API access or * standard full scale access. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #param_desc("boolean", "readOnly", "Sets whether the target user should * have only read-only API access or standard full scale access.") * @xmlrpc.returntype #return_int_success() */ public int setReadOnly(User loggedInUser, String login, Boolean readOnly) { //Logged in user must be an org admin. ensureOrgAdmin(loggedInUser); User targetUser = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); if (!targetUser.isReadOnly()) { if (readOnly && targetUser.hasRole(RoleFactory.ORG_ADMIN) && targetUser.getOrg().numActiveOrgAdmins() < 2) { throw new InvalidOperationException("error.readonly_org_admin", targetUser.getOrg().getName()); } if (readOnly && targetUser.hasRole(RoleFactory.SAT_ADMIN) && SatManager.getActiveSatAdmins().size() < 2) { throw new InvalidOperationException("error.readonly_sat_admin"); } } targetUser.setReadOnly(readOnly); return 1; } /** * @param loggedInUser The current user * @param login User to modify * @param value value to enable/disable errata mail notifications * @return Returns 1 if successful (exception thrown otherwise) * @xmlrpc.doc Enables/disables errata mail notifications for a specific user. * @xmlrpc.param #param("string", "sessionKey") * @xmlrpc.param #param_desc("string", "login", "User's login name.") * @xmlrpc.param #param_desc("boolean", "value", "True for enabling * errata notifications, False for disabling") * @xmlrpc.returntype #return_int_success() */ public int setErrataNotifications(User loggedInUser, String login, Boolean value) { //Logged in user must be an org admin. ensureOrgAdmin(loggedInUser); User targetUser = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); targetUser.setEmailNotify(BooleanUtils.toIntegerObject(value)); return 1; } }