View Javadoc

1   /*
2    * This software was designed and created by Jason Carroll.
3    * Copyright (c) 2002, 2003, 2004 Jason Carroll.
4    * The author can be reached at jcarroll@cowsultants.com
5    * ITracker website: http://www.cowsultants.com
6    * ITracker forums: http://www.cowsultants.com/phpBB/index.php
7    *
8    * This program is free software; you can redistribute it and/or modify
9    * it only under the terms of the GNU General Public License as published by
10   * the Free Software Foundation; either version 2 of the License, or
11   * (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   */
18  
19  package org.itracker.web.actions.preferences;
20  
21  import java.io.IOException;
22  
23  import javax.servlet.ServletException;
24  import javax.servlet.http.HttpServletRequest;
25  import javax.servlet.http.HttpServletResponse;
26  import javax.servlet.http.HttpSession;
27  
28  import org.apache.log4j.Logger;
29  import org.apache.struts.action.ActionForm;
30  import org.apache.struts.action.ActionForward;
31  import org.apache.struts.action.ActionMapping;
32  import org.apache.struts.action.ActionMessage;
33  import org.apache.struts.action.ActionMessages;
34  import org.itracker.core.resources.ITrackerResources;
35  import org.itracker.model.User;
36  import org.itracker.model.UserPreferences;
37  import org.itracker.services.UserService;
38  import org.itracker.services.exceptions.AuthenticatorException;
39  import org.itracker.services.exceptions.PasswordException;
40  import org.itracker.services.exceptions.UserException;
41  import org.itracker.services.util.AuthenticationConstants;
42  import org.itracker.services.util.UserUtilities;
43  import org.itracker.web.actions.base.ItrackerBaseAction;
44  import org.itracker.web.forms.UserForm;
45  import org.itracker.web.util.Constants;
46  import org.itracker.web.util.LoginUtilities;
47  
48  
49  
50  /**
51    * This class performas an update of the user's profile information based on their input.
52    * Only the users core profile information, password, and preferences are updated, no permissions
53    * can be updated from here.  Also each type of information is only updated, if it is allowed
54    * by the current systems plugable authentication.
55    */
56  public class EditPreferencesAction extends ItrackerBaseAction {
57  	private static final Logger log = Logger.getLogger(EditPreferencesAction.class);
58  	
59      public EditPreferencesAction() {
60      }
61  
62      public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
63          log.debug("Starting pref mod");
64          ActionMessages errors = new ActionMessages();
65  		//  TODO: Action Cleanup
66  
67          if(! isTokenValid(request)) {
68              log.debug("Invalid request token while editing user preferences.");
69  			errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
70  			"itracker.web.error.transaction"));
71  			saveErrors(request, errors);
72              return mapping.findForward("index");
73          }
74          resetToken(request);
75  
76          User user = null;
77          try {
78              UserService userService = getITrackerServices().getUserService();
79  
80              // TODO: the following checks make no sense from my perspective.
81              // This check should happen in the ExecuteAlways filter maybe
82              // Shall we remove it?
83              
84              HttpSession session = request.getSession();
85  //            user = (User) session.getAttribute(Constants.USER_KEY);
86  //            if(user == null) {
87  //                return mapping.findForward("login");
88  //            }
89  //
90  //            User existingUser = userService.getUser(user.getId());
91  //            if(existingUser == null || user.getId() != existingUser.getId()) {
92  //            	if (log.isDebugEnabled()) {
93  //            		log.debug("execute: Unauthorized edit preferences request from " + user.getLogin() + "(" + user.getId() + ") for " + existingUser.getLogin() + "(" + existingUser.getId() + ")");
94  //            	}
95  //                return mapping.findForward("unauthorized");
96  //            }
97              UserForm userForm = (UserForm) form;
98              
99              if (LoginUtilities.getCurrentUser(request) != null) {
100             	user = LoginUtilities.getCurrentUser(request);
101             }
102 
103             if (log.isInfoEnabled()) {
104             	log.info("execute: found user " + user);
105             }
106             errors = form.validate(mapping, request);
107 
108 //            User existingUser = userService.getUser(user.getId());
109             // edit user-object
110             if(errors.isEmpty()) {
111             	if (log.isDebugEnabled()){
112             		log.debug("execute: updating user-attributes.");
113             	}
114             		
115                 if(userService.allowPasswordUpdates(user, null, UserUtilities.AUTH_TYPE_UNKNOWN, UserUtilities.REQ_SOURCE_WEB)) {
116                     if(userForm.getPassword() != null && userForm.getPassword().trim().length() > 1) {
117                         if(userForm.getCurrPassword() == null || "".equals(userForm.getCurrPassword())) {
118                         	log.error("execute: current password was not set");
119                         	errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.missingpassword"));
120                         } else {
121                             try {
122                                 User passwordCheck = userService.checkLogin(user.getLogin(), userForm.getCurrPassword(), AuthenticationConstants.AUTH_TYPE_PASSWORD_PLAIN, AuthenticationConstants.REQ_SOURCE_WEB);
123                                 if(passwordCheck == null) {
124                                     throw new AuthenticatorException(AuthenticatorException.INVALID_DATA);
125                                 }
126                                 if (log.isDebugEnabled()) {
127                                 	log.debug("execute: setting new user password");
128                                 }
129                                 user.setPassword(UserUtilities.encryptPassword(userForm.getPassword()));
130                             } catch(AuthenticatorException ae) {
131                             	log.error("execute: current password was wrong, AuthenticatorException", ae);
132                             	errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.wrongpassword"));
133                             } catch (PasswordException e) {
134                             	log.error("execute: current password was wrong", e);
135                             	errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.wrongpassword"));
136 							}
137                         }
138                     }
139                 } else {
140 //                  itracker.web.error.noprofileupdates
141                 	log.info("execute: passwords can not be changed in preferences due to incapable authenticator");
142                 	errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.nopasswordupdates"));
143                 	saveErrors(request, errors);
144                     return mapping.findForward("error");
145                 }
146 
147                 // TODO: should this check happen earlier?
148                 if(userService.allowProfileUpdates(user, null, UserUtilities.AUTH_TYPE_UNKNOWN, UserUtilities.REQ_SOURCE_WEB)) {
149                 	if (log.isInfoEnabled()) {
150                 		log.info("execute: allowing profile updates for " + user);
151                 	}
152                 	user.setFirstName(userForm.getFirstName());
153                 	user.setLastName(userForm.getLastName());
154                 	user.setEmail(userForm.getEmail());
155                 } else {
156                 	log.error("execute: profile updates are not allowed for " + user);
157                 	errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.noprofileupdates"));
158                 	saveErrors(request, errors);
159                     return mapping.findForward("error");
160                 }
161             } else {
162             	// validation errors
163             	if (log.isInfoEnabled()) {
164             		log.info("execute: got actions errors from validation: " + errors);
165             	}
166             }
167 
168             if(errors.isEmpty()) {
169                 log.debug("Passed required checks.  Updating user info for " + user.getLogin());
170                 user = userService.updateUser(user);
171 
172                 UserPreferences userPrefs = user.getPreferences();
173                 if (userPrefs == null) userPrefs = new UserPreferences();
174                 
175                 if(userService.allowPreferenceUpdates(user, null, UserUtilities.AUTH_TYPE_UNKNOWN, UserUtilities.REQ_SOURCE_WEB)) {
176                     //userPrefs.setUser(existingUser);
177                 	userPrefs.setUser(user);
178 
179                     userPrefs.setUserLocale(userForm.getUserLocale());
180                     
181                     userPrefs.setSaveLogin(Boolean.valueOf(userForm.getSaveLogin()));
182                     try {
183                         userPrefs.setNumItemsOnIndex(Integer.valueOf(userForm.getNumItemsOnIndex()));
184                     } catch(NumberFormatException nfe) {
185                         userPrefs.setNumItemsOnIndex(-1);
186                     }
187                     try {
188                         userPrefs.setNumItemsOnIssueList(Integer.valueOf(userForm.getNumItemsOnIssueList()));
189                     } catch(NumberFormatException nfe) {
190                         userPrefs.setNumItemsOnIssueList(-1);
191                     }
192                     userPrefs.setShowClosedOnIssueList(Boolean.valueOf(userForm.getShowClosedOnIssueList()));
193                     userPrefs.setSortColumnOnIssueList(userForm.getSortColumnOnIssueList());
194 
195                     int hiddenSections = 0;
196                     Integer[] hiddenSectionsArray = userForm.getHiddenIndexSections();
197                     if(hiddenSectionsArray != null) {
198                         for(int i = 0; i < hiddenSectionsArray.length; i++) {
199                             hiddenSections += hiddenSectionsArray[i].intValue();
200                         }
201                     }
202                     userPrefs.setHiddenIndexSections(hiddenSections);
203 
204                     userPrefs.setRememberLastSearch(Boolean.valueOf(userForm.getRememberLastSearch()));
205                     userPrefs.setUseTextActions(Boolean.valueOf(userForm.getUseTextActions()));
206 
207                     userPrefs = userService.updateUserPreferences(userPrefs);
208                 }
209 
210                 //session.setAttribute(Constants.USER_KEY, existingUser);
211                 session.setAttribute(Constants.USER_KEY, user);
212                 session.setAttribute(Constants.PREFERENCES_KEY, userPrefs);
213                 session.setAttribute(Constants.LOCALE_KEY, ITrackerResources.getLocale(userPrefs.getUserLocale()));
214 
215         		request.setAttribute(Constants.LOCALE_KEY, ITrackerResources.getLocale(userPrefs.getUserLocale()));
216         		
217                 session.removeAttribute(Constants.EDIT_USER_KEY);
218                 session.removeAttribute(Constants.EDIT_USER_PREFS_KEY);
219             } else {
220             	// validation errors
221             	if (log.isInfoEnabled()) {
222             		log.info("execute: got actions errors from user manipulation: " + errors);
223             	}
224                 
225             }
226         } catch(RuntimeException e) {
227             log.error("execute", e);
228             errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.save"));
229         } catch (UserException e) {
230             log.error("execute", e);
231             errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.save"));
232 		}
233 
234       	if(! errors.isEmpty()) {
235       		
236         	if (log.isInfoEnabled()) {
237         		log.info("execute: got actions errors: " + errors);
238         	}
239             
240         	saveErrors(request, errors);
241             saveToken(request);
242       	}
243   		
244     	if (log.isDebugEnabled()) {
245     		log.debug("execute: done, forward to input forward");
246     	}
247         return mapping.getInputForward();
248     }
249 }
250