001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.kns.service.impl;
017
018import java.util.Collection;
019import java.util.Collections;
020import java.util.HashMap;
021import java.util.Iterator;
022import java.util.List;
023import java.util.Map;
024
025import org.apache.commons.beanutils.PropertyUtils;
026import org.apache.commons.collections.CollectionUtils;
027import org.apache.commons.lang.StringUtils;
028import org.kuali.rice.core.api.CoreApiServiceLocator;
029import org.kuali.rice.core.api.config.property.ConfigurationService;
030import org.kuali.rice.kim.api.KimConstants;
031import org.kuali.rice.kim.api.identity.Person;
032import org.kuali.rice.kim.api.permission.PermissionService;
033import org.kuali.rice.kim.api.services.KimApiServiceLocator;
034import org.kuali.rice.kns.authorization.BusinessObjectAuthorizer;
035import org.kuali.rice.kns.bo.authorization.InquiryOrMaintenanceDocumentAuthorizer;
036import org.kuali.rice.kns.bo.authorization.InquiryOrMaintenanceDocumentPresentationController;
037import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
038import org.kuali.rice.kns.datadictionary.FieldDefinition;
039import org.kuali.rice.kns.datadictionary.InquiryCollectionDefinition;
040import org.kuali.rice.kns.datadictionary.InquirySectionDefinition;
041import org.kuali.rice.kns.datadictionary.MaintainableCollectionDefinition;
042import org.kuali.rice.kns.datadictionary.MaintainableItemDefinition;
043import org.kuali.rice.kns.datadictionary.MaintainableSectionDefinition;
044import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry;
045import org.kuali.rice.kns.document.MaintenanceDocument;
046import org.kuali.rice.kns.document.authorization.BusinessObjectRestrictions;
047import org.kuali.rice.kns.document.authorization.BusinessObjectRestrictionsBase;
048import org.kuali.rice.kns.document.authorization.InquiryOrMaintenanceDocumentRestrictions;
049import org.kuali.rice.kns.document.authorization.InquiryOrMaintenanceDocumentRestrictionsBase;
050import org.kuali.rice.kns.document.authorization.MaintenanceDocumentAuthorizer;
051import org.kuali.rice.kns.document.authorization.MaintenanceDocumentPresentationController;
052import org.kuali.rice.kns.document.authorization.MaintenanceDocumentRestrictions;
053import org.kuali.rice.kns.document.authorization.MaintenanceDocumentRestrictionsBase;
054import org.kuali.rice.kns.inquiry.InquiryAuthorizer;
055import org.kuali.rice.kns.inquiry.InquiryPresentationController;
056import org.kuali.rice.kns.inquiry.InquiryRestrictions;
057import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
058import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
059import org.kuali.rice.kns.service.DocumentHelperService;
060import org.kuali.rice.kns.service.KNSServiceLocator;
061import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
062import org.kuali.rice.krad.bo.BusinessObject;
063import org.kuali.rice.krad.datadictionary.AttributeDefinition;
064import org.kuali.rice.krad.datadictionary.DataObjectEntry;
065import org.kuali.rice.krad.document.Document;
066import org.kuali.rice.krad.service.DataDictionaryService;
067import org.kuali.rice.krad.service.impl.DataObjectAuthorizationServiceImpl;
068import org.kuali.rice.krad.util.KRADConstants;
069import org.kuali.rice.krad.util.KRADUtils;
070import org.kuali.rice.krad.util.LegacyDataFramework;
071import org.kuali.rice.krad.util.ObjectUtils;
072
073/**
074 * @deprecated Use {@link DataObjectAuthorizationServiceImpl}.
075 */
076@Deprecated
077@LegacyDataFramework
078public class BusinessObjectAuthorizationServiceImpl extends DataObjectAuthorizationServiceImpl implements BusinessObjectAuthorizationService {
079        private DataDictionaryService dataDictionaryService;
080        private PermissionService permissionService;
081        private BusinessObjectDictionaryService businessObjectDictionaryService;
082        private DocumentHelperService documentHelperService;
083        private MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService;
084        private ConfigurationService kualiConfigurationService;
085
086        @Override
087    public BusinessObjectRestrictions getLookupResultRestrictions(
088                        Object dataObject, Person user) {
089                BusinessObjectRestrictions businessObjectRestrictions = new BusinessObjectRestrictionsBase();
090                considerBusinessObjectFieldUnmaskAuthorization(dataObject, user,
091                                businessObjectRestrictions, "", null);
092                return businessObjectRestrictions;
093        }
094
095        @Override
096    public InquiryRestrictions getInquiryRestrictions(
097                        BusinessObject businessObject, Person user) {
098                InquiryRestrictions inquiryRestrictions = new InquiryOrMaintenanceDocumentRestrictionsBase();
099                BusinessObjectEntry businessObjectEntry = (BusinessObjectEntry) getDataDictionaryService()
100                                .getDataDictionary().getBusinessObjectEntry(
101                                                businessObject.getClass().getName());
102                InquiryPresentationController inquiryPresentationController = getBusinessObjectDictionaryService()
103                                .getInquiryPresentationController(businessObject.getClass());
104                InquiryAuthorizer inquiryAuthorizer = getBusinessObjectDictionaryService()
105                                .getInquiryAuthorizer(businessObject.getClass());
106                considerBusinessObjectFieldUnmaskAuthorization(businessObject, user,
107                                inquiryRestrictions, "", null);
108                considerBusinessObjectFieldViewAuthorization(businessObjectEntry,
109                                businessObject, null, user, inquiryAuthorizer, inquiryRestrictions,
110                                "");
111                considerInquiryOrMaintenanceDocumentPresentationController(
112                                inquiryPresentationController, businessObject,
113                                inquiryRestrictions);
114                considerInquiryOrMaintenanceDocumentAuthorizer(inquiryAuthorizer,
115                                businessObject, user, inquiryRestrictions);
116                for (InquirySectionDefinition inquirySectionDefinition : businessObjectEntry.getInquiryDefinition().getInquirySections()) {
117                        if (inquirySectionDefinition.getInquiryCollections() != null) {
118                                addInquirableItemRestrictions(inquirySectionDefinition.getInquiryCollections().values(), inquiryAuthorizer,
119                                                inquiryRestrictions, businessObject, businessObject, "", user);
120                        }
121                        // Collections may also be stored in the inquiry fields, so we need to parse through that
122                        List<FieldDefinition> inquiryFields = inquirySectionDefinition.getInquiryFields();
123                        if (inquiryFields != null) {
124                                for (FieldDefinition fieldDefinition : inquiryFields) {
125                                        addInquirableItemRestrictions(inquiryFields, inquiryAuthorizer,
126                                                        inquiryRestrictions, businessObject, businessObject, "", user);
127                                }
128                        }
129                }
130
131                return inquiryRestrictions;
132        }
133
134        @Override
135    public MaintenanceDocumentRestrictions getMaintenanceDocumentRestrictions(
136                        MaintenanceDocument maintenanceDocument, Person user) {
137
138                MaintenanceDocumentRestrictions maintenanceDocumentRestrictions = new MaintenanceDocumentRestrictionsBase();
139                DataObjectEntry dataObjectEntry = getDataDictionaryService()
140                                .getDataDictionary().getDataObjectEntry(
141                                                maintenanceDocument.getNewMaintainableObject()
142                                                                .getDataObject().getClass().getName());
143                MaintenanceDocumentPresentationController maintenanceDocumentPresentationController = (MaintenanceDocumentPresentationController) getDocumentHelperService()
144                                .getDocumentPresentationController(maintenanceDocument);
145                MaintenanceDocumentAuthorizer maintenanceDocumentAuthorizer = (MaintenanceDocumentAuthorizer) getDocumentHelperService()
146                                .getDocumentAuthorizer(maintenanceDocument);
147                considerBusinessObjectFieldUnmaskAuthorization(maintenanceDocument
148                                .getNewMaintainableObject().getDataObject(), user,
149                                maintenanceDocumentRestrictions, "", maintenanceDocument );
150                considerBusinessObjectFieldViewAuthorization(dataObjectEntry,
151                                maintenanceDocument.getNewMaintainableObject().getDataObject(),
152                                null, user, maintenanceDocumentAuthorizer,
153                                maintenanceDocumentRestrictions, "");
154                considerBusinessObjectFieldModifyAuthorization(dataObjectEntry,
155                                maintenanceDocument.getNewMaintainableObject().getDataObject(),
156                                null, user, maintenanceDocumentAuthorizer,
157                                maintenanceDocumentRestrictions, "");
158                considerCustomButtonFieldAuthorization(dataObjectEntry,
159                                maintenanceDocument.getNewMaintainableObject().getDataObject(),
160                                null, user, maintenanceDocumentAuthorizer,
161                                maintenanceDocumentRestrictions, "");
162                considerInquiryOrMaintenanceDocumentPresentationController(
163                                maintenanceDocumentPresentationController, maintenanceDocument,
164                                maintenanceDocumentRestrictions);
165                considerInquiryOrMaintenanceDocumentAuthorizer(
166                                maintenanceDocumentAuthorizer, maintenanceDocument, user,
167                                maintenanceDocumentRestrictions);
168                considerMaintenanceDocumentPresentationController(
169                                maintenanceDocumentPresentationController, maintenanceDocument,
170                                maintenanceDocumentRestrictions);
171                considerMaintenanceDocumentAuthorizer(maintenanceDocumentAuthorizer,
172                                maintenanceDocument, user, maintenanceDocumentRestrictions);
173
174                MaintenanceDocumentEntry maintenanceDocumentEntry = getMaintenanceDocumentDictionaryService().getMaintenanceDocumentEntry(maintenanceDocument
175                                .getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
176                for (MaintainableSectionDefinition maintainableSectionDefinition : maintenanceDocumentEntry.getMaintainableSections()) {
177                        addMaintainableItemRestrictions(maintainableSectionDefinition.getMaintainableItems(), maintenanceDocumentAuthorizer, maintenanceDocumentRestrictions,
178                                        maintenanceDocument, maintenanceDocument.getNewMaintainableObject().getBusinessObject(), "", user);
179                }
180                return maintenanceDocumentRestrictions;
181        }
182
183        protected void considerBusinessObjectFieldUnmaskAuthorization(Object dataObject, Person user, BusinessObjectRestrictions businessObjectRestrictions, String propertyPrefix, Document document) {
184                DataObjectEntry objectEntry = getDataDictionaryService().getDataDictionary().getDataObjectEntry(dataObject.getClass().getName());
185                for (String attributeName : objectEntry.getAttributeNames()) {
186                        AttributeDefinition attributeDefinition = objectEntry.getAttributeDefinition(attributeName);
187                        if (attributeDefinition.getAttributeSecurity() != null) {
188                                if (attributeDefinition.getAttributeSecurity().isMask() &&
189                                                !canFullyUnmaskField(user, dataObject.getClass(), attributeName, document)) {
190                                        businessObjectRestrictions.addFullyMaskedField(propertyPrefix + attributeName, attributeDefinition.getAttributeSecurity().getMaskFormatter());
191                                }
192                                if (attributeDefinition.getAttributeSecurity().isPartialMask() &&
193                                                !canPartiallyUnmaskField(user, dataObject.getClass(), attributeName, document)) {
194                                        businessObjectRestrictions.addPartiallyMaskedField(propertyPrefix + attributeName, attributeDefinition.getAttributeSecurity().getPartialMaskFormatter());
195                                }
196                        }
197                }
198        }
199
200        /**
201         * @param dataObjectEntry if collectionItemBusinessObject is not null, then it is the DD entry for collectionItemBusinessObject.
202         * Otherwise, it is the entry for primaryBusinessObject
203         * @param primaryDataObject the top-level BO that is being inquiried or maintained
204         * @param collectionItemBusinessObject an element of a collection under the primaryBusinessObject that we are evaluating view auths for
205         * @param user the logged in user
206         * @param businessObjectAuthorizer
207         * @param inquiryOrMaintenanceDocumentRestrictions
208         * @param propertyPrefix
209         */
210        protected void considerBusinessObjectFieldViewAuthorization(
211                        DataObjectEntry dataObjectEntry,
212                        Object primaryDataObject,
213                        BusinessObject collectionItemBusinessObject,
214                        Person user,
215                        BusinessObjectAuthorizer businessObjectAuthorizer,
216                        InquiryOrMaintenanceDocumentRestrictions inquiryOrMaintenanceDocumentRestrictions,
217                        String propertyPrefix) {
218                for (String attributeName : dataObjectEntry.getAttributeNames()) {
219                        AttributeDefinition attributeDefinition = dataObjectEntry
220                                        .getAttributeDefinition(attributeName);
221                        if (attributeDefinition.getAttributeSecurity() != null) {
222                                if (attributeDefinition.getAttributeSecurity().isHide()) {
223                                        Map<String, String> collectionItemPermissionDetails = new HashMap<String, String>();
224                                        Map<String, String> collectionItemRoleQualifications = null;
225                                        if (ObjectUtils.isNotNull(collectionItemBusinessObject)) {
226                                                collectionItemPermissionDetails.putAll(getFieldPermissionDetails(collectionItemBusinessObject, attributeName));
227                                                collectionItemPermissionDetails.putAll(businessObjectAuthorizer.
228                                                                getCollectionItemPermissionDetails(collectionItemBusinessObject));
229                                                collectionItemRoleQualifications = new HashMap<String, String>(businessObjectAuthorizer.
230                                                                getCollectionItemRoleQualifications(collectionItemBusinessObject));
231                                        }
232                                        else {
233                                                collectionItemPermissionDetails.putAll(getFieldPermissionDetails(primaryDataObject, attributeName));
234                                        }
235                                        if (!businessObjectAuthorizer
236                                                        .isAuthorizedByTemplate(
237                                                                        primaryDataObject,
238                                                                        KRADConstants.KNS_NAMESPACE,
239                                                                        KimConstants.PermissionTemplateNames.VIEW_MAINTENANCE_INQUIRY_FIELD,
240                                                                        user.getPrincipalId(),
241                                                                        collectionItemPermissionDetails,
242                                                                        collectionItemRoleQualifications)) {
243                                                inquiryOrMaintenanceDocumentRestrictions
244                                                                .addHiddenField(propertyPrefix + attributeName);
245                                        }
246                                }
247                        }
248                }
249        }
250
251        /**
252         * @param dataObjectEntry if collectionItemBusinessObject is not null, then it is the DD entry for collectionItemBusinessObject.
253         * Otherwise, it is the entry for primaryBusinessObject
254         * @param primaryDataObject the top-level BO that is being inquiried or maintained
255         * @param collectionItemBusinessObject an element of a collection under the primaryBusinessObject that we are evaluating view auths for
256         * @param user the logged in user
257         * @param businessObjectAuthorizer
258         * @param inquiryOrMaintenanceDocumentRestrictions
259         * @param propertyPrefix
260         */
261        protected void considerBusinessObjectFieldModifyAuthorization(
262                        DataObjectEntry dataObjectEntry,
263                        Object primaryDataObject,
264                        BusinessObject collectionItemBusinessObject, Person user,
265                        BusinessObjectAuthorizer businessObjectAuthorizer,
266                        MaintenanceDocumentRestrictions maintenanceDocumentRestrictions,
267                        String propertyPrefix) {
268                for (String attributeName : dataObjectEntry.getAttributeNames()) {
269                        AttributeDefinition attributeDefinition = dataObjectEntry
270                                        .getAttributeDefinition(attributeName);
271                        if (attributeDefinition.getAttributeSecurity() != null) {
272                                Map<String, String> collectionItemPermissionDetails = new HashMap<String, String>();
273                                Map<String, String> collectionItemRoleQualifications = null;
274                                if (ObjectUtils.isNotNull(collectionItemBusinessObject)) {
275                                        collectionItemPermissionDetails.putAll(getFieldPermissionDetails(collectionItemBusinessObject, attributeName));
276                                        collectionItemPermissionDetails.putAll(businessObjectAuthorizer.
277                                                        getCollectionItemPermissionDetails(collectionItemBusinessObject));
278                                        collectionItemRoleQualifications = new HashMap<String, String>(businessObjectAuthorizer.
279                                                        getCollectionItemRoleQualifications(collectionItemBusinessObject));
280                                }
281                                else {
282                                        collectionItemPermissionDetails.putAll(getFieldPermissionDetails(primaryDataObject, attributeName));
283                                }
284                                if (attributeDefinition.getAttributeSecurity().isReadOnly()) {
285                                        if (!businessObjectAuthorizer
286                                                                .isAuthorizedByTemplate(
287                                                                                primaryDataObject,
288                                                                                KRADConstants.KNS_NAMESPACE,
289                                                                                KimConstants.PermissionTemplateNames.MODIFY_FIELD,
290                                                                                user.getPrincipalId(),
291                                                                                collectionItemPermissionDetails,
292                                                                                collectionItemRoleQualifications)) {
293                                                maintenanceDocumentRestrictions
294                                                                .addReadOnlyField(propertyPrefix + attributeName);
295                                        }
296                                }
297                        }
298                }
299        }
300
301        /**
302         * @param dataObjectEntry if collectionItemBusinessObject is not null, then it is the DD entry for collectionItemBusinessObject.
303         * Otherwise, it is the entry for primaryBusinessObject
304         * @param primaryDataObject the top-level BO that is being inquiried or maintained
305         * @param collectionItemBusinessObject an element of a collection under the primaryBusinessObject that we are evaluating view auths for
306         * @param user the logged in user
307         * @param businessObjectAuthorizer
308         * @param inquiryOrMaintenanceDocumentRestrictions
309         * @param propertyPrefix
310         */
311        protected void considerCustomButtonFieldAuthorization(
312                        DataObjectEntry dataObjectEntry,
313                        Object primaryDataObject,
314                        BusinessObject collectionItemBusinessObject,
315                        Person user,
316                        BusinessObjectAuthorizer businessObjectAuthorizer,
317                        MaintenanceDocumentRestrictions maintenanceDocumentRestrictions,
318                        String propertyPrefix) {
319                for (String attributeName : dataObjectEntry.getAttributeNames()) {
320                        AttributeDefinition attributeDefinition = dataObjectEntry
321                                        .getAttributeDefinition(attributeName);
322                        // TODO what is the equivalent of control.isButton in KRAD
323                        if (attributeDefinition.getControl() != null &&
324                                attributeDefinition.getControl().isButton()) {
325                                Map<String, String> collectionItemPermissionDetails = new HashMap<String, String>();
326                                Map<String, String> collectionItemRoleQualifications = null;
327                                if (ObjectUtils.isNotNull(collectionItemBusinessObject)) {
328                                        collectionItemPermissionDetails.putAll(getButtonFieldPermissionDetails(collectionItemBusinessObject, attributeName));
329                                        collectionItemPermissionDetails.putAll(businessObjectAuthorizer.
330                                                        getCollectionItemPermissionDetails(collectionItemBusinessObject));
331                                        collectionItemRoleQualifications = new HashMap<String, String>(businessObjectAuthorizer.
332                                                        getCollectionItemRoleQualifications(collectionItemBusinessObject));
333                                }
334                                else {
335                                        getButtonFieldPermissionDetails(primaryDataObject, attributeName);
336                                }
337
338                                if (!businessObjectAuthorizer
339                                                .isAuthorizedByTemplate(
340                                                                primaryDataObject,
341                                                                KRADConstants.KNS_NAMESPACE,
342                                                                KimConstants.PermissionTemplateNames.PERFORM_CUSTOM_MAINTENANCE_DOCUMENT_FUNCTION,
343                                                                user.getPrincipalId(),
344                                                                collectionItemPermissionDetails,
345                                                                collectionItemRoleQualifications)) {
346                                        maintenanceDocumentRestrictions
347                                                        .addHiddenField(propertyPrefix + attributeName);
348                                }
349                        }
350                }
351        }
352
353        protected void considerInquiryOrMaintenanceDocumentPresentationController(
354                        InquiryOrMaintenanceDocumentPresentationController businessObjectPresentationController,
355                        Object businessObject,
356                        InquiryOrMaintenanceDocumentRestrictions inquiryOrMaintenanceDocumentRestrictions) {
357                for (String attributeName : businessObjectPresentationController
358                                .getConditionallyHiddenPropertyNames(businessObject)) {
359                        inquiryOrMaintenanceDocumentRestrictions
360                                        .addHiddenField(attributeName);
361                }
362                for (String sectionId : businessObjectPresentationController
363                                .getConditionallyHiddenSectionIds(businessObject)) {
364                        inquiryOrMaintenanceDocumentRestrictions
365                                        .addHiddenSectionId(sectionId);
366                }
367        }
368
369        protected void considerInquiryOrMaintenanceDocumentAuthorizer(
370                        InquiryOrMaintenanceDocumentAuthorizer authorizer,
371                        Object businessObject, Person user,
372                        InquiryOrMaintenanceDocumentRestrictions restrictions) {
373                for (String sectionId : authorizer
374                                .getSecurePotentiallyHiddenSectionIds()) {
375                        Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
376                        additionalPermissionDetails
377                                        .put(KimConstants.AttributeConstants.SECTION_ID, sectionId);
378                        if (!authorizer.isAuthorizedByTemplate(businessObject,
379                                        KRADConstants.KNS_NAMESPACE,
380                                        KimConstants.PermissionTemplateNames.VIEW_SECTION, user
381                                                        .getPrincipalId(), additionalPermissionDetails,
382                                        null)) {
383                                restrictions.addHiddenSectionId(sectionId);
384                        }
385                }
386        }
387
388        protected void considerMaintenanceDocumentPresentationController(
389                        MaintenanceDocumentPresentationController presentationController,
390                        MaintenanceDocument document,
391                        MaintenanceDocumentRestrictions restrictions) {
392                for (String attributeName : presentationController
393                                .getConditionallyReadOnlyPropertyNames(document)) {
394                        restrictions.addReadOnlyField(attributeName);
395                }
396                for (String sectionId : presentationController
397                                .getConditionallyReadOnlySectionIds(document)) {
398                        restrictions.addReadOnlySectionId(sectionId);
399                }
400        }
401
402        protected void considerMaintenanceDocumentAuthorizer(
403                        MaintenanceDocumentAuthorizer authorizer,
404                        MaintenanceDocument document, Person user,
405                        MaintenanceDocumentRestrictions restrictions) {
406                for (String sectionId : authorizer
407                                .getSecurePotentiallyReadOnlySectionIds()) {
408                        Map<String, String> additionalPermissionDetails = new HashMap<String, String>();
409                        additionalPermissionDetails
410                                        .put(KimConstants.AttributeConstants.SECTION_ID, sectionId);
411                        if (!authorizer.isAuthorizedByTemplate(document,
412                                        KRADConstants.KNS_NAMESPACE,
413                                        KimConstants.PermissionTemplateNames.MODIFY_SECTION, user
414                                                        .getPrincipalId(), additionalPermissionDetails,
415                                        null)) {
416                                restrictions.addReadOnlySectionId(sectionId);
417                        }
418                }
419        }
420
421        @SuppressWarnings("rawtypes")
422    protected void addInquirableItemRestrictions(Collection sectionDefinitions,
423                        InquiryAuthorizer authorizer, InquiryRestrictions restrictions,
424                        BusinessObject primaryBusinessObject,
425                        BusinessObject businessObject, String propertyPrefix, Person user) {
426                for (Object inquirableItemDefinition : sectionDefinitions) {
427                        if (inquirableItemDefinition instanceof InquiryCollectionDefinition) {
428                                InquiryCollectionDefinition inquiryCollectionDefinition = (InquiryCollectionDefinition) inquirableItemDefinition;
429                                BusinessObjectEntry collectionBusinessObjectEntry = (BusinessObjectEntry) getDataDictionaryService()
430                                                .getDataDictionary().getBusinessObjectEntry(
431                                                                inquiryCollectionDefinition.getBusinessObjectClass().getName());
432
433                                try {
434                                        Collection<?> collection = (Collection<?>) PropertyUtils
435                                                        .getProperty(businessObject,
436                                                                        inquiryCollectionDefinition.getName());
437                                        int i = 0;
438                                        for (Iterator<?> iterator = collection.iterator(); iterator.hasNext();) {
439                                                String newPropertyPrefix = propertyPrefix + inquiryCollectionDefinition.getName() + "[" + i + "].";
440                                                Object collectionItemBusinessObject = iterator.next();
441                                                considerBusinessObjectFieldUnmaskAuthorization(
442                                                                collectionItemBusinessObject, user, restrictions,
443                                                                newPropertyPrefix, null);
444                                                if ( collectionItemBusinessObject instanceof BusinessObject ) {
445                                                considerBusinessObjectFieldViewAuthorization(
446                                                                collectionBusinessObjectEntry, primaryBusinessObject, (BusinessObject)collectionItemBusinessObject,
447                                                                user, authorizer, restrictions, newPropertyPrefix);
448                                                addInquirableItemRestrictions(
449                                                                inquiryCollectionDefinition
450                                                                                .getInquiryCollections(),
451                                                                authorizer,
452                                                                restrictions,
453                                                                primaryBusinessObject,
454                                                                (BusinessObject)collectionItemBusinessObject,
455                                                                newPropertyPrefix,
456                                                                user);
457                                                }
458                                                i++;
459                                        }
460                                } catch (Exception e) {
461                                        throw new RuntimeException(
462                                                        "Unable to resolve collection property: "
463                                                                        + businessObject.getClass() + ":"
464                                                                        + inquiryCollectionDefinition.getName(), e);
465                                }
466                        }
467                }
468        }
469
470        @SuppressWarnings("unchecked")
471        protected void addMaintainableItemRestrictions(List<? extends MaintainableItemDefinition> itemDefinitions,
472                        MaintenanceDocumentAuthorizer authorizer,
473                        MaintenanceDocumentRestrictions restrictions,
474                        MaintenanceDocument maintenanceDocument,
475                        BusinessObject businessObject, String propertyPrefix, Person user) {
476                for (MaintainableItemDefinition maintainableItemDefinition : itemDefinitions) {
477                        if (maintainableItemDefinition instanceof MaintainableCollectionDefinition) {
478                                try {
479                                        MaintainableCollectionDefinition maintainableCollectionDefinition = (MaintainableCollectionDefinition) maintainableItemDefinition;
480
481                                        Collection<BusinessObject> collection = (Collection<BusinessObject>) ObjectUtils
482                                                        .getNestedValue(businessObject,
483                                                                        maintainableItemDefinition.getName());
484                                        BusinessObjectEntry collectionBusinessObjectEntry = (BusinessObjectEntry) getDataDictionaryService()
485                                                        .getDataDictionary().getBusinessObjectEntry(
486                                                                        maintainableCollectionDefinition.getBusinessObjectClass().getName());
487                                        if (CollectionUtils.isNotEmpty(collection)) {
488                    //if (collection != null && !collection.isEmpty()) {
489                                        int i = 0;
490                                        for (Iterator<BusinessObject> iterator = collection.iterator(); iterator
491                                                        .hasNext();) {
492                                                String newPropertyPrefix = propertyPrefix + maintainableItemDefinition.getName() + "[" + i + "].";
493                                                BusinessObject collectionBusinessObject = iterator.next();
494                                                considerBusinessObjectFieldUnmaskAuthorization(
495                                                                collectionBusinessObject, user, restrictions,
496                                                                newPropertyPrefix, maintenanceDocument);
497                                                considerBusinessObjectFieldViewAuthorization(
498                                                                collectionBusinessObjectEntry, maintenanceDocument, collectionBusinessObject, user,
499                                                                authorizer, restrictions, newPropertyPrefix);
500                                                considerBusinessObjectFieldModifyAuthorization(
501                                                                collectionBusinessObjectEntry, maintenanceDocument, collectionBusinessObject, user,
502                                                                authorizer, restrictions, newPropertyPrefix);
503                                                addMaintainableItemRestrictions(
504                                                                ((MaintainableCollectionDefinition) maintainableItemDefinition)
505                                                                                .getMaintainableCollections(),
506                                                                authorizer, restrictions, maintenanceDocument,
507                                                                collectionBusinessObject, newPropertyPrefix,
508                                                                user);
509                                                addMaintainableItemRestrictions(
510                                                                ((MaintainableCollectionDefinition) maintainableItemDefinition)
511                                                                                .getMaintainableFields(), authorizer,
512                                                                restrictions, maintenanceDocument,
513                                                                collectionBusinessObject, newPropertyPrefix,
514                                                                user);
515                                                i++;
516                                        }
517                                        }
518                                } catch (Exception e) {
519                                        throw new RuntimeException(
520                                                        "Unable to resolve collection property: "
521                                                                        + businessObject.getClass() + ":"
522                                                                        + maintainableItemDefinition.getName(), e);
523                                }
524                        }
525                }
526        }
527
528        @Override
529    public boolean canFullyUnmaskField(Person user,
530                        Class<?> dataObjectClass, String fieldName, Document document) {
531                // KFSMI-5095
532                if(isNonProductionEnvAndUnmaskingTurnedOff()) {
533            return false;
534        }
535
536                if(user==null || StringUtils.isEmpty(user.getPrincipalId())) {
537            return false;
538        }
539                Boolean result = null;
540                if (document != null) { // if a document was passed, evaluate the permission in the context of a document
541                        try { // try/catch and fallthrough is a fix for KULRICE-3365
542                                result = getDocumentHelperService().getDocumentAuthorizer( document )
543                                .isAuthorizedByTemplate( document,
544                                                KRADConstants.KNS_NAMESPACE,
545                                                KimConstants.PermissionTemplateNames.FULL_UNMASK_FIELD,
546                                                user.getPrincipalId(), getFieldPermissionDetails(dataObjectClass, fieldName), null  );
547                        } catch (IllegalArgumentException e) {
548                                // document didn't have needed metadata
549                                // TODO: this requires intimate knowledge of DocumentHelperServiceImpl
550                        }
551                }
552                if (result == null) {
553                        result = getPermissionService().isAuthorizedByTemplate(user.getPrincipalId(), KRADConstants.KNS_NAMESPACE,
554                    KimConstants.PermissionTemplateNames.FULL_UNMASK_FIELD, new HashMap<String, String>(
555                    getFieldPermissionDetails(dataObjectClass, fieldName)), Collections.<String, String>emptyMap());
556                }
557                return result; // should be safe to return Boolean here since the only circumstances that
558                               // will leave it null will result in an exception being thrown above.
559        }
560
561        @Override
562    public boolean canPartiallyUnmaskField(
563                        Person user, Class<?> dataObjectClass, String fieldName, Document document) {
564                // KFSMI-5095
565                if(isNonProductionEnvAndUnmaskingTurnedOff()) {
566            return false;
567        }
568
569                if(user==null || StringUtils.isEmpty(user.getPrincipalId())) {
570            return false;
571        }
572
573                if ( document == null ) {
574                        return getPermissionService().isAuthorizedByTemplate(user.getPrincipalId(), KRADConstants.KNS_NAMESPACE,
575                    KimConstants.PermissionTemplateNames.PARTIAL_UNMASK_FIELD, new HashMap<String, String>(
576                    getFieldPermissionDetails(dataObjectClass, fieldName)), Collections.<String, String>emptyMap());
577                } else { // if a document was passed, evaluate the permission in the context of a document
578                        return getDocumentHelperService().getDocumentAuthorizer( document )
579                                        .isAuthorizedByTemplate( document,
580                                                                                         KRADConstants.KNS_NAMESPACE,
581                                                                                         KimConstants.PermissionTemplateNames.PARTIAL_UNMASK_FIELD,
582                                                                                         user.getPrincipalId(), getFieldPermissionDetails(dataObjectClass, fieldName), Collections.<String, String>emptyMap()  );
583                }
584        }
585
586        protected Map<String, String> getFieldPermissionDetails(
587                        Class<?> dataObjectClass, String attributeName) {
588                try {
589                        return getFieldPermissionDetails(dataObjectClass.newInstance(),
590                                        attributeName);
591                } catch (Exception e) {
592                        throw new RuntimeException(
593                                        "The getPermissionDetails method of BusinessObjectAuthorizationServiceImpl was unable to instantiate the dataObjectClass"
594                                                        + dataObjectClass, e);
595                }
596        }
597
598        protected Map<String, String> getFieldPermissionDetails(
599                        Object dataObject, String attributeName) {
600                Map<String, String> permissionDetails = null;
601                String namespaceCode = null;
602                String componentName = null;
603                String propertyName = null;
604                // JHK: commenting out for KFSMI-2398 - permission checks need to be done at the level specified
605                // that is, if the parent object specifies the security, that object should be used for the
606                // component
607//              if (attributeName.contains(".")) {
608//                      try {
609//                              permissionDetails = KimCommonUtils
610//                                              .getNamespaceAndComponentSimpleName(PropertyUtils
611//                                                              .getPropertyType(businessObject, attributeName
612//                                                                              .substring(0, attributeName
613//                                                                                              .lastIndexOf("."))));
614//                      } catch (Exception e) {
615//                              throw new RuntimeException(
616//                                              "Unable to discover nested business object class: "
617//                                                              + businessObject.getClass() + " : "
618//                                                              + attributeName, e);
619//                      }
620
621//                      permissionDetails.put(KimAttributes.PROPERTY_NAME, attributeName
622//                                      .substring(attributeName.indexOf(".") + 1));
623//              } else {
624                        permissionDetails = KRADUtils
625                                        .getNamespaceAndComponentSimpleName(dataObject.getClass());
626                        permissionDetails.put(KimConstants.AttributeConstants.PROPERTY_NAME, attributeName);
627//              }
628                return permissionDetails;
629        }
630
631        protected Map<String, String> getButtonFieldPermissionDetails(
632                        Object businessObject, String attributeName) {
633                Map<String, String> permissionDetails = new HashMap<String, String>();
634                if (attributeName.contains(".")) {
635                        permissionDetails.put(KimConstants.AttributeConstants.BUTTON_NAME, attributeName);
636                } else {
637                        permissionDetails.put(KimConstants.AttributeConstants.BUTTON_NAME, attributeName);
638                }
639                return permissionDetails;
640        }
641
642        private PermissionService getPermissionService() {
643                if (permissionService == null) {
644                        permissionService = KimApiServiceLocator
645                                        .getPermissionService();
646                }
647                return permissionService;
648        }
649
650        private BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
651                if (businessObjectDictionaryService == null) {
652                        businessObjectDictionaryService = KNSServiceLocator
653                                        .getBusinessObjectDictionaryService();
654                }
655                return businessObjectDictionaryService;
656        }
657
658        private MaintenanceDocumentDictionaryService getMaintenanceDocumentDictionaryService() {
659                if (maintenanceDocumentDictionaryService == null) {
660                        maintenanceDocumentDictionaryService = KNSServiceLocator
661                                        .getMaintenanceDocumentDictionaryService();
662                }
663                return maintenanceDocumentDictionaryService;
664        }
665
666        private ConfigurationService getKualiConfigurationService() {
667                if (kualiConfigurationService == null) {
668                        kualiConfigurationService = CoreApiServiceLocator.getKualiConfigurationService();
669                }
670                return kualiConfigurationService;
671        }
672
673        private boolean isNonProductionEnvAndUnmaskingTurnedOff(){
674                return !getKualiConfigurationService().getPropertyValueAsString(KRADConstants.PROD_ENVIRONMENT_CODE_KEY)
675                .equalsIgnoreCase(
676                        getKualiConfigurationService().getPropertyValueAsString(KRADConstants.ENVIRONMENT_KEY)) &&
677                                !getKualiConfigurationService().getPropertyValueAsBoolean(KRADConstants.ENABLE_NONPRODUCTION_UNMASKING);
678        }
679
680    protected DocumentHelperService getDocumentHelperService() {
681        return KNSServiceLocator.getDocumentHelperService();
682    }
683
684}