View Javadoc

1   /**
2    * Copyright 2005-2011 The Kuali Foundation
3    *
4    * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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  package org.kuali.rice.ksb.messaging.web;
17  
18  import java.util.HashMap;
19  import java.util.Iterator;
20  import java.util.Map;
21  
22  import javax.print.attribute.AttributeSet;
23  import javax.servlet.http.HttpServletRequest;
24  import javax.servlet.http.HttpServletResponse;
25  
26  import org.apache.commons.lang.StringUtils;
27  import org.apache.struts.action.ActionErrors;
28  import org.apache.struts.action.ActionForm;
29  import org.apache.struts.action.ActionForward;
30  import org.apache.struts.action.ActionMapping;
31  import org.apache.struts.action.ActionMessages;
32  import org.apache.struts.actions.DispatchAction;
33  import org.kuali.rice.core.api.CoreApiServiceLocator;
34  import org.kuali.rice.core.api.util.RiceConstants;
35  import org.kuali.rice.core.framework.parameter.ParameterService;
36  import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
37  import org.kuali.rice.core.impl.services.CoreImplServiceLocator;
38  import org.kuali.rice.kew.util.Utilities;
39  import org.kuali.rice.kim.api.KimConstants;
40  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
41  import org.kuali.rice.kns.service.KNSServiceLocator;
42  import org.kuali.rice.kns.util.KNSConstants;
43  import org.kuali.rice.kns.util.WebUtils;
44  import org.kuali.rice.kns.web.struts.action.KualiAction;
45  import org.kuali.rice.kns.web.struts.form.KualiForm;
46  import org.kuali.rice.krad.exception.AuthorizationException;
47  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
48  import org.kuali.rice.krad.service.KualiModuleService;
49  import org.kuali.rice.krad.service.ModuleService;
50  import org.kuali.rice.krad.util.GlobalVariables;
51  import org.kuali.rice.krad.util.KRADConstants;
52  import org.kuali.rice.krad.util.KRADUtils;
53  
54  /**
55   * An abstract super class for all Struts Actions in KEW.  Adds some custom
56   * dispatch behavior by extending the Struts DispatchAction.
57   *
58   * @author Kuali Rice Team (rice.collab@kuali.org)
59   */
60  public abstract class KSBAction extends DispatchAction {
61  
62  	private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KSBAction.class);
63  
64  	@Override
65  	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
66  
67  		checkAuthorization(form, "");
68  		
69  		if(isModuleLocked(form, findMethodToCall(form, request), request)) {
70  		    return mapping.findForward(RiceConstants.MODULE_LOCKED_MAPPING);
71  		}
72  		
73  		try {
74  
75  			
76  			ActionMessages messages = null;
77  			messages = establishRequiredState(request, form);
78  			if (messages != null && !messages.isEmpty()) {
79  				// XXX: HACK: FIXME:
80  				// obviously this implies that we can't return both ActionErrors
81  				// and ActionMessages... :(
82  				// probably establishRequiredState should be refactored to have
83  				// a generic 'should-we-continue'
84  				// boolean return, so that control flow can be more explicitly
85  				// specified by the subclass
86  				if (messages instanceof ActionErrors) {
87  					saveErrors(request, messages);
88  				} else {
89  					saveMessages(request, messages);
90  				}
91  				return mapping.findForward("requiredStateError");
92  			}
93  			LOG.info(request.getQueryString());
94  			ActionForward returnForward = null;
95  
96  			if (request.getParameterMap() != null) {
97  				for (Iterator iter = request.getParameterMap().entrySet().iterator(); iter.hasNext();) {
98  					String parameterName = (String) ((Map.Entry) iter.next()).getKey();
99  					if (parameterName.startsWith("methodToCall.") && parameterName.endsWith(".x")) {
100 						String methodToCall = parameterName.substring(parameterName.indexOf("methodToCall.") + 13, parameterName.lastIndexOf(".x"));
101 						if (methodToCall != null && methodToCall.length() > 0) {
102 							returnForward = this.dispatchMethod(mapping, form, request, response, methodToCall);
103 						}
104 					}
105 				}
106 			}
107 			if (returnForward == null) {
108 				if (request.getParameter("methodToCall") != null && !"".equals(request.getParameter("methodToCall")) && !"execute".equals(request.getParameter("methodToCall"))) {
109 					LOG.info("dispatch to methodToCall " + request.getParameter("methodToCall") + " called");
110 					returnForward = super.execute(mapping, form, request, response);
111 				} else {
112 					LOG.info("dispatch to default start methodToCall");
113 					returnForward = start(mapping, form, request, response);
114 				}
115 			}
116 
117 			
118 			
119 			messages = establishFinalState(request, form);
120 			if (messages != null && !messages.isEmpty()) {
121 				saveMessages(request, messages);
122 				return mapping.findForward("finalStateError");
123 			}
124 			return returnForward;
125 		} catch (Exception e) {
126 			LOG.error("Error processing action " + mapping.getPath(), e);
127 			throw new RuntimeException(e);
128 		}
129 	}
130 	
131 	protected void checkAuthorization( ActionForm form, String methodToCall) throws AuthorizationException 
132     {
133     	String principalId = GlobalVariables.getUserSession().getPrincipalId();
134     	Map<String, String> roleQualifier = new HashMap<String, String>(getRoleQualification(form, methodToCall));
135     	Map<String, String> permissionDetails = KRADUtils.getNamespaceAndActionClass(this.getClass());
136     	
137         if (!KimApiServiceLocator.getPermissionService().isAuthorizedByTemplateName(principalId, KRADConstants.KRAD_NAMESPACE,
138         		KimConstants.PermissionTemplateNames.USE_SCREEN, permissionDetails, roleQualifier ))
139         {
140         	throw new AuthorizationException(GlobalVariables.getUserSession().getPrincipalName(), 
141             		methodToCall,
142             		this.getClass().getSimpleName());
143         }
144     }
145     
146     /** 
147      * override this method to add data from the form for role qualification in the authorization check
148      */
149     protected Map<String,String> getRoleQualification(ActionForm form, String methodToCall) {
150     	return new HashMap<String,String>();
151     }
152 
153 	public abstract ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception;
154 
155 	public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
156 		return start(mapping, form, request, response);
157 	}
158 
159 	public abstract ActionMessages establishRequiredState(HttpServletRequest request, ActionForm form) throws Exception;
160 
161 	public ActionMessages establishFinalState(HttpServletRequest request, ActionForm form) throws Exception {
162 		return null;
163 	}
164 
165 	public ActionForward noOp(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
166 		return mapping.findForward("basic");
167 	}
168 	
169 	protected static KualiModuleService getKualiModuleService() {
170         return KRADServiceLocatorWeb.getKualiModuleService();
171     }
172 	
173 	protected String findMethodToCall(ActionForm form, HttpServletRequest request) throws Exception {
174 	    String methodToCall;
175 	    if (form instanceof KualiForm && StringUtils.isNotEmpty(((KualiForm) form).getMethodToCall())) {
176 	        methodToCall = ((KualiForm) form).getMethodToCall();
177 	    }
178 	    else {
179 	        // call utility method to parse the methodToCall from the request.
180 	        methodToCall = WebUtils.parseMethodToCall(form, request);
181 	    }
182 	    return methodToCall;
183 	}
184 
185 	protected boolean isModuleLocked(ActionForm form, String methodToCall, HttpServletRequest request) {
186 	    String boClass = request.getParameter(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE);
187 	    ModuleService moduleService = null;
188 	    if(StringUtils.isNotBlank(boClass)) {
189 	        try {
190 	            moduleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(Class.forName(boClass));
191 	        } catch (ClassNotFoundException e) {
192 	            LOG.warn("Module locking mechanism experienced a class not found exception while trying to load " + boClass, e);
193 	        }
194 	    } else {
195 	        moduleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(this.getClass());
196 	    }
197 	    if(moduleService != null && moduleService.isLocked()) {
198 	        String principalId = GlobalVariables.getUserSession().getPrincipalId();
199 	        String namespaceCode = KRADConstants.KUALI_RICE_SYSTEM_NAMESPACE;
200             String permissionName = KimConstants.PermissionNames.ACCESS_LOCKED_MODULE;
201 	        Map<String, String> permissionDetails = new HashMap<String, String>();
202 	        Map<String, String> qualification = new HashMap<String, String>(getRoleQualification(form, methodToCall));
203 	        if(!KimApiServiceLocator.getPermissionService().isAuthorized(principalId, namespaceCode, permissionName, permissionDetails, qualification)) {
204                 ParameterService parameterSerivce = CoreFrameworkServiceLocator.getParameterService();
205                 String messageParamNamespaceCode = moduleService.getModuleConfiguration().getNamespaceCode();
206                 String messageParamComponentCode = KRADConstants.DetailTypes.OLTP_LOCKOUT_DETAIL_TYPE;
207                 String messageParamName = KRADConstants.SystemGroupParameterNames.OLTP_LOCKOUT_MESSAGE_PARM;
208                 String lockoutMessage = parameterSerivce.getParameterValueAsString(messageParamNamespaceCode, messageParamComponentCode, messageParamName);
209                 
210                 if(StringUtils.isBlank(lockoutMessage)) {
211                     String defaultMessageParamName = KRADConstants.SystemGroupParameterNames.OLTP_LOCKOUT_DEFAULT_MESSAGE;
212                     lockoutMessage = parameterSerivce.getParameterValueAsString(KRADConstants.KRAD_NAMESPACE, messageParamComponentCode, defaultMessageParamName);
213                 }
214                 request.setAttribute(KualiAction.MODULE_LOCKED_MESSAGE, lockoutMessage);
215                 return true;
216             }
217 	    }
218 	    return false;
219 	}
220 }