View Javadoc

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