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.kim.service.impl; 017 018import java.util.ArrayList; 019import java.util.Collections; 020import java.util.List; 021 022import org.apache.commons.lang.StringUtils; 023import org.kuali.rice.core.api.membership.MemberType; 024import org.kuali.rice.kim.api.KimConstants; 025import org.kuali.rice.kim.api.group.Group; 026import org.kuali.rice.kim.api.identity.affiliation.EntityAffiliation; 027import org.kuali.rice.kim.api.identity.email.EntityEmail; 028import org.kuali.rice.kim.api.identity.employment.EntityEmployment; 029import org.kuali.rice.kim.api.identity.entity.Entity; 030import org.kuali.rice.kim.api.identity.name.EntityName; 031import org.kuali.rice.kim.api.identity.phone.EntityPhone; 032import org.kuali.rice.kim.api.identity.principal.Principal; 033import org.kuali.rice.kim.api.identity.type.EntityTypeContactInfo; 034import org.kuali.rice.kim.api.role.Role; 035import org.kuali.rice.kim.bo.ui.PersonDocumentAffiliation; 036import org.kuali.rice.kim.bo.ui.PersonDocumentEmail; 037import org.kuali.rice.kim.bo.ui.PersonDocumentEmploymentInfo; 038import org.kuali.rice.kim.bo.ui.PersonDocumentName; 039import org.kuali.rice.kim.bo.ui.PersonDocumentPhone; 040import org.kuali.rice.kim.document.IdentityManagementPersonDocument; 041import org.kuali.rice.kim.impl.common.delegate.DelegateTypeBo; 042import org.kuali.rice.kim.impl.group.GroupBo; 043import org.kuali.rice.kim.impl.group.GroupMemberBo; 044import org.kuali.rice.kim.impl.identity.entity.EntityBo; 045import org.kuali.rice.kim.impl.identity.principal.PrincipalBo; 046import org.kuali.rice.kim.impl.role.RoleBo; 047import org.kuali.rice.kim.impl.role.RoleMemberAttributeDataBo; 048import org.kuali.rice.kim.impl.role.RoleMemberBo; 049import org.kuali.rice.kim.impl.role.RoleResponsibilityActionBo; 050import org.kuali.rice.kim.impl.services.KimImplServiceLocator; 051import org.kuali.rice.krad.document.Document; 052import org.kuali.rice.krad.util.KRADUtils; 053 054/** 055 * Customized version of the UiDocumentServiceImpl to support LDAP communcation 056 * 057 * @author Leo Przybylski (przybyls@arizona.edu) 058 */ 059public class LdapUiDocumentServiceImpl extends org.kuali.rice.kim.service.impl.UiDocumentServiceImpl { 060 061 /** 062 * 063 * @see org.kuali.rice.kim.service.UiDocumentService#loadEntityToPersonDoc(IdentityManagementPersonDocument, String) 064 */ 065 @Override 066 public void loadEntityToPersonDoc(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId) { 067 Principal principal = this.getIdentityService().getPrincipal(principalId); 068 if(principal==null) { 069 throw new RuntimeException("Principal does not exist for principal id:"+principalId); 070 } 071 072 identityManagementPersonDocument.setPrincipalId(principal.getPrincipalId()); 073 identityManagementPersonDocument.setPrincipalName(principal.getPrincipalName()); 074 //identityManagementPersonDocument.setPassword(principal.getPassword()); 075 identityManagementPersonDocument.setActive(principal.isActive()); 076 Entity kimEntity = this.getIdentityService().getEntity(principal.getEntityId()); 077 identityManagementPersonDocument.setEntityId(kimEntity.getId()); 078 if ( KRADUtils.isNotNull( kimEntity.getPrivacyPreferences() ) ) { 079 identityManagementPersonDocument.setPrivacy(loadPrivacyReferences(kimEntity.getPrivacyPreferences())); 080 } 081 //identityManagementPersonDocument.setActive(kimEntity.isActive()); 082 identityManagementPersonDocument.setAffiliations(loadAffiliations(kimEntity.getAffiliations(),kimEntity.getEmploymentInformation())); 083 identityManagementPersonDocument.setNames(loadNames( identityManagementPersonDocument, principalId, kimEntity.getNames(), identityManagementPersonDocument.getPrivacy().isSuppressName() )); 084 EntityTypeContactInfo entityType = null; 085 for (EntityTypeContactInfo type : kimEntity.getEntityTypeContactInfos()) { 086 if (KimConstants.EntityTypes.PERSON.equals(type.getEntityTypeCode())) { 087 entityType = EntityTypeContactInfo.Builder.create(type).build(); 088 } 089 } 090 091 if(entityType!=null){ 092 identityManagementPersonDocument.setEmails(loadEmails(identityManagementPersonDocument, principalId, entityType.getEmailAddresses(), identityManagementPersonDocument.getPrivacy().isSuppressEmail())); 093 identityManagementPersonDocument.setPhones(loadPhones(identityManagementPersonDocument, principalId, entityType.getPhoneNumbers(), identityManagementPersonDocument.getPrivacy().isSuppressPhone())); 094 identityManagementPersonDocument.setAddrs(loadAddresses(identityManagementPersonDocument, principalId, entityType.getAddresses(), identityManagementPersonDocument.getPrivacy().isSuppressAddress())); 095 } 096 097 List<Group> groups = getGroupService().getGroups(getGroupService().getDirectGroupIdsByPrincipalId( 098 identityManagementPersonDocument.getPrincipalId())); 099 loadGroupToPersonDoc(identityManagementPersonDocument, groups); 100 loadRoleToPersonDoc(identityManagementPersonDocument); 101 loadDelegationsToPersonDoc(identityManagementPersonDocument); 102 } 103 104 protected String getInitiatorPrincipalId(Document document){ 105 try{ 106 return document.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId(); 107 } catch(Exception ex){ 108 return null; 109 } 110 } 111 112 /** 113 * @see org.kuali.rice.kim.service.UiDocumentService#saveEntityPerson(IdentityManagementPersonDocument) 114 */ 115 @Override 116 public void saveEntityPerson(IdentityManagementPersonDocument identityManagementPersonDocument) { 117 boolean inactivatingPrincipal = false; 118 119 List <GroupMemberBo> groupPrincipals = populateGroupMembers(identityManagementPersonDocument); 120 List <RoleMemberBo> rolePrincipals = populateRoleMembers(identityManagementPersonDocument); 121 List <DelegateTypeBo> personDelegations = populateDelegations(identityManagementPersonDocument); 122 List <Object> bos = new ArrayList<Object>(); 123 List <RoleResponsibilityActionBo> roleRspActions = populateRoleRspActions(identityManagementPersonDocument); 124 List <RoleMemberAttributeDataBo> blankRoleMemberAttrs = getBlankRoleMemberAttrs(rolePrincipals); 125 //if(ObjectUtils.isNotNull(kimEntity.getPrivacyPreferences())) 126 // bos.add(kimEntity.getPrivacyPreferences()); 127 bos.addAll(groupPrincipals); 128 bos.addAll(rolePrincipals); 129 bos.addAll(roleRspActions); 130 bos.addAll(personDelegations); 131 // boservice.save(bos) does not handle deleteawarelist 132 for ( Object bo : bos ) { 133 getDataObjectService().save(bo); 134 } 135 136 for ( RoleMemberAttributeDataBo blankRoleMemberAttr : blankRoleMemberAttrs ) { 137 getDataObjectService().delete(blankRoleMemberAttr); 138 } 139 if ( inactivatingPrincipal ) { 140 //when a person is inactivated, inactivate their group, role, and delegation memberships 141 KimImplServiceLocator.getRoleInternalService().principalInactivated(identityManagementPersonDocument.getPrincipalId()); 142 } 143 } 144 145 @Override 146 protected boolean setupPrincipal(IdentityManagementPersonDocument identityManagementPersonDocument,EntityBo kimEntity, List<PrincipalBo> origPrincipals) { 147 boolean inactivatingPrincipal = false; 148 List<PrincipalBo> principals = new ArrayList<PrincipalBo>(); 149 Principal.Builder principal = Principal.Builder.create(identityManagementPersonDocument.getPrincipalName()); 150 principal.setPrincipalId(identityManagementPersonDocument.getPrincipalId()); 151 //principal.setPassword(identityManagementPersonDocument.getPassword()); 152 principal.setActive(identityManagementPersonDocument.isActive()); 153 principal.setEntityId(identityManagementPersonDocument.getEntityId()); 154 if(KRADUtils.isNotNull(origPrincipals)){ 155 for (PrincipalBo prncpl : origPrincipals) { 156 if (prncpl.getPrincipalId()!=null && StringUtils.equals(prncpl.getPrincipalId(), principal.getPrincipalId())) { 157 principal.setVersionNumber(prncpl.getVersionNumber()); 158 principal.setObjectId(prncpl.getObjectId()); 159 // check if inactivating the principal 160 if ( prncpl.isActive() && !principal.isActive() ) { 161 inactivatingPrincipal = true; 162 } 163 } 164 } 165 } 166 principals.add(PrincipalBo.from(principal.build())); 167 168 kimEntity.setPrincipals(principals); 169 return inactivatingPrincipal; 170 } 171 172 @Override 173 protected List<PersonDocumentAffiliation> loadAffiliations(List <EntityAffiliation> affiliations, List<EntityEmployment> empInfos) { 174 List<PersonDocumentAffiliation> docAffiliations = new ArrayList<PersonDocumentAffiliation>(); 175 if(KRADUtils.isNotNull(affiliations)){ 176 for (EntityAffiliation affiliation: affiliations) { 177 if(affiliation.isActive()){ 178 PersonDocumentAffiliation docAffiliation = new PersonDocumentAffiliation(); 179 docAffiliation.setAffiliationTypeCode(affiliation.getAffiliationType().getCode()); 180 docAffiliation.setCampusCode(affiliation.getCampusCode()); 181 docAffiliation.setActive(affiliation.isActive()); 182 docAffiliation.setDflt(affiliation.isDefaultValue()); 183 docAffiliation.setEntityAffiliationId(affiliation.getId()); 184 docAffiliation.refreshReferenceObject("affiliationType"); 185 // EntityAffiliationImpl does not define empinfos as collection 186 docAffiliations.add(docAffiliation); 187 docAffiliation.setEdit(true); 188 // employment informations 189 List<PersonDocumentEmploymentInfo> docEmploymentInformations = new ArrayList<PersonDocumentEmploymentInfo>(); 190 if(KRADUtils.isNotNull(empInfos)){ 191 for (EntityEmployment empInfo: empInfos) { 192 if (empInfo.isActive() 193 && StringUtils.equals(docAffiliation.getEntityAffiliationId(), 194 (empInfo.getEntityAffiliation() != null ? empInfo.getEntityAffiliation().getId() : null))) { 195 PersonDocumentEmploymentInfo docEmpInfo = new PersonDocumentEmploymentInfo(); 196 docEmpInfo.setEntityEmploymentId(empInfo.getEmployeeId()); 197 docEmpInfo.setEmployeeId(empInfo.getEmployeeId()); 198 docEmpInfo.setEmploymentRecordId(empInfo.getEmploymentRecordId()); 199 docEmpInfo.setBaseSalaryAmount(empInfo.getBaseSalaryAmount()); 200 docEmpInfo.setPrimaryDepartmentCode(empInfo.getPrimaryDepartmentCode()); 201 docEmpInfo.setEmploymentStatusCode(empInfo.getEmployeeStatus() != null ? empInfo.getEmployeeStatus().getCode() : null); 202 docEmpInfo.setEmploymentTypeCode(empInfo.getEmployeeType() != null ? empInfo.getEmployeeType().getCode() : null); 203 docEmpInfo.setActive(empInfo.isActive()); 204 docEmpInfo.setPrimary(empInfo.isPrimary()); 205 docEmpInfo.setEntityAffiliationId(empInfo.getEntityAffiliation() != null ? empInfo.getEntityAffiliation().getId() : null); 206 // there is no version number on KimEntityEmploymentInformationInfo 207 //docEmpInfo.setVersionNumber(empInfo.getVersionNumber()); 208 docEmpInfo.setEdit(true); 209 docEmpInfo.refreshReferenceObject("employmentType"); 210 docEmploymentInformations.add(docEmpInfo); 211 } 212 } 213 } 214 docAffiliation.setEmpInfos(docEmploymentInformations); 215 } 216 } 217 } 218 return docAffiliations; 219 220 } 221 222 223 @Override 224 protected List<PersonDocumentName> loadNames( IdentityManagementPersonDocument personDoc, String principalId, List <EntityName> names, boolean suppressDisplay ) { 225 List<PersonDocumentName> docNames = new ArrayList<PersonDocumentName>(); 226 if(KRADUtils.isNotNull(names)){ 227 for (EntityName name: names) { 228 if(name.isActive()){ 229 PersonDocumentName docName = new PersonDocumentName(); 230 if (name.getNameType() != null) { 231 docName.setNameCode(name.getNameType().getCode()); 232 } 233 234 //We do not need to check the privacy setting here - The UI should care of it 235 docName.setFirstName(name.getFirstNameUnmasked()); 236 docName.setLastName(name.getLastNameUnmasked()); 237 docName.setMiddleName(name.getMiddleNameUnmasked()); 238 docName.setNamePrefix(name.getNamePrefixUnmasked()); 239 docName.setNameSuffix(name.getNameSuffixUnmasked()); 240 241 docName.setActive(name.isActive()); 242 docName.setDflt(name.isDefaultValue()); 243 docName.setEdit(true); 244 docName.setEntityNameId(name.getId()); 245 docNames.add(docName); 246 } 247 } 248 } 249 return docNames; 250 } 251 252 @Override 253 protected List<PersonDocumentEmail> loadEmails(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId, List<EntityEmail> entityEmails, boolean suppressDisplay ) { 254 List<PersonDocumentEmail> emails = new ArrayList<PersonDocumentEmail>(); 255 if(KRADUtils.isNotNull(entityEmails)){ 256 for (EntityEmail email: entityEmails) { 257 if(email.isActive()){ 258 PersonDocumentEmail docEmail = new PersonDocumentEmail(); 259 //docEmail.setEntityId(email.getEntityId()); 260 docEmail.setEntityTypeCode(email.getEntityTypeCode()); 261 if (email.getEmailType() != null) { 262 docEmail.setEmailTypeCode(email.getEmailType().getCode()); 263 } 264 // EmailType not on info object. 265 //docEmail.setEmailType(((KimEntityEmailImpl)email).getEmailType()); 266 //We do not need to check the privacy setting here - The UI should care of it 267 docEmail.setEmailAddress(email.getEmailAddressUnmasked()); 268 269 docEmail.setActive(email.isActive()); 270 docEmail.setDflt(email.isDefaultValue()); 271 docEmail.setEntityEmailId(email.getId()); 272 docEmail.setEdit(true); 273 emails.add(docEmail); 274 } 275 } 276 } 277 return emails; 278 } 279 280 @Override 281 protected List<PersonDocumentPhone> loadPhones(IdentityManagementPersonDocument identityManagementPersonDocument, String principalId, List<EntityPhone> entityPhones, boolean suppressDisplay ) { 282 List<PersonDocumentPhone> docPhones = new ArrayList<PersonDocumentPhone>(); 283 if(KRADUtils.isNotNull(entityPhones)){ 284 for (EntityPhone phone: entityPhones) { 285 if(phone.isActive()){ 286 PersonDocumentPhone docPhone = new PersonDocumentPhone(); 287 if (phone.getPhoneType() != null) { 288 docPhone.setPhoneTypeCode(phone.getPhoneType().getCode()); 289 } 290 //docPhone.setPhoneType(((KimEntityPhoneImpl)phone).getPhoneType()); 291 docPhone.setEntityTypeCode(phone.getEntityTypeCode()); 292 //We do not need to check the privacy setting here - The UI should care of it 293 docPhone.setPhoneNumber(phone.getPhoneNumberUnmasked()); 294 docPhone.setCountryCode(phone.getCountryCodeUnmasked()); 295 docPhone.setExtensionNumber(phone.getExtensionNumberUnmasked()); 296 297 docPhone.setActive(phone.isActive()); 298 docPhone.setDflt(phone.isDefaultValue()); 299 docPhone.setEntityPhoneId(phone.getId()); 300 docPhone.setEdit(true); 301 docPhones.add(docPhone); 302 } 303 } 304 } 305 return docPhones; 306 307 } 308 309 public Object getMember(String memberTypeCode, String memberId){ 310 Class<? extends Object> roleMemberTypeClass = null; 311 if(MemberType.PRINCIPAL.getCode().equals(memberTypeCode)){ 312 roleMemberTypeClass = PrincipalBo.class; 313 Principal principalInfo = getIdentityService().getPrincipal(memberId); 314 if (principalInfo != null) { 315 316 } 317 } else if(MemberType.GROUP.getCode().equals(memberTypeCode)){ 318 roleMemberTypeClass = GroupBo.class; 319 Group groupInfo = null; 320 groupInfo = getGroupService().getGroup(memberId); 321 if (groupInfo != null) { 322 323 } 324 } else if(MemberType.ROLE.getCode().equals(memberTypeCode)){ 325 roleMemberTypeClass = RoleBo.class; 326 Role role = getRoleService().getRole(memberId); 327 if (role != null) { 328 329 } 330 } 331 return getDataObjectService().find(roleMemberTypeClass, memberId); 332 } 333 334 /** 335 * Overridden to only check permission - users should not be able to edit themselves. 336 * 337 * @see org.kuali.rice.kim.service.impl.UiDocumentServiceImpl#canModifyEntity(java.lang.String, java.lang.String) 338 */ 339 @Override 340 public boolean canModifyEntity( String currentUserPrincipalId, String toModifyPrincipalId ){ 341 return (StringUtils.isNotBlank(currentUserPrincipalId) && StringUtils.isNotBlank(toModifyPrincipalId) && 342 currentUserPrincipalId.equals(toModifyPrincipalId)) || 343 getPermissionService().isAuthorized( 344 currentUserPrincipalId, 345 KimConstants.NAMESPACE_CODE, 346 KimConstants.PermissionNames.MODIFY_ENTITY, 347 Collections.singletonMap(KimConstants.AttributeConstants.PRINCIPAL_ID, currentUserPrincipalId)); 348 } 349 350// @Override 351// protected List<RoleMemberBo> updateRoleMembers(IdentityManagementRoleDocument identityManagementRoleDocument, List<RoleMemberBo> origRoleMembers){ 352// List<RoleMemberBo> roleMembers = new ArrayList<RoleMemberBo>(); 353// RoleMemberBo newRoleMember; 354// RoleMemberBo origRoleMemberImplTemp; 355// List<RoleMemberAttributeDataBo> origAttributes; 356// boolean activatingInactive = false; 357// String newRoleMemberIdAssigned = ""; 358// 359// identityManagementRoleDocument.setKimType(KimApiServiceLocator.getKimTypeInfoService().getKimType(identityManagementRoleDocument.getRoleTypeId())); 360// KimTypeService kimTypeService = KimFrameworkServiceLocator.getKimTypeService(identityManagementRoleDocument.getKimType()); 361// 362// if(CollectionUtils.isNotEmpty(identityManagementRoleDocument.getMembers())){ 363// for(KimDocumentRoleMember documentRoleMember: identityManagementRoleDocument.getMembers()){ 364// origRoleMemberImplTemp = null; 365// 366// newRoleMember = new RoleMemberBo(); 367// KimCommonUtilsInternal.copyProperties(newRoleMember, documentRoleMember); 368// newRoleMember.setRoleId(identityManagementRoleDocument.getRoleId()); 369// if(KRADUtils.isNotNull(origRoleMembers)){ 370// for(RoleMemberBo origRoleMemberImpl: origRoleMembers){ 371// if((origRoleMemberImpl.getRoleId()!=null && StringUtils.equals(origRoleMemberImpl.getRoleId(), newRoleMember.getRoleId())) && 372// (origRoleMemberImpl.getMemberId()!=null && StringUtils.equals(origRoleMemberImpl.getMemberId(), newRoleMember.getMemberId())) && 373// (origRoleMemberImpl.getType()!=null && org.apache.commons.lang.ObjectUtils.equals(origRoleMemberImpl.getType(), newRoleMember.getType())) && 374// !origRoleMemberImpl.isActive(new Timestamp(System.currentTimeMillis())) && 375// !kimTypeService.validateUniqueAttributes(identityManagementRoleDocument.getKimType().getId(), 376// documentRoleMember.getQualifierAsMap(), origRoleMemberImpl.getAttributes()).isEmpty()) { 377// 378// //TODO: verify if you want to add && newRoleMember.isActive() condition to if... 379// 380// newRoleMemberIdAssigned = newRoleMember.getId(); 381// newRoleMember.setId(origRoleMemberImpl.getId()); 382// activatingInactive = true; 383// } 384// if(origRoleMemberImpl.getId()!=null && StringUtils.equals(origRoleMemberImpl.getId(), newRoleMember.getId())){ 385// newRoleMember.setVersionNumber(origRoleMemberImpl.getVersionNumber()); 386// origRoleMemberImplTemp = origRoleMemberImpl; 387// } 388// } 389// } 390// origAttributes = (origRoleMemberImplTemp==null || origRoleMemberImplTemp.getAttributes()==null)? 391// new ArrayList<RoleMemberAttributeDataBo>():origRoleMemberImplTemp.getAttributeDetails(); 392// newRoleMember.setActiveFromDateValue(documentRoleMember.getActiveFromDate()); 393// newRoleMember.setActiveToDateValue(documentRoleMember.getActiveToDate()); 394// newRoleMember.setAttributeDetails(getRoleMemberAttributeData(documentRoleMember.getQualifiers(), origAttributes, activatingInactive, newRoleMemberIdAssigned)); 395// newRoleMember.setRoleRspActions(getRoleMemberResponsibilityActions(documentRoleMember, origRoleMemberImplTemp, activatingInactive, newRoleMemberIdAssigned)); 396// roleMembers.add(newRoleMember); 397// activatingInactive = false; 398// } 399// } 400// return roleMembers; 401// } 402}