KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > core > actions > AuthenticatedDispatchAction


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.core.actions;
21
22 import java.io.IOException JavaDoc;
23 import java.util.Enumeration JavaDoc;
24
25 import javax.servlet.ServletException JavaDoc;
26 import javax.servlet.http.HttpServletRequest JavaDoc;
27 import javax.servlet.http.HttpServletResponse JavaDoc;
28 import javax.servlet.http.HttpSession JavaDoc;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.struts.Globals;
33 import org.apache.struts.action.ActionForm;
34 import org.apache.struts.action.ActionForward;
35 import org.apache.struts.action.ActionMapping;
36 import org.apache.struts.action.ActionMessage;
37 import org.apache.struts.action.ActionMessages;
38
39 import com.sslexplorer.boot.ContextHolder;
40 import com.sslexplorer.boot.Util;
41 import com.sslexplorer.core.CoreUtil;
42 import com.sslexplorer.core.RedirectWithMessages;
43 import com.sslexplorer.core.ServletRequestAdapter;
44 import com.sslexplorer.core.ServletResponseAdapter;
45 import com.sslexplorer.core.forms.CoreForm;
46 import com.sslexplorer.policyframework.NoPermissionException;
47 import com.sslexplorer.policyframework.Permission;
48 import com.sslexplorer.policyframework.PolicyDatabaseFactory;
49 import com.sslexplorer.policyframework.ResourceType;
50 import com.sslexplorer.properties.PropertyProfile;
51 import com.sslexplorer.security.Constants;
52 import com.sslexplorer.security.LogonController;
53 import com.sslexplorer.security.LogonControllerFactory;
54 import com.sslexplorer.security.SessionInfo;
55 import com.sslexplorer.security.SystemDatabaseFactory;
56
57 /**
58  * <p>
59  * onward Abstract class for authenticated dispatch actions.
60  *
61  * @author James D Robinson <a HREF="mailto:james@3sp.com">&lt;james@3sp.com&gt;</a>
62  *
63  */

