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