001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.krad.document;
017
018import org.apache.commons.logging.Log;
019import org.apache.commons.logging.LogFactory;
020import org.kuali.rice.kew.api.WorkflowDocument;
021import org.kuali.rice.kim.api.KimConstants;
022import org.kuali.rice.kim.api.identity.Person;
023import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
024import org.kuali.rice.krad.uif.view.View;
025import org.kuali.rice.krad.uif.view.ViewAuthorizerBase;
026import org.kuali.rice.krad.uif.view.ViewModel;
027import org.kuali.rice.krad.util.KRADConstants;
028import org.kuali.rice.krad.util.ObjectUtils;
029import org.kuali.rice.krad.web.form.DocumentFormBase;
030
031import java.util.Map;
032import java.util.Set;
033
034/**
035 * Implementation of {@link org.kuali.rice.krad.uif.view.ViewAuthorizer} for
036 * {@link org.kuali.rice.krad.uif.view.DocumentView} instances
037 *
038 * <p>
039 * Performs KIM permission checks for the various document actions such as save, approve, cancel
040 * </p>
041 *
042 * <p>
043 * By default delegates to the {@link DocumentAuthorizer} configured for the document in the data dictionary
044 * </p>
045 *
046 * @author Kuali Rice Team (rice.collab@kuali.org)
047 */
048public class DocumentViewAuthorizerBase extends ViewAuthorizerBase implements DocumentAuthorizer {
049    private static final long serialVersionUID = 3800780934223224565L;
050
051    protected static Log LOG = LogFactory.getLog(DocumentViewAuthorizerBase.class);
052
053    public static final String PRE_ROUTING_ROUTE_NAME = "PreRoute";
054
055    private DocumentAuthorizer documentAuthorizer;
056
057    /**
058     * @see org.kuali.rice.krad.uif.view.ViewAuthorizer#getActionFlags(org.kuali.rice.krad.uif.view.View,
059     *      org.kuali.rice.krad.uif.view.ViewModel, org.kuali.rice.kim.api.identity.Person,
060     *      java.util.Set<java.lang.String>)
061     */
062    @Override
063    public Set<String> getActionFlags(View view, ViewModel model, Person user, Set<String> actions) {
064        Document document = ((DocumentFormBase) model).getDocument();
065
066        if (LOG.isDebugEnabled()) {
067            LOG.debug("calling DocumentAuthorizerBase.getDocumentActionFlags for document '"
068                    + document.getDocumentNumber()
069                    + "'. user '"
070                    + user.getPrincipalName()
071                    + "'");
072        }
073
074        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_EDIT) && !canEdit(document, user)) {
075            actions.remove(KRADConstants.KUALI_ACTION_CAN_EDIT);
076        }
077
078        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_COPY) && !canCopy(document, user)) {
079            actions.remove(KRADConstants.KUALI_ACTION_CAN_COPY);
080        }
081
082        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_CLOSE) && !canClose(document, user)) {
083            actions.remove(KRADConstants.KUALI_ACTION_CAN_CLOSE);
084        }
085
086        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_RELOAD) && !canReload(document, user)) {
087            actions.remove(KRADConstants.KUALI_ACTION_CAN_RELOAD);
088        }
089
090        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_BLANKET_APPROVE) && !canBlanketApprove(document, user)) {
091            actions.remove(KRADConstants.KUALI_ACTION_CAN_BLANKET_APPROVE);
092        }
093
094        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_CANCEL) && !canCancel(document, user)) {
095            actions.remove(KRADConstants.KUALI_ACTION_CAN_CANCEL);
096        }
097
098        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_RECALL) && !canRecall(document, user)) {
099            actions.remove(KRADConstants.KUALI_ACTION_CAN_RECALL);
100        }
101
102        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_SAVE) && !canSave(document, user)) {
103            actions.remove(KRADConstants.KUALI_ACTION_CAN_SAVE);
104        }
105
106        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_ROUTE) && !canRoute(document, user)) {
107            actions.remove(KRADConstants.KUALI_ACTION_CAN_ROUTE);
108        }
109
110        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_ACKNOWLEDGE) && !canAcknowledge(document, user)) {
111            actions.remove(KRADConstants.KUALI_ACTION_CAN_ACKNOWLEDGE);
112        }
113
114        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_FYI) && !canFyi(document, user)) {
115            actions.remove(KRADConstants.KUALI_ACTION_CAN_FYI);
116        }
117
118        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_APPROVE) && !canApprove(document, user)) {
119            actions.remove(KRADConstants.KUALI_ACTION_CAN_APPROVE);
120        }
121
122        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_DISAPPROVE) && !canDisapprove(document, user)) {
123            actions.remove(KRADConstants.KUALI_ACTION_CAN_DISAPPROVE);
124        }
125
126        if (!canSendAnyTypeAdHocRequests(document, user)) {
127            actions.remove(KRADConstants.KUALI_ACTION_CAN_ADD_ADHOC_REQUESTS);
128            actions.remove(KRADConstants.KUALI_ACTION_CAN_SEND_ADHOC_REQUESTS);
129            actions.remove(KRADConstants.KUALI_ACTION_CAN_SEND_NOTE_FYI);
130        }
131
132        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_SEND_NOTE_FYI) && !canSendNoteFyi(document, user)) {
133            actions.remove(KRADConstants.KUALI_ACTION_CAN_SEND_NOTE_FYI);
134        }
135
136        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_ANNOTATE) && !canAnnotate(document, user)) {
137            actions.remove(KRADConstants.KUALI_ACTION_CAN_ANNOTATE);
138        }
139
140        if (actions.contains(KRADConstants.KUALI_ACTION_CAN_EDIT_DOCUMENT_OVERVIEW) && !canEditDocumentOverview(
141                document, user)) {
142            actions.remove(KRADConstants.KUALI_ACTION_CAN_EDIT_DOCUMENT_OVERVIEW);
143        }
144
145        if (actions.contains(KRADConstants.KUALI_ACTION_PERFORM_ROUTE_REPORT) && !canPerformRouteReport(document,
146                user)) {
147            actions.remove(KRADConstants.KUALI_ACTION_PERFORM_ROUTE_REPORT);
148        }
149
150        return actions;
151    }
152
153    public final boolean canInitiate(String documentTypeName, Person user) {
154        return getDocumentAuthorizer().canInitiate(documentTypeName, user);
155    }
156
157    public final boolean canOpen(Document document, Person user) {
158        return getDocumentAuthorizer().canOpen(document, user);
159    }
160
161    @Override
162    public boolean canOpenView(View view, ViewModel model, Person user) {
163        DocumentFormBase documentForm = (DocumentFormBase) model;
164
165        return super.canOpenView(view, model, user) && canOpen(documentForm.getDocument(), user);
166    }
167
168    public boolean canEdit(Document document, Person user) {
169        return getDocumentAuthorizer().canEdit(document, user);
170    }
171
172    @Override
173    public boolean canEditView(View view, ViewModel model, Person user) {
174        DocumentFormBase documentForm = (DocumentFormBase) model;
175
176        return super.canEditView(view, model, user) && canEdit(documentForm.getDocument(), user);
177    }
178
179    public boolean canAnnotate(Document document, Person user) {
180        return getDocumentAuthorizer().canAnnotate(document, user);
181    }
182
183    public boolean canReload(Document document, Person user) {
184        return getDocumentAuthorizer().canReload(document, user);
185    }
186
187    public boolean canClose(Document document, Person user) {
188        return getDocumentAuthorizer().canClose(document, user);
189    }
190
191    public boolean canSave(Document document, Person user) {
192        return getDocumentAuthorizer().canSave(document, user);
193    }
194
195    public boolean canRoute(Document document, Person user) {
196        return getDocumentAuthorizer().canRoute(document, user);
197    }
198
199    public boolean canCancel(Document document, Person user) {
200        return getDocumentAuthorizer().canCancel(document, user);
201    }
202
203    public boolean canRecall(Document document, Person user) {
204        return getDocumentAuthorizer().canRecall(document, user);
205    }
206
207    public boolean canCopy(Document document, Person user) {
208        return getDocumentAuthorizer().canCopy(document, user);
209    }
210
211    public boolean canPerformRouteReport(Document document, Person user) {
212        return getDocumentAuthorizer().canPerformRouteReport(document, user);
213    }
214
215    public boolean canBlanketApprove(Document document, Person user) {
216        return getDocumentAuthorizer().canBlanketApprove(document, user);
217    }
218
219    public boolean canApprove(Document document, Person user) {
220        return getDocumentAuthorizer().canApprove(document, user);
221    }
222
223    public boolean canDisapprove(Document document, Person user) {
224        return getDocumentAuthorizer().canDisapprove(document, user);
225    }
226
227    public boolean canSendNoteFyi(Document document, Person user) {
228        return getDocumentAuthorizer().canSendNoteFyi(document, user);
229    }
230
231    public boolean canFyi(Document document, Person user) {
232        return getDocumentAuthorizer().canFyi(document, user);
233    }
234
235    public boolean canAcknowledge(Document document, Person user) {
236        return getDocumentAuthorizer().canAcknowledge(document, user);
237    }
238
239    public final boolean canReceiveAdHoc(Document document, Person user, String actionRequestCode) {
240        return getDocumentAuthorizer().canReceiveAdHoc(document, user, actionRequestCode);
241    }
242
243    public final boolean canAddNoteAttachment(Document document, String attachmentTypeCode, Person user) {
244        return getDocumentAuthorizer().canAddNoteAttachment(document, attachmentTypeCode, user);
245    }
246
247    public final boolean canDeleteNoteAttachment(Document document, String attachmentTypeCode,
248            String authorUniversalIdentifier, Person user) {
249        return getDocumentAuthorizer().canDeleteNoteAttachment(document, attachmentTypeCode, authorUniversalIdentifier,
250                user);
251    }
252
253    public final boolean canViewNoteAttachment(Document document, String attachmentTypeCode,
254            String authorUniversalIdentifier, Person user) {
255        return getDocumentAuthorizer().canViewNoteAttachment(document, attachmentTypeCode, authorUniversalIdentifier,
256                user);
257    }
258
259    public final boolean canSendAdHocRequests(Document document, String actionRequestCd, Person user) {
260        return getDocumentAuthorizer().canSendAdHocRequests(document, actionRequestCd, user);
261    }
262
263    public boolean canEditDocumentOverview(Document document, Person user) {
264        return getDocumentAuthorizer().canEditDocumentOverview(document, user);
265    }
266
267    public boolean canSendAnyTypeAdHocRequests(Document document, Person user) {
268        return getDocumentAuthorizer().canSendAnyTypeAdHocRequests(document, user);
269    }
270
271    public boolean canTakeRequestedAction(Document document, String actionRequestCode, Person user) {
272        return getDocumentAuthorizer().canTakeRequestedAction(document, actionRequestCode, user);
273    }
274
275    @Override
276    protected void addPermissionDetails(Object dataObject, Map<String, String> attributes) {
277        super.addPermissionDetails(dataObject, attributes);
278
279        if (dataObject instanceof Document) {
280            addStandardAttributes((Document) dataObject, attributes);
281        }
282    }
283
284    @Override
285    protected void addRoleQualification(Object dataObject, Map<String, String> attributes) {
286        super.addRoleQualification(dataObject, attributes);
287
288        if (dataObject instanceof Document) {
289            addStandardAttributes((Document) dataObject, attributes);
290        }
291    }
292
293    protected void addStandardAttributes(Document document, Map<String, String> attributes) {
294        WorkflowDocument wd = document.getDocumentHeader().getWorkflowDocument();
295        attributes.put(KimConstants.AttributeConstants.DOCUMENT_NUMBER, document.getDocumentNumber());
296        attributes.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, wd.getDocumentTypeName());
297
298        if (wd.isInitiated() || wd.isSaved()) {
299            attributes.put(KimConstants.AttributeConstants.ROUTE_NODE_NAME, PRE_ROUTING_ROUTE_NAME);
300        } else {
301            attributes.put(KimConstants.AttributeConstants.ROUTE_NODE_NAME,
302                    KRADServiceLocatorWeb.getWorkflowDocumentService().getCurrentRouteNodeNames(wd));
303        }
304
305        attributes.put(KimConstants.AttributeConstants.ROUTE_STATUS_CODE, wd.getStatus().getCode());
306    }
307
308    protected boolean isDocumentInitiator(Document document, Person user) {
309        WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
310
311        return workflowDocument.getInitiatorPrincipalId().equalsIgnoreCase(user.getPrincipalId());
312    }
313
314    public DocumentAuthorizer getDocumentAuthorizer() {
315        return documentAuthorizer;
316    }
317
318    public void setDocumentAuthorizer(DocumentAuthorizer documentAuthorizer) {
319        this.documentAuthorizer = documentAuthorizer;
320    }
321
322    public void setDocumentAuthorizerClass(Class<? extends DocumentAuthorizer> documentAuthorizerClass) {
323        this.documentAuthorizer = ObjectUtils.newInstance(documentAuthorizerClass);
324    }
325}