/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.xmlui.aspect.administrative;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.http.HttpEnvironment;
import org.apache.commons.lang.StringUtils;
import org.dspace.app.xmlui.utils.AuthenticationUtil;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
import org.dspace.eperson.AccountManager;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.EPersonDeletionException;
/**
* Utility methods to processes actions on EPeople. These methods are used
* exclusively from the administrative flow scripts.
*
* @author scott phillips
*/
public class FlowEPersonUtils {
/** Language Strings */
private static final Message T_add_eperson_success_notice =
new Message("default","xmlui.administrative.FlowEPersonUtils.add_eperson_success_notice");
private static final Message T_edit_eperson_success_notice =
new Message("default","xmlui.administrative.FlowEPersonUtils.edit_eperson_success_notice");
private static final Message T_reset_password_success_notice =
new Message("default","xmlui.administrative.FlowEPersonUtils.reset_password_success_notice");
private static final Message t_delete_eperson_success_notice =
new Message("default","xmlui.administrative.FlowEPersonUtils.delete_eperson_success_notice");
private static final Message t_delete_eperson_failed_notice =
new Message("default","xmlui.administrative.FlowEPersonUtils.delete_eperson_failed_notice");
/**
* Add a new eperson. This method will check that the email address,
* first name, and last name are non empty. Also a check is performed
* to see if the requested email address is already in use by another
* user.
*
* @param context The current DSpace context
* @param request The HTTP request parameters
* @param objectModel Cocoon's object model
* @return A process result's object.
*/
public static FlowResult processAddEPerson(Context context, Request request, Map objectModel) throws SQLException, AuthorizeException
{
FlowResult result = new FlowResult();
result.setContinue(false); // default to no continue
// Get all our request parameters
String email = request.getParameter("email_address").trim();
String first = request.getParameter("first_name").trim();
String last = request.getParameter("last_name").trim();
String phone = request.getParameter("phone").trim();
boolean login = (request.getParameter("can_log_in") != null) ? true : false;
boolean certificate = (request.getParameter("certificate") != null) ? true : false;
// If we have errors, the form needs to be resubmitted to fix those problems
if (StringUtils.isEmpty(email))
{
result.addError("email_address");
}
if (StringUtils.isEmpty(first))
{
result.addError("first_name");
}
if (StringUtils.isEmpty(last))
{
result.addError("last_name");
}
// Check if the email address is all ready being used.
EPerson potentialDupicate = EPerson.findByEmail(context,email);
if (potentialDupicate != null)
{
// special error that the front end knows about.
result.addError("eperson_email_key");
}
// No errors, so we try to create the EPerson from the data provided
if (result.getErrors() == null)
{
EPerson newPerson = AuthenticationUtil.createNewEperson(objectModel,email);
newPerson.setFirstName(first);
newPerson.setLastName(last);
newPerson.setMetadata("phone", phone);
newPerson.setCanLogIn(login);
newPerson.setRequireCertificate(certificate);
newPerson.setSelfRegistered(false);
newPerson.update();
context.commit();
// success
result.setContinue(true);
result.setOutcome(true);
result.setMessage(T_add_eperson_success_notice);
result.setParameter("epersonID", newPerson.getID());
}
return result;
}
/**
* Edit an eperson's metadata, the email address, first name, and last name are all
* required. The user's email address can be updated but it must remain unique, if
* the email address already exists then the an error is produced.
*
* @param context The current DSpace context
* @param request The HTTP request parameters
* @param ObjectModel Cocoon's object model
* @param epersonID The unique id of the eperson being edited.
* @return A process result's object.
*/
public static FlowResult processEditEPerson(Context context,
Request request, Map ObjectModel, int epersonID)
throws SQLException, AuthorizeException
{
FlowResult result = new FlowResult();
result.setContinue(false); // default to failure
// Get all our request parameters
String email = request.getParameter("email_address");
String first = request.getParameter("first_name");
String last = request.getParameter("last_name");
String phone = request.getParameter("phone");
boolean login = (request.getParameter("can_log_in") != null) ? true : false;
boolean certificate = (request.getParameter("certificate") != null) ? true : false;
// If we have errors, the form needs to be resubmitted to fix those problems
if (StringUtils.isEmpty(email))
{
result.addError("email_address");
}
if (StringUtils.isEmpty(first))
{
result.addError("first_name");
}
if (StringUtils.isEmpty(last))
{
result.addError("last_name");
}
// No errors, so we edit the EPerson with the data provided
if (result.getErrors() == null)
{
// Grab the person in question
EPerson personModified = EPerson.find(context, epersonID);
// Make sure the email address we are changing to is unique
String originalEmail = personModified.getEmail();
if (originalEmail == null || !originalEmail.equals(email))
{
EPerson potentialDupicate = EPerson.findByEmail(context,email);
if (potentialDupicate == null)
{
personModified.setEmail(email);
}
else if (potentialDupicate.equals(personModified))
{
// set a special field in error so that the transformer can display a pretty error.
result.addError("eperson_email_key");
return result;
}
}
String originalFirstName = personModified.getFirstName();
if (originalFirstName == null || !originalFirstName.equals(first)) {
personModified.setFirstName(first);
}
String originalLastName = personModified.getLastName();
if (originalLastName == null || !originalLastName.equals(last)) {
personModified.setLastName(last);
}
String originalPhone = personModified.getMetadata("phone");
if (originalPhone == null || !originalPhone.equals(phone)) {
personModified.setMetadata("phone", phone);
}
personModified.setCanLogIn(login);
personModified.setRequireCertificate(certificate);
personModified.update();
context.commit();
result.setContinue(true);
result.setOutcome(true);
// FIXME: rename this message
result.setMessage(T_edit_eperson_success_notice);
}
// Everything was fine
return result;
}
/**
* Send the user a forgot password email message. The message will
* contain a token that the user can use to login and pick a new password.
*
* @param context The current DSpace context
* @param epersonID The unique id of the eperson being edited.
* @return A process result's object.
*/
public static FlowResult processResetPassword(Context context, int epersonID) throws IOException, MessagingException, SQLException, AuthorizeException
{
EPerson eperson = EPerson.find(context, epersonID);
// Note, this may throw an error is the email is bad.
AccountManager.sendForgotPasswordInfo(context,eperson.getEmail());
FlowResult result = new FlowResult();
result.setContinue(true);
result.setOutcome(true);
result.setMessage(T_reset_password_success_notice);
return result;
}
/**
* Log this user in as another user. If the operation failed then the flow result
* will be set to failure with it's message set correctly. Note that after logging out
* the user may not have sufficient privileges to continue.
*
* @param context The current DSpace context.
* @param objectModel Object model to obtain the HTTP request from.
* @param epersonID The epersonID of the person to login as.
* @return The flow result.
*/
public static FlowResult processLoginAs(Context context, Map objectModel, int epersonID) throws SQLException
{
FlowResult result = new FlowResult();
result.setContinue(true);
result.setOutcome(true);
final HttpServletRequest request = (HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
EPerson eperson = EPerson.find(context,epersonID);
try {
AuthenticationUtil.loginAs(context, request, eperson);
}
catch (AuthorizeException ae)
{
// give the exception error as a notice.
result.setOutcome(false);
result.setMessage(new Message(null,ae.getMessage()));
}
return result;
}
/**
* Delete the epeople specified by the epeopleIDs parameter. This assumes that the
* deletion has been confirmed.
*
* @param context The current DSpace context
* @param epeopleIDs The unique id of the eperson being edited.
* @return A process result's object.
*/
public static FlowResult processDeleteEPeople(Context context, String[] epeopleIDs) throws NumberFormatException, SQLException, AuthorizeException, EPersonDeletionException
{
FlowResult result = new FlowResult();
List<String> unableList = new ArrayList<String>();
for (String id : epeopleIDs)
{
EPerson personDeleted = EPerson.find(context, Integer.valueOf(id));
try {
personDeleted.delete();
}
catch (EPersonDeletionException epde)
{
String firstName = personDeleted.getFirstName();
String lastName = personDeleted.getLastName();
String email = personDeleted.getEmail();
unableList.add(firstName + " " + lastName + " ("+email+")");
}
}
if (unableList.size() > 0)
{
result.setOutcome(false);
result.setMessage(t_delete_eperson_failed_notice);
String characters = null;
for(String unable : unableList )
{
if (characters == null)
{
characters = unable;
}
else
{
characters += ", " + unable;
}
}
result.setCharacters(characters);
}
else
{
result.setOutcome(true);
result.setMessage(t_delete_eperson_success_notice);
}
return result;
}
}