View Javadoc

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