View Javadoc
1   /*
2    * Copyright 2009 The Kuali Foundation.
3    * 
4    * Licensed under the Educational Community License, Version 1.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/ecl1.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.ole.sec.document.web;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.Map;
21  
22  import javax.servlet.jsp.JspException;
23  import javax.servlet.jsp.PageContext;
24  import javax.servlet.jsp.tagext.Tag;
25  
26  import org.apache.struts.Globals;
27  import org.apache.struts.action.ActionMessage;
28  import org.apache.struts.action.ActionMessages;
29  import org.kuali.ole.sec.SecConstants;
30  import org.kuali.ole.sec.SecKeyConstants;
31  import org.kuali.ole.sec.service.AccessSecurityService;
32  import org.kuali.ole.sys.context.SpringContext;
33  import org.kuali.ole.sys.document.AccountingDocument;
34  import org.kuali.ole.sys.document.datadictionary.AccountingLineGroupDefinition;
35  import org.kuali.ole.sys.document.web.DefaultAccountingLineGroupImpl;
36  import org.kuali.ole.sys.document.web.RenderableAccountingLineContainer;
37  import org.kuali.ole.sys.document.web.renderers.GroupErrorsRenderer;
38  import org.kuali.rice.kim.api.identity.Person;
39  import org.kuali.rice.krad.util.GlobalVariables;
40  
41  
42  /**
43   * Integrates with access security module to check security on accounting lines before rendering
44   */
45  public class SecAccountingLineGroupImpl extends DefaultAccountingLineGroupImpl {
46      protected boolean hasEditRestrictions;
47      protected boolean hasViewRestrictions;
48  
49      /**
50       * Constructs a SecAccountingLineGroupImpl
51       */
52      public SecAccountingLineGroupImpl() {
53          hasEditRestrictions = false;
54          hasViewRestrictions = false;
55      }
56  
57      /**
58       * Performs access security edit check and sets edit flag on container line to false if access is not allowed or removes
59       * container if view is not allowed
60       * 
61       * @see org.kuali.ole.sys.document.web.DefaultAccountingLineGroupImpl#initialize(org.kuali.ole.sys.document.datadictionary.AccountingLineGroupDefinition,
62       *      org.kuali.ole.sys.document.AccountingDocument, java.util.List, java.lang.String, java.lang.String, java.util.Map,
63       *      java.util.Map, java.util.Map, boolean)
64       */
65      @Override
66      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) {
67          AccessSecurityService accessSecurityService = SpringContext.getBean(AccessSecurityService.class);
68          Person currentUser = GlobalVariables.getUserSession().getPerson();
69  
70          // check view and edit access
71          List<RenderableAccountingLineContainer> unviewableContainers = new ArrayList<RenderableAccountingLineContainer>();
72          for (RenderableAccountingLineContainer container : containers) {
73              boolean lineHasError = false;
74              for (Object errorKeyAsObject : GlobalVariables.getMessageMap().getErrorMessages().keySet() ) {
75                  if (((String) errorKeyAsObject).startsWith(collectionItemPropertyName)) {
76                      lineHasError = true;
77              }
78              }
79  
80              if (lineHasError || container.isNewLine()) {
81                  container.setEditableLine(true);
82                  continue;
83              }
84  
85              boolean viewAllowed = accessSecurityService.canViewDocumentAccountingLine(accountingDocument, container.getAccountingLine(), currentUser);
86              if (!viewAllowed) {
87                  unviewableContainers.add(container);
88                  hasViewRestrictions = true;
89              }
90              else {
91                  boolean editAllowed = accessSecurityService.canEditDocumentAccountingLine(accountingDocument, container.getAccountingLine(), currentUser);
92  
93                  if (container.isEditableLine() && !editAllowed) {
94                      container.setEditableLine(false);
95                      hasEditRestrictions = true;
96                  }
97              }
98          }
99  
100         // remove containers that are not viewable
101         for (RenderableAccountingLineContainer container : unviewableContainers) {
102             containers.remove(container);
103         }
104 
105         super.initialize(groupDefinition, accountingDocument, containers, collectionPropertyName, collectionItemPropertyName, displayedErrors, displayedWarnings, displayedInfo, canEdit);
106     }
107 
108     /**
109      * Adds info message if we have restricted view of any accounting lines and adds an additional key to match on
110      * 
111      * @see org.kuali.ole.sys.document.web.DefaultAccountingLineGroupImpl#renderErrors(javax.servlet.jsp.PageContext,
112      *      javax.servlet.jsp.tagext.Tag)
113      */
114     @Override
115     protected void renderErrors(PageContext pageContext, Tag parentTag) throws JspException {
116         renderSecurityMessage(pageContext, parentTag);
117 
118         renderMessages(pageContext, parentTag, groupDefinition.getErrorKey());
119     }
120 
121     /**
122      * Helper method for outputting messages
123      * 
124      * @param pageContext
125      * @param parentTag
126      * @param messageKey - key for messages to display
127      * @throws JspException
128      */
129     protected void renderMessages(PageContext pageContext, Tag parentTag, String messageKey) throws JspException {
130         GroupErrorsRenderer errorRenderer = getErrorRenderer();
131         errorRenderer.setErrorKeyMatch(messageKey);
132         errorRenderer.setColSpan(getWidthInCells());
133         errorRenderer.render(pageContext, parentTag);
134 
135         moveListToMap(errorRenderer.getErrorsRendered(), getDisplayedErrors());
136         moveListToMap(errorRenderer.getWarningsRendered(), getDisplayedWarnings());
137         moveListToMap(errorRenderer.getInfoRendered(), getDisplayedInfo());
138 
139         errorRenderer.clear();
140     }
141 
142     /**
143      * Adds info message for any security restrictions that have been applied
144      * 
145      * @param pageContext
146      * @param parentTag
147      * @throws JspException
148      */
149     protected void renderSecurityMessage(PageContext pageContext, Tag parentTag) throws JspException {
150         String secErrorKey = SecConstants.ACCOUNTING_GROUP_ERROR_KEY_PREFIX + collectionItemPropertyName + collectionPropertyName;
151 
152         // add info message if we are restricting any lines from view
153         if (hasEditRestrictions || hasViewRestrictions) {
154             List pageWarnings = (List) pageContext.getRequest().getAttribute("InfoPropertyList");
155             if (pageWarnings == null) {
156                 pageWarnings = new ArrayList();
157             }
158             pageWarnings.add(secErrorKey);
159             pageContext.getRequest().setAttribute("InfoPropertyList", pageWarnings);
160 
161             ActionMessages requestErrors = (ActionMessages) pageContext.getRequest().getAttribute("InfoActionMessages");
162             if (requestErrors == null) {
163                 requestErrors = new ActionMessages();
164             }
165 
166             if (hasViewRestrictions) {
167                 requestErrors.add(secErrorKey, new ActionMessage(SecKeyConstants.MESSAGE_ACCOUNTING_LINE_VIEW_RESTRICTED));
168             }
169             else {
170                 requestErrors.add(secErrorKey, new ActionMessage(SecKeyConstants.MESSAGE_ACCOUNTING_LINE_EDIT_RESTRICTED));
171             }
172 
173             pageContext.getRequest().setAttribute(Globals.ERROR_KEY, requestErrors);
174         }
175 
176         renderMessages(pageContext, parentTag, secErrorKey);
177     }
178 
179 }