View Javadoc

1   package org.appfuse.webapp.action;
2   
3   import com.opensymphony.xwork2.Preparable;
4   import org.apache.struts2.ServletActionContext;
5   import org.appfuse.Constants;
6   import org.appfuse.dao.SearchException;
7   import org.appfuse.model.Role;
8   import org.appfuse.model.User;
9   import org.appfuse.service.UserExistsException;
10  import org.appfuse.webapp.util.RequestUtil;
11  import org.springframework.dao.DataIntegrityViolationException;
12  import org.springframework.mail.MailException;
13  import org.springframework.security.access.AccessDeniedException;
14  import org.springframework.security.authentication.AuthenticationTrustResolver;
15  import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
16  import org.springframework.security.core.Authentication;
17  import org.springframework.security.core.context.SecurityContext;
18  import org.springframework.security.core.context.SecurityContextHolder;
19  
20  import javax.servlet.http.HttpServletRequest;
21  import javax.servlet.http.HttpServletResponse;
22  import java.io.IOException;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  /**
27   * Action for facilitating User Management feature.
28   */
29  public class UserAction extends BaseAction implements Preparable {
30      private static final long serialVersionUID = 6776558938712115191L;
31      private List<User> users;
32      private User user;
33      private String id;
34      private String query;
35  
36      /**
37       * Grab the entity from the database before populating with request parameters
38       */
39      public void prepare() {
40          // prevent failures on new
41          if (getRequest().getMethod().equalsIgnoreCase("post") && (!"".equals(getRequest().getParameter("user.id")))) {
42              user = userManager.getUser(getRequest().getParameter("user.id"));
43          }
44      }
45  
46      /**
47       * Holder for users to display on list screen
48       *
49       * @return list of users
50       */
51      public List<User> getUsers() {
52          return users;
53      }
54  
55      public void setId(String id) {
56          this.id = id;
57      }
58  
59      public User getUser() {
60          return user;
61      }
62  
63      public void setUser(User user) {
64          this.user = user;
65      }
66  
67      public void setQ(String q) {
68          this.query = q;
69      }
70  
71      /**
72       * Delete the user passed in.
73       *
74       * @return success
75       */
76      public String delete() {
77          userManager.removeUser(user.getId().toString());
78          List<Object> args = new ArrayList<Object>();
79          args.add(user.getFullName());
80          saveMessage(getText("user.deleted", args));
81  
82          return SUCCESS;
83      }
84  
85      /**
86       * Grab the user from the database based on the "id" passed in.
87       *
88       * @return success if user found
89       * @throws IOException can happen when sending a "forbidden" from response.sendError()
90       */
91      public String edit() throws IOException {
92          HttpServletRequest request = getRequest();
93          boolean editProfile = request.getRequestURI().contains("editProfile");
94  
95          // if URL is "editProfile" - make sure it's the current user
96          if (editProfile && ((request.getParameter("id") != null) || (request.getParameter("from") != null))) {
97              ServletActionContext.getResponse().sendError(HttpServletResponse.SC_FORBIDDEN);
98              log.warn("User '" + request.getRemoteUser() + "' is trying to edit user '" +
99                      request.getParameter("id") + "'");
100             return null;
101         }
102 
103         // if a user's id is passed in
104         if (id != null) {
105             // lookup the user using that id
106             user = userManager.getUser(id);
107         } else if (editProfile) {
108             user = userManager.getUserByUsername(request.getRemoteUser());
109         } else {
110             user = new User();
111             user.addRole(new Role(Constants.USER_ROLE));
112         }
113 
114         if (user.getUsername() != null) {
115             user.setConfirmPassword(user.getPassword());
116 
117             // if user logged in with remember me, display a warning that they can't change passwords
118             log.debug("checking for remember me login...");
119 
120             AuthenticationTrustResolver resolver = new AuthenticationTrustResolverImpl();
121             SecurityContext ctx = SecurityContextHolder.getContext();
122 
123             if (ctx != null) {
124                 Authentication auth = ctx.getAuthentication();
125 
126                 if (resolver.isRememberMe(auth)) {
127                     getSession().setAttribute("cookieLogin", "true");
128                     saveMessage(getText("userProfile.cookieLogin"));
129                 }
130             }
131         }
132 
133         return SUCCESS;
134     }
135 
136     /**
137      * Default: just returns "success"
138      *
139      * @return "success"
140      */
141     public String execute() {
142         return SUCCESS;
143     }
144 
145     /**
146      * Sends users to "home" when !from.equals("list"). Sends everyone else to "cancel"
147      *
148      * @return "home" or "cancel"
149      */
150     public String cancel() {
151         if (!"list".equals(from)) {
152             return "home";
153         }
154         return "cancel";
155     }
156 
157     /**
158      * Save user
159      *
160      * @return success if everything worked, otherwise input
161      * @throws Exception when setting "access denied" fails on response
162      */
163     public String save() throws Exception {
164 
165         Integer originalVersion = user.getVersion();
166 
167         boolean isNew = ("".equals(getRequest().getParameter("user.version")));
168         // only attempt to change roles if user is admin
169         // for other users, prepare() method will handle populating
170         if (getRequest().isUserInRole(Constants.ADMIN_ROLE)) {
171             user.getRoles().clear(); // APF-788: Removing roles from user doesn't work
172             String[] userRoles = getRequest().getParameterValues("userRoles");
173 
174             for (int i = 0; userRoles != null && i < userRoles.length; i++) {
175                 String roleName = userRoles[i];
176                 try {
177                     user.addRole(roleManager.getRole(roleName));
178                 } catch (DataIntegrityViolationException e) {
179                     return showUserExistsException(originalVersion);
180                 }
181             }
182         }
183 
184         try {
185             userManager.saveUser(user);
186         } catch (AccessDeniedException ade) {
187             // thrown by UserSecurityAdvice configured in aop:advisor userManagerSecurity
188             log.warn(ade.getMessage());
189             getResponse().sendError(HttpServletResponse.SC_FORBIDDEN);
190             return null;
191         } catch (UserExistsException e) {
192             return showUserExistsException(originalVersion);
193         }
194 
195         if (!"list".equals(from)) {
196             // add success messages
197             saveMessage(getText("user.saved"));
198             return "home";
199         } else {
200             // add success messages
201             List<Object> args = new ArrayList<Object>();
202             args.add(user.getFullName());
203             if (isNew) {
204                 saveMessage(getText("user.added", args));
205                 // Send an account information e-mail
206                 mailMessage.setSubject(getText("signup.email.subject"));
207                 try {
208                     sendUserMessage(user, getText("newuser.email.message", args), RequestUtil.getAppURL(getRequest()));
209                 } catch (MailException me) {
210                     addActionError(me.getCause().getLocalizedMessage());
211                 }
212                 return SUCCESS;
213             } else {
214                 user.setConfirmPassword(user.getPassword());
215                 saveMessage(getText("user.updated.byAdmin", args));
216                 return INPUT;
217             }
218         }
219     }
220 
221     private String showUserExistsException(Integer originalVersion) {
222         List<Object> args = new ArrayList<Object>();
223         args.add(user.getUsername());
224         args.add(user.getEmail());
225         addActionError(getText("errors.existing.user", args));
226 
227         // reset the version # to what was passed in
228         user.setVersion(originalVersion);
229         // redisplay the unencrypted passwords
230         user.setPassword(user.getConfirmPassword());
231         return INPUT;
232     }
233 
234     /**
235      * Fetch all users from database and put into local "users" variable for retrieval in the UI.
236      *
237      * @return "success" if no exceptions thrown
238      */
239     public String list() {
240         try {
241             users = userManager.search(query);
242         } catch (SearchException se) {
243             addActionError(se.getMessage());
244             users = userManager.getUsers();
245         }
246         return SUCCESS;
247     }
248 
249 }