View Javadoc

1   /*
2    * Copyright 2000-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.jetspeed.modules.actions;
18  
19   
20  // Java Core Classes
21  import java.util.Properties;
22  import java.util.Locale;
23  import java.io.StringWriter;
24  
25  import javax.servlet.http.Cookie;
26  
27  // Turbine Modules
28  import org.apache.velocity.context.Context;
29  import org.apache.turbine.TurbineConstants;
30  import org.apache.turbine.modules.ActionEvent;
31  import org.apache.turbine.services.localization.Localization;
32  import org.apache.turbine.services.velocity.TurbineVelocity;
33  import org.apache.turbine.services.template.TurbineTemplate;
34  import org.apache.turbine.util.mail.SimpleEmail;
35  import org.apache.turbine.util.DynamicURI;
36  import org.apache.turbine.util.RunData;
37  
38  // Jetspeed modules
39  import org.apache.jetspeed.services.TemplateLocator;
40  import org.apache.jetspeed.om.security.JetspeedUser;
41  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
42  import org.apache.jetspeed.services.logging.JetspeedLogger;
43  import org.apache.jetspeed.services.security.nosecurity.FakeJetspeedUser;
44  import org.apache.jetspeed.services.rundata.JetspeedRunData;
45  import org.apache.jetspeed.services.resources.JetspeedResources;
46  import org.apache.jetspeed.services.JetspeedSecurity;
47  import org.apache.jetspeed.services.security.JetspeedSecurityException;
48  import org.apache.jetspeed.services.security.LoginException;
49  import org.apache.jetspeed.services.security.FailedLoginException;
50  import org.apache.jetspeed.services.security.CredentialExpiredException;
51  import org.apache.jetspeed.services.security.AccountExpiredException;
52  
53  /***
54      This class is responsible for logging a user into the system. It is also
55      responsible for making sure that the user has been marked as confirmed. 
56      If the user is not marked as confirmed, then it will show them the 
57      
58  */
59  public class JLoginUser extends ActionEvent
60  {
61  
62      /***
63       * Static initialization of the logger for this class
64       */    
65      private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(JLoginUser.class.getName());    
66      
67      /***
68      * called when the password reminder button is pressed.
69      * sends a user their password
70      **/
71      public void doReminder( RunData rundata ) throws Exception
72      {
73          JetspeedRunData data = (JetspeedRunData)rundata;
74  
75          try {
76              String username = data.getParameters().getString("username", "");
77  
78              JetspeedUser user = null;
79  
80              try {
81                  user = JetspeedSecurity.getUser(username);
82              } catch (JetspeedSecurityException ignored) {
83              }
84  
85              if (user == null)
86              {
87                  data.setScreenTemplate("LoginHelp");
88                  data.setMessage(Localization.getString("JLOGINUSER_PASSWORDREMINDER_INVALIDUSER"));
89                  if (logger.isDebugEnabled())
90                      logger.debug(Localization.getString(rundata, "JLOGINUSER_PASSWORDREMINDER_INVALIDUSER"));
91                  return;
92              }
93  
94              user.setHasLoggedIn( Boolean.FALSE);
95              data.setUser(user);
96   
97              DynamicURI url = new DynamicURI(data);
98  
99              //build body via template
100             StringWriter email_body = new StringWriter();
101 
102             Context context = TurbineVelocity.getContext(data);
103             context.put( "data", data );
104             context.put( "user", user );
105             context.put("userurl",url);
106             context.put("config",new JetspeedResources());
107 
108             //determine the language to be used for the notification email
109             String lang = (String)user.getPerm("language");
110             String ctry = (String)user.getPerm("country");
111             Locale loc = null;
112             if (lang != null && ctry != null)
113             {
114                 loc = new Locale(lang,ctry); 
115             }
116 
117             String templatePath = TemplateLocator.locateEmailTemplate(data, JetspeedResources.getString("password.reminder.template"), loc);
118 
119             SimpleEmail se = new SimpleEmail();
120 
121             context.put("email",se);
122 
123             TurbineVelocity.handleRequest(context, templatePath, email_body);
124 
125             se.setMsg(email_body.toString());
126 
127             Properties props = System.getProperties();
128             String mailServerMachine = JetspeedResources.getString( "mail.server" );
129             props.put("mail.host", mailServerMachine );
130             props.put("mail.smtp.host", mailServerMachine);
131 
132             se.send();
133 
134             data.setMessage (Localization.getString(rundata, "JLOGINUSER_PASSWORDREMINDER_SENT"));
135             logger.info( "Password for user " + user.getUserName() + " was sent to " + user.getEmail());
136             logger.info(Localization.getString(rundata, "JLOGINUSER_PASSWORDREMINDER_SENT"));
137             data.setScreenTemplate("Login");
138         } catch ( Exception e ) {
139             data.setScreenTemplate("LoginHelp");
140             String errorTitle = Localization.getString(rundata, "JLOGINUSER_PASSWORDREMINDER_ERROR") ;
141             String errorMessage = errorTitle + e.toString();
142 
143             logger.warn( errorMessage, e );
144             data.setMessage ( errorMessage );
145         }
146     }
147 
148 
149     public void doPerform( RunData rundata ) throws Exception
150     {
151         JetspeedRunData data = (JetspeedRunData)rundata;
152         
153         String username = data.getParameters().getString("username", "");
154         String password = data.getParameters().getString("password", "");
155 
156         boolean newUserApproval = JetspeedResources.getBoolean("newuser.approval.enable", false);
157         String secretkey = (String) data.getParameters().getString("secretkey", null);
158         if ( secretkey != null )
159         {
160 
161             // its the first logon - we are verifying the secretkey
162 
163             // handle the buttons on the ConfirmRegistration page
164             String button1 = data.getParameters().getString ( "submit1", null );
165             if ( button1 != null && button1.equalsIgnoreCase("Cancel") )
166             {
167                 data.setScreenTemplate(TurbineTemplate.getDefaultScreen());
168                 return;
169             }
170             
171             // check to make sure the user entered the right confirmation key
172             // if not, then send them to the ConfirmRegistration screen            
173             JetspeedUser user = JetspeedSecurity.getUser(username);
174 
175             if (user == null)
176             {
177                 logger.warn("JLogin User: Unexpected condition : user is NULL");
178                 return;   
179             }
180             String confirm_value = user.getConfirmed();
181             if ( ! secretkey.equals ( confirm_value ) && ! confirm_value.equals ( JetspeedResources.CONFIRM_VALUE ) )
182             {
183                 if ( newUserApproval )
184                 {
185                     data.setMessage(Localization.getString(rundata, "JLOGINUSER_KEYNOTVALID"));
186                     data.setScreenTemplate("NewUserAwaitingAcceptance");
187                     return;
188                 }
189                 else
190                 {
191                   if ( user.getConfirmed().equals(JetspeedResources.CONFIRM_VALUE_REJECTED))
192                   {
193                     data.setMessage(Localization.getString(rundata, "JLOGINUSER_KEYNOTVALID"));
194                     data.setScreenTemplate("NewUserRejected");
195                     return;
196                   }
197                   else
198                   {
199                     data.setMessage(Localization.getString(rundata, "JLOGINUSER_KEYNOTVALID"));
200                     data.setScreenTemplate("ConfirmRegistration");
201                     return;
202                   }
203                 }
204             }
205              
206             user.setConfirmed( JetspeedResources.CONFIRM_VALUE );
207             data.setMessage (Localization.getString(rundata, "JLOGINUSER_WELCOME"));
208             JetspeedSecurity.saveUser(user);
209         }
210         
211         JetspeedUser user = null;
212         try
213         {
214             user = JetspeedSecurity.login(username, password);
215             JetspeedSecurity.saveUser(user);
216         }
217         catch (LoginException e)
218         {            
219             data.setScreenTemplate(JetspeedResources.getString(TurbineConstants.TEMPLATE_LOGIN));
220             String message = e.getMessage() != null ? e.getMessage() : e.toString();
221             data.setMessage(message);
222             data.setUser(JetspeedSecurity.getAnonymousUser());
223             data.getUser().setHasLoggedIn(new Boolean (false) );            
224 
225             if (e instanceof FailedLoginException)
226             {
227                 if (!disableCheck(data))
228                 {                
229                     logger.info("JLoginUser: Credential Failure on login for user: " + username);
230                     data.setMessage(Localization.getString(rundata, "PASSWORDFORM_FAILED_MSG"));
231                 }
232             }
233             else if (e instanceof AccountExpiredException)
234             {
235                 logger.info("JLoginUser: Account Expired for user " + username);
236             } 
237             else if (e instanceof CredentialExpiredException)
238             {
239                 logger.info("JLoginUser: Credentials expired for user: " + username);
240                 data.setScreenTemplate(
241                     JetspeedResources.getString(JetspeedResources.CHANGE_PASSWORD_TEMPLATE, "ChangePassword")
242                     );
243                 data.setMessage(Localization.getString(rundata, "PASSWORDFORM_EXPIRED_MSG"));
244                 data.getParameters().setString("username", username);
245             } 
246 
247             return;
248         }
249         catch (Throwable other)
250         {
251             data.setScreenTemplate(JetspeedResources.getString(TurbineConstants.TEMPLATE_ERROR));
252             String message = other.getMessage() != null ? other.getMessage() : other.toString();
253             data.setMessage(message);
254             data.setStackTrace(org.apache.turbine.util.StringUtils.stackTrace(other), other);
255             JetspeedUser juser = new FakeJetspeedUser(JetspeedSecurity.getAnonymousUserName(), false);
256             data.setUser(juser);
257             return;
258         }
259         if (user.getDisabled())
260         {
261             data.setMessage(Localization.getString(rundata, "JLOGINUSER_ACCOUNT_DISABLED"));
262             data.setScreenTemplate(JetspeedResources.getString("logon.disabled.form"));
263             data.getUser().setHasLoggedIn(new Boolean (false) );
264             return;
265         }
266 
267         // check for being confirmed before allowing someone to finish logging in
268         if ( data.getUser().hasLoggedIn())
269         {
270             if  (JetspeedSecurity.isDisableAccountCheckEnabled())
271             {
272                 // dst: this needs some refactoring. I don't believe this api is necessary
273                 JetspeedSecurity.resetDisableAccountCheck(data.getParameters().getString("username", ""));
274             }        
275 
276             String confirmed = data.getUser().getConfirmed();
277             if (confirmed == null || !confirmed.equals(JetspeedResources.CONFIRM_VALUE ))
278             {
279                 if (confirmed != null && confirmed.equals(JetspeedResources.CONFIRM_VALUE_REJECTED))
280                 {
281                   data.setMessage(Localization.getString(rundata, "JLOGINUSER_KEYNOTVALID"));
282                   data.setScreenTemplate("NewUserRejected");
283                   data.getUser().setHasLoggedIn(new Boolean (false) );
284                   return;
285                 }
286                 else
287                 {
288                   data.setMessage(Localization.getString(rundata, "JLOGINUSER_CONFIRMFIRST"));
289                   data.setScreenTemplate("ConfirmRegistration");
290                   data.getUser().setHasLoggedIn(new Boolean (false) );
291                   return;
292                 }
293             }
294 
295             // user has logged in successfully at this point
296   
297             boolean automaticLogonEnabled = JetspeedResources.getBoolean("automatic.logon.enable", false);
298             if (automaticLogonEnabled)
299             {
300               //Does the user want to use this facility?
301               boolean userRequestsRememberMe = data.getParameters().getBoolean("rememberme",false);
302               if (userRequestsRememberMe)
303               {
304                 //save cookies on the users machine.
305                 int maxage = JetspeedResources.getInt("automatic.logon.cookie.maxage",-1);
306                 String comment = JetspeedResources.getString("automatic.logon.cookie.comment","");
307                 String domain = JetspeedResources.getString("automatic.logon.cookie.domain");
308                 String path = JetspeedResources.getString("automatic.logon.cookie.path","/");
309 
310                 if (domain == null)
311                 {
312                   String server = data.getServerName();
313                   domain = "." + server;
314                 }
315 
316                 String loginCookieValue = null;
317 
318                 if ( JetspeedResources.getString("automatic.logon.cookie.generation","everylogon").equals("everylogon") )
319                 {
320                   loginCookieValue = ""+Math.random();
321                   data.getUser().setPerm("logincookie",loginCookieValue);
322                   JetspeedSecurity.saveUser( data.getJetspeedUser() );
323                 } 
324                 else 
325                 {
326                   loginCookieValue = (String)data.getUser().getPerm("logincookie");
327                   if (loginCookieValue == null || loginCookieValue.length() == 0)
328                   {
329                     loginCookieValue = ""+Math.random();
330                     data.getUser().setPerm("logincookie",loginCookieValue);
331                     JetspeedSecurity.saveUser( data.getJetspeedUser() );
332                   }
333                 }
334 
335                 Cookie userName = new Cookie("username",data.getUser().getUserName());
336                 Cookie loginCookie = new Cookie("logincookie",loginCookieValue);
337 
338                 userName.setMaxAge(maxage);
339                 userName.setComment(comment);
340                 userName.setDomain(domain);
341                 userName.setPath(path);
342 
343                 loginCookie.setMaxAge(maxage);
344                 loginCookie.setComment(comment);
345                 loginCookie.setDomain(domain);
346                 loginCookie.setPath(path);
347 
348                 data.getResponse().addCookie(userName);
349                 data.getResponse().addCookie(loginCookie);
350 
351               }
352                     
353             }
354 
355         }
356         else
357         {
358             disableCheck(data);
359         }
360 
361     }
362 
363     private boolean disableCheck(JetspeedRunData data)
364     {
365         boolean disabled = false;
366         // disable user after a configurable number of strikes
367         if  (JetspeedSecurity.isDisableAccountCheckEnabled())
368         {
369             disabled = JetspeedSecurity.checkDisableAccount(data.getParameters().getString("username", ""));
370             
371             if (disabled)
372             {
373                 data.setMessage(Localization.getString(data, "JLOGINUSER_ACCOUNT_DISABLED"));
374                 data.setScreenTemplate(JetspeedResources.getString("logon.disabled.form"));
375                 data.getUser().setHasLoggedIn(new Boolean (false) );
376             }
377         }
378         return disabled;
379     }
380 }