/**
* Copyright (c) 2009--2014 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.action.user;
import com.redhat.rhn.common.security.PermissionException;
import com.redhat.rhn.domain.org.Org;
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.user.User;
import com.redhat.rhn.frontend.action.common.BadParameterException;
import com.redhat.rhn.frontend.struts.RequestContext;
import com.redhat.rhn.frontend.struts.RhnHelper;
import com.redhat.rhn.frontend.struts.StrutsDelegate;
import com.redhat.rhn.manager.system.ServerGroupManager;
import com.redhat.rhn.manager.user.UserManager;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.DynaActionForm;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* UserEditSubmitAction, edit action submit handler for user detail page
* @version $Rev: 1196 $
*/
public class AdminUserEditAction extends UserEditActionHelper {
private static Logger log = Logger.getLogger(AdminUserEditAction.class);
private static final String ROLE_SETTING_PREFIX = "role_";
/** {@inheritDoc} */
public ActionForward execute(ActionMapping mapping,
ActionForm formIn,
HttpServletRequest request,
HttpServletResponse response) {
DynaActionForm form = (DynaActionForm)formIn;
RequestContext requestContext = new RequestContext(request);
StrutsDelegate strutsDelegate = getStrutsDelegate();
//We could be editing ourself, we could be editing another user...
User targetUser = UserManager.lookupUser(requestContext.getCurrentUser(),
requestContext.getParamAsLong("uid"));
request.setAttribute(RhnHelper.TARGET_USER, targetUser);
//Make sure we got a user, if not, we must have gotten a bad uid
if (targetUser == null) {
throw new BadParameterException("Invalid uid, targetUser not found");
}
User loggedInUser = requestContext.getCurrentUser();
//Update the users details with info entered on the form
ActionErrors errors = updateDetails(loggedInUser, targetUser, form);
//If we have validation/form errors, return now and let the user fix those first
if (!errors.isEmpty()) {
return returnFailure(mapping, request, errors, targetUser.getId());
}
//Create the user info updated success message
createSuccessMessage(request, "message.userInfoUpdated", null);
//Now we need to update user roles. If we get errors here, return failure
errors = updateRoles(request, targetUser, loggedInUser);
if (!errors.isEmpty()) {
return returnFailure(mapping, request, errors, targetUser.getId());
}
//Everything must have gone smoothly
UserManager.storeUser(targetUser);
ActionForward dest = mapping.findForward("success");
/*
* Does the user still have the roles needed to see /users/UserDetails.do?
* Check here and make a decision so user doesn't go to a permission error page.
*/
//If the logged in user is the same as the target user and we have removed the
//target users org admin status, forward to noaccess instead
if (loggedInUser.equals(targetUser) &&
!targetUser.hasRole(RoleFactory.ORG_ADMIN)) {
dest = mapping.findForward("noaccess");
}
return strutsDelegate.forwardParam(dest, "uid", String.valueOf(targetUser.getId()));
}
/**
* Private helper method to save errors to the request and forward to the
* failure mapping
*/
private ActionForward returnFailure(ActionMapping mapping,
HttpServletRequest request,
ActionErrors errors,
Long uid) {
addErrors(request, errors);
return getStrutsDelegate().forwardParam(mapping.findForward("failure"), "uid",
String.valueOf(uid));
}
/**
* Private helper method to handle getting the new roles from the form and calling
* UserManager.updateUserRolesFromRoleLabels().
* @param form The form containing selectedRoles. selectedRoles are the new set of
* roles to associate with the user.
* @param targetUser The user who is having their roles updated.
* @return Returns an ActionErrors object containing any errors that occurred while
* updating the users roles
*/
private ActionErrors updateRoles(HttpServletRequest request,
User targetUser,
User loggedInUser) {
log.debug(this.getClass().getName() + ".updateRoles()");
Set<String> disabledRoles = extractDisabledRoles(request);
ActionErrors errors = new ActionErrors();
Org org = targetUser.getOrg();
Set<Role> orgRoles = org.getRoles();
// Build a set of the users current role labels to help determine what we need
// to add and remove:
Set<String> existingRoles = new HashSet<String>();
for (Role r : targetUser.getPermanentRoles()) {
existingRoles.add(r.getLabel());
}
// Look for an add/remove setting for each org role in the form:
List<String> rolesToAdd = new LinkedList<String>();
List<String> rolesToRemove = new LinkedList<String>();
for (Role role : orgRoles) {
if (disabledRoles.contains(role.getLabel())) {
// Role was disabled when we built this form, so skip:
continue;
}
String roleSetting = request.getParameter(ROLE_SETTING_PREFIX +
role.getLabel());
log.debug(" " + role.getName() + " / " + roleSetting);
if (roleSetting != null && !existingRoles.contains(role.getLabel())) {
// Must have been newly checked:
rolesToAdd.add(role.getLabel());
}
else if (roleSetting == null && existingRoles.contains(role.getLabel())) {
// Must have been newly unchecked:
rolesToRemove.add(role.getLabel());
}
}
try {
UserManager.addRemoveUserRoles(targetUser, rolesToAdd,
rolesToRemove);
//if he is an org amin make sure he does NOT
// have any subscribed Server Groups, because
// by becoming an org admin he is automatically
// subscribed to every group... and so his list
// will be empty..
if (targetUser.hasRole(RoleFactory.ORG_ADMIN) &&
!targetUser.getAssociatedServerGroups().isEmpty()) {
ServerGroupManager manager = ServerGroupManager.getInstance();
Set admins = new HashSet();
admins.add(targetUser);
for (Iterator itr = targetUser.getAssociatedServerGroups().iterator();
itr.hasNext();) {
ManagedServerGroup sg = (ManagedServerGroup) itr.next();
manager.dissociateAdmins(sg, admins, loggedInUser);
itr.remove();
}
}
}
catch (PermissionException pe) {
errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("userdetails.jsp.error.lastorgadmin"));
}
return errors;
}
private Set<String> extractDisabledRoles(HttpServletRequest request) {
String hiddenInput = request.getParameter("disabledRoles");
Set<String> returnVal = new HashSet<String>(
Arrays.asList(hiddenInput.split("\\|")));
log.debug("Found disabled inputs: " + returnVal);
return returnVal;
}
}