/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/user/branches/sakai-2.8.1/user-tool/tool/src/java/org/sakaiproject/user/tool/UsersAction.java $
* $Id: UsersAction.java 95036 2011-07-12 15:17:57Z ottenhoff@longsight.com $
***********************************************************************************
*
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 The Sakai Foundation
*
* Licensed under the Educational Community 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.osedu.org/licenses/ECL-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 org.sakaiproject.user.tool;
import java.util.List;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.tanesha.recaptcha.ReCaptcha;
import net.tanesha.recaptcha.ReCaptchaFactory;
import net.tanesha.recaptcha.ReCaptchaResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.validator.EmailValidator;
import org.sakaiproject.authz.cover.SecurityService;
import org.sakaiproject.cheftool.Context;
import org.sakaiproject.cheftool.JetspeedRunData;
import org.sakaiproject.cheftool.PagedResourceActionII;
import org.sakaiproject.cheftool.PortletConfig;
import org.sakaiproject.cheftool.RunData;
import org.sakaiproject.cheftool.VelocityPortlet;
import org.sakaiproject.cheftool.api.Menu;
import org.sakaiproject.cheftool.api.MenuItem;
import org.sakaiproject.cheftool.menu.MenuEntry;
import org.sakaiproject.cheftool.menu.MenuImpl;
import org.sakaiproject.component.cover.ServerConfigurationService;
import org.sakaiproject.event.api.SessionState;
import org.sakaiproject.event.cover.UsageSessionService;
import org.sakaiproject.thread_local.cover.ThreadLocalManager;
import org.sakaiproject.tool.api.Session;
import org.sakaiproject.tool.cover.SessionManager;
import org.sakaiproject.user.api.Authentication;
import org.sakaiproject.user.api.AuthenticationException;
import org.sakaiproject.user.api.Evidence;
import org.sakaiproject.user.api.User;
import org.sakaiproject.user.api.UserAlreadyDefinedException;
import org.sakaiproject.user.api.UserEdit;
import org.sakaiproject.user.api.UserIdInvalidException;
import org.sakaiproject.user.api.UserLockedException;
import org.sakaiproject.user.api.UserNotDefinedException;
import org.sakaiproject.user.api.UserPermissionException;
import org.sakaiproject.user.cover.AuthenticationManager;
import org.sakaiproject.user.cover.UserDirectoryService;
import org.sakaiproject.util.ExternalTrustedEvidence;
import org.sakaiproject.util.RequestFilter;
import org.sakaiproject.util.ResourceLoader;
import org.sakaiproject.util.StringUtil;
/**
* <p>
* UsersAction is the Sakai users editor.
* </p>
*/
public class UsersAction extends PagedResourceActionII
{
private static ResourceLoader rb = new ResourceLoader("admin");
/**
* {@inheritDoc}
*/
protected List readResourcesPage(SessionState state, int first, int last)
{
// search?
String search = StringUtils.trimToNull((String) state.getAttribute(STATE_SEARCH));
if (search != null)
{
return UserDirectoryService.searchUsers(search, first, last);
}
return UserDirectoryService.getUsers(first, last);
}
/**
* {@inheritDoc}
*/
protected int sizeResources(SessionState state)
{
// search?
String search = StringUtils.trimToNull((String) state.getAttribute(STATE_SEARCH));
if (search != null)
{
return UserDirectoryService.countSearchUsers(search);
}
return UserDirectoryService.countUsers();
}
/**
* Populate the state object, if needed.
*/
protected void initState(SessionState state, VelocityPortlet portlet, JetspeedRunData rundata)
{
super.initState(state, portlet, rundata);
PortletConfig config = portlet.getPortletConfig();
if (state.getAttribute("single-user") == null)
{
state.setAttribute("single-user", new Boolean(config.getInitParameter("single-user", "false")));
state.setAttribute("include-password", new Boolean(config.getInitParameter("include-password", "true")));
}
if (state.getAttribute("create-user") == null)
{
state.setAttribute("create-user", new Boolean(config.getInitParameter("create-user", "false")));
state.setAttribute("create-login", new Boolean(config.getInitParameter("create-login", "false")));
}
if (state.getAttribute("create-type") == null)
{
state.setAttribute("create-type", config.getInitParameter("create-type", ""));
}
if (state.getAttribute("user.recaptcha-enabled") == null)
{
String publicKey = ServerConfigurationService.getString("user.recaptcha.public-key", "");
String privateKey = ServerConfigurationService.getString("user.recaptcha.private-key", "");
Boolean systemEnabled = ServerConfigurationService.getBoolean("user.recaptcha.enabled", false);
Boolean toolEnabled = Boolean.parseBoolean(config.getInitParameter("user.recaptcha-enabled", "false"));
Boolean enabled = systemEnabled && toolEnabled;
if (enabled)
{
if (publicKey == null || publicKey.length() == 0)
{
Log.warn("chef", "recaptcha is enabled but no public key is found.");
enabled = Boolean.FALSE;
}
if (privateKey == null || privateKey.length() == 0)
{
Log.warn("chef", "recaptcha is enabled but no private key is found.");
enabled = Boolean.FALSE;
}
}
state.setAttribute("user.recaptcha-public-key", publicKey);
state.setAttribute("user.recaptcha-private-key", privateKey);
state.setAttribute("user.recaptcha-enabled", enabled);
}
} // initState
/**
* build the context
*/
public String buildMainPanelContext(VelocityPortlet portlet, Context context, RunData rundata, SessionState state)
{
context.put("tlang", rb);
boolean singleUser = ((Boolean) state.getAttribute("single-user")).booleanValue();
boolean createUser = ((Boolean) state.getAttribute("create-user")).booleanValue();
// if not logged in as the super user, we won't do anything
if ((!singleUser) && (!createUser) && (!SecurityService.isSuperUser()))
{
context.put("tlang",rb);
return (String) getContext(rundata).get("template") + "_noaccess";
}
String template = null;
// for the create-user create-login case, we set this in the do so we can process the redirect here
if (state.getAttribute("redirect") != null)
{
state.removeAttribute("redirect");
Session s = SessionManager.getCurrentSession();
// TODO: Decide if this should be in "getPortalUrl"
// I don't think so but could be convinced - /chuck
String controllingPortal = (String) s.getAttribute("sakai-controlling-portal");
String portalUrl = ServerConfigurationService.getPortalUrl();
if ( controllingPortal != null ) {
portalUrl = portalUrl + "/" + controllingPortal;
}
sendParentRedirect((HttpServletResponse) ThreadLocalManager.get(RequestFilter.CURRENT_HTTP_RESPONSE),
portalUrl);
return template;
}
// put $action into context for menus, forms and links
context.put(Menu.CONTEXT_ACTION, state.getAttribute(STATE_ACTION));
// check mode and dispatch
String mode = (String) state.getAttribute("mode");
if ((singleUser) && (mode != null) && (mode.equals("edit")))
{
template = buildEditContext(state, context);
}
else if (singleUser)
{
String id = SessionManager.getCurrentSessionUserId();
state.setAttribute("user-id", id);
template = buildViewContext(state, context);
}
else if (createUser)
{
template = buildCreateContext(state, context);
}
else if (mode == null)
{
template = buildListContext(state, context);
}
else if (mode.equals("new"))
{
template = buildNewContext(state, context);
}
else if (mode.equals("edit"))
{
template = buildEditContext(state, context);
}
else if (mode.equals("confirm"))
{
template = buildConfirmRemoveContext(state, context);
}
else
{
Log.warn("chef", "UsersAction: mode: " + mode);
template = buildListContext(state, context);
}
String prefix = (String) getContext(rundata).get("template");
return prefix + template;
} // buildNormalContext
/**
* Build the context for the main list mode.
*/
private String buildListContext(SessionState state, Context context)
{
// put the service in the context
context.put("service", UserDirectoryService.getInstance());
// put all (internal) users into the context
context.put("users", prepPage(state));
// build the menu
Menu bar = new MenuImpl();
if (UserDirectoryService.allowAddUser())
{
bar.add(new MenuEntry(rb.getString("useact.newuse"), null, true, MenuItem.CHECKED_NA, "doNew"));
}
// add the paging commands
//addListPagingMenus(bar, state);
int pageSize = Integer.valueOf(state.getAttribute(STATE_PAGESIZE).toString()).intValue();
int currentPageNubmer = Integer.valueOf(state.getAttribute(STATE_CURRENT_PAGE).toString()).intValue();
int startNumber = pageSize * (currentPageNubmer - 1) + 1;
int endNumber = pageSize * currentPageNubmer;
int totalNumber = 0;
Object[] params;
ArrayList list = new ArrayList();
list.add(new Integer[]{Integer.valueOf(5)});
list.add(new Integer[]{Integer.valueOf(10)});
list.add(new Integer[]{Integer.valueOf(20)});
list.add(new Integer[]{Integer.valueOf(50)});
list.add(new Integer[]{Integer.valueOf(100)});
list.add(new Integer[]{Integer.valueOf(200)});
try
{
totalNumber = Integer.valueOf(state.getAttribute(STATE_NUM_MESSAGES).toString()).intValue();
}
catch (java.lang.NullPointerException ignore) {}
catch (java.lang.NumberFormatException ignore) {}
if (totalNumber < endNumber) endNumber = totalNumber;
params = new Object[]{startNumber, endNumber, totalNumber};
context.put("startNumber", Integer.valueOf(startNumber));
context.put("endNumber", Integer.valueOf(endNumber));
context.put("totalNumber", Integer.valueOf(totalNumber));
context.put("params", params);
context.put("list", list);
pagingInfoToContext(state, context);
// add the search commands
addSearchMenus(bar, state);
// add the refresh commands
addRefreshMenus(bar, state);
if (bar.size() > 0)
{
context.put(Menu.CONTEXT_MENU, bar);
}
return "_list";
} // buildListContext
/**
* Build the context for the new user mode.
*/
private String buildNewContext(SessionState state, Context context)
{
// put the service in the context
context.put("service", UserDirectoryService.getInstance());
// name the html form for user edit fields
context.put("form-name", "user-form");
// include the password fields?
context.put("incPw", state.getAttribute("include-password"));
context.put("incType", Boolean.valueOf(true));
context.put("superUser", Boolean.valueOf(SecurityService.isSuperUser()));
String value = (String) state.getAttribute("valueEid");
if (value != null) context.put("valueEid", value);
value = (String) state.getAttribute("valueFirstName");
if (value != null) context.put("valueFirstName", value);
value = (String) state.getAttribute("valueLastName");
if (value != null) context.put("valueLastName", value);
value = (String) state.getAttribute("valueEmail");
if (value != null) context.put("valueEmail", value);
value = (String) state.getAttribute("valueType");
if (value != null) context.put("valueType", value);
return "_edit";
} // buildNewContext
/**
* Build the context for the create user mode.
*/
private String buildCreateContext(SessionState state, Context context)
{
// put the service in the context
context.put("service", UserDirectoryService.getInstance());
// is the type to be pre-set
context.put("type", state.getAttribute("create-type"));
// password is required when using Gateway New Account tool
// attribute "create-user" is true only for New Account tool
context.put("pwRequired", state.getAttribute("create-user"));
// is super user/admin user?
context.put("superUser", Boolean.valueOf(SecurityService.isSuperUser()));
String value = (String) state.getAttribute("valueEid");
if (value != null) context.put("valueEid", value);
value = (String) state.getAttribute("valueFirstName");
if (value != null) context.put("valueFirstName", value);
value = (String) state.getAttribute("valueLastName");
if (value != null) context.put("valueLastName", value);
value = (String) state.getAttribute("valueEmail");
if (value != null) context.put("valueEmail", value);
if ((Boolean)state.getAttribute("user.recaptcha-enabled"))
{
ReCaptcha captcha = ReCaptchaFactory.newReCaptcha((String)state.getAttribute("user.recaptcha-public-key"), (String)state.getAttribute("user.recaptcha-private-key"), false);
String captchaScript = captcha.createRecaptchaHtml((String)state.getAttribute("recaptcha-error"), null);
state.removeAttribute("recaptcha-error");
context.put("recaptchaScript", captchaScript);
}
return "_create";
} // buildCreateContext
/**
* Build the context for the new user mode.
*/
private String buildEditContext(SessionState state, Context context)
{
// put the service in the context
context.put("service", UserDirectoryService.getInstance());
// name the html form for user edit fields
context.put("form-name", "user-form");
// get the user to edit
UserEdit user = (UserEdit) state.getAttribute("user");
context.put("user", user);
// is super user/admin user?
context.put("superUser", Boolean.valueOf(SecurityService.isSuperUser()));
// include the password fields?
context.put("incPw", state.getAttribute("include-password"));
// include type fields (not if single user)
boolean singleUser = ((Boolean) state.getAttribute("single-user")).booleanValue();
context.put("incType", Boolean.valueOf(!singleUser));
// build the menu
// we need the form fields for the remove...
boolean menuPopulated = false;
Menu bar = new MenuImpl();
if ((!singleUser) && (UserDirectoryService.allowRemoveUser(user.getId())))
{
bar.add(new MenuEntry(rb.getString("useact.remuse"), null, true, MenuItem.CHECKED_NA, "doRemove", "user-form"));
menuPopulated = true;
}
if (menuPopulated)
{
context.put(Menu.CONTEXT_MENU, bar);
}
String value = (String) state.getAttribute("valueEid");
if (value != null) context.put("valueEid", value);
value = (String) state.getAttribute("valueFirstName");
if (value != null) context.put("valueFirstName", value);
value = (String) state.getAttribute("valueLastName");
if (value != null) context.put("valueLastName", value);
value = (String) state.getAttribute("valueEmail");
if (value != null) context.put("valueEmail", value);
value = (String) state.getAttribute("valueType");
if (value != null) context.put("valueType", value);
return "_edit";
} // buildEditContext
/**
* Build the context for the view user mode.
*/
private String buildViewContext(SessionState state, Context context)
{
if (Log.getLogger("chef").isDebugEnabled())
{
Log.debug("chef", this + ".buildViewContext");
}
// get current user's id
String id = (String) state.getAttribute("user-id");
// get the user and put in state as "user"
try
{
User user = UserDirectoryService.getUser(id);
context.put("user", user);
// name the html form for user edit fields
context.put("form-name", "user-form");
state.setAttribute("mode", "view");
// make sure we can do an edit
try
{
UserEdit edit = UserDirectoryService.editUser(id);
UserDirectoryService.cancelEdit(edit);
context.put("enableEdit", "true");
}
catch (UserNotDefinedException e)
{
}
catch (UserPermissionException e)
{
}
catch (UserLockedException e)
{
}
//SAK-19498
//check if user can change pw (this is used to determine if user should
//view createdBy and modifiedBy info (assuming you can't change pw for provided users)
if(UserDirectoryService.getInstance().allowUpdateUserPassword(id)){
context.put("viewCreatedModifiedBy", "true");
}
// disable auto-updates while not in list mode
disableObservers(state);
}
catch (UserNotDefinedException e)
{
Log.warn("chef", "UsersAction.doEdit: user not found: " + id);
Object[] params = new Object[]{id};
addAlert(state, rb.getFormattedMessage("useact.use_notfou", params));
state.removeAttribute("mode");
// make sure auto-updates are enabled
enableObserver(state);
}
return "_view";
} // buildViewContext
/**
* Build the context for the new user mode.
*/
private String buildConfirmRemoveContext(SessionState state, Context context)
{
// get the user to edit
UserEdit user = (UserEdit) state.getAttribute("user");
context.put("user", user);
return "_confirm_remove";
} // buildConfirmRemoveContext
/**
* doNew called when "eventSubmit_doNew" is in the request parameters to add a new user
*/
public void doNew(RunData data, Context context)
{
SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid());
state.setAttribute("mode", "new");
// mark the user as new, so on cancel it can be deleted
state.setAttribute("new", "true");
// disable auto-updates while not in list mode
disableObservers(state);
} // doNew
/**
* doEdit called when "eventSubmit_doEdit" is in the request parameters to edit a user
*/
public void doEdit(RunData data, Context context)
{
SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid());
String id = data.getParameters().getString("id");
state.removeAttribute("user");
state.removeAttribute("newuser");
// get the user
try
{
UserEdit user = UserDirectoryService.editUser(id);
state.setAttribute("user", user);
state.setAttribute("mode", "edit");
// disable auto-updates while not in list mode
disableObservers(state);
}
catch (UserNotDefinedException e)
{
Log.warn("chef", "UsersAction.doEdit: user not found: " + id);
Object[] params = new Object[]{id};
addAlert(state, rb.getFormattedMessage("useact.use_notfou", params));
state.removeAttribute("mode");
// make sure auto-updates are enabled
enableObserver(state);
}
catch (UserPermissionException e)
{
addAlert(state, rb.getString("useact.youdonot1") + " " + id);
state.removeAttribute("mode");
// make sure auto-updates are enabled
enableObserver(state);
}
catch (UserLockedException e)
{
addAlert(state, rb.getString("useact.somone") + " " + id);
state.removeAttribute("mode");
// make sure auto-updates are enabled
enableObserver(state);
}
} // doEdit
/**
* doModify called when "eventSubmit_doModify" is in the request parameters to edit a user
*/
public void doModify(RunData data, Context context)
{
if (Log.getLogger("chef").isDebugEnabled())
{
Log.debug("chef", this + ".doModify");
}
SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid());
String id = data.getParameters().getString("id");
state.removeAttribute("user");
state.removeAttribute("newuser");
// get the user
try
{
UserEdit user = UserDirectoryService.editUser(id);
state.setAttribute("user", user);
state.setAttribute("mode", "edit");
// disable auto-updates while not in list mode
disableObservers(state);
}
catch (UserNotDefinedException e)
{
Log.warn("chef", "UsersAction.doEdit: user not found: " + id);
Object[] params = new Object[]{id};
addAlert(state, rb.getFormattedMessage("useact.use_notfou", params));
state.removeAttribute("mode");
// make sure auto-updates are enabled
enableObserver(state);
}
catch (UserPermissionException e)
{
addAlert(state, rb.getString("useact.youdonot1") + " " + id);
state.removeAttribute("mode");
// make sure auto-updates are enabled
enableObserver(state);
}
catch (UserLockedException e)
{
addAlert(state, rb.getString("useact.somone") + " " + id);
state.removeAttribute("mode");
// make sure auto-updates are enabled
enableObserver(state);
}
} // doModify
/**
* doSave called when "eventSubmit_doSave" is in the request parameters to save user edits
*/
public void doSave(RunData data, Context context)
{
SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid());
if (!"POST".equals(data.getRequest().getMethod())) {
return;
}
// read the form - if rejected, leave things as they are
if (!readUserForm(data, state)) return;
// commit the change
UserEdit edit = (UserEdit) state.getAttribute("user");
if (edit != null)
{
try
{
UserDirectoryService.commitEdit(edit);
}
catch (UserAlreadyDefinedException e)
{
// TODO: this means the EID value is not unique... when we implement EID fully, we need to check this and send it back to the user
Log.warn("chef", "UsersAction.doSave()" + e);
addAlert(state, rb.getString("useact.theuseid1"));
return;
}
}
User user = edit;
if (user == null)
{
user = (User) state.getAttribute("newuser");
}
// cleanup
state.removeAttribute("user");
state.removeAttribute("newuser");
state.removeAttribute("new");
state.removeAttribute("valueEid");
state.removeAttribute("valueFirstName");
state.removeAttribute("valueLastName");
state.removeAttribute("valueEmail");
state.removeAttribute("valueType");
// return to main mode
state.removeAttribute("mode");
// make sure auto-updates are enabled
enableObserver(state);
if ((user != null) && ((Boolean) state.getAttribute("create-login")).booleanValue())
{
try
{
// login - use the fact that we just created the account as external evidence
Evidence e = new ExternalTrustedEvidence(user.getEid());
Authentication a = AuthenticationManager.authenticate(e);
if (!UsageSessionService.login(a, (HttpServletRequest) ThreadLocalManager.get(RequestFilter.CURRENT_HTTP_REQUEST)))
{
addAlert(state, rb.getString("useact.tryloginagain"));
}
}
catch (AuthenticationException ex)
{
Log.warn("chef", "UsersAction.doSave: authentication failure: " + ex);
}
// redirect to home (on next build)
state.setAttribute("redirect", "");
}
} // doSave
/**
* doCancel called when "eventSubmit_doCancel" is in the request parameters to cancel user edits
*/
public void doCancel(RunData data, Context context)
{
SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid());
if (!"POST".equals(data.getRequest().getMethod())) {
return;
}
// get the user
UserEdit user = (UserEdit) state.getAttribute("user");
if (user != null)
{
// if this was a new, delete the user
if ("true".equals(state.getAttribute("new")))
{
// remove
try
{
UserDirectoryService.removeUser(user);
}
catch (UserPermissionException e)
{
addAlert(state, rb.getString("useact.youdonot2") + " " + user.getId());
}
}
else
{
UserDirectoryService.cancelEdit(user);
}
}
// cleanup
state.removeAttribute("user");
state.removeAttribute("newuser");
state.removeAttribute("new");
state.removeAttribute("valueEid");
state.removeAttribute("valueFirstName");
state.removeAttribute("valueLastName");
state.removeAttribute("valueEmail");
state.removeAttribute("valueType");
// return to main mode
state.removeAttribute("mode");
// make sure auto-updates are enabled
enableObserver(state);
} // doCancel
/**
* doRemove called when "eventSubmit_doRemove" is in the request par ameters to confirm removal of the user
*/
public void doRemove(RunData data, Context context)
{
SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid());
// set mode so we can skip some checks in readUserForm
state.setAttribute("mode", "remove");
// read the form - if rejected, leave things as they are
if (!readUserForm(data, state)) return;
// go to remove confirm mode
state.setAttribute("mode", "confirm");
} // doRemove
/**
* doRemove_confirmed called when "eventSubmit_doRemove_confirmed" is in the request parameters to remove the user
*/
public void doRemove_confirmed(RunData data, Context context)
{
SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid());
if (!"POST".equals(data.getRequest().getMethod())) {
return;
}
// get the user
UserEdit user = (UserEdit) state.getAttribute("user");
// remove
try
{
UserDirectoryService.removeUser(user);
}
catch (UserPermissionException e)
{
addAlert(state, rb.getString("useact.youdonot2") + " " + user.getId());
}
// cleanup
state.removeAttribute("user");
state.removeAttribute("newuser");
state.removeAttribute("new");
state.removeAttribute("valueEid");
state.removeAttribute("valueFirstName");
state.removeAttribute("valueLastName");
state.removeAttribute("valueEmail");
state.removeAttribute("valueType");
// go to main mode
state.removeAttribute("mode");
// make sure auto-updates are enabled
enableObserver(state);
} // doRemove_confirmed
/**
* doCancel_remove called when "eventSubmit_doCancel_remove" is in the request parameters to cancel user removal
*/
public void doCancel_remove(RunData data, Context context)
{
SessionState state = ((JetspeedRunData) data).getPortletSessionState(((JetspeedRunData) data).getJs_peid());
if (!"POST".equals(data.getRequest().getMethod())) {
return;
}
// return to edit mode
state.setAttribute("mode", "edit");
} // doCancel_remove
/**
* Read the user form and update the user in state.
*
* @return true if the form is accepted, false if there's a validation error (an alertMessage will be set)
*/
private boolean readUserForm(RunData data, SessionState state)
{
// boolean parameters and values
// --------------Mode--singleUser-createUser-typeEnable
// Admin New-----new---false------false------true
// Admin Update--edit--false------false------true
// Gateway New---null---false------true-------false
// Account Edit--edit--true-------false------false
// read the form
String id = StringUtils.trimToNull(data.getParameters().getString("id"));
String eid = StringUtils.trimToNull(data.getParameters().getString("eid"));
state.setAttribute("valueEid", eid);
String firstName = StringUtils.trimToNull(data.getParameters().getString("first-name"));
state.setAttribute("valueFirstName", firstName);
String lastName = StringUtils.trimToNull(data.getParameters().getString("last-name"));
state.setAttribute("valueLastName", lastName);
String email = StringUtils.trimToNull(data.getParameters().getString("email"));
state.setAttribute("valueEmail", email);
String pw = StringUtils.trimToNull(data.getParameters().getString("pw"));
String pwConfirm = StringUtils.trimToNull(data.getParameters().getString("pw0"));
String pwcur = StringUtils.trimToNull(data.getParameters().getString("pwcur"));
String mode = (String) state.getAttribute("mode");
boolean singleUser = ((Boolean) state.getAttribute("single-user")).booleanValue();
boolean createUser = ((Boolean) state.getAttribute("create-user")).booleanValue();
boolean typeEnable = false;
String type = null;
if ((mode != null) && (mode.equalsIgnoreCase("new")))
{
typeEnable = true;
}
else if ((mode != null) && (mode.equalsIgnoreCase("edit")) && (!singleUser))
{
typeEnable = true;
}
if (typeEnable)
{
// for the case of Admin User tool creating new user
type = StringUtils.trimToNull(data.getParameters().getString("type"));
state.setAttribute("valueType", type);
}
else
{
if (createUser)
{
// for the case of Gateway Account tool creating new user
type = (String) state.getAttribute("create-type");
}
}
if ((Boolean)state.getAttribute("user.recaptcha-enabled"))
{
String challengeField = data.getParameters().getString("recaptcha_challenge_field");
String responseField = data.getParameters().getString("recaptcha_response_field");
if (challengeField == null) challengeField = "";
if (responseField == null) responseField = "";
ReCaptcha captcha = ReCaptchaFactory.newReCaptcha((String)state.getAttribute("user.recaptcha-public-key"), (String)state.getAttribute("user.recaptcha-private-key"), false);
ReCaptchaResponse response = captcha.checkAnswer(data.getRequest().getRemoteAddr(), challengeField, responseField);
if (!response.isValid())
{
addAlert(state, rb.getString("useact.capterr"));
state.setAttribute("recaptcha-error", response.getErrorMessage());
return false;
}
}
//insure valid email address
//email.matches(".+@.+\\..+")
if(email != null && !EmailValidator.getInstance().isValid(email)) {
addAlert(state, rb.getString("useact.invemail"));
return false;
}
// get the user
UserEdit user = (UserEdit) state.getAttribute("user");
// add if needed
if (user == null)
{
// make sure we have eid
if (eid == null)
{
addAlert(state, rb.getString("usecre.eidmis"));
return false;
}
// if in create mode, make sure we have a password
if (createUser)
{
if (pw == null)
{
addAlert(state, rb.getString("usecre.pasismis"));
return false;
}
}
// make sure we have matching password fields
if (StringUtil.different(pw, pwConfirm))
{
addAlert(state, rb.getString("usecre.pass"));
return false;
}
try
{
// add the user in one step so that all you need is add not update permission
// (the added might be "anon", and anon has add but not update permission)
//SAK-18209 only an admin user should be able to specify a ID
if (!SecurityService.isSuperUser()) {
id = null;
}
User newUser = UserDirectoryService.addUser(id, eid, firstName, lastName, email, pw, type, null);
// put the user in the state
state.setAttribute("newuser", newUser);
}
catch (UserAlreadyDefinedException e)
{
addAlert(state, rb.getString("useact.theuseid1"));
return false;
}
catch (UserIdInvalidException e)
{
addAlert(state, rb.getString("useact.theuseid2"));
return false;
}
catch (UserPermissionException e)
{
addAlert(state, rb.getString("useact.youdonot3"));
return false;
}
}
// update
else
{
if (!user.isActiveEdit())
{
try
{
// add the user in one step so that all you need is add not update permission
// (the added might be "anon", and anon has add but not update permission)
user = UserDirectoryService.editUser(user.getId());
// put the user in the state
state.setAttribute("user", user);
}
catch (UserLockedException e)
{
addAlert(state, rb.getString("useact.somels"));
return false;
}
catch (UserNotDefinedException e)
{
Object[] params = new Object[]{id};
addAlert(state, rb.getFormattedMessage("useact.use_notfou", params));
return false;
}
catch (UserPermissionException e)
{
addAlert(state, rb.getString("useact.youdonot3"));
return false;
}
}
// eid, pw, type might not be editable
if (eid != null) user.setEid(eid);
// only super user can edit name.
if (SecurityService.isSuperUser()) {
user.setFirstName(firstName);
user.setLastName(lastName);
}
user.setEmail(email);
if (type != null) user.setType(type);
// make sure the old password matches, but don't check for super users
if (!SecurityService.isSuperUser()) {
if (!user.checkPassword(pwcur)) {
addAlert(state, rb.getString("usecre.curpass"));
return false;
}
}
if (mode == null || !mode.equalsIgnoreCase("remove")) {
// make sure we have matching password fields
if (StringUtil.different(pw, pwConfirm))
{
addAlert(state, rb.getString("usecre.pass"));
return false;
}
if (pw != null) user.setPassword(pw);
}
}
return true;
}
}