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.uif.view;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.config.property.ConfigurationService;
20  import org.kuali.rice.kim.api.KimConstants;
21  import org.kuali.rice.kim.api.identity.Person;
22  import org.kuali.rice.krad.bo.DataObjectAuthorizerBase;
23  import org.kuali.rice.krad.datadictionary.AttributeSecurity;
24  import org.kuali.rice.krad.service.KRADServiceLocator;
25  import org.kuali.rice.krad.uif.component.Component;
26  import org.kuali.rice.krad.uif.component.ComponentSecurity;
27  import org.kuali.rice.krad.uif.component.DataBinding;
28  import org.kuali.rice.krad.uif.container.CollectionGroup;
29  import org.kuali.rice.krad.uif.container.Group;
30  import org.kuali.rice.krad.uif.field.ActionField;
31  import org.kuali.rice.krad.uif.field.DataField;
32  import org.kuali.rice.krad.uif.field.Field;
33  import org.kuali.rice.krad.uif.field.FieldSecurity;
34  import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
35  import org.kuali.rice.krad.uif.widget.Widget;
36  import org.kuali.rice.krad.util.KRADConstants;
37  import org.kuali.rice.krad.util.KRADUtils;
38  
39  import java.util.HashMap;
40  import java.util.HashSet;
41  import java.util.Map;
42  import java.util.Set;
43  
44  /**
45   * Implementation of {@link ViewAuthorizer} that verifies authorization with KIM permission checks
46   *
47   * <p>
48   * Each permission goes through one of the isAuthorized methods provided by
49   * {@link org.kuali.rice.krad.bo.DataObjectAuthorizer}, these in turn call {@link #addPermissionDetails(Object, java.util.Map)}
50   * and {@link #addRoleQualification(Object, java.util.Map)} for building the permission and role maps to send with
51   * the permission check. Subclasses can override these methods to add additional attributes
52   * </p>
53   *
54   * @author Kuali Rice Team (rice.collab@kuali.org)
55   */
56  public class ViewAuthorizerBase extends DataObjectAuthorizerBase implements ViewAuthorizer {
57      private static final long serialVersionUID = -2687378084630965412L;
58      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ViewAuthorizerBase.class);
59  
60      private ConfigurationService configurationService;
61  
62      /**
63       * @see ViewAuthorizer#getActionFlags(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
64       *      org.kuali.rice.kim.api.identity.Person, java.util.Set<java.lang.String>)
65       */
66      public Set<String> getActionFlags(View view, ViewModel model, Person user, Set<String> actions) {
67          if (actions.contains(KRADConstants.KUALI_ACTION_CAN_EDIT) && !canEditView(view, model, user)) {
68              actions.remove(KRADConstants.KUALI_ACTION_CAN_EDIT);
69          }
70  
71          return actions;
72      }
73  
74      /**
75       * @see ViewAuthorizer#getEditModes(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
76       *      org.kuali.rice.kim.api.identity.Person, java.util.Set<java.lang.String>)
77       */
78      public Set<String> getEditModes(View view, ViewModel model, Person user, Set<String> editModes) {
79          Set<String> unauthorizedEditModes = new HashSet<String>();
80  
81          Object dataObjectForContext = getDataObjectContext(view, model);
82  
83          for (String editMode : editModes) {
84              Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
85              additionalPermissionDetails.put(KimConstants.AttributeConstants.EDIT_MODE, editMode);
86              if (permissionExistsByTemplate(dataObjectForContext, KRADConstants.KNS_NAMESPACE,
87                      KimConstants.PermissionTemplateNames.USE_TRANSACTIONAL_DOCUMENT, additionalPermissionDetails)
88                      && !isAuthorizedByTemplate(dataObjectForContext, KRADConstants.KNS_NAMESPACE,
89                      KimConstants.PermissionTemplateNames.USE_TRANSACTIONAL_DOCUMENT, user.getPrincipalId(),
90                      additionalPermissionDetails, null)) {
91                  unauthorizedEditModes.add(editMode);
92              }
93          }
94          editModes.removeAll(unauthorizedEditModes);
95  
96          return editModes;
97      }
98  
99      /**
100      * Checks for an open view permission for the view id, and if found verifies the user has that permission
101      *
102      * @see ViewAuthorizer#canOpenView(View, ViewModel, org.kuali.rice.kim.api.identity.Person)
103      */
104     public boolean canOpenView(View view, ViewModel model, Person user) {
105         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
106         additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, view.getViewNamespaceCode());
107         additionalPermissionDetails.put(KimConstants.AttributeConstants.VIEW_ID, model.getViewId());
108 
109         if (permissionExistsByTemplate(model, KRADConstants.KRAD_NAMESPACE,
110                 KimConstants.PermissionTemplateNames.OPEN_VIEW, additionalPermissionDetails)) {
111             return isAuthorizedByTemplate(model, KRADConstants.KRAD_NAMESPACE,
112                     KimConstants.PermissionTemplateNames.OPEN_VIEW, user.getPrincipalId(), additionalPermissionDetails,
113                     null);
114         }
115 
116         return true;
117     }
118 
119     /**
120      * Checks for an edit view permission for the view id, and if found verifies the user has that permission
121      *
122      * @see ViewAuthorizer#canEditView(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
123      *      org.kuali.rice.kim.api.identity.Person)
124      */
125     public boolean canEditView(View view, ViewModel model, Person user) {
126         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
127         additionalPermissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, view.getViewNamespaceCode());
128         additionalPermissionDetails.put(KimConstants.AttributeConstants.VIEW_ID, model.getViewId());
129 
130         if (permissionExistsByTemplate(model, KRADConstants.KRAD_NAMESPACE,
131                 KimConstants.PermissionTemplateNames.EDIT_VIEW, additionalPermissionDetails)) {
132             return isAuthorizedByTemplate(model, KRADConstants.KRAD_NAMESPACE,
133                     KimConstants.PermissionTemplateNames.EDIT_VIEW, user.getPrincipalId(), additionalPermissionDetails,
134                     null);
135         }
136 
137         return true;
138     }
139 
140     /**
141      * @see ViewAuthorizer#canUnmaskField(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
142      * org.kuali.rice.krad.uif.field.DataField, java.lang.String, org.kuali.rice.kim.api.identity.Person)
143      */
144     public boolean canUnmaskField(View view, ViewModel model, DataField field, String propertyName, Person user) {
145         // check mask authz flag is set
146         AttributeSecurity attributeSecurity = field.getComponentSecurity().getAttributeSecurity();
147         if (attributeSecurity == null || !attributeSecurity.isMask()) {
148             return true;
149         }
150 
151         // for non-production environments the ability to unmask can be disabled by a system parameter
152         if (isNonProductionEnvAndUnmaskingTurnedOff()) {
153             return false;
154         }
155 
156         Object dataObjectForContext = getDataObjectContext(view, model);
157 
158         Map<String, String> permissionDetails = new HashMap<String, String>();
159         permissionDetails = KRADUtils.getNamespaceAndComponentSimpleName(dataObjectForContext.getClass());
160         permissionDetails.put(KimConstants.AttributeConstants.PROPERTY_NAME, propertyName);
161         // TODO: check for namespace, component, attribute override on attribute security
162 
163         if (field.getComponentSecurity().getAdditionalPermissionDetails() != null) {
164             permissionDetails.putAll(field.getComponentSecurity().getAdditionalPermissionDetails());
165         }
166 
167         Map<String, String> roleQualifications = new HashMap<String, String>();
168         if (field.getComponentSecurity().getAdditionalRoleQualifiers() != null) {
169             roleQualifications.putAll(field.getComponentSecurity().getAdditionalRoleQualifiers());
170         }
171 
172         return isAuthorizedByTemplate(dataObjectForContext, KRADConstants.KNS_NAMESPACE,
173                 KimConstants.PermissionTemplateNames.FULL_UNMASK_FIELD, user.getPrincipalId(), permissionDetails,
174                 roleQualifications);
175     }
176 
177     /**
178      * @see ViewAuthorizer#canPartialUnmaskField(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
179      * org.kuali.rice.krad.uif.field.DataField, java.lang.String, org.kuali.rice.kim.api.identity.Person)
180      */
181     public boolean canPartialUnmaskField(View view, ViewModel model, DataField field, String propertyName,
182             Person user) {
183         // check partial mask authz flag is set
184         AttributeSecurity attributeSecurity = field.getComponentSecurity().getAttributeSecurity();
185         if (attributeSecurity == null || !attributeSecurity.isPartialMask()) {
186             return true;
187         }
188 
189         // for non-production environments the ability to unmask can be disabled by a system parameter
190         if (isNonProductionEnvAndUnmaskingTurnedOff()) {
191             return false;
192         }
193 
194         Object dataObjectForContext = getDataObjectContext(view, model);
195 
196         Map<String, String> permissionDetails = new HashMap<String, String>();
197         permissionDetails = KRADUtils.getNamespaceAndComponentSimpleName(dataObjectForContext.getClass());
198         permissionDetails.put(KimConstants.AttributeConstants.PROPERTY_NAME, propertyName);
199         // TODO: check for namespace, component, attribute override on attribute security
200 
201         if (field.getComponentSecurity().getAdditionalPermissionDetails() != null) {
202             permissionDetails.putAll(field.getComponentSecurity().getAdditionalPermissionDetails());
203         }
204 
205         Map<String, String> roleQualifications = new HashMap<String, String>();
206         if (field.getComponentSecurity().getAdditionalRoleQualifiers() != null) {
207             roleQualifications.putAll(field.getComponentSecurity().getAdditionalRoleQualifiers());
208         }
209 
210         return isAuthorizedByTemplate(dataObjectForContext, KRADConstants.KNS_NAMESPACE,
211                 KimConstants.PermissionTemplateNames.PARTIAL_UNMASK_FIELD, user.getPrincipalId(), permissionDetails,
212                 roleQualifications);
213     }
214 
215     /**
216      * @see ViewAuthorizer#canEditField(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
217      * org.kuali.rice.krad.uif.field.Field, java.lang.String, org.kuali.rice.kim.api.identity.Person)
218      */
219     public boolean canEditField(View view, ViewModel model, Field field, String propertyName, Person user) {
220         // check edit authz flag is set
221         if (!field.getComponentSecurity().isEditAuthz()) {
222             return true;
223         }
224 
225         return isAuthorizedByTemplate(view, field, model, KimConstants.PermissionTemplateNames.EDIT_FIELD, user, null,
226                 null, false);
227     }
228 
229     /**
230      * @see ViewAuthorizer#canViewField(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
231      * org.kuali.rice.krad.uif.field.Field, java.lang.String, org.kuali.rice.kim.api.identity.Person)
232      */
233     public boolean canViewField(View view, ViewModel model, Field field, String propertyName, Person user) {
234         // check view authz flag is set
235         if (!field.getComponentSecurity().isViewAuthz()) {
236             return true;
237         }
238 
239         return isAuthorizedByTemplate(view, field, model, KimConstants.PermissionTemplateNames.VIEW_FIELD, user, null,
240                 null, false);
241     }
242 
243     /**
244      * @see ViewAuthorizer#canEditGroup(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
245      * org.kuali.rice.krad.uif.container.Group, java.lang.String, org.kuali.rice.kim.api.identity.Person)
246      */
247     public boolean canEditGroup(View view, ViewModel model, Group group, String groupId, Person user) {
248         // check edit group authz flag is set
249         if (!group.getComponentSecurity().isEditAuthz()) {
250             return true;
251         }
252 
253         return isAuthorizedByTemplate(view, group, model, KimConstants.PermissionTemplateNames.EDIT_GROUP, user, null,
254                 null, false);
255     }
256 
257     /**
258      * @see ViewAuthorizer#canViewGroup(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
259      * org.kuali.rice.krad.uif.container.Group, java.lang.String, org.kuali.rice.kim.api.identity.Person)
260      */
261     public boolean canViewGroup(View view, ViewModel model, Group group, String groupId, Person user) {
262         // check view group authz flag is set
263         if (!group.getComponentSecurity().isViewAuthz()) {
264             return true;
265         }
266 
267         return isAuthorizedByTemplate(view, group, model, KimConstants.PermissionTemplateNames.VIEW_GROUP, user, null,
268                 null, false);
269     }
270 
271     /**
272      * @see ViewAuthorizer#canEditWidget(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
273      * org.kuali.rice.krad.uif.widget.Widget, java.lang.String, org.kuali.rice.kim.api.identity.Person)
274      */
275     public boolean canEditWidget(View view, ViewModel model, Widget widget, String widgetId, Person user) {
276         // check edit widget authz flag is set
277         if (!widget.getComponentSecurity().isViewAuthz()) {
278             return true;
279         }
280 
281         return isAuthorizedByTemplate(view, widget, model, KimConstants.PermissionTemplateNames.EDIT_WIDGET, user, null,
282                 null, false);
283     }
284 
285     /**
286      * @see ViewAuthorizer#canViewWidget(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
287      * org.kuali.rice.krad.uif.widget.Widget, java.lang.String, org.kuali.rice.kim.api.identity.Person)
288      */
289     public boolean canViewWidget(View view, ViewModel model, Widget widget, String widgetId, Person user) {
290         // check view widget authz flag is set
291         if (!widget.getComponentSecurity().isViewAuthz()) {
292             return true;
293         }
294 
295         return isAuthorizedByTemplate(view, widget, model, KimConstants.PermissionTemplateNames.VIEW_WIDGET, user, null,
296                 null, false);
297     }
298 
299     /**
300      * @see ViewAuthorizer#canPerformAction(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
301      * org.kuali.rice.krad.uif.field.ActionField, java.lang.String, java.lang.String, org.kuali.rice.kim.api.identity.Person)
302      */
303     public boolean canPerformAction(View view, ViewModel model, ActionField actionField, String actionEvent,
304             String actionId, Person user) {
305         // check action authz flag is set
306         if (!actionField.getComponentSecurity().isPerformActionAuthz()) {
307             return true;
308         }
309 
310         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
311         if (StringUtils.isNotBlank(actionEvent)) {
312             additionalPermissionDetails.put(KimConstants.AttributeConstants.ACTION_EVENT, actionEvent);
313         }
314 
315         return isAuthorizedByTemplate(view, actionField, model, KimConstants.PermissionTemplateNames.PERFORM_ACTION,
316                 user, additionalPermissionDetails, null, false);
317     }
318 
319     public boolean canEditLine(View view, ViewModel model, CollectionGroup collectionGroup,
320             String collectionPropertyName, Object line, Person user) {
321         // check edit line authz flag is set
322         if (!collectionGroup.getComponentSecurity().isEditLineAuthz()) {
323             return true;
324         }
325 
326         return isAuthorizedByTemplate(view, collectionGroup, model, KimConstants.PermissionTemplateNames.EDIT_LINE,
327                 user, null, null, false);
328     }
329 
330     public boolean canViewLine(View view, ViewModel model, CollectionGroup collectionGroup,
331             String collectionPropertyName, Object line, Person user) {
332         // check view line authz flag is set
333         if (!collectionGroup.getComponentSecurity().isViewLineAuthz()) {
334             return true;
335         }
336 
337         return isAuthorizedByTemplate(view, collectionGroup, model, KimConstants.PermissionTemplateNames.VIEW_LINE,
338                 user, null, null, false);
339     }
340 
341     public boolean canEditLineField(View view, ViewModel model, CollectionGroup collectionGroup,
342             String collectionPropertyName, Object line, Field field, String propertyName, Person user) {
343         // check edit line field authz flag is set
344         if (!((FieldSecurity) field.getComponentSecurity()).isEditInLineAuthz()) {
345             return true;
346         }
347 
348         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
349         additionalPermissionDetails.put(KimConstants.AttributeConstants.GROUP_ID, collectionGroup.getId());
350         additionalPermissionDetails.put(KimConstants.AttributeConstants.COLLECTION_PROPERTY_NAME,
351                 collectionGroup.getPropertyName());
352 
353         return isAuthorizedByTemplate(view, field, model,
354                 KimConstants.PermissionTemplateNames.EDIT_LINE_FIELD, user, additionalPermissionDetails, null, false);
355     }
356 
357     public boolean canViewLineField(View view, ViewModel model, CollectionGroup collectionGroup,
358             String collectionPropertyName, Object line, Field field, String propertyName, Person user) {
359         // check view line field authz flag is set
360         if (!((FieldSecurity) field.getComponentSecurity()).isViewInLineAuthz()) {
361             return true;
362         }
363 
364         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
365         additionalPermissionDetails.put(KimConstants.AttributeConstants.GROUP_ID, collectionGroup.getId());
366         additionalPermissionDetails.put(KimConstants.AttributeConstants.COLLECTION_PROPERTY_NAME,
367                 collectionGroup.getPropertyName());
368 
369         return isAuthorizedByTemplate(view, field, model,
370                 KimConstants.PermissionTemplateNames.VIEW_LINE_FIELD, user, additionalPermissionDetails, null, false);
371     }
372 
373     public boolean canPerformLineAction(View view, ViewModel model, CollectionGroup collectionGroup,
374             String collectionPropertyName, Object line, ActionField actionField, String actionEvent, String actionId,
375             Person user) {
376         // check perform line action authz flag is set
377         if (!actionField.getComponentSecurity().isPerformLineActionAuthz()) {
378             return true;
379         }
380 
381         Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
382         additionalPermissionDetails.put(KimConstants.AttributeConstants.GROUP_ID, collectionGroup.getId());
383         additionalPermissionDetails.put(KimConstants.AttributeConstants.COLLECTION_PROPERTY_NAME,
384                 collectionGroup.getPropertyName());
385         if (StringUtils.isNotBlank(actionEvent)) {
386             additionalPermissionDetails.put(KimConstants.AttributeConstants.ACTION_EVENT, actionEvent);
387         }
388 
389         return isAuthorizedByTemplate(view, actionField, model,
390                 KimConstants.PermissionTemplateNames.PERFORM_LINE_ACTION, user, additionalPermissionDetails, null,
391                 false);
392     }
393 
394     /**
395      * Retrieves the object from the model that is used as the context for permission checks
396      *
397      * <p>
398      * Used to derive namespace and component details. Subclasses can override to return the object to be used
399      * </p>
400      *
401      * @param view - view instance the permission checks are being done for
402      * @param model - model object containing the data and from which the data object should be pulled
403      * @return Object data object instance to use
404      */
405     protected Object getDataObjectContext(View view, ViewModel model) {
406         Object dataObject = model;
407 
408         if (StringUtils.isNotBlank(view.getDefaultBindingObjectPath())) {
409             Object defaultObject = ObjectPropertyUtils.getPropertyValue(model, view.getDefaultBindingObjectPath());
410             if (defaultObject != null) {
411                 dataObject = defaultObject;
412             }
413         }
414 
415         return dataObject;
416     }
417 
418     /**
419      * Builds the permission details map for a field which includes the component namespace, component name, and
420      * field id, in addition to property name for data binding fields
421      *
422      * @param view - view instance the field belongs to
423      * @param dataObject - default object from the data model (used for subclasses to build details)
424      * @param field - field instance the details are being built for
425      * @return Map<String, String> permission details for the field
426      */
427     protected Map<String, String> getFieldPermissionDetails(View view, Object dataObject, Field field) {
428         Map<String, String> permissionDetails = new HashMap<String, String>();
429 
430         permissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, view.getViewNamespaceCode());
431         permissionDetails.put(KimConstants.AttributeConstants.VIEW_ID, view.getId());
432         permissionDetails.put(KimConstants.AttributeConstants.FIELD_ID, field.getId());
433 
434         if (field instanceof DataBinding) {
435             permissionDetails.put(KimConstants.AttributeConstants.PROPERTY_NAME,
436                     ((DataBinding) field).getPropertyName());
437         }
438 
439         return permissionDetails;
440     }
441 
442     /**
443      * Builds the permission details map for a group which includes the component namespace, component name, and
444      * group id, in addition to property name for collection groups
445      *
446      * @param view - view instance the group belongs to
447      * @param dataObject - default object from the data model (used for subclasses to build details)
448      * @param group - group instance the details are being built for
449      * @return Map<String, String> permission details for the group
450      */
451     protected Map<String, String> getGroupPermissionDetails(View view, Object dataObject, Group group) {
452         Map<String, String> permissionDetails = new HashMap<String, String>();
453 
454         permissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, view.getViewNamespaceCode());
455         permissionDetails.put(KimConstants.AttributeConstants.VIEW_ID, view.getId());
456         permissionDetails.put(KimConstants.AttributeConstants.GROUP_ID, group.getId());
457 
458         if (group instanceof CollectionGroup) {
459             permissionDetails.put(KimConstants.AttributeConstants.COLLECTION_PROPERTY_NAME,
460                     ((CollectionGroup) group).getPropertyName());
461         }
462 
463         return permissionDetails;
464     }
465 
466     /**
467      * Builds the permission details map for a widget which includes the namespace, view id, and
468      * widget id
469      *
470      * @param view - view instance the widget belongs to
471      * @param dataObject - default object from the data model (used for subclasses to build details)
472      * @param widget - group instance the details are being built for
473      * @return Map<String, String> permission details for group
474      */
475     protected Map<String, String> getWidgetPermissionDetails(View view, Object dataObject, Widget widget) {
476         Map<String, String> permissionDetails = new HashMap<String, String>();
477 
478         permissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE, view.getViewNamespaceCode());
479         permissionDetails.put(KimConstants.AttributeConstants.VIEW_ID, view.getId());
480         permissionDetails.put(KimConstants.AttributeConstants.WIDGET_ID, widget.getId());
481 
482         return permissionDetails;
483     }
484 
485     /**
486      * Performs a permission check for the given template name in the context of the given view and component
487      *
488      * <p>
489      * First standard permission details are added based on the type of component the permission check is being
490      * done for.
491      * Then the {@link ComponentSecurity} of the given component is used to pick up additional permission details and
492      * role qualifiers.
493      * </p>
494      *
495      * @param view - view instance the component belongs to
496      * @param component - component instance the permission check is being done for
497      * @param model - object containing the views data
498      * @param permissionTemplateName - template name for the permission to check
499      * @param user - user to perform the authorization for
500      * @param additionalPermissionDetails - additional key/value pairs to pass with the permission details
501      * @param additionalRoleQualifications - additional key/value paris to pass with the role qualifiers
502      * @param checkPermissionExistence - boolean indicating whether the existence of the permission should be checked
503      * before performing the authorization
504      * @return boolean indicating whether the user has authorization, this will be the case if the user has been
505      * granted the permission or checkPermissionExistence is true and the permission does not exist
506      */
507     protected boolean isAuthorizedByTemplate(View view, Component component, ViewModel model,
508             String permissionTemplateName, Person user, Map<String, String> additionalPermissionDetails,
509             Map<String, String> additionalRoleQualifications, boolean checkPermissionExistence) {
510         Map<String, String> permissionDetails = new HashMap<String, String>();
511         Map<String, String> roleQualifications = new HashMap<String, String>();
512 
513         if (additionalPermissionDetails != null) {
514             permissionDetails.putAll(additionalPermissionDetails);
515         }
516 
517         if (additionalRoleQualifications != null) {
518             roleQualifications.putAll(additionalRoleQualifications);
519         }
520 
521         Object dataObjectForContext = getDataObjectContext(view, model);
522 
523         // add permission details depending on the type of component
524         if (component instanceof Field) {
525             permissionDetails.putAll(getFieldPermissionDetails(view, dataObjectForContext, (Field) component));
526         } else if (component instanceof Group) {
527             permissionDetails.putAll(getGroupPermissionDetails(view, dataObjectForContext, (Group) component));
528         } else if (component instanceof Widget) {
529             permissionDetails.putAll(getWidgetPermissionDetails(view, dataObjectForContext, (Widget) component));
530         }
531 
532         // pick up additional attributes and overrides from component security
533         ComponentSecurity componentSecurity = component.getComponentSecurity();
534 
535         // add configured overrides
536         if (StringUtils.isNotBlank(componentSecurity.getNamespaceAttribute())) {
537             permissionDetails.put(KimConstants.AttributeConstants.NAMESPACE_CODE,
538                     componentSecurity.getNamespaceAttribute());
539         }
540         if (StringUtils.isNotBlank(componentSecurity.getComponentAttribute())) {
541             permissionDetails.put(KimConstants.AttributeConstants.COMPONENT_NAME,
542                     componentSecurity.getComponentAttribute());
543         }
544         if (StringUtils.isNotBlank(componentSecurity.getIdAttribute())) {
545             if (component instanceof Field) {
546                 permissionDetails.put(KimConstants.AttributeConstants.FIELD_ID, componentSecurity.getIdAttribute());
547             } else if (component instanceof Group) {
548                 permissionDetails.put(KimConstants.AttributeConstants.GROUP_ID, componentSecurity.getIdAttribute());
549             } else if (component instanceof Widget) {
550                 permissionDetails.put(KimConstants.AttributeConstants.WIDGET_ID, componentSecurity.getIdAttribute());
551             }
552         }
553 
554         if (componentSecurity.getAdditionalPermissionDetails() != null) {
555             permissionDetails.putAll(componentSecurity.getAdditionalPermissionDetails());
556         }
557 
558         if (componentSecurity.getAdditionalRoleQualifiers() != null) {
559             roleQualifications.putAll(componentSecurity.getAdditionalRoleQualifiers());
560         }
561 
562         boolean result = true;
563         if (!checkPermissionExistence || (checkPermissionExistence && permissionExistsByTemplate(dataObjectForContext,
564                 KRADConstants.KRAD_NAMESPACE, permissionTemplateName, permissionDetails))) {
565             result = isAuthorizedByTemplate(dataObjectForContext, KRADConstants.KRAD_NAMESPACE, permissionTemplateName,
566                     user.getPrincipalId(), permissionDetails, roleQualifications);
567 
568             if (LOG.isDebugEnabled()) {
569                 LOG.debug("Performed permission check for: " + permissionTemplateName + " and got result: " + result);
570             }
571         }
572 
573         return result;
574     }
575 
576     /**
577      * Indicates whether the environment is non production and unmasking is not enabled by system parameter
578      *
579      * @return boolean true if unmasking is turned off, false if unmasking is allowed
580      */
581     private boolean isNonProductionEnvAndUnmaskingTurnedOff() {
582         return !getConfigurationService().getPropertyValueAsString(KRADConstants.PROD_ENVIRONMENT_CODE_KEY).
583                 equalsIgnoreCase(getConfigurationService().getPropertyValueAsString(KRADConstants.ENVIRONMENT_KEY))
584                 && !getConfigurationService().getPropertyValueAsBoolean(KRADConstants.ENABLE_NONPRODUCTION_UNMASKING);
585     }
586 
587     protected ConfigurationService getConfigurationService() {
588         if (configurationService == null) {
589             return KRADServiceLocator.getKualiConfigurationService();
590         }
591         return configurationService;
592     }
593 
594     public void setConfigurationService(ConfigurationService configurationService) {
595         this.configurationService = configurationService;
596     }
597 
598 }