/**
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
* The Original Code is OpenELIS code.
*
* Copyright (C) The Minnesota Department of Health. All Rights Reserved.
*
* Contributor(s): CIRG, University of Washington, Seattle WA.
*/
package us.mn.state.health.lims.systemuser.action;
import java.lang.reflect.InvocationTargetException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.validator.GenericValidator;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import us.mn.state.health.lims.common.action.BaseAction;
import us.mn.state.health.lims.common.util.DateUtil;
import us.mn.state.health.lims.common.util.StringUtil;
import us.mn.state.health.lims.login.dao.LoginDAO;
import us.mn.state.health.lims.login.dao.UserModuleDAO;
import us.mn.state.health.lims.login.daoimpl.LoginDAOImpl;
import us.mn.state.health.lims.login.daoimpl.UserModuleDAOImpl;
import us.mn.state.health.lims.login.valueholder.Login;
import us.mn.state.health.lims.role.action.bean.DisplayRole;
import us.mn.state.health.lims.role.dao.RoleDAO;
import us.mn.state.health.lims.role.daoimpl.RoleDAOImpl;
import us.mn.state.health.lims.role.valueholder.Role;
import us.mn.state.health.lims.systemuser.dao.SystemUserDAO;
import us.mn.state.health.lims.systemuser.daoimpl.SystemUserDAOImpl;
import us.mn.state.health.lims.systemuser.valueholder.SystemUser;
import us.mn.state.health.lims.systemuser.valueholder.UnifiedSystemUser;
import us.mn.state.health.lims.userrole.dao.UserRoleDAO;
import us.mn.state.health.lims.userrole.daoimpl.UserRoleDAOImpl;
@SuppressWarnings("unchecked")
public class UnifiedSystemUserAction extends BaseAction {
private boolean isNew = false;
private static final String MAINTENANCE_ADMIN = "Maintenance Admin";
private static String MAINTENANCE_ADMIN_ID;
private boolean doFiltering = true;
public static final char DEFAULT_PASSWORD_FILLER = '?';
{
RoleDAO roleDAO = new RoleDAOImpl();
List<Role> roles = roleDAO.getAllRoles();
for (Role role : roles) {
if (MAINTENANCE_ADMIN.equals(role.getName().trim())) {
MAINTENANCE_ADMIN_ID = role.getId();
break;
}
}
}
protected ActionForward performAction(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws Exception {
String id = request.getParameter(ID);
doFiltering = true;
String forward = FWD_SUCCESS;
request.setAttribute(ALLOW_EDITS_KEY, "true");
request.setAttribute(PREVIOUS_DISABLED, "true");
request.setAttribute(NEXT_DISABLED, "true");
DynaActionForm dynaForm = (DynaActionForm) form;
dynaForm.initialize(mapping);
isNew = GenericValidator.isBlankOrNull(id) || "0".equals(id);
List<Role> roles = getAllRoles();
setDefaultProperties(dynaForm);
if (!isNew) {
setPropertiesForExistingUser(dynaForm, id);
}
UserModuleDAO userModuleDAO = new UserModuleDAOImpl();
doFiltering &= !userModuleDAO.isUserAdmin(request);
if (doFiltering) {
roles = doRoleFiltering(roles, getSysUserId(request));
}
List<DisplayRole> displayRoles = convertToDisplayRoles( roles );
displayRoles = sortAndGroupRoles(displayRoles);
PropertyUtils.setProperty(dynaForm, "roles", displayRoles);
return mapping.findForward(forward);
}
private List<DisplayRole> convertToDisplayRoles(List<Role> roles) {
int elementCount = 0;
List<DisplayRole> displayRoles = new ArrayList<DisplayRole>();
for( Role role: roles){
elementCount++;
displayRoles.add(convertToDisplayRole(role, elementCount));
}
return displayRoles;
}
private DisplayRole convertToDisplayRole(Role role, int count) {
DisplayRole displayRole = new DisplayRole();
displayRole.setRoleName(role.getLocalizedName());
displayRole.setElementID(String.valueOf(count));
displayRole.setRoleId(role.getId());
displayRole.setGroupingRole(role.getGroupingRole());
displayRole.setParentRole(role.getGroupingParent());
return displayRole;
}
private List<DisplayRole> sortAndGroupRoles(List<DisplayRole> roles) {
/*
* The sorting we want to end up with is first alphabetical and then by
* groups What makes things a little more difficult is that we may have
* roles which have parents which don't exist, we shouldn't but we
* might. So... First sweep is to find all the orphaned roles and set
* their parents to null Then move all the first generation groups to a
* new list. Then scan for all for all groups and move their members,
* repeat until the first list is empty, which is why we didn't want
* orphans. Lastly we will add the role ID as a child to all of it's parents
*/
Collections.sort(roles, new Comparator() {
public int compare(Object obj1, Object obj2) {
DisplayRole role1 = (DisplayRole) obj1;
DisplayRole role2 = (DisplayRole) obj2;
return role1.getRoleName().toUpperCase().compareTo(role2.getRoleName().toUpperCase());
}
});
/*
* The reason we're not making a map is that we want to preserve the
* order during this whole process
*/
List<String> groupIds = new ArrayList<String>();
for (DisplayRole role : roles) {
if (role.isGroupingRole()) {
groupIds.add(role.getRoleId());
}
}
for (DisplayRole role : roles) {
if (!GenericValidator.isBlankOrNull(role.getParentRole()) && !groupIds.contains(role.getParentRole())) {
role.setParentRole(null);
}
}
List<DisplayRole> mergeList = new ArrayList<DisplayRole>();
List<DisplayRole> currentWorkingList = new ArrayList<DisplayRole>();
List<DisplayRole> unplacedList = new ArrayList<DisplayRole>();
for (DisplayRole role : roles) {
if (GenericValidator.isBlankOrNull(role.getParentRole())) {
role.setNestingLevel(0);
currentWorkingList.add(role);
} else {
unplacedList.add(role);
}
}
int indentCount = 0;
while (unplacedList.size() > 0) {
indentCount++;
for (DisplayRole placedRole : currentWorkingList) {
mergeList.add(placedRole);
if (placedRole.isGroupingRole()) {
List<DisplayRole> removeList = new ArrayList<DisplayRole>();
for (DisplayRole unplacedRole : unplacedList) {
if (unplacedRole.getParentRole().equals(placedRole.getRoleId())) {
unplacedRole.setNestingLevel(indentCount);
mergeList.add(unplacedRole);
removeList.add(unplacedRole);
placedRole.addChildID(unplacedRole.getRoleId());
}
}
unplacedList.removeAll(removeList);
}
}
currentWorkingList = mergeList;
mergeList = new ArrayList<DisplayRole>();
}
/* For finding all parents we are going to iterate backwards since all parents are
* in front of children role
*/
for( int i = currentWorkingList.size() - 1; i > 0; i--){
DisplayRole role = currentWorkingList.get(i);
if( !GenericValidator.isBlankOrNull(role.getParentRole())){
String roleID = role.getRoleId();
String currentParentID = role.getParentRole();
for( int parent = i - 1; parent >= 0; parent--){
if( currentWorkingList.get(parent).getRoleId().equals(currentParentID)){
DisplayRole parentRole = currentWorkingList.get(parent);
parentRole.addChildID(roleID);
if( GenericValidator.isBlankOrNull(parentRole.getParentRole())){
break;
}else{
currentParentID = parentRole.getParentRole();
}
}
}
}
}
return currentWorkingList;
}
private List<Role> doRoleFiltering(List<Role> roles, String loggedInUserId) {
UserRoleDAO userRoleDAO = new UserRoleDAOImpl();
List<String> rolesForLoggedInUser = userRoleDAO.getRoleIdsForUser(loggedInUserId);
if (!rolesForLoggedInUser.contains(MAINTENANCE_ADMIN_ID)) {
List<Role> tmpRoles = new ArrayList<Role>();
for (Role role : roles) {
if (!MAINTENANCE_ADMIN_ID.equals(role.getId())) {
tmpRoles.add(role);
}
}
roles = tmpRoles;
}
return roles;
}
private void setDefaultProperties(DynaActionForm dynaForm) throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
String expireDate = getYearsFromNow(10);
PropertyUtils.setProperty(dynaForm, "expirationDate", expireDate);
PropertyUtils.setProperty(dynaForm, "timeout", "480");
PropertyUtils.setProperty(dynaForm, "systemUserLastupdated", new Timestamp(System.currentTimeMillis()));
}
private void setPropertiesForExistingUser(DynaActionForm dynaForm, String id) throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
Login login = getLoginFromCombinedId(id);
SystemUser systemUser = getSystemUserFromCombinedId(id);
if (login != null) {
String proxyPassword = getProxyPassword(login);
PropertyUtils.setProperty(dynaForm, "loginUserId", login.getId());
PropertyUtils.setProperty(dynaForm, "accountDisabled", login.getAccountDisabled());
PropertyUtils.setProperty(dynaForm, "accountLocked", login.getAccountLocked());
PropertyUtils.setProperty(dynaForm, "userLoginName", login.getLoginName());
PropertyUtils.setProperty(dynaForm, "userPassword1", proxyPassword );
PropertyUtils.setProperty(dynaForm, "userPassword2", proxyPassword);
PropertyUtils.setProperty(dynaForm, "expirationDate", login.getPasswordExpiredDateForDisplay());
PropertyUtils.setProperty(dynaForm, "timeout", login.getUserTimeOut());
}
if (systemUser != null) {
PropertyUtils.setProperty(dynaForm, "systemUserId", systemUser.getId());
PropertyUtils.setProperty(dynaForm, "userFirstName", systemUser.getFirstName());
PropertyUtils.setProperty(dynaForm, "userLastName", systemUser.getLastName());
PropertyUtils.setProperty(dynaForm, "accountActive", systemUser.getIsActive());
PropertyUtils.setProperty(dynaForm, "systemUserLastupdated", systemUser.getLastupdated());
UserRoleDAO userRoleDAO = new UserRoleDAOImpl();
List<String> roleIds = userRoleDAO.getRoleIdsForUser(systemUser.getId());
PropertyUtils.setProperty(dynaForm, "selectedRoles", roleIds.toArray(new String[0]));
doFiltering = !roleIds.contains(MAINTENANCE_ADMIN_ID);
}
}
private String getProxyPassword(Login login) {
return StringUtil.replaceAllChars(login.getPassword(), DEFAULT_PASSWORD_FILLER);
}
private Login getLoginFromCombinedId(String id) {
Login login = null;
String loginId = UnifiedSystemUser.getLoginUserIDFromCombinedID(id);
if (!GenericValidator.isBlankOrNull(loginId)) {
LoginDAO loginDAO = new LoginDAOImpl();
login = new Login();
login.setId(loginId);
loginDAO.getData(login);
}
return login;
}
private SystemUser getSystemUserFromCombinedId(String id) {
SystemUser systemUser = null;
String systemUserId = UnifiedSystemUser.getSystemUserIDFromCombinedID(id);
if (!GenericValidator.isBlankOrNull(systemUserId)) {
SystemUserDAO systemUserDAO = new SystemUserDAOImpl();
systemUser = new SystemUser();
systemUser.setId(systemUserId);
systemUserDAO.getData(systemUser);
}
return systemUser;
}
private String getYearsFromNow(int years) {
Calendar today = Calendar.getInstance();
today.add(Calendar.YEAR, years);
return DateUtil.formatDateAsText(today.getTime());
}
private List<Role> getAllRoles() {
RoleDAO roleDAO = new RoleDAOImpl();
return roleDAO.getAllActiveRoles();
}
protected String getPageTitleKey() {
return isNew ? "unifiedSystemUser.add.title" : "unifiedSystemUser.edit.title";
}
protected String getPageSubtitleKey() {
return isNew ? "unifiedSystemUser.add.title" : "unifiedSystemUser.edit.title";
}
}