/*
* 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.bc.identity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.businessobject.Organization;
import org.kuali.kfs.coa.identity.OrganizationOptionalHierarchyRoleTypeServiceImpl;
import org.kuali.kfs.module.bc.BCConstants;
import org.kuali.kfs.module.bc.BCKeyConstants;
import org.kuali.kfs.module.bc.BCPropertyConstants;
import org.kuali.kfs.module.bc.businessobject.BudgetConstructionAccountOrganizationHierarchy;
import org.kuali.kfs.module.bc.document.BudgetConstructionDocument;
import org.kuali.kfs.module.bc.document.service.BudgetConstructionProcessorService;
import org.kuali.kfs.module.bc.document.service.BudgetDocumentService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.identity.KfsKimAttributes;
import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
import org.kuali.rice.core.api.uif.RemotableAttributeError;
import org.kuali.rice.core.api.util.KeyValue;
import org.kuali.rice.kim.api.KimConstants;
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.kim.api.type.KimAttributeField;
import org.kuali.rice.kns.kim.role.RoleTypeServiceBase;
import org.kuali.rice.krad.util.MessageMap;
public class DocumentDerivedRoleTypeServiceImpl extends RoleTypeServiceBase implements BudgetConstructionNoAccessMessageSetting {
private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentDerivedRoleTypeServiceImpl.class);
protected static final String UNMATCHABLE_QUALIFICATION = "!~!~!~!~!~";
protected BudgetConstructionProcessorService budgetConstructionProcessorService;
protected BudgetDocumentService budgetDocumentService;
@Override
public Map<String,String> convertQualificationForMemberRoles(String namespaceCode, String roleName, String memberRoleNamespaceCode, String memberRoleName, Map<String,String> qualification) {
Map<String,String> newQualification = new HashMap<String,String>();
if(qualification!=null && !qualification.isEmpty()){
String universityFiscalYear = qualification.get(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR);
String chartOfAccountsCode = qualification.get(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE);
String accountNumber = qualification.get(KfsKimAttributes.ACCOUNT_NUMBER);
String orgChartOfAccountsCode = qualification.get(BCPropertyConstants.ORGANIZATION_CHART_OF_ACCOUNTS_CODE);
String organizationCode = qualification.get(KfsKimAttributes.ORGANIZATION_CODE);
String accountReportExists = qualification.get(BCPropertyConstants.ACCOUNT_REPORTS_EXIST);
Integer organizationLevelCode = qualification.get(BCPropertyConstants.ORGANIZATION_LEVEL_CODE)!=null?Integer.parseInt(qualification.get(BCPropertyConstants.ORGANIZATION_LEVEL_CODE)):null;
if (BCConstants.KimApiConstants.BC_PROCESSOR_ROLE_NAME.equals(memberRoleName)) {
if (BCConstants.KimApiConstants.DOCUMENT_EDITOR_ROLE_NAME.equals(roleName) && (organizationLevelCode!=null && organizationLevelCode.intValue() == 0)) {
organizationCode = UNMATCHABLE_QUALIFICATION;
}
}
else {
if (organizationLevelCode!=null && organizationLevelCode.intValue() != 0) {
if (BCConstants.KimApiConstants.DOCUMENT_EDITOR_ROLE_NAME.equals(roleName) || Boolean.TRUE.toString().equals(accountReportExists)) {
accountNumber = UNMATCHABLE_QUALIFICATION;
}
}
}
String descendHierarchy = OrganizationOptionalHierarchyRoleTypeServiceImpl.DESCEND_HIERARCHY_FALSE_VALUE;
if (BCConstants.KimApiConstants.DOCUMENT_VIEWER_ROLE_NAME.equals(roleName)) {
descendHierarchy = OrganizationOptionalHierarchyRoleTypeServiceImpl.DESCEND_HIERARCHY_TRUE_VALUE;
newQualification.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, universityFiscalYear);
newQualification.put(BCPropertyConstants.ORGANIZATION_LEVEL_CODE, organizationLevelCode!=null?organizationLevelCode.toString():null);
}
newQualification.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
newQualification.put(KfsKimAttributes.ACCOUNT_NUMBER, accountNumber);
newQualification.put(BCPropertyConstants.ORGANIZATION_CHART_OF_ACCOUNTS_CODE, orgChartOfAccountsCode);
newQualification.put(KfsKimAttributes.ORGANIZATION_CODE, organizationCode);
newQualification.put(KfsKimAttributes.DESCEND_HIERARCHY, descendHierarchy);
newQualification.put(BCPropertyConstants.ACCOUNT_REPORTS_EXIST, accountReportExists);
if (qualification.containsKey(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME)) {
newQualification.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, qualification.get(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME));
}
}
return newQualification;
}
/**
* @see org.kuali.kfs.module.bc.identity.BudgetConstructionNoAccessMessageSetting#setNoAccessMessage(org.kuali.kfs.module.bc.document.BudgetConstructionDocument,
* org.kuali.rice.kim.api.identity.Person, org.kuali.rice.krad.util.MessageMap)
*/
@Override
public void setNoAccessMessage(BudgetConstructionDocument document, Person user, MessageMap messageMap) {
LOG.info("Started DocumentDerivedRoleTypeServiceImpl.setNoAccessMessage");
Map<String,String> qualification = new HashMap<String,String>(3);
qualification.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, document.getChartOfAccountsCode());
qualification.put(KfsKimAttributes.ACCOUNT_NUMBER, document.getAccountNumber());
qualification.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, BCConstants.BUDGET_CONSTRUCTION_DOCUMENT_NAME);
RoleService roleService = KimApiServiceLocator.getRoleService();
boolean isFiscalOfficerOrDelegate = roleService.principalHasRole(user.getPrincipalId()
, Collections.singletonList(roleService.getRoleIdByNamespaceCodeAndName(KFSConstants.CoreModuleNamespaces.KFS, KFSConstants.SysKimApiConstants.FISCAL_OFFICER_KIM_ROLE_NAME))
, qualification);
boolean isBCProcessor = false;
boolean isProcessorInAccountHierarchy = false;
List<Organization> userProcessingOrgs = budgetConstructionProcessorService.getProcessorOrgs(user);
if (userProcessingOrgs != null && !userProcessingOrgs.isEmpty()) {
isBCProcessor = true;
List<BudgetConstructionAccountOrganizationHierarchy> accountOrganizationHierarchy = (List<BudgetConstructionAccountOrganizationHierarchy>) budgetDocumentService.retrieveOrBuildAccountOrganizationHierarchy(document.getUniversityFiscalYear(), document.getChartOfAccountsCode(), document.getAccountNumber());
for (BudgetConstructionAccountOrganizationHierarchy accountOrganization : accountOrganizationHierarchy) {
if (userProcessingOrgs.contains(accountOrganization.getOrganization())) {
isProcessorInAccountHierarchy = true;
}
}
}
if (document.getOrganizationLevelCode().intValue() == 0) {
messageMap.putError(KFSConstants.DOCUMENT_ERRORS, BCKeyConstants.ERROR_BUDGET_USER_NOT_IN_HIERARCHY);
}
else {
if (isFiscalOfficerOrDelegate || isProcessorInAccountHierarchy) {
messageMap.putError(KFSConstants.DOCUMENT_ERRORS, BCKeyConstants.ERROR_BUDGET_USER_BELOW_DOCLEVEL);
}
else if (isBCProcessor) {
messageMap.putError(KFSConstants.DOCUMENT_ERRORS, BCKeyConstants.ERROR_BUDGET_USER_NOT_IN_HIERARCHY);
}
else {
messageMap.putError(KFSConstants.DOCUMENT_ERRORS, BCKeyConstants.ERROR_BUDGET_USER_NOT_ORG_APPROVER);
}
}
LOG.info("Finished DocumentDerivedRoleTypeServiceImpl.setNoAccessMessage");
}
public void setBudgetConstructionProcessorService(BudgetConstructionProcessorService budgetConstructionProcessorService) {
this.budgetConstructionProcessorService = budgetConstructionProcessorService;
}
public void setBudgetDocumentService(BudgetDocumentService budgetDocumentService) {
this.budgetDocumentService = budgetDocumentService;
}
public List<KeyValue> getAttributeValidValues(String kimTypeId, String attributeName) {
return Collections.emptyList();
}
@Override
public List<String> getQualifiersForExactMatch() {
return Collections.emptyList();
}
public List<RoleMembership> getRoleMembersFromApplicationRole(String namespaceCode, String roleName, Map<String, String> qualification) throws RiceIllegalArgumentException {
return Collections.emptyList();
}
@Override
public List<RoleMembership> getRoleMembersFromDerivedRole(String namespaceCode, String roleName, Map<String, String> qualification) throws RiceIllegalArgumentException {
return Collections.emptyList();
}
@Override
public List<RoleMembership> sortRoleMembers(List<RoleMembership> roleMembers) throws RiceIllegalArgumentException {
return Collections.emptyList();
}
@Override
public List<RemotableAttributeError> validateUniqueAttributes(String kimTypeId, Map<String, String> newAttributes, Map<String, String> oldAttributes) throws RiceIllegalArgumentException {
return Collections.emptyList();
}
@Override
public List<RemotableAttributeError> validateUnmodifiableAttributes(String kimTypeId, Map<String, String> originalAttributes, Map<String, String> newAttributes) throws RiceIllegalArgumentException {
return Collections.emptyList();
}
@Override
public String getWorkflowDocumentTypeName() {
return null;
}
@Override
public List<String> getWorkflowRoutingAttributes(String routeLevel) {
if (StringUtils.isBlank(routeLevel)) {
throw new RiceIllegalArgumentException("routeLevel was null or blank");
}
return Collections.emptyList();
}
@Override
public List<KimAttributeField> getAttributeDefinitions(String kimTypeId) {
if (StringUtils.isBlank(kimTypeId)) {
throw new RiceIllegalArgumentException("kimTypeId was null or blank");
}
return Collections.emptyList();
}
@Override
public List<RemotableAttributeError> validateAttributes(String kimTypeId, Map<String, String> attributes) {
if (StringUtils.isBlank(kimTypeId)) {
throw new RiceIllegalArgumentException("kimTypeId was null or blank");
}
if (attributes == null) {
throw new RiceIllegalArgumentException("attributes was null or blank");
}
return Collections.emptyList();
}
@Override
public List<RemotableAttributeError> validateAttributesAgainstExisting(String kimTypeId, Map<String, String> newAttributes, Map<String, String> oldAttributes){
if (StringUtils.isBlank(kimTypeId)) {
throw new RiceIllegalArgumentException("kimTypeId was null or blank");
}
if (newAttributes == null) {
throw new RiceIllegalArgumentException("newAttributes was null or blank");
}
if (oldAttributes == null) {
throw new RiceIllegalArgumentException("oldAttributes was null or blank");
}
return Collections.emptyList();
}
@Override
public boolean doesRoleQualifierMatchQualification(Map<String, String> qualification, Map<String, String> roleQualifier) {
if (qualification == null) {
throw new RiceIllegalArgumentException("qualification was null");
}
if (roleQualifier == null) {
throw new RiceIllegalArgumentException("roleQualifier was null");
}
return true;
}
@Override
public List<RoleMembership> getMatchingRoleMemberships(Map<String, String> qualification,
List<RoleMembership> roleMemberList) {
if (qualification == null) {
throw new RiceIllegalArgumentException("qualification was null");
}
if (roleMemberList == null) {
throw new RiceIllegalArgumentException("roleMemberList was null");
}
return Collections.unmodifiableList(new ArrayList<RoleMembership>(roleMemberList));
}
@Override
public boolean isDerivedRoleType() {
return true;
}
@Override
public boolean hasDerivedRole(String principalId, List<String> groupIds, String namespaceCode, String roleName, Map<String, String> qualification) {
if (StringUtils.isBlank(principalId)) {
throw new RiceIllegalArgumentException("principalId was null or blank");
}
if (groupIds == null) {
throw new RiceIllegalArgumentException("groupIds was null or blank");
}
if (StringUtils.isBlank(namespaceCode)) {
throw new RiceIllegalArgumentException("namespaceCode was null or blank");
}
if (StringUtils.isBlank(roleName)) {
throw new RiceIllegalArgumentException("roleName was null or blank");
}
if (qualification == null) {
throw new RiceIllegalArgumentException("qualification was null");
}
return false;
}
@Override
public boolean dynamicRoleMembership(String namespaceCode, String roleName) {
if (StringUtils.isBlank(namespaceCode)) {
throw new RiceIllegalArgumentException("namespaceCode was null or blank");
}
if (StringUtils.isBlank(roleName)) {
throw new RiceIllegalArgumentException("roleName was null or blank");
}
return false;
}
}