64 public abstract class AuthenticatedDispatchAction extends DefaultDispatchAction implements CoreAction {
65     static Log log = LogFactory.getLog(AuthenticatedAction.class);
66     protected ResourceType resourceType, requiresResourcesOfType;
67     protected Permission[] permissions;
68
69     /**
70      * Use this constructor for actions that do not require any resource
71      * permissions
72      */

73     public AuthenticatedDispatchAction() {
74     }
75     
76     
77     /**
78      * Use this constructor for actions that require a resource permission to
79      * operator
80      *
81      * @param resourceType resource type
82      * @param permissions permission required
83      */

84     public AuthenticatedDispatchAction(ResourceType resourceType, Permission permissions[]) {
85         this(resourceType, permissions, null);
86     }
87
88     /**
89      * Use this constructor for actions that require a resource permission to
90      * operator
91      *
92      * @param resourceType resource type
93      * @param permissions permission required
94      * @param requiresResources requires access to resources of type
95      */

96     public AuthenticatedDispatchAction(ResourceType resourceType, Permission permissions[], ResourceType requiresResources) {
97         this.resourceType = resourceType;
98         this.requiresResourcesOfType = requiresResources;
99         this.permissions = permissions;
100     }
101
102     /**
103      * This abstract class will populate all the common variables required by an
104      * action within the webstudio framework, such as current user, permission
105      * database, user database etc
106      *
107      * @param mapping
108      * @param form
109      * @param request
110      * @param response
111      *
112      * @exception Exception if business logic throws an exception
113      */

114     public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
115                     throws Exception JavaDoc {
116         // Setup mode
117
boolean setupMode = ContextHolder.getContext().isSetupMode();
118         if (setupMode) {
119             if ((getNavigationContext(mapping, form, request, response) & SessionInfo.SETUP_CONSOLE_CONTEXT) == 0) {
120                 return mapping.findForward("setup");
121             } else {
122                 /*
123                  * Make the mapping and form available, this helps with reusing
124                  * some JSP pages
125                  */

126                 request.setAttribute(Constants.REQ_ATTR_ACTION_MAPPING, mapping);
127                 request.setAttribute(Constants.REQ_ATTR_FORM, form);
128
129                 //
130
CoreUtil.checkNavigationContext(this, mapping, form, request, response);
131                 return super.execute(mapping, form, request, response);
132             }
133         }
134         try {
135             try {
136                 if (!SystemDatabaseFactory.getInstance().verifyIPAddress(request.getRemoteAddr())) {
137                     String JavaDoc link = null;
138                     log.error(request.getRemoteHost() + " is not authorized");
139                     if (log.isInfoEnabled())
140                         log.info("Logging off, IP address verification failed.");
141
142                     if(LogonControllerFactory.getInstance().hasClientLoggedOn(request, response) == LogonController.LOGGED_ON) {
143                         LogonControllerFactory.getInstance().logoffSession(request, response);
144                     }
145                     
146                     if (link != null) {
147                         ActionForward fwd = new ActionForward(link, true);
148                         return fwd;
149                     } else {
150                         // Do not direct to logon page for Ajax requests
151
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
152                             response.setStatus(HttpServletResponse.SC_FORBIDDEN);
153                             return null;
154                         }
155                         return (mapping.findForward("logon"));
156                     }
157                 } else {
158                     /*
159                      * Make the mapping and form available, this helps with
160                      * reusing some JSP pages
161                      */

162                     request.setAttribute(Constants.REQ_ATTR_ACTION_MAPPING, mapping);
163                     request.setAttribute(Constants.REQ_ATTR_FORM, form);
164
165                     int logonStatus = LogonControllerFactory.getInstance().hasClientLoggedOn(request, response);
166                     if (logonStatus == LogonController.INVALID_TICKET) {
167                         ActionMessages msgs = new ActionMessages();
168                         msgs.add(Globals.ERROR_KEY, new ActionMessage("login.invalidTicket"));
169                         saveErrors(request, msgs);
170                     } else if (logonStatus == LogonController.LOGGED_ON) {
171                         SessionInfo session = LogonControllerFactory.getInstance().getSessionInfo(request);
172                         // Set the logon ticket / domain logon ticket again
173
LogonControllerFactory.getInstance().addCookies(new ServletRequestAdapter(request),
174                             new ServletResponseAdapter(response),
175                             (String JavaDoc) request.getSession().getAttribute(Constants.LOGON_TICKET), getSessionInfo(request));
176
177                         ActionForward fwd = checkIntercept(mapping, request, response);
178                         if (fwd != null) {
179                            return fwd;
180                         }
181
182                         /*
183                          * Make sure the current navigation context is correct.
184                          * If not, then check the user can switch to the correct
185                          * and switch it.
186                          */

187                         CoreUtil.checkNavigationContext(this, mapping, form, request, response);
188
189                         PropertyProfile profile = null;
190                         if (request.getSession().getAttribute(Constants.SESSION_LOCKED) == null) {
191                             profile = (PropertyProfile) request.getSession().getAttribute(Constants.SELECTED_PROFILE);
192                             if (profile == null) {
193                                 request.getSession().setAttribute(Constants.ORIGINAL_REQUEST, Util.getOriginalRequest(request));
194                                 return mapping.findForward("selectPropertyProfile");
195                             }
196                             doCheckPermissions(mapping, session, request);
197                             return super.execute(mapping, form, request, response);
198                         }
199                     }
200                 }
201             } catch (NoPermissionException e) {
202                 if (log.isDebugEnabled())
203                     log.debug("User " + e.getPrincipalName()
204                                     + " attempted to access page they do have have permission for. Resource type = "
205                                     + e.getResourceType()
206                                     + ". Now attempting to find the first valid item in the current menu tree to display.", e);
207                 response.sendError(HttpServletResponse.SC_FORBIDDEN);
208                 return null;
209             } catch (SecurityException JavaDoc ex) {
210                 // Not logged in or expired
211
} catch (ServletException JavaDoc ex) {
212                 throw ex;
213             }
214
215             // Do not direct to logon page for Ajax requests
216
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
217                 response.setStatus(HttpServletResponse.SC_NO_CONTENT);
218                 return null;
219             }
220
221             return gotoLogon(mapping, form, request, response);
222         } catch (Throwable JavaDoc t) {
223             log.error("Failed to process authenticated request.", t);
224             throw t instanceof Exception JavaDoc ? (Exception JavaDoc) t : new Exception JavaDoc(t);
225         }
226     }
227
228     protected void doCheckPermissions(ActionMapping mapping, SessionInfo session, HttpServletRequest JavaDoc request) throws Exception JavaDoc {
229
230         // Check the user has the permissions to access this
231
// page
232
boolean ok = true;
233         if (resourceType != null && permissions != null) {
234             ok = PolicyDatabaseFactory.getInstance().isPermitted(resourceType, permissions, session.getUser(), false);
235         }
236         if (!ok && requiresResourcesOfType != null) {
237             ok = PolicyDatabaseFactory.getInstance().isPrincipalGrantedResourcesOfType(session.getUser(), requiresResourcesOfType, null);
238         }
239         if (!ok) {
240             throw new NoPermissionException(session.getUser(), resourceType);
241         }
242     }
243
244     /**
245      * Logon is required. By default this will direct to the logon page.
246      * Subclasses may overide this method to go somewhere different.
247      *
248      * @param mapping mapping
249      * @param form form
250      * @param request request
251      * @param response response
252      * @return forward
253      * @throws Exception
254      */

