View Javadoc
1   /**
2    * Copyright 2005-2014 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.krad.document;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  import org.kuali.rice.kew.api.WorkflowDocument;
22  import org.kuali.rice.kim.api.KimConstants;
23  import org.kuali.rice.kim.api.identity.Person;
24  import org.kuali.rice.krad.UserSessionUtils;
25  import org.kuali.rice.krad.datadictionary.AttributeSecurity;
26  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
27  import org.kuali.rice.krad.uif.field.DataField;
28  import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
29  import org.kuali.rice.krad.uif.view.View;
30  import org.kuali.rice.krad.uif.view.ViewAuthorizerBase;
31  import org.kuali.rice.krad.uif.view.ViewModel;
32  import org.kuali.rice.krad.util.GlobalVariables;
33  import org.kuali.rice.krad.util.KRADConstants;
34  import org.kuali.rice.krad.util.KRADUtils;
35  import org.kuali.rice.krad.web.form.DocumentFormBase;
36  
37  import java.util.Map;
38  import java.util.Set;
39  
40  /**
41   * Implementation of {@link org.kuali.rice.krad.uif.view.ViewAuthorizer} for
42   * {@link org.kuali.rice.krad.uif.view.DocumentView} instances
43   *
44   * <p>
45   * Performs KIM permission checks for the various document actions such as save, approve, cancel
46   * </p>
47   *
48   * <p>
49   * By default delegates to the {@link DocumentAuthorizer} configured for the document in the data dictionary
50   * </p>
51   *
52   * @author Kuali Rice Team (rice.collab@kuali.org)
53   */
54  public class DocumentViewAuthorizerBase extends ViewAuthorizerBase implements DocumentAuthorizer {
55      private static final long serialVersionUID = 3800780934223224565L;
56  
57      protected static Log LOG = LogFactory.getLog(DocumentViewAuthorizerBase.class);
58  
59      public static final String PRE_ROUTING_ROUTE_NAME = "PreRoute";
60  
61      private DocumentAuthorizer documentAuthorizer;
62  
63      /**
64       * {@inheritDoc}
65       */
66      @Override
67      public Set<String> getActionFlags(View view, ViewModel model, Person user, Set<String> actions) {
68          Document document = ((DocumentFormBase) model).getDocument();
69  
70          if (LOG.isDebugEnabled()) {
71              LOG.debug("calling DocumentAuthorizerBase.getDocumentActionFlags for document '"
72                      + document.getDocumentNumber()
73                      + "'. user '"
74                      + user.getPrincipalName()
75                      + "'");
76          }
77  
78          if (actions.contains(KRADConstants.KUALI_ACTION_CAN_EDIT) && !canEdit(document, user)) {
79              actions.remove(KRADConstants.KUALI_ACTION_CAN_EDIT);
80          }
81  
82          if (actions.contains(KRADConstants.KUALI_ACTION_CAN_COPY) && !canCopy(document, user)) {
83              actions.remove(KRADConstants.KUALI_ACTION_CAN_COPY);
84          }
85  
86          if (actions.contains(KRADConstants.KUALI_ACTION_CAN_CLOSE) && !canClose(document, user)) {
87              actions.remove(KRADConstants.KUALI_ACTION_CAN_CLOSE);
88          }
89  
90          if (actions.contains(KRADConstants.KUALI_ACTION_CAN_RELOAD) && !canReload(document, user)) {
91              actions.remove(KRADConstants.KUALI_ACTION_CAN_RELOAD);
92          }
93  
94          if (actions.contains(KRADConstants.KUALI_ACTION_CAN_BLANKET_APPROVE) && !canBlanketApprove(document, user)) {
95              actions.remove(KRADConstants.KUALI_ACTION_CAN_BLANKET_APPROVE);
96          }
97  
98          if (actions.contains(KRADConstants.KUALI_ACTION_CAN_CANCEL) && !canCancel(document, user)) {
99              actions.remove(KRADConstants.KUALI_ACTION_CAN_CANCEL);
100         }
101 
102         if (actions.contains(KRADConstants.KUALI_ACTION_CAN_RECALL) && !canRecall(document, user)) {
103             actions.remove(KRADConstants.KUALI_ACTION_CAN_RECALL);
104         }
105 
106         if (actions.contains(KRADConstants.KUALI_ACTION_CAN_SAVE) && !canSave(document, user)) {
107             actions.remove(KRADConstants.KUALI_ACTION_CAN_SAVE);
108         }
109 
110         if (actions.contains(KRADConstants.KUALI_ACTION_CAN_ROUTE) && !canRoute(document, user)) {
111             actions.remove(KRADConstants.KUALI_ACTION_CAN_ROUTE);
112         }
113 
114         if (actions.contains(KRADConstants.KUALI_ACTION_CAN_ACKNOWLEDGE) && !canAcknowledge(document, user)) {
115             actions.remove(KRADConstants.KUALI_ACTION_CAN_ACKNOWLEDGE);
116         }
117 
118         if (actions.contains(KRADConstants.KUALI_ACTION_CAN_FYI) && !canFyi(document, user)) {
119             actions.remove(KRADConstants.KUALI_ACTION_CAN_FYI);
120         }
121 
122         if (actions.contains(KRADConstants.KUALI_ACTION_CAN_APPROVE) && !canApprove(document, user)) {
123             actions.remove(KRADConstants.KUALI_ACTION_CAN_APPROVE);
124         }
125 
126         if (actions.contains(KRADConstants.KUALI_ACTION_CAN_DISAPPROVE) && !canDisapprove(document, user)) {
127             actions.remove(KRADConstants.KUALI_ACTION_CAN_DISAPPROVE);
128         }
129 
130         if (!canSendAnyTypeAdHocRequests(document, user)) {
131             actions.remove(KRADConstants.KUALI_ACTION_CAN_ADD_ADHOC_REQUESTS);
132             actions.remove(KRADConstants.KUALI_ACTION_CAN_SEND_ADHOC_REQUESTS);
133             actions.remove(KRADConstants.KUALI_ACTION_CAN_SEND_NOTE_FYI);
134         }
135 
136         if (actions.contains(KRADConstants.KUALI_ACTION_CAN_SEND_NOTE_FYI) && !canSendNoteFyi(document, user)) {
137             actions.remove(KRADConstants.KUALI_ACTION_CAN_SEND_NOTE_FYI);
138         }
139 
140         if (actions.contains(KRADConstants.KUALI_ACTION_CAN_ANNOTATE) && !canAnnotate(document, user)) {
141             actions.remove(KRADConstants.KUALI_ACTION_CAN_ANNOTATE);
142         }
143 
144         if (actions.contains(KRADConstants.KUALI_ACTION_CAN_EDIT_DOCUMENT_OVERVIEW) && !canEditDocumentOverview(
145                 document, user)) {
146             actions.remove(KRADConstants.KUALI_ACTION_CAN_EDIT_DOCUMENT_OVERVIEW);
147         }
148 
149         if (actions.contains(KRADConstants.KUALI_ACTION_PERFORM_ROUTE_REPORT) && !canPerformRouteReport(document,
150                 user)) {
151             actions.remove(KRADConstants.KUALI_ACTION_PERFORM_ROUTE_REPORT);
152         }
153 
154         return actions;
155     }
156 
157     public final boolean canInitiate(String documentTypeName, Person user) {
158         return getDocumentAuthorizer().canInitiate(documentTypeName, user);
159     }
160 
161     public final boolean canOpen(Document document, Person user) {
162         return getDocumentAuthorizer().canOpen(document, user);
163     }
164 
165     @Override
166     public boolean canOpenView(View view, ViewModel model, Person user) {
167         DocumentFormBase documentForm = (DocumentFormBase) model;
168 
169         return super.canOpenView(view, model, user) && canOpen(documentForm.getDocument(), user);
170     }
171 
172     public boolean canEdit(Document document, Person user) {
173         return getDocumentAuthorizer().canEdit(document, user);
174     }
175 
176     @Override
177     public boolean canEditView(View view, ViewModel model, Person user) {
178         DocumentFormBase documentForm = (DocumentFormBase) model;
179 
180         return super.canEditView(view, model, user) && canEdit(documentForm.getDocument(), user);
181     }
182 
183     /**
184      * @see org.kuali.rice.krad.uif.view.ViewAuthorizer#canUnmaskField(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
185      * org.kuali.rice.krad.uif.field.DataField, java.lang.String, org.kuali.rice.kim.api.identity.Person)
186      */
187     public boolean canUnmaskField(View view, ViewModel model, DataField field, String propertyName, Person user) {
188         if (field.getDataFieldSecurity() == null) {
189             return true;
190         }
191 
192         // check mask authz flag is set
193         AttributeSecurity attributeSecurity = field.getDataFieldSecurity().getAttributeSecurity();
194         if (attributeSecurity == null || !attributeSecurity.isMask()) {
195             return true;
196         }
197 
198         // don't mask empty fields when user is the initiator (allows document creation when masked field exists)
199         String fieldValue = ObjectPropertyUtils.getPropertyValue(model, field.getBindingInfo().getBindingPath());
200         if (StringUtils.isBlank(fieldValue) && isInitiator(model, user)) {
201             return true;
202         }
203 
204         return super.canUnmaskField(view, model, field, propertyName, user);
205     }
206 
207     /**
208      * Checks if the user is the initiator for the current document
209      *
210      * @param model object containing the view data
211      * @param user user we are authorizing
212      * @return true if user is the initiator, false otherwise
213      */
214     protected boolean isInitiator(ViewModel model, Person user) {
215             WorkflowDocument workflowDocument = UserSessionUtils.getWorkflowDocument(GlobalVariables.getUserSession(),
216                     ((DocumentFormBase) model).getDocument().getDocumentNumber());
217             return StringUtils.equals(user.getPrincipalId(), workflowDocument.getInitiatorPrincipalId());
218     }
219 
220 
221     public boolean canAnnotate(Document document, Person user) {
222         return getDocumentAuthorizer().canAnnotate(document, user);
223     }
224 
225     public boolean canReload(Document document, Person user) {
226         return getDocumentAuthorizer().canReload(document, user);
227     }
228 
229     public boolean canClose(Document document, Person user) {
230         return getDocumentAuthorizer().canClose(document, user);
231     }
232 
233     public boolean canSave(Document document, Person user) {
234         return getDocumentAuthorizer().canSave(document, user);
235     }
236 
237     public boolean canRoute(Document document, Person user) {
238         return getDocumentAuthorizer().canRoute(document, user);
239     }
240 
241     public boolean canCancel(Document document, Person user) {
242         return getDocumentAuthorizer().canCancel(document, user);
243     }
244 
245     public boolean canRecall(Document document, Person user) {
246         return getDocumentAuthorizer().canRecall(document, user);
247     }
248 
249     public boolean canCopy(Document document, Person user) {
250         return getDocumentAuthorizer().canCopy(document, user);
251     }
252 
253     public boolean canPerformRouteReport(Document document, Person user) {
254         return getDocumentAuthorizer().canPerformRouteReport(document, user);
255     }
256 
257     public boolean canBlanketApprove(Document document, Person user) {
258         return getDocumentAuthorizer().canBlanketApprove(document, user);
259     }
260 
261     public boolean canApprove(Document document, Person user) {
262         return getDocumentAuthorizer().canApprove(document, user);
263     }
264 
265     public boolean canDisapprove(Document document, Person user) {
266         return getDocumentAuthorizer().canDisapprove(document, user);
267     }
268 
269     public boolean canSendNoteFyi(Document document, Person user) {
270         return getDocumentAuthorizer().canSendNoteFyi(document, user);
271     }
272 
273     public boolean canFyi(Document document, Person user) {
274         return getDocumentAuthorizer().canFyi(document, user);
275     }
276 
277     public boolean canAcknowledge(Document document, Person user) {
278         return getDocumentAuthorizer().canAcknowledge(document, user);
279     }
280 
281     public final boolean canReceiveAdHoc(Document document, Person user, String actionRequestCode) {
282         return getDocumentAuthorizer().canReceiveAdHoc(document, user, actionRequestCode);
283     }
284 
285     public final boolean canAddNoteAttachment(Document document, String attachmentTypeCode, Person user) {
286         return getDocumentAuthorizer().canAddNoteAttachment(document, attachmentTypeCode, user);
287     }
288 
289     public final boolean canDeleteNoteAttachment(Document document, String attachmentTypeCode,
290             String authorUniversalIdentifier, Person user) {
291         return getDocumentAuthorizer().canDeleteNoteAttachment(document, attachmentTypeCode, authorUniversalIdentifier,
292                 user);
293     }
294 
295     public final boolean canViewNoteAttachment(Document document, String attachmentTypeCode,
296             String authorUniversalIdentifier, Person user) {
297         return getDocumentAuthorizer().canViewNoteAttachment(document, attachmentTypeCode, authorUniversalIdentifier,
298                 user);
299     }
300 
301     public final boolean canSendAdHocRequests(Document document, String actionRequestCd, Person user) {
302         return getDocumentAuthorizer().canSendAdHocRequests(document, actionRequestCd, user);
303     }
304 
305     public boolean canEditDocumentOverview(Document document, Person user) {
306         return getDocumentAuthorizer().canEditDocumentOverview(document, user);
307     }
308 
309     public boolean canSendAnyTypeAdHocRequests(Document document, Person user) {
310         return getDocumentAuthorizer().canSendAnyTypeAdHocRequests(document, user);
311     }
312 
313     public boolean canTakeRequestedAction(Document document, String actionRequestCode, Person user) {
314         return getDocumentAuthorizer().canTakeRequestedAction(document, actionRequestCode, user);
315     }
316 
317     @Override
318     protected void addPermissionDetails(Object dataObject, Map<String, String> attributes) {
319         super.addPermissionDetails(dataObject, attributes);
320 
321         if (dataObject instanceof Document) {
322             addStandardAttributes((Document) dataObject, attributes);
323         }
324     }
325 
326     @Override
327     protected void addRoleQualification(Object dataObject, Map<String, String> attributes) {
328         super.addRoleQualification(dataObject, attributes);
329 
330         if (dataObject instanceof Document) {
331             addStandardAttributes((Document) dataObject, attributes);
332         }
333     }
334 
335     protected void addStandardAttributes(Document document, Map<String, String> attributes) {
336         WorkflowDocument wd = document.getDocumentHeader().getWorkflowDocument();
337         attributes.put(KimConstants.AttributeConstants.DOCUMENT_NUMBER, document.getDocumentNumber());
338         attributes.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, wd.getDocumentTypeName());
339 
340         if (wd.isInitiated() || wd.isSaved()) {
341             attributes.put(KimConstants.AttributeConstants.ROUTE_NODE_NAME, PRE_ROUTING_ROUTE_NAME);
342         } else {
343             attributes.put(KimConstants.AttributeConstants.ROUTE_NODE_NAME,
344                     KRADServiceLocatorWeb.getWorkflowDocumentService().getCurrentRouteNodeNames(wd));
345         }
346 
347         attributes.put(KimConstants.AttributeConstants.ROUTE_STATUS_CODE, wd.getStatus().getCode());
348     }
349 
350     protected boolean isDocumentInitiator(Document document, Person user) {
351         WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
352 
353         return workflowDocument.getInitiatorPrincipalId().equalsIgnoreCase(user.getPrincipalId());
354     }
355 
356     public DocumentAuthorizer getDocumentAuthorizer() {
357         return documentAuthorizer;
358     }
359 
360     public void setDocumentAuthorizer(DocumentAuthorizer documentAuthorizer) {
361         this.documentAuthorizer = documentAuthorizer;
362     }
363 
364     public void setDocumentAuthorizerClass(Class<? extends DocumentAuthorizer> documentAuthorizerClass) {
365         this.documentAuthorizer = KRADUtils.createNewObjectFromClass(documentAuthorizerClass);
366     }
367 }