001 /* 002 * Copyright 2011 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.kfs.sec.document; 017 018 import java.util.Iterator; 019 import java.util.Map; 020 021 import org.apache.commons.lang.StringUtils; 022 import org.kuali.kfs.sec.SecConstants; 023 import org.kuali.kfs.sec.businessobject.SecurityDefinition; 024 import org.kuali.kfs.sec.businessobject.SecurityModelMember; 025 import org.kuali.kfs.sec.businessobject.SecurityPrincipal; 026 import org.kuali.kfs.sec.businessobject.SecurityPrincipalDefinition; 027 import org.kuali.kfs.sec.identity.SecKimAttributes; 028 import org.kuali.kfs.sec.util.KimUtil; 029 import org.kuali.kfs.sys.context.SpringContext; 030 import org.kuali.kfs.sys.document.FinancialSystemMaintainable; 031 import org.kuali.rice.kew.exception.WorkflowException; 032 import org.kuali.rice.kim.bo.role.dto.KimRoleInfo; 033 import org.kuali.rice.kim.bo.role.dto.RoleMembershipInfo; 034 import org.kuali.rice.kim.bo.types.dto.AttributeSet; 035 import org.kuali.rice.kim.service.IdentityManagementService; 036 import org.kuali.rice.kim.service.RoleManagementService; 037 import org.kuali.rice.kim.util.KimConstants; 038 import org.kuali.rice.kns.bo.DocumentHeader; 039 import org.kuali.rice.kns.bo.PersistableBusinessObject; 040 import org.kuali.rice.kns.document.MaintenanceDocument; 041 import org.kuali.rice.kns.service.DocumentService; 042 import org.kuali.rice.kns.util.KNSConstants; 043 044 045 /** 046 * Maintainable implementation for the Security Principal maintenance document. Hooks into Post processing to create the KIM permissions for the principal and assign security role 047 * members 048 */ 049 public class SecurityPrincipalMaintainableImpl extends FinancialSystemMaintainable { 050 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SecurityPrincipalMaintainableImpl.class); 051 052 /** 053 * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#refresh(java.lang.String, java.util.Map, org.kuali.rice.kns.document.MaintenanceDocument) 054 */ 055 @Override 056 public void refresh(String refreshCaller, Map fieldValues, MaintenanceDocument document) { 057 super.refresh(refreshCaller, fieldValues, document); 058 059 this.getBusinessObject().refreshNonUpdateableReferences(); 060 for (Iterator iterator = newCollectionLines.values().iterator(); iterator.hasNext();) { 061 PersistableBusinessObject businessObject = (PersistableBusinessObject) iterator.next(); 062 businessObject.refreshNonUpdateableReferences(); 063 } 064 } 065 066 /** 067 * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#doRouteStatusChange(org.kuali.rice.kns.bo.DocumentHeader) 068 */ 069 @Override 070 public void doRouteStatusChange(DocumentHeader documentHeader) { 071 super.doRouteStatusChange(documentHeader); 072 073 if (documentHeader.getWorkflowDocument().stateIsProcessed()) { 074 DocumentService documentService = SpringContext.getBean(DocumentService.class); 075 try { 076 MaintenanceDocument document = (MaintenanceDocument) documentService.getByDocumentHeaderId(documentHeader.getDocumentNumber()); 077 SecurityPrincipal oldSecurityPrincipal = (SecurityPrincipal) document.getOldMaintainableObject().getBusinessObject(); 078 SecurityPrincipal newSecurityPrincipal = (SecurityPrincipal) document.getNewMaintainableObject().getBusinessObject(); 079 080 boolean newMaintenanceAction = getMaintenanceAction().equalsIgnoreCase(KNSConstants.MAINTENANCE_NEW_ACTION) || getMaintenanceAction().equalsIgnoreCase(KNSConstants.MAINTENANCE_COPY_ACTION); 081 082 assignOrUpdatePrincipalMembershipToDefinitionRoles(oldSecurityPrincipal, newSecurityPrincipal, newMaintenanceAction); 083 assignOrUpdatePrincipalModelRoles(newSecurityPrincipal); 084 085 SpringContext.getBean(IdentityManagementService.class).flushAllCaches(); 086 } 087 catch (WorkflowException e) { 088 LOG.error("caught exception while handling handleRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e); 089 throw new RuntimeException("caught exception while handling handleRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e); 090 } 091 } 092 } 093 094 /** 095 * Iterates through the principal definition list and assigns the principal to the definition role if necessary or updates the current member assignment 096 * 097 * @param oldSecurityPrincipal SecurityPrincipal before updates 098 * @param newSecurityPrincipal SecurityPrincipal which contains the definition list and principal 099 * @param newMaintenanceAction boolean indicating whether this is a new record (old side will not contain data) 100 */ 101 protected void assignOrUpdatePrincipalMembershipToDefinitionRoles(SecurityPrincipal oldSecurityPrincipal, SecurityPrincipal newSecurityPrincipal, boolean newMaintenanceAction) { 102 RoleManagementService roleService = SpringContext.getBean(RoleManagementService.class); 103 104 String principalId = newSecurityPrincipal.getPrincipalId(); 105 106 for (SecurityPrincipalDefinition securityPrincipalDefinition : newSecurityPrincipal.getPrincipalDefinitions()) { 107 SecurityDefinition securityDefinition = securityPrincipalDefinition.getSecurityDefinition(); 108 109 KimRoleInfo definitionRoleInfo = roleService.getRole(securityDefinition.getRoleId()); 110 111 RoleMembershipInfo principalMembershipInfo = null; 112 if (!newMaintenanceAction) { 113 SecurityPrincipalDefinition oldPrincipalDefinition = null; 114 for (SecurityPrincipalDefinition principalDefinition : oldSecurityPrincipal.getPrincipalDefinitions()) { 115 if ((principalDefinition.getPrincipalDefinitionId() != null) && principalDefinition.getPrincipalDefinitionId().equals(securityPrincipalDefinition.getPrincipalDefinitionId())) { 116 oldPrincipalDefinition = principalDefinition; 117 } 118 } 119 120 if (oldPrincipalDefinition != null) { 121 AttributeSet membershipQualifications = new AttributeSet(); 122 membershipQualifications.put(SecKimAttributes.CONSTRAINT_CODE, oldPrincipalDefinition.getConstraintCode()); 123 membershipQualifications.put(SecKimAttributes.OPERATOR, oldPrincipalDefinition.getOperatorCode()); 124 membershipQualifications.put(SecKimAttributes.PROPERTY_VALUE, oldPrincipalDefinition.getAttributeValue()); 125 membershipQualifications.put(SecKimAttributes.OVERRIDE_DENY, Boolean.toString(oldPrincipalDefinition.isOverrideDeny())); 126 127 principalMembershipInfo = KimUtil.getRoleMembershipInfoForMemberType(definitionRoleInfo.getRoleId(), principalId, KimConstants.KimUIConstants.MEMBER_TYPE_PRINCIPAL_CODE, membershipQualifications); 128 } 129 } 130 131 // only create membership if principal definition record is active 132 boolean membershipActive = securityPrincipalDefinition.isActive(); 133 134 // if membership already exists, need to remove if the principal record is now inactive or the qualifications need updated 135 String principalMembershipId = ""; 136 if (principalMembershipInfo != null) { 137 principalMembershipId = principalMembershipInfo.getRoleMemberId(); 138 boolean qualificationsMatch = KimUtil.doMembershipQualificationsMatchValues(principalMembershipInfo.getQualifier(), securityPrincipalDefinition.getConstraintCode(), securityPrincipalDefinition.getOperatorCode(), securityPrincipalDefinition.getAttributeValue()); 139 if (!membershipActive || !qualificationsMatch) { 140 roleService.removeRoleFromRole(principalMembershipInfo.getMemberId(), definitionRoleInfo.getNamespaceCode(), definitionRoleInfo.getRoleName(), principalMembershipInfo.getQualifier()); 141 } 142 } 143 144 // create of update role if membership should be active 145 if (membershipActive) { 146 AttributeSet membershipQualifications = new AttributeSet(); 147 membershipQualifications.put(SecKimAttributes.CONSTRAINT_CODE, securityPrincipalDefinition.getConstraintCode()); 148 membershipQualifications.put(SecKimAttributes.OPERATOR, securityPrincipalDefinition.getOperatorCode()); 149 membershipQualifications.put(SecKimAttributes.PROPERTY_VALUE, securityPrincipalDefinition.getAttributeValue()); 150 membershipQualifications.put(SecKimAttributes.OVERRIDE_DENY, Boolean.toString(securityPrincipalDefinition.isOverrideDeny())); 151 152 roleService.saveRoleMemberForRole(principalMembershipId, principalId, KimConstants.KimUIConstants.MEMBER_TYPE_PRINCIPAL_CODE, definitionRoleInfo.getRoleId(), membershipQualifications, null, null); 153 } 154 } 155 } 156 157 /** 158 * Iterates through the principal model list and assigns the principal to the model role or updates the membership 159 * 160 * @param securityPrincipal SecurityPrincipal which contains the model list and principal 161 */ 162 protected void assignOrUpdatePrincipalModelRoles(SecurityPrincipal securityPrincipal) { 163 RoleManagementService roleService = SpringContext.getBean(RoleManagementService.class); 164 165 String principalId = securityPrincipal.getPrincipalId(); 166 167 for (SecurityModelMember principalModel : securityPrincipal.getPrincipalModels()) { 168 KimRoleInfo modelRoleInfo = roleService.getRole(principalModel.getSecurityModel().getRoleId()); 169 170 RoleMembershipInfo membershipInfo = KimUtil.getRoleMembershipInfoForMemberType(modelRoleInfo.getRoleId(), principalId, KimConstants.KimUIConstants.MEMBER_TYPE_PRINCIPAL_CODE, null); 171 172 String membershipId = ""; 173 if (membershipInfo != null) { 174 membershipId = membershipInfo.getRoleMemberId(); 175 } 176 177 java.sql.Date fromDate = null; 178 java.sql.Date toDate = null; 179 if ( principalModel.getActiveFromDate() != null ) { 180 fromDate = new java.sql.Date( principalModel.getActiveFromDate().getTime() ); 181 } 182 if ( principalModel.getActiveToDate() != null ) { 183 toDate = new java.sql.Date( principalModel.getActiveToDate().getTime() ); 184 } 185 roleService.saveRoleMemberForRole(membershipId, principalId, KimConstants.KimUIConstants.MEMBER_TYPE_PRINCIPAL_CODE, modelRoleInfo.getRoleId(), new AttributeSet(), fromDate, toDate); 186 } 187 } 188 189 }