diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 59a4579d6c..a2a41e250c 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -106,6 +106,10 @@ webui.site.authenticator = edu.mit.dspace.MITAuthenticator # Certificate authority webui.cert.ca = /dspace/etc/certificate-ca.pem +# Can users self-register? i.e. can anyone type in an e-mail and give themselves +# an e-person record? +webui.self.register = true + ##### OAI protocol for metadata harvesting settings ##### diff --git a/dspace/etc/database_schema.sql b/dspace/etc/database_schema.sql index c0405f176d..c35198f692 100644 --- a/dspace/etc/database_schema.sql +++ b/dspace/etc/database_schema.sql @@ -389,7 +389,7 @@ CREATE TABLE TasklistItem CREATE TABLE RegistrationData ( registrationdata_id INTEGER PRIMARY KEY, - eperson_id INTEGER REFERENCES EPerson(eperson_id), + email VARCHAR(64) UNIQUE, token VARCHAR(48), expires TIMESTAMP ); diff --git a/dspace/jsp/register/registration-sent.jsp b/dspace/jsp/register/registration-sent.jsp index 0050507f25..9b2a1b87f1 100644 --- a/dspace/jsp/register/registration-sent.jsp +++ b/dspace/jsp/register/registration-sent.jsp @@ -50,6 +50,6 @@
You have been sent an e-mail containing a special URL, or "token". When you visit this URL, you will need to fill out some simple information. - After that, you'll be ready to submit your work to DSpace!
+ After that, you'll be ready to log into DSpace! diff --git a/dspace/src/org/dspace/app/webui/servlet/RegisterServlet.java b/dspace/src/org/dspace/app/webui/servlet/RegisterServlet.java index 59ceadaa1c..ed5b605980 100644 --- a/dspace/src/org/dspace/app/webui/servlet/RegisterServlet.java +++ b/dspace/src/org/dspace/app/webui/servlet/RegisterServlet.java @@ -53,6 +53,7 @@ import org.apache.log4j.Logger; import org.dspace.app.webui.util.JSPManager; import org.dspace.app.webui.util.UIUtil; import org.dspace.authorize.AuthorizeException; +import org.dspace.core.ConfigurationManager; import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.eperson.AccountManager; @@ -114,6 +115,8 @@ public class RegisterServlet extends DSpaceServlet * password" page as appropriate. */ + boolean updated = false; + // Get the key String key = request.getParameter("token"); @@ -136,7 +139,40 @@ public class RegisterServlet extends DSpaceServlet else { // Find out who the key is for + String email = AccountManager.getEmail(context, key); EPerson eperson = AccountManager.getEPerson(context, key); + + if (eperson == null && + email != null && + ConfigurationManager.getBooleanProperty("webui.self.register") && + registering) + { + /* + * The token relates to a user who is trying to register + * themselves, and the site configuration allows this. + * FIXME: Obviously the user has no real authorisation to + * create an e-person record, so we switch off authorisation + * TEMPORARILY + */ + context.setIgnoreAuthorization(true); + EPerson e = EPerson.create(context); + context.setCurrentUser(e); + context.setIgnoreAuthorization(false); + + // Fill out what we know + e.setEmail(email); + e.setFirstName(""); // Avoid NullPointer nastiness + e.setLastName(""); + e.setSelfRegistered(true); + e.setCanLogIn(false); // they don't have a password yet + e.setRequireCertificate(false); // FIXME: Maybe site policy + // should be able to require certs in this case + e.update(); + + eperson = e; // Remainder of code displays "profile" page + updated = true; + } + /* Display an error if it's: * An invalid token @@ -176,6 +212,12 @@ public class RegisterServlet extends DSpaceServlet "/register/new-password.jsp"); } } + + if (updated) + { + // New e-person record created during self-registration + context.complete(); + } } @@ -229,7 +271,7 @@ public class RegisterServlet extends DSpaceServlet HttpServletResponse response) throws ServletException, IOException, SQLException, AuthorizeException { - String email = request.getParameter("email"); + String email = request.getParameter("email").toLowerCase(); EPerson eperson = EPerson.findByEmail(context, email); @@ -313,6 +355,35 @@ public class RegisterServlet extends DSpaceServlet JSPManager.showInternalError(request, response); } } + else if (registering && + ConfigurationManager.getBooleanProperty("webui.self.register")) + { + try + { + // Unrecognised e-mail address, so assume a new user and send + // initial registration email. + log.info(LogManager.getHeader(context, + "sendtoken_newuser", + "email=" + email)); + + AccountManager.sendRegistrationInfo(context, email); + JSPManager.showJSP(request, + response, + "/register/registration-sent.jsp"); + + // Context needs completing to write registration data + context.complete(); + } + catch (MessagingException me) + { + log.info(LogManager.getHeader(context, + "error_emailing", + "email=" + email), + me); + + JSPManager.showInternalError(request, response); + } + } else { log.info(LogManager.getHeader(context, diff --git a/dspace/src/org/dspace/eperson/AccountManager.java b/dspace/src/org/dspace/eperson/AccountManager.java index e389d5e6aa..4f9e52af28 100644 --- a/dspace/src/org/dspace/eperson/AccountManager.java +++ b/dspace/src/org/dspace/eperson/AccountManager.java @@ -80,7 +80,6 @@ public class AccountManager * Email registration info to the given email address. * * Potential error conditions: - * No EPerson with that email (returns null) * Cannot create registration data in database (throws SQLException) * Error sending email (throws MessagingException) * Error reading email template (throws IOException) @@ -129,6 +128,29 @@ public class AccountManager */ public static EPerson getEPerson(Context context, String token) + throws SQLException, AuthorizeException + { + String email = getEmail(context, token); + + if (email == null) + { + return null; + } + + EPerson ep = EPerson.findByEmail(context, email); + return ep; + } + + + /** + * Return the e-mail address referred to by a token + * + * @param context DSpace context + * @param token Account token + * @return The email address corresponding to token, or null. + */ + public static String getEmail(Context context, + String token) throws SQLException { TableRow rd = DatabaseManager.findByUnique(context, @@ -146,19 +168,10 @@ public class AccountManager return null; } - if (rd.isColumnNull("eperson_id")) - throw new IllegalStateException("Eperson id not specified"); - - // This could conceivably happen if someone deleted the EPerson - // without removing the token. - EPerson ep = EPerson.find(context, rd.getIntColumn("eperson_id")); - - if (ep == null) - return null; - - return ep; + return rd.getStringColumn("email"); } + /** * Delete the callback for token. * @@ -203,15 +216,10 @@ public class AccountManager boolean send) throws SQLException, IOException, MessagingException, AuthorizeException { - EPerson ep = EPerson.findByEmail(context, email); - - if (ep == null) - return null; - TableRow rd = DatabaseManager.create(context, "RegistrationData"); rd.setColumn("token", Utils.generateHexKey()); rd.setColumn("expires", getDefaultExpirationDate()); - rd.setColumn("eperson_id", ep.getID()); + rd.setColumn("email", email); DatabaseManager.update(context, rd); // This is a potential problem -- if we create the callback @@ -222,7 +230,6 @@ public class AccountManager log.debug("Created callback " + rd.getIntColumn("registrationdata_id") + " with token " + rd.getStringColumn("token") + - " for eperson " + ep.getID() + " with email \"" + email + "\""); if (send)