/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.tem.businessobject.lookup; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.module.tem.TemConstants; import org.kuali.kfs.module.tem.businessobject.TemProfile; import org.kuali.kfs.module.tem.businessobject.TravelerProfileForLookup; import org.kuali.kfs.module.tem.identity.TemKimAttributes; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.identity.KfsKimAttributes; import org.kuali.rice.kew.api.WorkflowDocument; import org.kuali.rice.kim.api.KimConstants; import org.kuali.rice.kim.api.permission.PermissionService; import org.kuali.rice.kns.util.FieldUtils; import org.kuali.rice.kns.util.KNSGlobalVariables; import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; import org.kuali.rice.kns.web.struts.form.KualiForm; import org.kuali.rice.kns.web.struts.form.LookupForm; import org.kuali.rice.krad.bo.BusinessObject; import org.kuali.rice.krad.service.SessionDocumentService; import org.kuali.rice.krad.util.GlobalVariables; /** * Overridden to filter results to only those available to the currently logged in user to use. This will be used within TA, TR, ENT, and RELO * document traveler lookups - NOT the non-document TemProfile lookup */ public class TravelerProfileDocLookupableHelperServiceImpl extends TemProfileLookupableHelperServiceImpl { protected PermissionService permissionService; /** * Filters searched for profiles so they include only those the user should be able to access to use as a traveler on a travel, relocation, or entertainment document * @see org.kuali.kfs.module.tem.businessobject.lookup.TemProfileLookupableHelperServiceImpl#getSearchResults(java.util.Map) */ @Override public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) { final Map<String, String> viewRecordPermissionDetails = getPermissionDetailsForViewRecordsCheck(); final String currentUserPrincipalId = GlobalVariables.getUserSession().getPrincipalId(); final String documentTypeName = updateAuthorizationDocumentType(getCurrentDocumentTypeName()); final List<TemProfile> allProfiles = (List<TemProfile>)super.getSearchResults(fieldValues); List<TemProfile> qualifyingProfiles = new ArrayList<TemProfile>(); for (TemProfile profile : allProfiles) { final Map<String, String> roleQualifier = getRoleQualifierForViewRecordsCheck(profile, documentTypeName); if (getPermissionService().isAuthorizedByTemplate(currentUserPrincipalId, KFSConstants.PermissionTemplate.VIEW_RECORD.namespace, KFSConstants.PermissionTemplate.VIEW_RECORD.name, viewRecordPermissionDetails, roleQualifier)) { qualifyingProfiles.add(profile); } } return qualifyingProfiles; } /** * @return the PermissionDetails map to do permission checks on TravelerProfileForLookup records */ protected Map<String, String> getPermissionDetailsForViewRecordsCheck() { Map<String, String> permissionDetails = new HashMap<String, String>(); permissionDetails.put(KimConstants.AttributeConstants.COMPONENT_NAME, TravelerProfileForLookup.class.getSimpleName()); return permissionDetails; } /** * Pulls the principal id, home chart, and home organization codes from the profile to build a role qualifier * @param profile the profile to pull qualifications from * @return a role qualifier with attribute values from the profile */ protected Map<String, String> getRoleQualifierForViewRecordsCheck(TemProfile profile, String documentTypeName) { Map<String, String> roleQualifier = new HashMap<String, String>(); roleQualifier.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, profile.getHomeDeptChartOfAccountsCode()); roleQualifier.put(KfsKimAttributes.ORGANIZATION_CODE, profile.getHomeDeptOrgCode()); roleQualifier.put(KfsKimAttributes.PROFILE_PRINCIPAL_ID, profile.getPrincipalId()); roleQualifier.put(TemKimAttributes.CUSTOMER_PROFILE_ID, profile.getCustomerNumber()); roleQualifier.put(TemKimAttributes.PROFILE_ID, profile.getProfileId().toString()); if (!StringUtils.isBlank(documentTypeName)) { roleQualifier.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, documentTypeName); } return roleQualifier; } /** * Looks in the form from KNSGlobalVariables to try to figure out what the document type of the current document is * @return */ protected String getCurrentDocumentTypeName() { final KualiForm form = KNSGlobalVariables.getKualiForm(); if (form != null) { if (form instanceof KualiDocumentFormBase) { return ((KualiDocumentFormBase)KNSGlobalVariables.getKualiForm()).getDocTypeName(); } else if (form instanceof LookupForm) { final String docNum = ((LookupForm)KNSGlobalVariables.getKualiForm()).getDocNum(); if(!StringUtils.isBlank(docNum)) { WorkflowDocument workflowDocument = SpringContext.getBean(SessionDocumentService.class).getDocumentFromSession(GlobalVariables.getUserSession(), docNum); return workflowDocument.getDocumentTypeName(); } } } return null; } /** * If the passed in document type represents one of the travel authorization child documents, upgrade to travel authorization document; otherwise return the given document type unmodified * @param documentType the document type name to filter * @return TA if TAC or TAA is passed in as the document type, otherwise the passed in document type */ protected String updateAuthorizationDocumentType(String documentType) { if (!StringUtils.isBlank(documentType) && (TemConstants.TravelDocTypes.TRAVEL_AUTHORIZATION_CLOSE_DOCUMENT.equals(documentType) || TemConstants.TravelDocTypes.TRAVEL_AUTHORIZATION_AMEND_DOCUMENT.equals(documentType))) { return TemConstants.TravelDocTypes.TRAVEL_AUTHORIZATION_DOCUMENT; } return documentType; } /** * Overridden to always return TemProfile * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getBusinessObjectClass() */ @Override public Class getBusinessObjectClass() { return TemProfile.class; } /** * This lookup only occurs within documents; it should never have a supplemental menu bar * @see org.kuali.kfs.module.tem.businessobject.lookup.TemProfileLookupableHelperServiceImpl#getSupplementalMenuBar() */ @Override public String getSupplementalMenuBar() { return KFSConstants.EMPTY_STRING; } /** * Overrides set rows so that the _rows_ always look at TravelerProfileForLookup as the business object class - we want that lookup, * but we want to search for TemProfiles.... * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#setRows() */ @Override protected void setRows() { List<String> lookupFieldAttributeList = null; final Class<? extends BusinessObject> businessObjectClazz = TravelerProfileForLookup.class; if (getBusinessObjectMetaDataService().isLookupable(businessObjectClazz)) { lookupFieldAttributeList = getBusinessObjectMetaDataService().getLookupableFieldNames( businessObjectClazz); } if (lookupFieldAttributeList == null) { throw new RuntimeException("Lookup not defined for business object " + getBusinessObjectClass()); } // construct field object for each search attribute List fields = new ArrayList(); try { fields = FieldUtils.createAndPopulateFieldsForLookup(lookupFieldAttributeList, getReadOnlyFieldsList(), businessObjectClazz); } catch (InstantiationException e) { throw new RuntimeException("Unable to create instance of business object class" + e.getMessage()); } catch (IllegalAccessException e) { throw new RuntimeException("Unable to create instance of business object class" + e.getMessage()); } int numCols = getBusinessObjectDictionaryService().getLookupNumberOfColumns(businessObjectClazz); this.rows = FieldUtils.wrapFields(fields, numCols); } /** * @return the injected implementation KIM's PermissionService */ public PermissionService getPermissionService() { return permissionService; } /** * Injects an implementation of KIM's PermissionService * @param permissionService an implementation of KIM's PermissionService */ public void setPermissionService(PermissionService permissionService) { this.permissionService = permissionService; } }