View Javadoc

1   /**
2    * Copyright 2005-2012 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.kuali.rice.kew.api.KewApiConstants;
19  import org.kuali.rice.kew.api.KewApiServiceLocator;
20  import org.kuali.rice.kew.api.WorkflowDocument;
21  import org.kuali.rice.kew.api.action.ActionType;
22  import org.kuali.rice.kew.api.doctype.ProcessDefinition;
23  import org.kuali.rice.kew.api.doctype.RoutePath;
24  import org.kuali.rice.kim.api.KimConstants;
25  import org.kuali.rice.kim.api.identity.Person;
26  import org.kuali.rice.krad.bo.DataObjectAuthorizerBase;
27  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
28  import org.kuali.rice.krad.util.KRADConstants;
29  
30  import java.util.Collections;
31  import java.util.HashMap;
32  import java.util.Map;
33  
34  /**
35   * Default implementation for {@link DocumentAuthorizer} that perform KIM permission checks to authorize the actions
36   *
37   * @author Kuali Rice Team (rice.collab@kuali.org)
38   */
39  public class DocumentAuthorizerBase extends DataObjectAuthorizerBase implements DocumentAuthorizer {
40      private static final long serialVersionUID = -5354518767379472681L;
41  
42      public static final String PRE_ROUTING_ROUTE_NAME = "PreRoute";
43  
44      public final boolean canInitiate(String documentTypeName, Person user) {
45          String nameSpaceCode = KRADConstants.KUALI_RICE_SYSTEM_NAMESPACE;
46          Map<String, String> permissionDetails = new HashMap<String, String>();
47          permissionDetails.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, documentTypeName);
48  
49          return getPermissionService().isAuthorizedByTemplate(user.getPrincipalId(), nameSpaceCode,
50                  KimConstants.PermissionTemplateNames.INITIATE_DOCUMENT, permissionDetails,
51                  Collections.<String, String>emptyMap());
52      }
53  
54      public boolean canOpen(Document document, Person user) {
55          return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
56                  KimConstants.PermissionTemplateNames.OPEN_DOCUMENT, user.getPrincipalId());
57      }
58  
59      public boolean canEdit(Document document, Person user) {
60          return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
61                  KimConstants.PermissionTemplateNames.EDIT_DOCUMENT, user.getPrincipalId());
62      }
63  
64      public boolean canAnnotate(Document document, Person user) {
65          return canEdit(document, user);
66      }
67  
68      public boolean canReload(Document document, Person user) {
69          return true;
70      }
71  
72      public boolean canClose(Document document, Person user) {
73          return true;
74      }
75  
76      public boolean canSave(Document document, Person user) {
77          return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
78                  KimConstants.PermissionTemplateNames.SAVE_DOCUMENT, user.getPrincipalId());
79      }
80  
81      public boolean canRoute(Document document, Person user) {
82          return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
83                  KimConstants.PermissionTemplateNames.ROUTE_DOCUMENT, user.getPrincipalId());
84      }
85  
86      public boolean canCancel(Document document, Person user) {
87          return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
88                  KimConstants.PermissionTemplateNames.CANCEL_DOCUMENT, user.getPrincipalId());
89      }
90  
91      public boolean canRecall(Document document, Person user) {
92          return KewApiServiceLocator.getWorkflowDocumentActionsService().determineValidActions(document.getDocumentNumber(), user.getPrincipalId()).getValidActions().contains(ActionType.RECALL);
93      }
94  
95      public boolean canCopy(Document document, Person user) {
96          return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
97                  KimConstants.PermissionTemplateNames.COPY_DOCUMENT, user.getPrincipalId());
98      }
99  
100     public boolean canPerformRouteReport(Document document, Person user) {
101         return true;
102     }
103 
104     public boolean canBlanketApprove(Document document, Person user) {
105         return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
106                 KimConstants.PermissionTemplateNames.BLANKET_APPROVE_DOCUMENT, user.getPrincipalId());
107     }
108 
109     public boolean canApprove(Document document, Person user) {
110         return canTakeRequestedAction(document, KewApiConstants.ACTION_REQUEST_APPROVE_REQ, user);
111     }
112 
113     public boolean canDisapprove(Document document, Person user) {
114         return canApprove(document, user);
115     }
116 
117     public boolean canSendNoteFyi(Document document, Person user) {
118         return canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_FYI_REQ, user);
119     }
120 
121     public boolean canFyi(Document document, Person user) {
122         return canTakeRequestedAction(document, KewApiConstants.ACTION_REQUEST_FYI_REQ, user);
123     }
124 
125     public boolean canAcknowledge(Document document, Person user) {
126         return canTakeRequestedAction(document, KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, user);
127     }
128 
129     public boolean canReceiveAdHoc(Document document, Person user, String actionRequestCode) {
130         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
131         additionalPermissionDetails.put(KimConstants.AttributeConstants.ACTION_REQUEST_CD, actionRequestCode);
132 
133         return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
134                 KimConstants.PermissionTemplateNames.AD_HOC_REVIEW_DOCUMENT, user.getPrincipalId(),
135                 additionalPermissionDetails, null);
136     }
137 
138     public boolean canAddNoteAttachment(Document document, String attachmentTypeCode, Person user) {
139         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
140         if (attachmentTypeCode != null) {
141             additionalPermissionDetails.put(KimConstants.AttributeConstants.ATTACHMENT_TYPE_CODE, attachmentTypeCode);
142         }
143 
144         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
145                 KimConstants.PermissionTemplateNames.ADD_NOTE_ATTACHMENT, user.getPrincipalId(),
146                 additionalPermissionDetails, null);
147     }
148 
149     public boolean canDeleteNoteAttachment(Document document, String attachmentTypeCode,
150             String authorUniversalIdentifier, Person user) {
151         boolean canDeleteNoteAttachment = false;
152 
153         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
154         if (attachmentTypeCode != null) {
155             additionalPermissionDetails.put(KimConstants.AttributeConstants.ATTACHMENT_TYPE_CODE, attachmentTypeCode);
156         }
157 
158         // first check permissions that does not restrict on the author
159         additionalPermissionDetails.put(KimConstants.AttributeConstants.CREATED_BY_SELF, "false");
160         canDeleteNoteAttachment = isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
161                 KimConstants.PermissionTemplateNames.DELETE_NOTE_ATTACHMENT, user.getPrincipalId(),
162                 additionalPermissionDetails, null);
163 
164         if (!canDeleteNoteAttachment) {
165             // check for permissions restricted by author
166             additionalPermissionDetails.put(KimConstants.AttributeConstants.CREATED_BY_SELF, "true");
167             canDeleteNoteAttachment = isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
168                     KimConstants.PermissionTemplateNames.DELETE_NOTE_ATTACHMENT, user.getPrincipalId(),
169                     additionalPermissionDetails, null);
170 
171             // if permission has been granted user must be the author
172             if (canDeleteNoteAttachment && !authorUniversalIdentifier.equals(user.getPrincipalId())) {
173                 canDeleteNoteAttachment = false;
174             }
175         }
176 
177         return canDeleteNoteAttachment;
178     }
179 
180     public boolean canViewNoteAttachment(Document document, String attachmentTypeCode, String authorUniversalIdentifier,
181             Person user) {
182         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
183         if (attachmentTypeCode != null) {
184             additionalPermissionDetails.put(KimConstants.AttributeConstants.ATTACHMENT_TYPE_CODE, attachmentTypeCode);
185         }
186 
187         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
188                 KimConstants.PermissionTemplateNames.VIEW_NOTE_ATTACHMENT, user.getPrincipalId(),
189                 additionalPermissionDetails, null);
190     }
191 
192     public boolean canSendAdHocRequests(Document document, String actionRequestCd, Person user) {
193         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
194         if (actionRequestCd != null) {
195             additionalPermissionDetails.put(KimConstants.AttributeConstants.ACTION_REQUEST_CD, actionRequestCd);
196         }
197 
198         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
199                 KimConstants.PermissionTemplateNames.SEND_AD_HOC_REQUEST, user.getPrincipalId(),
200                 additionalPermissionDetails, null);
201     }
202 
203     public boolean canEditDocumentOverview(Document document, Person user) {
204         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
205                 KimConstants.PermissionTemplateNames.EDIT_DOCUMENT, user.getPrincipalId()) && this.isDocumentInitiator(
206                 document, user);
207     }
208 
209     public boolean canSendAnyTypeAdHocRequests(Document document, Person user) {
210         if (canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_FYI_REQ, user)) {
211             RoutePath routePath = KewApiServiceLocator.getDocumentTypeService().getRoutePathForDocumentTypeName(
212                     document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
213             ProcessDefinition processDefinition = routePath.getPrimaryProcess();
214             if (processDefinition != null) {
215                 if (processDefinition.getInitialRouteNode() == null) {
216                     return false;
217                 }
218             } else {
219                 return false;
220             }
221 
222             return true;
223         } else if (canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, user)) {
224             return true;
225         }
226 
227         return canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_APPROVE_REQ, user);
228     }
229 
230     public boolean canTakeRequestedAction(Document document, String actionRequestCode, Person user) {
231         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
232         additionalPermissionDetails.put(KimConstants.AttributeConstants.ACTION_REQUEST_CD, actionRequestCode);
233 
234         return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
235                 KimConstants.PermissionTemplateNames.TAKE_REQUESTED_ACTION, user.getPrincipalId(),
236                 additionalPermissionDetails, null);
237     }
238 
239     @Override
240     protected void addPermissionDetails(Object dataObject, Map<String, String> attributes) {
241         super.addPermissionDetails(dataObject, attributes);
242 
243         if (dataObject instanceof Document) {
244             addStandardAttributes((Document) dataObject, attributes);
245         }
246     }
247 
248     @Override
249     protected void addRoleQualification(Object dataObject, Map<String, String> attributes) {
250         super.addRoleQualification(dataObject, attributes);
251 
252         if (dataObject instanceof Document) {
253             addStandardAttributes((Document) dataObject, attributes);
254         }
255     }
256 
257     protected void addStandardAttributes(Document document, Map<String, String> attributes) {
258         WorkflowDocument wd = document.getDocumentHeader().getWorkflowDocument();
259         attributes.put(KimConstants.AttributeConstants.DOCUMENT_NUMBER, document.getDocumentNumber());
260         attributes.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, wd.getDocumentTypeName());
261 
262         if (wd.isInitiated() || wd.isSaved()) {
263             attributes.put(KimConstants.AttributeConstants.ROUTE_NODE_NAME, PRE_ROUTING_ROUTE_NAME);
264         } else {
265             attributes.put(KimConstants.AttributeConstants.ROUTE_NODE_NAME,
266                     KRADServiceLocatorWeb.getWorkflowDocumentService().getCurrentRouteNodeNames(wd));
267         }
268 
269         attributes.put(KimConstants.AttributeConstants.ROUTE_STATUS_CODE, wd.getStatus().getCode());
270     }
271 
272     protected boolean isDocumentInitiator(Document document, Person user) {
273         WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
274 
275         return workflowDocument.getInitiatorPrincipalId().equalsIgnoreCase(user.getPrincipalId());
276     }
277 }