001    /**
002     * Copyright 2005-2012 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.apache.commons.logging.Log;
019    import org.apache.commons.logging.LogFactory;
020    import org.kuali.rice.kew.api.WorkflowDocument;
021    import org.kuali.rice.kim.api.KimConstants;
022    import org.kuali.rice.kim.api.identity.Person;
023    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
024    import org.kuali.rice.krad.uif.view.View;
025    import org.kuali.rice.krad.uif.view.ViewAuthorizerBase;
026    import org.kuali.rice.krad.uif.view.ViewModel;
027    import org.kuali.rice.krad.util.KRADConstants;
028    import org.kuali.rice.krad.util.ObjectUtils;
029    import org.kuali.rice.krad.web.form.DocumentFormBase;
030    
031    import java.util.Map;
032    import 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     */
048    public 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    }