001    /**
002     * Copyright 2005-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kns.web.struts.action;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.apache.struts.action.ActionForm;
020    import org.apache.struts.action.ActionForward;
021    import org.apache.struts.action.ActionMapping;
022    import org.kuali.rice.core.api.config.property.ConfigContext;
023    import org.kuali.rice.core.api.exception.RiceRuntimeException;
024    import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
025    import org.kuali.rice.kew.api.KewApiConstants;
026    import org.kuali.rice.kim.api.KimConstants;
027    import org.kuali.rice.kim.api.permission.Permission;
028    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
029    import org.kuali.rice.kns.web.struts.form.BackdoorForm;
030    import org.kuali.rice.krad.UserSession;
031    import org.kuali.rice.krad.util.GlobalVariables;
032    import org.kuali.rice.krad.util.KRADConstants;
033    
034    import javax.servlet.http.HttpServletRequest;
035    import javax.servlet.http.HttpServletResponse;
036    import java.util.Collections;
037    import java.util.HashMap;
038    import java.util.List;
039    import java.util.Map;
040    
041    /**
042     * A Struts Action which permits a user to execute a backdoor login to masquerade
043     * as another user.
044     *
045     * @author Kuali Rice Team (rice.collab@kuali.org)
046     */
047    public class BackdoorAction extends KualiAction {
048    
049        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BackdoorAction.class);
050        private List<Permission> perms;
051    
052        @Override
053        public ActionForward execute(ActionMapping mapping, ActionForm form,
054                HttpServletRequest request, HttpServletResponse response)
055                throws Exception {
056            this.initForm(request, form);
057            return super.execute(mapping, form, request, response);
058        }
059    
060        public ActionForward menu(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
061            LOG.debug("menu");
062            return mapping.findForward("basic");
063        }
064    
065        @Override
066        public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
067            return portal(mapping, form, request, response);
068        }
069        
070        public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
071            LOG.debug("start");
072            return portal(mapping, form, request, response);
073        }
074    
075        public ActionForward portal(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{
076            LOG.debug("portal started");
077            return mapping.findForward("viewPortal");
078        }
079    
080        public ActionForward administration(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
081            LOG.debug("administration");
082            return mapping.findForward("administration");
083        }
084    
085        public ActionForward logout(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
086            LOG.debug("logout");
087            
088            String forward = "viewPortal";
089            UserSession uSession = getUserSession(request);
090            
091            if (uSession.isBackdoorInUse()) {
092                uSession.clearBackdoorUser();
093                setFormGroupPermission((BackdoorForm)form, request);
094                //request.setAttribute("reloadPage","true");
095                
096                org.kuali.rice.krad.UserSession KnsUserSession;
097                KnsUserSession = GlobalVariables.getUserSession();
098                KnsUserSession.clearBackdoorUser();
099            }
100            else {
101                forward = "logout";
102            }
103            
104            return mapping.findForward(forward);
105        }
106    
107        public ActionForward login(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
108            LOG.debug("login");
109            UserSession uSession = getUserSession(request);
110            BackdoorForm backdoorForm = (BackdoorForm) form;
111    
112            uSession.clearObjectMap();
113    
114            if (!isBackdoorAuthorized(uSession, request)) {
115                request.setAttribute("backdoorRestriction", "User " + uSession.getActualPerson().getPrincipalName()
116                        + " not permitted to use backdoor functionality inside application: "
117                        + ConfigContext.getCurrentContextConfig().getProperty("app.code") + ".");
118                return logout(mapping, form, request, response);
119            }
120    
121            //if backdoor Id is empty or equal to currently logged in user, clear backdoor id
122            if (uSession.isBackdoorInUse() &&
123                    (StringUtils.isEmpty(backdoorForm.getBackdoorId())
124                    || uSession.getLoggedInUserPrincipalName().equals(backdoorForm.getBackdoorId()))) {
125                return logout(mapping, form, request, response);
126            }
127    
128            try {
129                    uSession.setBackdoorUser(backdoorForm.getBackdoorId());
130            } catch (RiceRuntimeException e) {
131                    LOG.warn("invalid backdoor id " + backdoorForm.getBackdoorId(), e);
132                //Commenting this out since it is not being read anywhere
133                //request.setAttribute("badbackdoor", "Invalid backdoor Id given '" + backdoorForm.getBackdoorId() + "'");
134                return mapping.findForward("invalid_backdoor_portal");
135            }
136    
137            setFormGroupPermission(backdoorForm, request);
138            
139            return mapping.findForward("portal");
140        }
141    
142        private void setFormGroupPermission(BackdoorForm backdoorForm, HttpServletRequest request) {
143            // based on whether or not they have permission to use the fictional "AdministrationAction", kind of a hack for now since I don't have time to
144            // split this single action up and I can't pass the methodToCall to the permission check
145            Map<String, String> permissionDetails = new HashMap<String, String>();
146            permissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, KewApiConstants.KEW_NAMESPACE);
147            permissionDetails.put(KimConstants.AttributeConstants.ACTION_CLASS, "org.kuali.rice.kew.web.backdoor.AdministrationAction");
148            boolean isAdmin = KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(getUserSession(request)
149                    .getPrincipalId(), KRADConstants.KNS_NAMESPACE, KimConstants.PermissionTemplateNames.USE_SCREEN,
150                    permissionDetails, new HashMap<String, String>());
151            backdoorForm.setIsAdmin(isAdmin);
152        }
153    
154        public void initForm(HttpServletRequest request, ActionForm form) throws Exception {
155            BackdoorForm backdoorForm = (BackdoorForm) form;
156    
157            Boolean showBackdoorLogin = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.BACKDOOR_DETAIL_TYPE, KewApiConstants.SHOW_BACK_DOOR_LOGIN_IND);
158            backdoorForm.setShowBackdoorLogin(showBackdoorLogin);
159            setFormGroupPermission(backdoorForm, request);
160            if (backdoorForm.getGraphic() != null) {
161                    request.getSession().setAttribute("showGraphic", backdoorForm.getGraphic());
162            }
163        }
164    
165        public static UserSession getUserSession(HttpServletRequest request) {
166            return GlobalVariables.getUserSession();
167        }
168    
169        public boolean isBackdoorAuthorized(UserSession uSession, HttpServletRequest request) {
170            boolean isAuthorized = true;
171    
172            //we should check to see if a kim permission exists for the requested application first
173            Map<String, String> permissionDetails = new HashMap<String, String>();
174            String requestAppCode = ConfigContext.getCurrentContextConfig().getProperty("app.code");
175            permissionDetails.put(KimConstants.AttributeConstants.APP_CODE, requestAppCode);
176            List<Permission> perms = KimApiServiceLocator.getPermissionService().findPermissionsByTemplate(
177                    KRADConstants.KUALI_RICE_SYSTEM_NAMESPACE, KimConstants.PermissionTemplateNames.BACKDOOR_RESTRICTION);
178            for (Permission kpi : perms) {
179                if (kpi.getAttributes().values().contains(requestAppCode)) {
180                    //if a permission exists, is the user granted permission to use backdoor?
181                    isAuthorized = KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(
182                            uSession.getActualPerson().getPrincipalId(), KRADConstants.KUALI_RICE_SYSTEM_NAMESPACE,
183                            KimConstants.PermissionTemplateNames.BACKDOOR_RESTRICTION, permissionDetails,
184                            Collections.<String, String>emptyMap());
185                }
186            }
187            if (!isAuthorized) {
188                LOG.warn("Attempt to backdoor was made by user: "
189                        + uSession.getPerson().getPrincipalId()
190                        + " into application with app code: "
191                        + requestAppCode
192                        + " but they do not have appropriate permissions. Backdoor processing aborted.");
193            }
194            return isAuthorized;
195        }
196    }