KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > app > webui > servlet > RegisterServlet


1 /*
2  * RegisterServlet.java
3  *
4  * Version: $Revision: 1.18 $
5  *
6  * Date: $Date: 2006/09/12 10:39:14 $
7  *
8  * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
9  * Institute of Technology. All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * - Neither the name of the Hewlett-Packard Company nor the name of the
23  * Massachusetts Institute of Technology nor the names of their
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */

40 package org.dspace.app.webui.servlet;
41
42 import java.io.IOException JavaDoc;
43 import java.sql.SQLException JavaDoc;
44
45 import javax.mail.Message JavaDoc;
46 import javax.mail.MessagingException JavaDoc;
47 import javax.mail.internet.AddressException JavaDoc;
48 import javax.mail.internet.InternetAddress JavaDoc;
49 import javax.servlet.ServletException JavaDoc;
50 import javax.servlet.http.HttpServletRequest JavaDoc;
51 import javax.servlet.http.HttpServletResponse JavaDoc;
52
53 import org.apache.log4j.Logger;
54 import org.dspace.app.webui.util.Authenticate;
55 import org.dspace.app.webui.util.JSPManager;
56 import org.dspace.app.webui.util.UIUtil;
57 import org.dspace.authorize.AuthorizeException;
58 import org.dspace.core.ConfigurationManager;
59 import org.dspace.core.Context;
60 import org.dspace.core.LogManager;
61 import org.dspace.eperson.AccountManager;
62 import org.dspace.eperson.EPerson;
63 import org.dspace.eperson.AuthenticationManager;
64
65 import com.sun.mail.smtp.SMTPAddressFailedException;
66
67 import java.util.Hashtable JavaDoc;
68 import javax.naming.*;
69 import javax.naming.directory.*;
70
71 /**
72  * Servlet for handling user registration and forgotten passwords.
73  * <P>
74  * This servlet handles both forgotten passwords and initial registration of
75  * users. Which it handles depends on the initialisation parameter "register" -
76  * if it's "true", it is treated as an initial registration and the user is
77  * asked to input their personal information.
78  * <P>
79  * The sequence of events is this: The user clicks on "register" or "I forgot my
80  * password." This servlet then displays the relevant "enter your e-mail" form.
81  * An e-mail address is POSTed back, and if this is valid, a token is created
82  * and e-mailed, otherwise an error is displayed, with another "enter your
83  * e-mail" form.
84  * <P>
85  * When the user clicks on the token URL mailed to them, this servlet receives a
86  * GET with the token as the parameter "KEY". If this is a valid token, the
87  * servlet then displays the "edit profile" or "edit password" screen as
88  * appropriate.
89  */

