/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.sec.document.web; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.Tag; import org.apache.struts.Globals; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import org.kuali.kfs.sec.SecConstants; import org.kuali.kfs.sec.SecKeyConstants; import org.kuali.kfs.sec.service.AccessSecurityService; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.document.AccountingDocument; import org.kuali.kfs.sys.document.datadictionary.AccountingLineGroupDefinition; import org.kuali.kfs.sys.document.web.DefaultAccountingLineGroupImpl; import org.kuali.kfs.sys.document.web.RenderableAccountingLineContainer; import org.kuali.kfs.sys.document.web.renderers.GroupErrorsRenderer; import org.kuali.rice.kim.api.identity.Person; import org.kuali.rice.krad.util.GlobalVariables; /** * Integrates with access security module to check security on accounting lines before rendering */ public class SecAccountingLineGroupImpl extends DefaultAccountingLineGroupImpl { protected boolean hasEditRestrictions; protected boolean hasViewRestrictions; /** * Constructs a SecAccountingLineGroupImpl */ public SecAccountingLineGroupImpl() { hasEditRestrictions = false; hasViewRestrictions = false; } /** * Performs access security edit check and sets edit flag on container line to false if access is not allowed or removes * container if view is not allowed * * @see org.kuali.kfs.sys.document.web.DefaultAccountingLineGroupImpl#initialize(org.kuali.kfs.sys.document.datadictionary.AccountingLineGroupDefinition, * org.kuali.kfs.sys.document.AccountingDocument, java.util.List, java.lang.String, java.lang.String, java.util.Map, * java.util.Map, java.util.Map, boolean) */ @Override public void initialize(AccountingLineGroupDefinition groupDefinition, AccountingDocument accountingDocument, List<RenderableAccountingLineContainer> containers, String collectionPropertyName, String collectionItemPropertyName, Map<String, Object> displayedErrors, Map<String, Object> displayedWarnings, Map<String, Object> displayedInfo, boolean canEdit) { AccessSecurityService accessSecurityService = SpringContext.getBean(AccessSecurityService.class); Person currentUser = GlobalVariables.getUserSession().getPerson(); // check view and edit access List<RenderableAccountingLineContainer> unviewableContainers = new ArrayList<RenderableAccountingLineContainer>(); for (RenderableAccountingLineContainer container : containers) { boolean lineHasError = false; for (Object errorKeyAsObject : GlobalVariables.getMessageMap().getErrorMessages().keySet() ) { if (((String) errorKeyAsObject).startsWith(collectionItemPropertyName)) { lineHasError = true; } } if (lineHasError || container.isNewLine()) { container.setEditableLine(true); continue; } boolean viewAllowed = accessSecurityService.canViewDocumentAccountingLine(accountingDocument, container.getAccountingLine(), currentUser); if (!viewAllowed) { unviewableContainers.add(container); hasViewRestrictions = true; } else { boolean editAllowed = accessSecurityService.canEditDocumentAccountingLine(accountingDocument, container.getAccountingLine(), currentUser); if (container.isEditableLine() && !editAllowed) { container.setEditableLine(false); hasEditRestrictions = true; } } } // remove containers that are not viewable for (RenderableAccountingLineContainer container : unviewableContainers) { containers.remove(container); } super.initialize(groupDefinition, accountingDocument, containers, collectionPropertyName, collectionItemPropertyName, displayedErrors, displayedWarnings, displayedInfo, canEdit); } /** * Adds info message if we have restricted view of any accounting lines and adds an additional key to match on * * @see org.kuali.kfs.sys.document.web.DefaultAccountingLineGroupImpl#renderErrors(javax.servlet.jsp.PageContext, * javax.servlet.jsp.tagext.Tag) */ @Override protected void renderErrors(PageContext pageContext, Tag parentTag) throws JspException { renderSecurityMessage(pageContext, parentTag); renderMessages(pageContext, parentTag, groupDefinition.getErrorKey()); } /** * Helper method for outputting messages * * @param pageContext * @param parentTag * @param messageKey - key for messages to display * @throws JspException */ protected void renderMessages(PageContext pageContext, Tag parentTag, String messageKey) throws JspException { GroupErrorsRenderer errorRenderer = getErrorRenderer(); errorRenderer.setErrorKeyMatch(messageKey); errorRenderer.setColSpan(getWidthInCells()); errorRenderer.render(pageContext, parentTag); moveListToMap(errorRenderer.getErrorsRendered(), getDisplayedErrors()); moveListToMap(errorRenderer.getWarningsRendered(), getDisplayedWarnings()); moveListToMap(errorRenderer.getInfoRendered(), getDisplayedInfo()); errorRenderer.clear(); } /** * Adds info message for any security restrictions that have been applied * * @param pageContext * @param parentTag * @throws JspException */ protected void renderSecurityMessage(PageContext pageContext, Tag parentTag) throws JspException { String secErrorKey = SecConstants.ACCOUNTING_GROUP_ERROR_KEY_PREFIX + collectionItemPropertyName + collectionPropertyName; // add info message if we are restricting any lines from view if (hasEditRestrictions || hasViewRestrictions) { List pageWarnings = (List) pageContext.getRequest().getAttribute("InfoPropertyList"); if (pageWarnings == null) { pageWarnings = new ArrayList(); } pageWarnings.add(secErrorKey); pageContext.getRequest().setAttribute("InfoPropertyList", pageWarnings); ActionMessages requestErrors = (ActionMessages) pageContext.getRequest().getAttribute("InfoActionMessages"); if (requestErrors == null) { requestErrors = new ActionMessages(); } if (hasViewRestrictions) { requestErrors.add(secErrorKey, new ActionMessage(SecKeyConstants.MESSAGE_ACCOUNTING_LINE_VIEW_RESTRICTED)); } else { requestErrors.add(secErrorKey, new ActionMessage(SecKeyConstants.MESSAGE_ACCOUNTING_LINE_EDIT_RESTRICTED)); } pageContext.getRequest().setAttribute(Globals.ERROR_KEY, requestErrors); } renderMessages(pageContext, parentTag, secErrorKey); } }