001 /**
002 * Copyright 2005-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.krad.document;
017
018 import org.kuali.rice.kew.api.KewApiConstants;
019 import org.kuali.rice.kew.api.KewApiServiceLocator;
020 import org.kuali.rice.kew.api.WorkflowDocument;
021 import org.kuali.rice.kew.api.action.ActionType;
022 import org.kuali.rice.kew.api.doctype.ProcessDefinition;
023 import org.kuali.rice.kew.api.doctype.RoutePath;
024 import org.kuali.rice.kim.api.KimConstants;
025 import org.kuali.rice.kim.api.identity.Person;
026 import org.kuali.rice.krad.bo.DataObjectAuthorizerBase;
027 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
028 import org.kuali.rice.krad.util.KRADConstants;
029
030 import java.util.Collections;
031 import java.util.HashMap;
032 import java.util.Map;
033
034 /**
035 * Default implementation for {@link DocumentAuthorizer} that perform KIM permission checks to authorize the actions
036 *
037 * @author Kuali Rice Team (rice.collab@kuali.org)
038 */
039 public class DocumentAuthorizerBase extends DataObjectAuthorizerBase implements DocumentAuthorizer {
040 private static final long serialVersionUID = -5354518767379472681L;
041
042 public static final String PRE_ROUTING_ROUTE_NAME = "PreRoute";
043
044 public final boolean canInitiate(String documentTypeName, Person user) {
045 String nameSpaceCode = KRADConstants.KUALI_RICE_SYSTEM_NAMESPACE;
046 Map<String, String> permissionDetails = new HashMap<String, String>();
047 permissionDetails.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, documentTypeName);
048
049 return getPermissionService().isAuthorizedByTemplate(user.getPrincipalId(), nameSpaceCode,
050 KimConstants.PermissionTemplateNames.INITIATE_DOCUMENT, permissionDetails,
051 Collections.<String, String>emptyMap());
052 }
053
054 public boolean canOpen(Document document, Person user) {
055 return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
056 KimConstants.PermissionTemplateNames.OPEN_DOCUMENT, user.getPrincipalId());
057 }
058
059 public boolean canEdit(Document document, Person user) {
060 return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
061 KimConstants.PermissionTemplateNames.EDIT_DOCUMENT, user.getPrincipalId());
062 }
063
064 public boolean canAnnotate(Document document, Person user) {
065 return canEdit(document, user);
066 }
067
068 public boolean canReload(Document document, Person user) {
069 return true;
070 }
071
072 public boolean canClose(Document document, Person user) {
073 return true;
074 }
075
076 public boolean canSave(Document document, Person user) {
077 return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
078 KimConstants.PermissionTemplateNames.SAVE_DOCUMENT, user.getPrincipalId());
079 }
080
081 public boolean canRoute(Document document, Person user) {
082 return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
083 KimConstants.PermissionTemplateNames.ROUTE_DOCUMENT, user.getPrincipalId());
084 }
085
086 public boolean canCancel(Document document, Person user) {
087 return isAuthorizedByTemplate(document, KRADConstants.KUALI_RICE_WORKFLOW_NAMESPACE,
088 KimConstants.PermissionTemplateNames.CANCEL_DOCUMENT, user.getPrincipalId());
089 }
090
091 public boolean canRecall(Document document, Person user) {
092 return KewApiServiceLocator.getWorkflowDocumentActionsService().determineValidActions(document.getDocumentNumber(), user.getPrincipalId()).getValidActions().contains(ActionType.RECALL);
093 }
094
095 public boolean canCopy(Document document, Person user) {
096 return isAuthorizedByTemplate(document, KRADConstants.KNS_NAMESPACE,
097 KimConstants.PermissionTemplateNames.COPY_DOCUMENT, user.getPrincipalId());
098 }
099
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 }