90 public class RegisterServlet extends DSpaceServlet
91 {
92     /** Logger */
93     private static Logger log = Logger.getLogger(RegisterServlet.class);
94
95     /** The "enter e-mail" step */
96     public static final int ENTER_EMAIL_PAGE = 1;
97
98     /** The "enter personal info" page, for a registering user */
99     public static final int PERSONAL_INFO_PAGE = 2;
100
101     /** The simple "enter new password" page, for user who's forgotten p/w */
102     public static final int NEW_PASSWORD_PAGE = 3;
103
104     /** true = registering users, false = forgotten passwords */
105     private boolean registering;
106
107     /** ldap is enabled */
108     private boolean ldap_enabled;
109
110     public void init()
111     {
112         registering = getInitParameter("register").equalsIgnoreCase("true");
113         ldap_enabled = ConfigurationManager.getBooleanProperty("ldap.enable");
114     }
115
116     protected void doDSGet(Context context, HttpServletRequest JavaDoc request,
117             HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc,
118             SQLException JavaDoc, AuthorizeException
119     {
120         /*
121          * Respond to GETs. A simple GET with no parameters will display the
122          * relevant "type in your e-mail" form. A GET with a "token" parameter
123          * will go to the "enter personal info" or "enter new password" page as
124          * appropriate.
125          */

126         boolean updated = false;
127
128         // Get the token
129
String JavaDoc token = request.getParameter("token");
130
131         if (token == null)
132         {
133             // Simple "enter your e-mail" page
134
if (registering)
135             {
136                 // Registering a new user
137
if (ldap_enabled) JSPManager.showJSP(request, response, "/register/new-ldap-user.jsp");
138                 JSPManager.showJSP(request, response, "/register/new-user.jsp");
139             }
140             else
141             {
142                 // User forgot their password
143
JSPManager.showJSP(request, response,
144                         "/register/forgot-password.jsp");
145             }
146         }
147         else
148         {
149             // We have a token. Find out who the it's for
150
String JavaDoc email = AccountManager.getEmail(context, token);
151
152             EPerson eperson = null;
153
154             if (email != null)
155             {
156                 eperson = EPerson.findByEmail(context, email);
157             }
158
159             // Both forms need an EPerson object (if any)
160
request.setAttribute("eperson", eperson);
161
162             // And the token
163
request.setAttribute("token", token);
164
165             if (registering && (email != null))
166             {
167                 // Indicate if user can set password
168
boolean setPassword =
169                     AuthenticationManager.allowSetPassword(context, request, email);
170                 request.setAttribute("set.password", new Boolean JavaDoc(setPassword));
171
172                 // Forward to "personal info page"
173
JSPManager.showJSP(request, response,
174                         "/register/registration-form.jsp");
175             }
176             else if (!registering && (eperson != null))
177             {
178                 // Token relates to user who's forgotten password
179
JSPManager.showJSP(request, response,
180                         "/register/new-password.jsp");
181             }
182             else
183             {
184                 // Duff token!
185
JSPManager.showJSP(request, response,
186                         "/register/invalid-token.jsp");
187
188                 return;
189             }
190         }
191     }
192
193     protected void doDSPost(Context context, HttpServletRequest JavaDoc request,
194             HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc,
195             SQLException JavaDoc, AuthorizeException
196     {
197         /*
198          * POSTs are the result of entering an e-mail in the "forgot my
199          * password" or "new user" forms, or the "enter profile information" or
200          * "enter new password" forms.
201          */

202
203         // First get the step
204
int step = UIUtil.getIntParameter(request, "step");
205
206         switch (step)
207         {
208         case ENTER_EMAIL_PAGE:
209             processEnterEmail(context, request, response);
210
211             break;
212
213         case PERSONAL_INFO_PAGE:
214             processPersonalInfo(context, request, response);
215
216             break;
217
218         case NEW_PASSWORD_PAGE:
219             processNewPassword(context, request, response);
220
221             break;
222
223         default:
224             log.warn(LogManager.getHeader(context, "integrity_error", UIUtil
225                     .getRequestLogInfo(request)));
226             JSPManager.showIntegrityError(request, response);
227         }
228     }
229
230     /**
231      * Process information from the "enter e-mail" page. If the e-mail
232      * corresponds to a valid user of the system, a token is generated and sent
233      * to that user.
234      *
235      * @param context
236      * current DSpace context
237      * @param request
238      * current servlet request object
239      * @param response
240      * current servlet response object
241      */

242     private void processEnterEmail(Context context, HttpServletRequest JavaDoc request,
243             HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc,
244             SQLException JavaDoc, AuthorizeException
245     {
246         String JavaDoc email = request.getParameter("email").toLowerCase().trim();
247         String JavaDoc netid = request.getParameter("netid");
248         String JavaDoc password = request.getParameter("password");
249         EPerson eperson = EPerson.findByEmail(context, email);
250         EPerson eperson2 = null;
251         if (netid!=null) eperson2 = EPerson.findByNetid(context, netid);
252
253         try
254         {
255             if (registering)
256             {
257                 // If an already-active user is trying to register, inform them so
258
if ((eperson != null && eperson.canLogIn()) || (eperson2 != null && eperson2.canLogIn()))
259                 {
260                     log.info(LogManager.getHeader(context,
261                             "already_registered", "email=" + email));
262
263                     JSPManager.showJSP(request, response,
264                             "/register/already-registered.jsp");
265                 }
266                 else
267                 {
268                     // Find out from site authenticator whether this email can
269
// self-register
270
boolean canRegister =
271                         AuthenticationManager.canSelfRegister(context, request, email);
272
273                     if (canRegister)
274                     {
275                         //-- registering by email
276
if ((!ldap_enabled)||(netid==null)||(netid.trim().equals("")))
277                         {
278                             // OK to register. Send token.
279
log.info(LogManager.getHeader(context,
280                                 "sendtoken_register", "email=" + email));
281
282                             try
283                             {
284                                 AccountManager.sendRegistrationInfo(context, email);
285                             }
286                             catch (javax.mail.SendFailedException JavaDoc e)
287                             {
288                                 if (e.getNextException() instanceof SMTPAddressFailedException)
289                                 {
290                                     // If we reach here, the email is email is invalid for the SMTP server (i.e. fbotelho).
291
log.info(LogManager.getHeader(context,
292                                         "invalid_email",
293                                         "email=" + email));
294                                     request.setAttribute("retry", new Boolean JavaDoc(true));
295                                     JSPManager.showJSP(request, response, "/register/new-user.jsp");
296                                     return;
297                                 }
298                                 else
299                                 {
300                                     throw e;
301                                 }
302                             }
303                             JSPManager.showJSP(request, response,
304                                 "/register/registration-sent.jsp");
305
306                             // Context needs completing to write registration data
307
context.complete();
308                         }
309                         //-- registering by netid
310
else
311                         {
312                             //--------- START LDAP AUTH SECTION -------------
313
if (password!=null && !password.equals(""))
314                             {
315                                 String JavaDoc ldap_provider_url = ConfigurationManager.getProperty("ldap.provider_url");
316                                 String JavaDoc ldap_id_field = ConfigurationManager.getProperty("ldap.id_field");
317                                 String JavaDoc ldap_search_context = ConfigurationManager.getProperty("ldap.search_context");
318                            
319                                 // Set up environment for creating initial context
320
Hashtable JavaDoc env = new Hashtable JavaDoc(11);
321                                 env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
322                                 env.put(javax.naming.Context.PROVIDER_URL, ldap_provider_url);
323                         
324                                 // Authenticate
325
env.put(javax.naming.Context.SECURITY_AUTHENTICATION, "simple");
326                                 env.put(javax.naming.Context.SECURITY_PRINCIPAL, ldap_id_field+"="+netid+","+ldap_search_context);
327                                 env.put(javax.naming.Context.SECURITY_CREDENTIALS, password);
328                         
329                                 try {
330                                    // Create initial context
331
DirContext ctx = new InitialDirContext(env);
332              
333                                    // Close the context when we're done
334
ctx.close();
335                                 }
336                                 catch (NamingException e)
337                                 {
338                                     // If we reach here, supplied email/password was duff.
339
log.info(LogManager.getHeader(context,
340                                         "failed_login",
341                                         "netid=" + netid + e));
342                                     JSPManager.showJSP(request, response, "/login/ldap-incorrect.jsp");
343                                     return;
344                                 }
345                             }
346                             //--------- END LDAP AUTH SECTION -------------
347
// Forward to "personal info page"
348
JSPManager.showJSP(request, response, "/register/registration-form.jsp");
349                         }
350                     }
351                     else
352                     {
353                         JSPManager.showJSP(request, response,
354                             "/register/cannot-register.jsp");
355                     }
356                 }
357             }
358             else
359             {
360                 if (eperson == null)
361                 {
362                     // Invalid email address
363
log.info(LogManager.getHeader(context, "unknown_email",
364                             "email=" + email));
365
366                     request.setAttribute("retry", new Boolean JavaDoc(true));
367
368                     JSPManager.showJSP(request, response,
369                             "/register/forgot-password.jsp");
370                 }
371                 else if (!eperson.canLogIn())
372                 {
373                     // Can't give new password to inactive user
374
log.info(LogManager.getHeader(context,
375                             "unregistered_forgot_password", "email=" + email));
376
377                     JSPManager.showJSP(request, response,
378                             "/register/inactive-account.jsp");
379                 }
380                 else if (eperson.getRequireCertificate() && !registering)
381                 {
382                     // User that requires certificate can't get password
383
log.info(LogManager.getHeader(context,
384                             "certificate_user_forgot_password", "email="
385                                     + email));
386
387                     JSPManager.showJSP(request, response,
388                             "/error/require-certificate.jsp");
389                 }
390                 else
391                 {
392                     // OK to send forgot pw token.
393
log.info(LogManager.getHeader(context,
394                             "sendtoken_forgotpw", "email=" + email));
395
396                     AccountManager.sendForgotPasswordInfo(context, email);
397                     JSPManager.showJSP(request, response,
398                             "/register/password-token-sent.jsp");
399
400                     // Context needs completing to write registration data
401
context.complete();
402                 }
403             }
404         }
405         catch (AddressException JavaDoc ae)
406         {
407             // Malformed e-mail address
408
log.info(LogManager.getHeader(context, "bad_email", "email="
409                     + email));
410
411             request.setAttribute("retry", new Boolean JavaDoc(true));
412
413             if (registering)
414             {
415                 if (ldap_enabled) JSPManager.showJSP(request, response, "/register/new-ldap-user.jsp");
416                 else JSPManager.showJSP(request, response, "/register/new-user.jsp");
417             }
418             else
419             {
420                 JSPManager.showJSP(request, response,
421                         "/register/forgot-password.jsp");
422             }
423         }
424         catch (MessagingException JavaDoc me)
425         {
426             // Some other mailing error
427
log.info(LogManager.getHeader(context, "error_emailing", "email="
428                     + email), me);
429
430             JSPManager.showInternalError(request, response);
431         }
432     }
433
434     /**
435      * Process information from "Personal information page"
436      *
437      * @param context
438      * current DSpace context
439      * @param request
440      * current servlet request object
441      * @param response
442      * current servlet response object
443      */

444     private void processPersonalInfo(Context context,
445             HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
446             throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc,
447             AuthorizeException
448     {
449         // Get the token
450
String JavaDoc token = request.getParameter("token");
451
452         // Get the email address
453
String JavaDoc email = AccountManager.getEmail(context, token);
454         String JavaDoc netid = request.getParameter("netid");
455         if ((netid!=null)&&(email==null)) email = request.getParameter("email");
456         
457         // If the token isn't valid, show an error
458
if (email == null && netid==null)
459         {
460             log.info(LogManager.getHeader(context, "invalid_token", "token="
461                 + token));
462
463             // Invalid token
464
JSPManager
465                 .showJSP(request, response, "/register/invalid-token.jsp");
466
467             return;
468         }
469
470         // If the token is valid, we create an eperson record if need be
471
EPerson eperson = null;
472         if (email!=null) eperson = EPerson.findByEmail(context, email);
473         EPerson eperson2 = null;
474         eperson2 = EPerson.findByNetid(context, netid);
475         if (eperson2 !=null) eperson = eperson2;
476         
477         if (eperson == null)
478         {
479             // Need to create new eperson
480
// FIXME: TEMPORARILY need to turn off authentication, as usually
481
// only site admins can create e-people
482
context.setIgnoreAuthorization(true);
483             eperson = EPerson.create(context);
484             eperson.setEmail(email);
485             eperson.setNetid(netid);
486             eperson.update();
487             context.setIgnoreAuthorization(false);
488         }
489
490         // Now set the current user of the context
491
// to the user associated with the token, so they can update their
492
// info
493
context.setCurrentUser(eperson);
494
495         // Set the user profile info
496
boolean infoOK = EditProfileServlet.updateUserProfile(eperson, request);
497
498         eperson.setCanLogIn(true);
499         eperson.setSelfRegistered(true);
500
501         // Give site auth a chance to set/override appropriate fields
502
AuthenticationManager.initEPerson(context, request, eperson);
503
504         // If the user set a password, make sure it's OK
505
boolean passwordOK = true;
506         if (eperson.getRequireCertificate() == false && netid==null &&
507             AuthenticationManager.allowSetPassword(context, request,
508                 eperson.getEmail()))
509         {
510             passwordOK = EditProfileServlet.confirmAndSetPassword(eperson,
511                     request);
512         }
513
514         if (infoOK && passwordOK)
515         {
516             // All registered OK.
517
log.info(LogManager.getHeader(context, "usedtoken_register",
518                     "email=" + eperson.getEmail()));
519
520             // delete the token
521
if (token!=null) AccountManager.deleteToken(context, token);
522             
523             // Update user record
524
eperson.update();
525
526             request.setAttribute("eperson", eperson);
527             JSPManager.showJSP(request, response, "/register/registered.jsp");
528             context.complete();
529         }
530         else
531         {
532             request.setAttribute("token", token);
533             request.setAttribute("eperson", eperson);
534             request.setAttribute("netid", netid);
535             request.setAttribute("missing.fields", new Boolean JavaDoc(!infoOK));
536             request.setAttribute("password.problem", new Boolean JavaDoc(!passwordOK));
537
538             // Indicate if user can set password
539
boolean setPassword = AuthenticationManager.allowSetPassword(
540                     context, request, email);
541             request.setAttribute("set.password", new Boolean JavaDoc(setPassword));
542
543             JSPManager.showJSP(request, response,
544                     "/register/registration-form.jsp");
545
546             // Changes to/creation of e-person in DB cancelled
547
context.abort();
548         }
549     }
550
551     /**
552      * Process information from "enter new password"
553      *
554      * @param context
555      * current DSpace context
556      * @param request
557      * current servlet request object
558      * @param response
559      * current servlet response object
560      */

561     private void processNewPassword(Context context,
562             HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
563             throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc,
564             AuthorizeException
565     {
566         // Get the token
567
String JavaDoc token = request.getParameter("token");
568
569         // Get the eperson associated with the password change
570
EPerson eperson = AccountManager.getEPerson(context, token);
571
572         // If the token isn't valid, show an error
573
if (eperson == null)
574         {
575             log.info(LogManager.getHeader(context, "invalid_token", "token="
576                     + token));
577
578             // Invalid token
579
JSPManager
580                     .showJSP(request, response, "/register/invalid-token.jsp");
581
582             return;
583         }
584
585         // If the token is valid, we set the current user of the context
586
// to the user associated with the token, so they can update their
587
// info
588
context.setCurrentUser(eperson);
589
590         // Confirm and set the password
591
boolean passwordOK = EditProfileServlet.confirmAndSetPassword(eperson,
592                 request);
593
594         if (passwordOK)
595         {
596             log.info(LogManager.getHeader(context, "usedtoken_forgotpw",
597                     "email=" + eperson.getEmail()));
598
599             eperson.update();
600             AccountManager.deleteToken(context, token);
601
602             JSPManager.showJSP(request, response,
603                     "/register/password-changed.jsp");
604             context.complete();
605         }
606         else
607         {
608             request.setAttribute("password.problem", new Boolean JavaDoc(true));
609             request.setAttribute("token", token);
610             request.setAttribute("eperson", eperson);
611
612             JSPManager.showJSP(request, response, "/register/new-password.jsp");
613         }
614     }
615 }
616
Popular Tags