255     protected ActionForward gotoLogon(ActionMapping mapping, ActionForm form, HttpServletRequest JavaDoc request,
256                                       HttpServletResponse JavaDoc response) throws Exception JavaDoc {
257         request.getSession().setAttribute(Constants.ORIGINAL_REQUEST, Util.getOriginalRequest(request));
258         return mapping.findForward("logon");
259     }
260
261     /**
262      * Get the {@link SessionInfo} for this session. This will only be available
263      * after
264      * {@link #execute(ActionMapping, ActionForm, HttpServletRequest, HttpServletResponse)}
265      * has been called.
266      * <p>
267      * There are many places where the session info object is required. The
268      * usual way is to use
269      * {@link LogonController#getSessionInfo(HttpServletRequest)}. Whereever
270      * possible that method should be replaced with a call to this method.
271      *
272      * @param request request
273      * @return session info for request
274      */

275     public SessionInfo getSessionInfo(HttpServletRequest JavaDoc request) {
276         return LogonControllerFactory.getInstance().getSessionInfo(request);
277
278     }
279
280     /**
281      * @return ResourceType
282      */

283     public ResourceType getResourceType() {
284         return resourceType;
285     }
286
287     /**
288      * @param mapping
289      * @param form
290      * @param request
291      * @param response
292      * @return ActionForward
293      * @throws Exception
294      */

295     public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
296                     throws Exception JavaDoc {
297         return cleanUpAndReturnToReferer(mapping, form, request, response);
298     }
299
300     /**
301      * @param mapping
302      * @param form
303      * @param request
304      * @param response
305      * @return ActionForward
306      * @throws Exception
307      */

308     public ActionForward cleanUpAndReturnToReferer(ActionMapping mapping, ActionForm form, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws Exception JavaDoc {
309         HttpSession JavaDoc session = request.getSession();
310         String JavaDoc toRemove = null;
311         for (Enumeration JavaDoc e = session.getAttributeNames(); toRemove == null && e.hasMoreElements();) {
312             String JavaDoc n = (String JavaDoc) e.nextElement();
313             if (session.getAttribute(n) == form) {
314                 toRemove = n;
315             }
316         }
317         if (toRemove != null) {
318             request.getSession().removeAttribute(toRemove);
319         }
320         request.getSession().removeAttribute(Constants.EDITING_ITEM);
321         
322         // First look for a 'done' forward in the current mapping. If there is
323
// none, then use the referer in the form, otherwise redirect to home
324
ActionForward fwd = mapping.findForward("done");
325         if(fwd != null) {
326             return new RedirectWithMessages(fwd, request);
327         }
328         if (((CoreForm) form).getReferer() == null) {
329             log.warn("Original referer was null, forwarding to home");
330             return mapping.findForward("home");
331         } else {
332             return new RedirectWithMessages(((CoreForm) form).getReferer(), request);
333         }
334     }
335
336     /**
337      * @param response
338      * @throws IOException
339      */

340     void sendAuthorizationError(HttpServletResponse JavaDoc response) throws IOException JavaDoc {
341         response.setHeader("WWW-Authenticate", "Basic realm=\"SSL-Explorer\"");
342         response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
343     }
344     
345     protected void saveError(HttpServletRequest JavaDoc request, String JavaDoc message ) {
346         saveError(request, message, "");
347     }
348     
349     protected void saveError(HttpServletRequest JavaDoc request, String JavaDoc message, Object JavaDoc... objects) {
350         saveError(request, new ActionMessage(message, objects));
351     }
352
353     protected void saveError(HttpServletRequest JavaDoc request, ActionMessage message) {
354         ActionMessages actionMessages = new ActionMessages();
355         actionMessages.add(Globals.ERROR_KEY, message);
356         saveErrors(request, actionMessages);
357     }
358     
359     protected void saveMessage(HttpServletRequest JavaDoc request, String JavaDoc message ) {
360         saveMessage(request, message, "");
361     }
362
363     protected void saveMessage(HttpServletRequest JavaDoc request, String JavaDoc message, Object JavaDoc... objects) {
364         ActionMessages actionMessages = new ActionMessages();
365         actionMessages.add(Globals.MESSAGE_KEY, new ActionMessage(message, objects));
366         saveMessages(request, actionMessages);
367     }
368     
369     protected static ActionForward getRedirectWithMessages(ActionMapping mapping, HttpServletRequest JavaDoc request) {
370         return getRedirectWithMessages("refresh", mapping, request);
371     }
372
373     protected static ActionForward getRedirectWithMessages(String JavaDoc redirect, ActionMapping mapping, HttpServletRequest JavaDoc request) {
374         return new RedirectWithMessages(mapping.findForward(redirect), request);
375     }
376 }
Popular Tags