/* * 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.service.impl; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.kuali.kfs.module.tem.TemConstants; import org.kuali.kfs.module.tem.TemConstants.TravelDocTypes; import org.kuali.kfs.module.tem.TemPropertyConstants; import org.kuali.kfs.module.tem.TemPropertyConstants.TemProfileProperties; import org.kuali.kfs.module.tem.businessobject.TemProfile; import org.kuali.kfs.module.tem.businessobject.TemProfileArranger; import org.kuali.kfs.module.tem.document.TravelDocument; import org.kuali.kfs.module.tem.document.service.TravelArrangerDocumentService; import org.kuali.kfs.module.tem.service.TemRoleService; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.identity.KfsKimAttributes; import org.kuali.rice.kim.api.identity.Person; import org.kuali.rice.kim.api.role.RoleMembership; import org.kuali.rice.kim.api.role.RoleService; import org.kuali.rice.kim.api.services.KimApiServiceLocator; import org.kuali.rice.krad.service.BusinessObjectService; import org.kuali.rice.krad.util.ObjectUtils; public class TemRoleServiceImpl implements TemRoleService{ public static Logger LOG = Logger.getLogger(TemRoleServiceImpl.class); protected RoleService roleService; protected BusinessObjectService businessObjectService; protected TravelArrangerDocumentService arrangerDocumentService; /** * @see org.kuali.kfs.module.tem.service.TemRoleService#canAccessTravelDocument(org.kuali.kfs.module.tem.document.TravelDocument, org.kuali.rice.kim.bo.Person) */ @Override public boolean canAccessTravelDocument(TravelDocument travelDocument, Person currentUser){ boolean canAccess = false; String initiatorId = travelDocument.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId(); if (initiatorId.equals(currentUser.getPrincipalId())) { canAccess = true; } else if (ObjectUtils.isNotNull(travelDocument.getTemProfileId())) { //Get the profile from the document TemProfile profile = SpringContext.getBean(BusinessObjectService.class).findBySinglePrimaryKey(TemProfile.class, travelDocument.getTemProfileId()); if (ObjectUtils.isNotNull(profile)){ //user is the traveler if (currentUser.getPrincipalId().equals(profile.getPrincipalId())) { canAccess = true; } else { String profileId = travelDocument.getTemProfileId().toString(); String documentType = travelDocument.getDocumentTypeName(); //profile exists and user does not have access as the arranger if(isTravelArranger(currentUser, profile.getHomeDepartment(), profileId, documentType)) { canAccess = true; } } } } return canAccess; } /** * @see org.kuali.kfs.module.tem.service.TemRoleService#isArrangerForProfile(java.lang.String, int) */ @Override public boolean isArrangerForProfile(String principalId, int profileId) { boolean isArranger = false; if(ObjectUtils.isNotNull(profileId) && ObjectUtils.isNotNull(principalId)) { isArranger = ObjectUtils.isNotNull(arrangerDocumentService.findTemProfileArranger(principalId, profileId)); } return isArranger; } /** * @see org.kuali.kfs.module.tem.document.service.TravelArrangerDocumentService#isTravelDocumentArrangerForProfile(java.lang.String, java.lang.String, int) */ @Override public boolean isTravelDocumentArrangerForProfile(String documentType, String principalId, Integer profileId) { boolean isTravelArranger = false; TemProfileArranger arranger = arrangerDocumentService.findTemProfileArranger(principalId, profileId); if (arranger != null){ if (TravelDocTypes.getAuthorizationDocTypes().contains(documentType)){ isTravelArranger = arranger.getTaInd(); }else if (TravelDocTypes.getReimbursementDocTypes().contains(documentType)){ isTravelArranger = arranger.getTrInd(); } } return isTravelArranger; } /** * @see org.kuali.kfs.module.tem.service.TemRoleService#isProfileArranger(java.lang.String) */ @SuppressWarnings("rawtypes") @Override public boolean isProfileArranger(String arrangerId) { boolean isProfileArranger = false; if(StringUtils.isNotBlank(arrangerId)) { Map fieldValues = new HashMap(); fieldValues.put(TemProfileProperties.PRINCIPAL_ID, arrangerId); List<TemProfileArranger> profileArrangers = new ArrayList<TemProfileArranger>( businessObjectService.findMatching(TemProfileArranger.class, fieldValues)); isProfileArranger = ObjectUtils.isNotNull(profileArrangers) && !profileArrangers.isEmpty(); } return isProfileArranger; } /** * @see org.kuali.kfs.module.tem.service.TemRoleService#isProfileAdmin(org.kuali.rice.kim.bo.Person, java.lang.String) */ @Override public boolean isProfileAdmin(Person currentUser, String homeDepartment) { boolean hasAdminRole = checkUserRole(currentUser, TemConstants.TemRoleNames.TEM_PROFILE_ADMINISTRATOR, TemConstants.PARAM_NAMESPACE, null); boolean hasOrgRole = checkOrganizationRole(currentUser, TemConstants.TemRoleNames.TEM_PROFILE_ADMINISTRATOR, TemConstants.PARAM_NAMESPACE, homeDepartment); return hasAdminRole && hasOrgRole; } /** * @see org.kuali.kfs.module.tem.document.service.TravelDocumentService#isTravelArranger(org.kuali.rice.kim.bo.Person, java.lang.String, java.lang.String, java.lang.String) */ @Override public boolean isTravelArranger(final Person user, final String primaryDepartmentCode, String profileId, String documentType) { //add the role qualification Map<String,String> qualification = new HashMap<String,String>(); if (isProfileAlsoUser(user, profileId)) { qualification.put(KfsKimAttributes.PROFILE_PRINCIPAL_ID, user.getPrincipalId()); } else { qualification.put(TemProfileProperties.PROFILE_ID, profileId); } qualification.put(KFSPropertyConstants.DOCUMENT_TYPE_NAME, documentType); boolean checkProfileAssignedRole = checkUserRole(user, TemConstants.TEM_ASSIGNED_PROFILE_ARRANGER, TemConstants.PARAM_NAMESPACE, qualification); boolean checkOrgRole = checkOrganizationRole(user, TemConstants.TEM_ORGANIZATION_PROFILE_ARRANGER, TemConstants.PARAM_NAMESPACE, primaryDepartmentCode); //user is an arranger if either check is successful return checkProfileAssignedRole || checkOrgRole; } /** * Determines if the given profile id represents the profile of the given user * @param user a user * @param profileId a profile id * @return true if the profile and the user represent the same entity; false otherwise */ protected boolean isProfileAlsoUser(Person user, String profileId) { final TemProfile profile = getProfile(profileId); return (profile != null && StringUtils.equals(profile.getPrincipalId(), user.getPrincipalId())); } /** * Looks up the active profile for the given profile id; null if nothing is found or the profile is not active * @param profileId the profile id to look up * @return */ protected TemProfile getProfile(String profileId) { if (!StringUtils.isBlank(profileId)) { final TemProfile profile = businessObjectService.findBySinglePrimaryKey(TemProfile.class, profileId); if (profile != null && profile.isActive()) { return profile; } } return null; } /** * @see org.kuali.kfs.module.tem.document.service.TravelDocumentService#isTravelArranger(org.kuali.rice.kim.bo.Person) */ @Override public boolean isTravelArranger(final Person user) { Map fieldValues = new HashMap(); fieldValues.put(TemPropertyConstants.TemProfileProperties.PRINCIPAL_ID, user.getPrincipalId()); fieldValues.put(KFSPropertyConstants.ACTIVE, "Y"); int count = businessObjectService.countMatching(TemProfileArranger.class, fieldValues); boolean isArranger = count > 0 ? true : false; boolean checkOrgRole = checkOrganizationRole(user, TemConstants.TEM_ORGANIZATION_PROFILE_ARRANGER, TemConstants.PARAM_NAMESPACE, null); //user is an arranger if either check is successful return isArranger || checkOrgRole; } /** * @see org.kuali.kfs.module.tem.document.service.TravelDocumentService#isTravelManager(org.kuali.rice.kim.bo.Person) */ @Override public boolean isTravelManager(final Person user) { return checkUserRole(user, TemConstants.TRAVEL_MANAGER, KFSConstants.CoreModuleNamespaces.KFS, null); } /** * @see org.kuali.kfs.module.tem.service.TemRoleService#checkUserRole(org.kuali.rice.kim.bo.Person, java.lang.String, java.lang.String, org.kuali.rice.kim.bo.types.dto.Map<String,String>) */ @Override public boolean checkUserRole(final Person user, String role, String parameterNamespace, Map<String,String> qualification){ try{ List<String> roleIds = new ArrayList<String>(); roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(parameterNamespace, role)); return roleService.principalHasRole(user.getPrincipalId(), roleIds, qualification); } catch (NullPointerException e) { LOG.error(e); } return false; } /** * @see org.kuali.kfs.module.tem.service.TemRoleService#checkOrganizationRole(org.kuali.rice.kim.bo.Person, java.lang.String, java.lang.String, java.lang.String) */ @Override public boolean checkOrganizationRole(final Person user, String role, String parameterNamespace, String primaryDepartmentCode){ try{ List<String> roleIds = new ArrayList<String>(); roleIds.add(roleService.getRoleIdByNamespaceCodeAndName(parameterNamespace, role)); Map<String,String> qualification = null; String chartOfAccounts, organizationCode = null; if (StringUtils.isNotEmpty(primaryDepartmentCode)) { String[] split = primaryDepartmentCode.split("-"); if(split != null){ chartOfAccounts = split[0]; qualification = new HashMap<String,String>(); qualification.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, chartOfAccounts); qualification.put("performQualifierMatch", "True"); if(split.length == 2){ organizationCode = split[1]; qualification.put(KfsKimAttributes.ORGANIZATION_CODE, organizationCode); } } } if (roleService.principalHasRole(user.getPrincipalId(), roleIds, qualification)) { return true; } } catch (NullPointerException e) { LOG.error(e); } return false; } /** * This method gets the contract manager user identifier. * @return contractManagerId */ @Override public Collection<RoleMembership> getTravelArrangers(String chartCode, String orgCode) { Map<String,String> qualification = new HashMap<String,String>(); qualification.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, chartCode); qualification.put(KfsKimAttributes.ORGANIZATION_CODE, orgCode); qualification.put(KfsKimAttributes.DESCEND_HIERARCHY, "Y"); RoleService roleService = KimApiServiceLocator.getRoleService(); String roleId = roleService.getRoleIdByNamespaceCodeAndName(TemConstants.PARAM_NAMESPACE, TemConstants.TemRoleNames.TEM_ORGANIZATION_PROFILE_ARRANGER); Collection<RoleMembership> roleMemberships = roleService.getRoleMembers(Collections.singletonList(roleId), qualification); return roleMemberships; } public void setRoleService(RoleService roleService) { this.roleService = roleService; } public void setBusinessObjectService(BusinessObjectService businessObjectService) { this.businessObjectService = businessObjectService; } public void setArrangerDocumentService(TravelArrangerDocumentService travelArrangerDocumentService) { this.arrangerDocumentService = travelArrangerDocumentService; } }