blob: 321ec6358ae507a0b99ad42d641569e05188ec5b [file] [log] [blame]
package org.eclipse.openk.contactbasedata.service;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.eclipse.openk.contactbasedata.exceptions.NotFoundException;
import org.eclipse.openk.contactbasedata.model.RefCommunicationType;
import org.eclipse.openk.contactbasedata.model.TblCommunication;
import org.eclipse.openk.contactbasedata.model.TblInternalPerson;
import org.eclipse.openk.contactbasedata.repository.CommunicationRepository;
import org.eclipse.openk.contactbasedata.repository.CommunicationTypeRepository;
import org.eclipse.openk.contactbasedata.repository.InternalPersonRepository;
import org.eclipse.openk.contactbasedata.service.util.LdapUserAttributesMapper;
import org.eclipse.openk.contactbasedata.viewmodel.LdapUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.springframework.ldap.query.LdapQueryBuilder.query;
@Log4j2
@Service
public class LdapService {
@Value("${authnauth-sync.scheduling.enabled}")
private Boolean ldapEnabled;
@Value("${ldap-sync.attribute-mapping.uid}")
private String uid;
@Value("${ldap-sync.db-id-mapping.telephone-number-id}")
private Long telephoneNumberId;
@Value("${ldap-sync.db-id-mapping.mail-id}")
private Long mailId;
@Autowired
LdapUserAttributesMapper ldapUserAttributesMapper;
@Autowired
private InternalPersonRepository internalPersonRepository;
@Autowired
private LdapTemplate ldapTemplate;
@Autowired
private CommunicationTypeRepository communicationTypeRepository;
@Autowired
CommunicationRepository communicationRepository;
/**
* Retrieves all the LdapUsers in the ldap server, using {@link LdapUserAttributesMapper}
* @return list of LdapUsers
*/
public List<LdapUser> getAllLdapUsers() {
return ldapEnabled.booleanValue()
? ldapTemplate.search(query().where("objectclass").is("person"), ldapUserAttributesMapper)
: new ArrayList<>();
}
/**
* Retrieves the distinct the LdapUsers from the ldap server, using {@link LdapUserAttributesMapper}
* @return ldapUsers
*/
public List<LdapUser> getLdapUserByUID(String uid) {
return ldapTemplate.search(query()
.where("objectclass").is("person").and(this.uid).is(uid), ldapUserAttributesMapper);
}
@Transactional
public void synchronizeLDAP() {
List<TblInternalPerson> internalPersonList = internalPersonRepository.findByUidNotNull();
Map<String, TblInternalPerson> uidToInternalPersonMap = internalPersonList.stream().collect(
Collectors.toMap(TblInternalPerson::getUid, Function.identity()));
List<LdapUser> allFoundLdapUsers = new ArrayList<>();
List<TblInternalPerson> allNotExistingLdapUsers = new ArrayList<>();
findExistingAndNotExistingLdapUsers(internalPersonList, allFoundLdapUsers, allNotExistingLdapUsers);
List<TblInternalPerson> internalPersonListSynchronized = new ArrayList<>();
RefCommunicationType refCommunicationTypeMail = getRefCommunicationType(mailId);
RefCommunicationType refCommunicationTypePhone = getRefCommunicationType(telephoneNumberId);
for (LdapUser ldapUser : allFoundLdapUsers) {
TblInternalPerson tblInternalPerson = uidToInternalPersonMap.get(ldapUser.getUid());
if (tblInternalPerson == null) continue;
boolean attributesChanged = mapLdapUserToInternaPerson(tblInternalPerson, ldapUser, refCommunicationTypeMail, refCommunicationTypePhone);
if (attributesChanged) {
internalPersonListSynchronized.add(tblInternalPerson);
}
}
//Update all not found users notes with the sync error message
internalPersonRepository.saveAll(allNotExistingLdapUsers);
//Update all found Users with the synchronized LDAP data
internalPersonRepository.saveAll(internalPersonListSynchronized);
log.info("Synchronization changed data of: " + internalPersonListSynchronized.size() + " internal user/s");
log.info("Attribute/s of the following internal user/s were updated:");
for (TblInternalPerson tblInternalPerson : internalPersonListSynchronized) {
log.info("Id: " + tblInternalPerson.getId() + " Firstname: " + tblInternalPerson.getFirstName() + " Lastname: " + tblInternalPerson.getLastName());
}
}
private RefCommunicationType getRefCommunicationType(Long refCommunicationTypeId) {
return communicationTypeRepository.findAll().stream()
.filter(x -> x.getId().equals(refCommunicationTypeId))
.findFirst()
.orElseThrow(NotFoundException::new);
}
private void findExistingAndNotExistingLdapUsers(List<TblInternalPerson> internalPersonList, List<LdapUser> allFoundLdapUsers, List<TblInternalPerson> allNotExistingLdapUsers) {
for (TblInternalPerson tblInternalPerson : internalPersonList) {
String uidTblInternalPerson = tblInternalPerson.getUid();
List<LdapUser> ldapUserByUIDResult = getLdapUserByUID(uidTblInternalPerson);
if(ldapUserByUIDResult.isEmpty()){
String errorMsg = String.format("[LDAP Sync Error] User with Uid: [ %s ] can not be found in LDAP", uidTblInternalPerson);
setNoteAndLogSyncError(allNotExistingLdapUsers, tblInternalPerson, errorMsg);
}
else if(ldapUserByUIDResult.size() > 1){
String errorMsg = String.format("[LDAP Sync Error] More than one result for UID: [ %s ] in LDAP", uidTblInternalPerson);
setNoteAndLogSyncError(allNotExistingLdapUsers, tblInternalPerson, errorMsg);
}
else {
LdapUser ldapUser = ldapUserByUIDResult.get(0);
allFoundLdapUsers.add(ldapUser);
}
}
}
private void setNoteAndLogSyncError(List<TblInternalPerson> allNotExistingLdapUsers, TblInternalPerson tblInternalPerson, String errorMsg) {
log.error(errorMsg);
String note = tblInternalPerson.getContact().getNote();
if (note == null) note = "";
if (!note.contains(errorMsg)) {
note = note + System.lineSeparator() + errorMsg;
tblInternalPerson.getContact().setNote(note);
allNotExistingLdapUsers.add(tblInternalPerson);
}
}
private boolean mapLdapUserToInternaPerson(TblInternalPerson tblInternalPerson, LdapUser ldapUser, RefCommunicationType refCommunicationTypeMail, RefCommunicationType refCommunicationTypePhone) {
boolean attributesChanged = false;
attributesChanged = isCommunicationDataChangedAndSync(tblInternalPerson, ldapUser.getMail(), refCommunicationTypeMail, attributesChanged, mailId);
attributesChanged = isCommunicationDataChangedAndSync(tblInternalPerson, ldapUser.getTelephoneNumber(), refCommunicationTypePhone, attributesChanged, telephoneNumberId);
if (!Objects.equals(tblInternalPerson.getFirstName(), ldapUser.getFirstName())
|| !Objects.equals(tblInternalPerson.getLastName(), ldapUser.getLastName())
|| !Objects.equals(tblInternalPerson.getTitle(), ldapUser.getTitle())
|| !Objects.equals(tblInternalPerson.getDepartment(), ldapUser.getDepartment())) {
attributesChanged = true;
tblInternalPerson.setFirstName(ldapUser.getFirstName());
tblInternalPerson.setLastName(ldapUser.getLastName());
tblInternalPerson.setTitle(ldapUser.getTitle());
tblInternalPerson.setDepartment(ldapUser.getDepartment());
}
return attributesChanged;
}
private boolean isCommunicationDataChangedAndSync(TblInternalPerson tblInternalPerson, String communicationdata, RefCommunicationType refCommunicationType, boolean attributesChanged, Long communicationTypeId) {
List<TblCommunication> tblCommunicationList = tblInternalPerson.getContact().getCommunications();
Optional<TblCommunication> optionalTblCommunication = tblCommunicationList.stream()
.filter(tblCommunication -> tblCommunication.getRefCommunicationType().getId().equals(communicationTypeId))
.findFirst();
if (optionalTblCommunication.isPresent()) {
if (!Objects.equals(optionalTblCommunication.get().getCommunicationData(), communicationdata)){
optionalTblCommunication.get().setCommunicationData(communicationdata);
attributesChanged = true;
}
} else {
attributesChanged = createAndSaveNewTblCommunication(tblInternalPerson, communicationdata, refCommunicationType, attributesChanged);
}
return attributesChanged;
}
private boolean createAndSaveNewTblCommunication(TblInternalPerson tblInternalPerson, String communicationData, RefCommunicationType refCommunicationType, boolean attributesChanged) {
if (StringUtils.isEmpty(communicationData)) return attributesChanged;
TblCommunication tblCommunication = new TblCommunication();
tblCommunication.setUuid(UUID.randomUUID());
tblCommunication.setTblContact(tblInternalPerson.getContact());
tblCommunication.setRefCommunicationType(refCommunicationType);
tblCommunication.setCommunicationData(communicationData);
communicationRepository.save(tblCommunication);
tblInternalPerson.getContact().getCommunications().add(tblCommunication);
return true;
}
}