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.kns.document.authorization;
17  
18  import org.apache.commons.logging.Log;
19  import org.apache.commons.logging.LogFactory;
20  import org.kuali.rice.kew.api.KewApiConstants;
21  import org.kuali.rice.kew.api.KewApiServiceLocator;
22  import org.kuali.rice.kew.api.WorkflowDocument;
23  import org.kuali.rice.kew.api.action.ActionType;
24  import org.kuali.rice.kew.api.doctype.ProcessDefinition;
25  import org.kuali.rice.kew.api.doctype.RoutePath;
26  import org.kuali.rice.kim.api.KimConstants;
27  import org.kuali.rice.kim.api.identity.Person;
28  import org.kuali.rice.kns.bo.authorization.BusinessObjectAuthorizerBase;
29  import org.kuali.rice.krad.document.Document;
30  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
31  import org.kuali.rice.krad.util.KRADConstants;
32  
33  import java.util.Collections;
34  import java.util.HashMap;
35  import java.util.Map;
36  import java.util.Set;
37  
38  /**
39   * DocumentAuthorizer containing common, reusable document-level authorization
40   * code.
41   *
42   * @deprecated Use {@link org.kuali.rice.krad.document.DocumentAuthorizerBase}.
43   */
44  @Deprecated
45  public class DocumentAuthorizerBase extends BusinessObjectAuthorizerBase implements DocumentAuthorizer {
46      protected static Log LOG = LogFactory.getLog(DocumentAuthorizerBase.class);
47  
48      public static final String PRE_ROUTING_ROUTE_NAME = "PreRoute";
49      public static final String EDIT_MODE_DEFAULT_TRUE_VALUE = "TRUE";
50      public static final String USER_SESSION_METHOD_TO_CALL_OBJECT_KEY = "METHOD_TO_CALL_KEYS_METHOD_OBJECT_KEY";
51      public static final String USER_SESSION_METHOD_TO_CALL_COMPLETE_OBJECT_KEY =
52              "METHOD_TO_CALL_KEYS_COMPLETE_OBJECT_KEY";
53      public static final String USER_SESSION_METHOD_TO_CALL_COMPLETE_MARKER = "_EXITING";
54  
55      /**
56       * Individual document families will need to reimplement this according to
57       * their own needs; this version should be good enough to be usable during
58       * initial development.
59       */
60      public Set<String> getDocumentActions(Document document, Person user, Set<String> documentActions) {
61          if (LOG.isDebugEnabled()) {
62              LOG.debug("calling DocumentAuthorizerBase.getDocumentActionFlags for document '"
63                      + document.getDocumentNumber()
64                      + "'. user '"
65                      + user.getPrincipalName()
66                      + "'");
67          }
68          if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_EDIT) && !canEdit(document, user)) {
69              documentActions.remove(KRADConstants.KUALI_ACTION_CAN_EDIT);
70          }
71  
72          if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_COPY) && !canCopy(document, user)) {
73              documentActions.remove(KRADConstants.KUALI_ACTION_CAN_COPY);
74          }
75  
76          if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_CLOSE) && !canClose(document, user)) {
77              documentActions.remove(KRADConstants.KUALI_ACTION_CAN_CLOSE);
78          }
79  
80          if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_RELOAD) && !canReload(document, user)) {
81              documentActions.remove(KRADConstants.KUALI_ACTION_CAN_RELOAD);
82          }
83  
84          if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_BLANKET_APPROVE) && !canBlanketApprove(document, user)) {
85              documentActions.remove(KRADConstants.KUALI_ACTION_CAN_BLANKET_APPROVE);
86          }
87  
88          if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_CANCEL) && !canCancel(document, user)) {
89              documentActions.remove(KRADConstants.KUALI_ACTION_CAN_CANCEL);
90          }
91  
92          if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_RECALL) && !canRecall(document, user)) {
93              documentActions.remove(KRADConstants.KUALI_ACTION_CAN_RECALL);
94          }
95  
96          if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_SAVE) && !canSave(document, user)) {
97              documentActions.remove(KRADConstants.KUALI_ACTION_CAN_SAVE);
98          }
99  
100         if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_ROUTE) && !canRoute(document, user)) {
101             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_ROUTE);
102         }
103 
104         if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_ACKNOWLEDGE) && !canAcknowledge(document, user)) {
105             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_ACKNOWLEDGE);
106         }
107 
108         if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_FYI) && !canFyi(document, user)) {
109             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_FYI);
110         }
111 
112         if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_APPROVE) && !canApprove(document, user)) {
113             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_APPROVE);
114         }
115 
116         if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_DISAPPROVE) && !canDisapprove(document, user)) {
117             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_DISAPPROVE);
118         }
119 
120         if (!canSendAnyTypeAdHocRequests(document, user)) {
121             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_ADD_ADHOC_REQUESTS);
122             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_SEND_ADHOC_REQUESTS);
123             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_SEND_NOTE_FYI);
124         }
125 
126         if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_SEND_NOTE_FYI) && !canSendNoteFyi(document, user)) {
127             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_SEND_NOTE_FYI);
128         }
129 
130         if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_ANNOTATE) && !canAnnotate(document, user)) {
131             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_ANNOTATE);
132         }
133 
134         if (documentActions.contains(KRADConstants.KUALI_ACTION_CAN_EDIT_DOCUMENT_OVERVIEW) && !canEditDocumentOverview(
135                 document, user)) {
136             documentActions.remove(KRADConstants.KUALI_ACTION_CAN_EDIT_DOCUMENT_OVERVIEW);
137         }
138 
139         if (documentActions.contains(KRADConstants.KUALI_ACTION_PERFORM_ROUTE_REPORT) && !canPerformRouteReport(document,
140                 user)) {
141             documentActions.remove(KRADConstants.KUALI_ACTION_PERFORM_ROUTE_REPORT);
142         }
143 
144         return documentActions;
145     }
146 
147     public boolean canInitiate(String documentTypeName, Person user) {
148         String nameSpaceCode = KRADConstants.KUALI_RICE_SYSTEM_NAMESPACE;
149         Map<String, String> permissionDetails = new HashMap<String, String>();
150         permissionDetails.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, documentTypeName);
151         return getPermissionService().isAuthorizedByTemplate(user.getPrincipalId(), nameSpaceCode,
152                 KimConstants.PermissionTemplateNames.INITIATE_DOCUMENT, permissionDetails,
153                 Collections.<String, String>emptyMap());
154     }
155 
156     public boolean canEdit(Document document, Person user) {
157         // KULRICE-7864: document can be editable on adhoc route for completion 
158         return document.getDocumentHeader().getWorkflowDocument().isCompletionRequested()
159                 || isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE, KimConstants.PermissionTemplateNames.EDIT_DOCUMENT, user.getPrincipalId());
160     }
161 
162     public boolean canAnnotate(Document document, Person user) {
163         return canEdit(document, user);
164     }
165 
166     public boolean canReload(Document document, Person user) {
167         return true;
168     }
169 
170     public boolean canClose(Document document, Person user) {
171         return true;
172     }
173 
174     public boolean canSave(Document document, Person user) {
175         return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
176                 KimConstants.PermissionTemplateNames.SAVE_DOCUMENT, user.getPrincipalId());
177     }
178 
179     public boolean canRoute(Document document, Person user) {
180         return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
181                 KimConstants.PermissionTemplateNames.ROUTE_DOCUMENT, user.getPrincipalId());
182     }
183 
184     public boolean canCancel(Document document, Person user) {
185         // KULRICE-8762: CANCEL button should be enabled for a person who is doing COMPLETE action 
186         boolean isCompletionRequested = document.getDocumentHeader().getWorkflowDocument().isCompletionRequested();
187         return isCompletionRequested || isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
188                 KimConstants.PermissionTemplateNames.CANCEL_DOCUMENT, user.getPrincipalId());
189     }
190 
191     public boolean canRecall(Document document, Person user) {
192         return KewApiServiceLocator.getWorkflowDocumentActionsService().determineValidActions(document.getDocumentNumber(), user.getPrincipalId()).getValidActions().contains(ActionType.RECALL);
193     }
194 
195     public boolean canCopy(Document document, Person user) {
196         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
197                 KimConstants.PermissionTemplateNames.COPY_DOCUMENT, user.getPrincipalId());
198     }
199 
200     public boolean canPerformRouteReport(Document document, Person user) {
201         return true;
202     }
203 
204     public boolean canBlanketApprove(Document document, Person user) {
205         return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
206                 KimConstants.PermissionTemplateNames.BLANKET_APPROVE_DOCUMENT, user.getPrincipalId());
207     }
208 
209     public boolean canApprove(Document document, Person user) {
210         return canTakeRequestedAction(document, KewApiConstants.ACTION_REQUEST_APPROVE_REQ, user);
211     }
212 
213     public boolean canDisapprove(Document document, Person user) {
214         return canApprove(document, user);
215     }
216 
217     public boolean canSendNoteFyi(Document document, Person user) {
218         return canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_FYI_REQ, user);
219     }
220 
221     public boolean canFyi(Document document, Person user) {
222         return canTakeRequestedAction(document, KewApiConstants.ACTION_REQUEST_FYI_REQ, user);
223     }
224 
225     public boolean canAcknowledge(Document document, Person user) {
226         return canTakeRequestedAction(document, KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, user);
227     }
228 
229     public boolean canReceiveAdHoc(Document document, Person user, String actionRequestCode) {
230         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
231         additionalPermissionDetails.put(KimConstants.AttributeConstants.ACTION_REQUEST_CD, actionRequestCode);
232         return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
233                 KimConstants.PermissionTemplateNames.AD_HOC_REVIEW_DOCUMENT, user.getPrincipalId(),
234                 additionalPermissionDetails, Collections.<String, String>emptyMap());
235     }
236 
237     public boolean canOpen(Document document, Person user) {
238         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
239                 KimConstants.PermissionTemplateNames.OPEN_DOCUMENT, user.getPrincipalId());
240     }
241 
242     public boolean canAddNoteAttachment(Document document, String attachmentTypeCode, Person user) {
243         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
244         if (attachmentTypeCode != null) {
245             additionalPermissionDetails.put(KimConstants.AttributeConstants.ATTACHMENT_TYPE_CODE, attachmentTypeCode);
246         }
247         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
248                 KimConstants.PermissionTemplateNames.ADD_NOTE_ATTACHMENT, user.getPrincipalId(),
249                 additionalPermissionDetails, Collections.<String, String>emptyMap());
250     }
251 
252     public boolean canDeleteNoteAttachment(Document document, String attachmentTypeCode, String createdBySelfOnly,
253             Person user) {
254         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
255         if (attachmentTypeCode != null) {
256             additionalPermissionDetails.put(KimConstants.AttributeConstants.ATTACHMENT_TYPE_CODE, attachmentTypeCode);
257         }
258         additionalPermissionDetails.put(KimConstants.AttributeConstants.CREATED_BY_SELF, createdBySelfOnly);
259         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
260                 KimConstants.PermissionTemplateNames.DELETE_NOTE_ATTACHMENT, user.getPrincipalId(),
261                 additionalPermissionDetails, Collections.<String, String>emptyMap());
262     }
263 
264     public boolean canViewNoteAttachment(Document document, String attachmentTypeCode, Person user) {
265         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
266         if (attachmentTypeCode != null) {
267             additionalPermissionDetails.put(KimConstants.AttributeConstants.ATTACHMENT_TYPE_CODE, attachmentTypeCode);
268         }
269         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
270                 KimConstants.PermissionTemplateNames.VIEW_NOTE_ATTACHMENT, user.getPrincipalId(),
271                 additionalPermissionDetails, Collections.<String, String>emptyMap());
272     }
273 
274     public boolean canViewNoteAttachment(Document document, String attachmentTypeCode, String authorUniversalIdentifier,
275             Person user) {
276         return canViewNoteAttachment(document, attachmentTypeCode, user);
277     }
278 
279     public boolean canSendAdHocRequests(Document document, String actionRequestCd, Person user) {
280         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
281         if (actionRequestCd != null) {
282             additionalPermissionDetails.put(KimConstants.AttributeConstants.ACTION_REQUEST_CD, actionRequestCd);
283         }
284         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
285                 KimConstants.PermissionTemplateNames.SEND_AD_HOC_REQUEST, user.getPrincipalId(),
286                 additionalPermissionDetails, Collections.<String, String>emptyMap());
287     }
288 
289     public boolean canEditDocumentOverview(Document document, Person user) {
290         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
291                 KimConstants.PermissionTemplateNames.EDIT_DOCUMENT, user.getPrincipalId()) && this.isDocumentInitiator(
292                 document, user);
293     }
294 
295     public boolean canSendAnyTypeAdHocRequests(Document document, Person user) {
296         if (canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_FYI_REQ, user)) {
297             RoutePath routePath = KewApiServiceLocator.getDocumentTypeService().getRoutePathForDocumentTypeName(
298                     document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
299             ProcessDefinition processDefinition = routePath.getPrimaryProcess();
300             if (processDefinition != null) {
301                 if (processDefinition.getInitialRouteNode() == null) {
302                     return false;
303                 }
304             } else {
305                 return false;
306             }
307             return true;
308         } else if (canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, user)) {
309             return true;
310         }
311         return canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_APPROVE_REQ, user);
312     }
313 
314     public boolean canTakeRequestedAction(Document document, String actionRequestCode, Person user) {
315         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
316         additionalPermissionDetails.put(KimConstants.AttributeConstants.ACTION_REQUEST_CD, actionRequestCode);
317         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
318                 KimConstants.PermissionTemplateNames.TAKE_REQUESTED_ACTION, user.getPrincipalId(),
319                 additionalPermissionDetails, Collections.<String, String>emptyMap());
320     }
321 
322     @Override
323     protected void addPermissionDetails(Object dataObject, Map<String, String> attributes) {
324         super.addPermissionDetails(dataObject, attributes);
325         if (dataObject instanceof Document) {
326             addStandardAttributes((Document) dataObject, attributes);
327         }
328     }
329 
330     @Override
331     protected void addRoleQualification(Object dataObject, Map<String, String> attributes) {
332         super.addRoleQualification(dataObject, attributes);
333         if (dataObject instanceof Document) {
334             addStandardAttributes((Document) dataObject, attributes);
335         }
336     }
337 
338     protected void addStandardAttributes(Document document, Map<String, String> attributes) {
339         WorkflowDocument wd = document.getDocumentHeader().getWorkflowDocument();
340         attributes.put(KimConstants.AttributeConstants.DOCUMENT_NUMBER, document.getDocumentNumber());
341         attributes.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, wd.getDocumentTypeName());
342         if (wd.isInitiated() || wd.isSaved()) {
343             attributes.put(KimConstants.AttributeConstants.ROUTE_NODE_NAME, PRE_ROUTING_ROUTE_NAME);
344         } else {
345             attributes.put(KimConstants.AttributeConstants.ROUTE_NODE_NAME,
346                     KRADServiceLocatorWeb.getWorkflowDocumentService().getCurrentRouteNodeNames(wd));
347         }
348         attributes.put(KimConstants.AttributeConstants.ROUTE_STATUS_CODE, wd.getStatus().getCode());
349     }
350 
351     protected boolean isDocumentInitiator(Document document, Person user) {
352         WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
353         return workflowDocument.getInitiatorPrincipalId().equalsIgnoreCase(user.getPrincipalId());
354     }
355 }