org.mifos.framework.struts.action.MifosRequestProcessor.java Source code

Java tutorial

Introduction

Here is the source code for org.mifos.framework.struts.action.MifosRequestProcessor.java

Source

/*
 * Copyright (c) 2005-2011 Grameen Foundation USA
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * See also http://www.apache.org/licenses/LICENSE-2.0.html for an
 * explanation of the license and how it is applied.
 */

package org.mifos.framework.struts.action;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.Globals;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.tiles.TilesRequestProcessor;
import org.mifos.application.servicefacade.ApplicationContextProvider;
import org.mifos.customers.client.util.helpers.ClientConstants;
import org.mifos.framework.util.helpers.Constants;
import org.mifos.framework.util.helpers.PreviousRequestValues;
import org.mifos.security.rolesandpermission.persistence.LegacyRolesPermissionsDao;
import org.mifos.security.util.ActivityContext;
import org.mifos.security.util.ActivityMapper;
import org.mifos.security.util.SecurityConstants;
import org.mifos.security.util.UserContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MifosRequestProcessor extends TilesRequestProcessor {
    private static final Logger logger = LoggerFactory.getLogger(MifosRequestProcessor.class);

    private ActivityContext setActivityContextFromRequest(HttpServletRequest request, Short activityId) {
        HttpSession session = request.getSession();
        ActivityContext activityContext = (ActivityContext) session.getAttribute("ActivityContext");
        if (activityContext != null) {
            // get the values from the request
            String recordOfficeId = request.getParameter("recordOfficeId");
            String recordLoanOfficerId = request.getParameter("recordLoanOfficerId");
            short recordOffId = -1;
            short recordLoOffId = -1;
            try {
                /*
                 * The null case is if one or both parameters was omitted.
                 * What's the difference between supplying these as parameters
                 * versus the UserContext, versus just using what is in the
                 * ActivityContext?
                 */
                if (recordOfficeId != null) {
                    recordOffId = Short.valueOf(recordOfficeId).shortValue();
                }
                if (recordLoanOfficerId != null) {
                    recordLoOffId = Short.valueOf(recordLoanOfficerId).shortValue();
                }
            } catch (NumberFormatException e) {
                throw new RuntimeException(e);
            }
            if (recordOffId > 0 && recordLoOffId > 0) {
                activityContext.setRecordOfficeId(recordOffId);
                activityContext.setRecordLoanOfficer(recordLoOffId);
            } else if (recordOffId == 0 && recordLoOffId == 0) {
                if (session.getAttribute("UserContext") != null) {
                    UserContext uc = (UserContext) session.getAttribute("UserContext");

                    activityContext.setRecordOfficeId(uc.getBranchId());
                    activityContext.setRecordLoanOfficer(uc.getId());
                }
            }
            activityContext.setActivityId(activityId);
            return activityContext;
        } else {
            // No activity context
            // TODO: Can this happen? Why? Is null right?
            return null;
        }
    }

    protected boolean checkProcessRoles(HttpServletRequest request, HttpServletResponse response,
            ActionMapping mapping) {
        boolean returnValue = true;
        if (request.getSession() != null && request.getSession().getAttribute("UserContext") != null)

        {
            HttpSession session = request.getSession();
            ActivityMapper activityMapper = ActivityMapper.getInstance();
            String path = mapping.getPath();
            String method = request.getParameter("method");
            String key = path + "-" + method;
            Short activityId = null;
            if (null != method && (method.equals("cancel") || method.equals("validate")
                    || method.equals("searchPrev") || method.equals("searchNext"))) {
                return true;
            }
            String activityKey = null;

            if (isReportRequest(request)) {
                String reportId = request.getParameter("reportId");
                activityKey = key + "-" + reportId;
                activityId = activityMapper.getActivityId(activityKey);
            } else {
                activityId = activityMapper.getActivityId(key);
                request.setAttribute(Globals.ERROR_KEY, null);
            }

            if (null == activityId) {
                activityKey = path + "-" + request.getParameter("viewPath");
                activityId = activityMapper.getActivityId(activityKey);
            }
            // Check for fine-grained permissions
            if (null == activityId) {
                activityKey = key + "-" + session.getAttribute(SecurityConstants.SECURITY_PARAM);
                activityId = activityMapper.getActivityId(activityKey);
            }
            if (null == activityId) {
                return false;
            } else if (activityId.shortValue() == 0) {
                return true;
            }
            returnValue = ApplicationContextProvider.getBean(LegacyRolesPermissionsDao.class).isActivityAllowed(
                    (UserContext) session.getAttribute("UserContext"),
                    setActivityContextFromRequest(request, activityId));
        }
        return returnValue;
    }

    /*
     * Seems bolted-on. Is there a more elegant way to control per-report
     * permissions?
     */
    private boolean isReportRequest(HttpServletRequest request) {
        String reportId = request.getParameter("reportId");
        String method = request.getParameter("method");

        return StringUtils.isNotEmpty(reportId) && "loadAddList".equals(method);
    }

    /**
     * This method is overridden because in case of exception we need to
     * populate the request with the old values so that when the user goes back
     * to the previous page it has all the values in the request.For this we
     * create an object which will store the values of previous request in case
     * the request is successful and if there is an exception it reads values
     * from that object and context and dups all in the request.
     */
    @Override
    protected ActionForward processActionPerform(HttpServletRequest request, HttpServletResponse response,
            Action action, ActionForm form, ActionMapping mapping) throws IOException, ServletException {

        ActivityContext activityContext = null;
        ActionForward forward = null;
        HttpSession session = request.getSession();

        // gets the object where we will store values from request.
        PreviousRequestValues previousRequestValues = (PreviousRequestValues) session
                .getAttribute(Constants.PREVIOUS_REQUEST);
        if (null == previousRequestValues) {
            previousRequestValues = new PreviousRequestValues();
            session.setAttribute(Constants.PREVIOUS_REQUEST, previousRequestValues);
        }

        // getting the activity context from the session
        activityContext = (ActivityContext) session.getAttribute("ActivityContext");

        // check if the action desired is permissible or not.
        // if allowed invoke the execute method of the action class

        try {
            String currentFlowKey = request.getParameter(Constants.CURRENTFLOWKEY);
            if (currentFlowKey != null) {
                previousRequestValues.getPreviousRequestValueMap().put(Constants.CURRENTFLOWKEY, currentFlowKey);
            }

            forward = (action.execute(mapping, form, request, response));

            String method = request.getParameter("method");
            if (method.equals(ClientConstants.METHOD_RETRIEVE_PICTURE)) {
                forward = mapping.findForward("get_success");
            }

            // set the last forward in the activity context
            if (activityContext != null) {
                activityContext.setLastForward(forward);
            }

            // read the request and add the values to the PreviousRequestValues
            // object. this will set every thing in the request apart from
            // context and value object.
            Enumeration requestAttributes = request.getAttributeNames();
            while (requestAttributes.hasMoreElements()) {
                String nextName = (String) requestAttributes.nextElement();
                if (nextName.startsWith(Constants.STORE_ATTRIBUTE)
                        || nextName.equalsIgnoreCase(Constants.CURRENTFLOWKEY)) {
                    logger.debug(nextName + "=" + request.getAttribute(nextName));
                    previousRequestValues.getPreviousRequestValueMap().put(nextName,
                            request.getAttribute(nextName));
                }

            }
        }

        catch (Exception e) {
            // processException logs an error (see MifosExceptionHandler)
            forward = (processException(request, response, e, form, mapping));

            // set the last forward in the activity context
            if (activityContext != null) {
                activityContext.setLastForward(forward);
            }
            populateTheRequestFromPreviousValues(request, previousRequestValues);

        } finally {
            try {
                session.removeAttribute(SecurityConstants.SECURITY_PARAM);
            } catch (Exception e) {
                // FIXME: yikes, what is being swallowed here?
            }
        }

        if (null != forward) {
            logger.info("forward.path=" + forward.getPath());
        }

        return forward;
    }

    private void populateTheRequestFromPreviousValues(HttpServletRequest request,
            PreviousRequestValues previousRequestValues) {
        // also read the previous request values map and put things in
        // request.
        Set<String> keySet = previousRequestValues.getPreviousRequestValueMap().keySet();
        if (null != keySet) {
            for (String key : keySet) {
                request.setAttribute(key, previousRequestValues.getPreviousRequestValueMap().get(key));
            }
        }

    }

    @Override
    protected boolean processRoles(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping)
            throws IOException, ServletException {
        HttpSession session = request.getSession();

        PreviousRequestValues previousRequestValues = (PreviousRequestValues) session
                .getAttribute(Constants.PREVIOUS_REQUEST);
        if (null == previousRequestValues) {
            previousRequestValues = new PreviousRequestValues();
            session.setAttribute(Constants.PREVIOUS_REQUEST, previousRequestValues);
        }
        if (!checkProcessRoles(request, response, mapping)) {

            ActionErrors error = new ActionErrors();
            error.add(SecurityConstants.KEY_ACTIVITY_NOT_ALLOWED,
                    new ActionMessage(SecurityConstants.KEY_ACTIVITY_NOT_ALLOWED));
            request.setAttribute(Globals.ERROR_KEY, error);
            ActivityContext activityContext = (ActivityContext) request.getSession()
                    .getAttribute("ActivityContext");
            populateTheRequestFromPreviousValues(request, previousRequestValues);
            processForwardConfig(request, response, activityContext.getLastForward());
            return false;
        }
        return true;
    }

}