001    /**
002     * Copyright 2005-2012 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.krad.uif.view;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.rice.core.api.config.property.ConfigurationService;
020    import org.kuali.rice.kim.api.KimConstants;
021    import org.kuali.rice.kim.api.identity.Person;
022    import org.kuali.rice.krad.bo.DataObjectAuthorizerBase;
023    import org.kuali.rice.krad.datadictionary.AttributeSecurity;
024    import org.kuali.rice.krad.service.KRADServiceLocator;
025    import org.kuali.rice.krad.uif.component.Component;
026    import org.kuali.rice.krad.uif.component.ComponentSecurity;
027    import org.kuali.rice.krad.uif.component.DataBinding;
028    import org.kuali.rice.krad.uif.container.CollectionGroup;
029    import org.kuali.rice.krad.uif.container.Group;
030    import org.kuali.rice.krad.uif.field.ActionField;
031    import org.kuali.rice.krad.uif.field.DataField;
032    import org.kuali.rice.krad.uif.field.Field;
033    import org.kuali.rice.krad.uif.field.FieldSecurity;
034    import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
035    import org.kuali.rice.krad.uif.widget.Widget;
036    import org.kuali.rice.krad.util.KRADConstants;
037    import org.kuali.rice.krad.util.KRADUtils;
038    
039    import java.util.HashMap;
040    import java.util.HashSet;
041    import java.util.Map;
042    import java.util.Set;
043    
044    /**
045     * Implementation of {@link ViewAuthorizer} that verifies authorization with KIM permission checks
046     *
047     * <p>
048     * Each permission goes through one of the isAuthorized methods provided by
049     * {@link org.kuali.rice.krad.bo.DataObjectAuthorizer}, these in turn call {@link #addPermissionDetails(Object, java.util.Map)}
050     * and {@link #addRoleQualification(Object, java.util.Map)} for building the permission and role maps to send with
051     * the permission check. Subclasses can override these methods to add additional attributes
052     * </p>
053     *
054     * @author Kuali Rice Team (rice.collab@kuali.org)
055     */
056    public class ViewAuthorizerBase extends DataObjectAuthorizerBase implements ViewAuthorizer {
057        private static final long serialVersionUID = -2687378084630965412L;
058        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ViewAuthorizerBase.class);
059    
060        private ConfigurationService configurationService;
061    
062        /**
063         * @see ViewAuthorizer#getActionFlags(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
064         *      org.kuali.rice.kim.api.identity.Person, java.util.Set<java.lang.String>)
065         */
066        public Set<String> getActionFlags(View view, ViewModel model, Person user, Set<String> actions) {
067            if (actions.contains(KRADConstants.KUALI_ACTION_CAN_EDIT) && !canEditView(view, model, user)) {
068                actions.remove(KRADConstants.KUALI_ACTION_CAN_EDIT);
069            }
070    
071            return actions;
072        }
073    
074        /**
075         * @see ViewAuthorizer#getEditModes(org.kuali.rice.krad.uif.view.View, org.kuali.rice.krad.uif.view.ViewModel,
076         *      org.kuali.rice.kim.api.identity.Person, java.util.Set<java.lang.String>)
077         */
078        public Set<String> getEditModes(View view, ViewModel model, Person user, Set<String> editModes) {
079            Set<String> unauthorizedEditModes = new HashSet<String>();
080    
081            Object dataObjectForContext = getDataObjectContext(view, model);
082    
083            for (String editMode : editModes) {
084                Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
085                additionalPermissionDetails.put(KimConstants.AttributeConstants.EDIT_MODE, editMode);
086                if (permissionExistsByTemplate(dataObjectForContext, KRADConstants.KNS_NAMESPACE,
087                        KimConstants.PermissionTemplateNames.USE_TRANSACTIONAL_DOCUMENT, additionalPermissionDetails)
088                        && !isAuthorizedByTemplate(dataObjectForContext, KRADConstants.KNS_NAMESPACE,
089                        KimConstants.PermissionTemplateNames.USE_TRANSACTIONAL_DOCUMENT, user.getPrincipalId(),
090                        additionalPermissionDetails, null)) {
091                    unauthorizedEditModes.add(editMode);
092                }
093            }
094            editModes.removeAll(unauthorizedEditModes);
095    
096            return editModes;
097        }
098    
099        /**
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    }