KON-13 KON-533 Anonymisieren eines Kontaktes KON-532 Tabelle um anonymisiert-Flag erweitern
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/constants/Constants.java b/src/main/java/org/eclipse/openk/contactbasedata/constants/Constants.java index c62049a..02c7d4e 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/constants/Constants.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/constants/Constants.java
@@ -19,6 +19,8 @@ public static final String ADDRESS_TYPE_UUID_NOT_EXISTING = "addressType.uuid.not.existing"; public static final String CONTACT_UUID_NOT_EXISTING = "contact.uuid.not.existing"; public static final String MODULE_ASSIGNMENT_UUID_NOT_EXISTING = "module.assignment.uuid.not.existing"; + public static final String ANONYMOUS_TAG = "***"; + public static final String ADDRESS_UUID_NOT_EXISTING = "address.uuid.not.existing"; private Constants() { // empty Constructor for the sake of SONAR
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/controller/ContactController.java b/src/main/java/org/eclipse/openk/contactbasedata/controller/ContactController.java index 2770869..d6320be 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/controller/ContactController.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/controller/ContactController.java
@@ -19,6 +19,7 @@ import io.swagger.annotations.ApiResponses; import lombok.extern.log4j.Log4j2; import org.eclipse.openk.contactbasedata.model.VwDetailedContact; +import org.eclipse.openk.contactbasedata.service.ContactAnonymizerService; import org.eclipse.openk.contactbasedata.service.ContactService; import org.eclipse.openk.contactbasedata.service.util.SearchContactsFilterParams; import org.springframework.beans.factory.annotation.Autowired; @@ -26,6 +27,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; @@ -41,6 +43,9 @@ @Autowired private ContactService contactService; + @Autowired + private ContactAnonymizerService contactAnonymizerService; + @ApiOperation(value = "Anzeigen aller gespeicherter Kontakte") @ApiResponses(value = {@ApiResponse(code = 200, message = "Erfolgreich durchgeführt")}) @ResponseStatus(HttpStatus.OK) @@ -71,4 +76,17 @@ filter, pageable); } + @ApiOperation(value = "Anonymisieren eines Kontaktes") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Kontakt wurde anonymisiert"), + @ApiResponse(code = 404, message = "Nicht gefunden")}) + @ResponseStatus(HttpStatus.OK) + @Secured({"ROLE_KON-WRITER", "ROLE_KON-ADMIN"}) + @PutMapping("/{contactUuid}/anonymize") + public ResponseEntity anonymizeContact( + @PathVariable("contactUuid") String contactUuid) { + + contactAnonymizerService.anonymize(UUID.fromString(contactUuid)); + return ResponseEntity.ok().build(); + } }
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/exceptions/InternalServerErrorException.java b/src/main/java/org/eclipse/openk/contactbasedata/exceptions/InternalServerErrorException.java new file mode 100644 index 0000000..7e8101f --- /dev/null +++ b/src/main/java/org/eclipse/openk/contactbasedata/exceptions/InternalServerErrorException.java
@@ -0,0 +1,29 @@ +/* + ******************************************************************************* + * Copyright (c) 2019 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ******************************************************************************* + */ +package org.eclipse.openk.contactbasedata.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR) +public class InternalServerErrorException extends RuntimeException{ + + public InternalServerErrorException() { + } + + public InternalServerErrorException(String message) { + super(message); + } +}
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/repository/DetailedContactRepository.java b/src/main/java/org/eclipse/openk/contactbasedata/repository/DetailedContactRepository.java index f0ab807..ba554e0 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/repository/DetailedContactRepository.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/repository/DetailedContactRepository.java
@@ -41,7 +41,7 @@ + " and (COALESCE(:filterDelLockExceeded) = false or COALESCE(:filterDelLockExceeded) = true and dc.fkContactId in " + " (select distinct amc.tblContact.id from TblAssignmentModulContact amc where " + " amc.deletionLockUntil is not null and amc.deletionLockUntil < :dateTimeNow ))" - + " and (COALESCE(:showAnonymized) = false or COALESCE(:showAnonymized) = true and dc.anonymized = true)" + + " and (COALESCE(:showAnonymized) = false and COALESCE(dc.anonymized, false) = false or COALESCE(:showAnonymized) = true and dc.anonymized = true)" ) Page<VwDetailedContact> findByFilter(@Param("contactType")String contactType, // NOSONAR _fd 07.02.2020 moving to a param object will not increase the readability here! @Param("personType") UUID personType,
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/AddressService.java b/src/main/java/org/eclipse/openk/contactbasedata/service/AddressService.java index 54790a6..f06ce72 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/service/AddressService.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/service/AddressService.java
@@ -15,6 +15,7 @@ package org.eclipse.openk.contactbasedata.service; import lombok.extern.log4j.Log4j2; +import org.eclipse.openk.contactbasedata.constants.Constants; import org.eclipse.openk.contactbasedata.enums.OperationType; import org.eclipse.openk.contactbasedata.exceptions.BadRequestException; import org.eclipse.openk.contactbasedata.exceptions.NotFoundException; @@ -29,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + import java.util.List; import java.util.UUID; import java.util.stream.Collectors; @@ -59,7 +61,7 @@ public AddressDto getAddress(UUID contactUuid, UUID addressUuid){ TblAddress tblAddress = addressRepository.findByUuid(addressUuid) - .orElseThrow( () -> new NotFoundException("address.uuid.not.existing")); + .orElseThrow( () -> new NotFoundException(Constants.ADDRESS_UUID_NOT_EXISTING)); if(!tblAddress.getTblContact().getUuid().equals(contactUuid)) { throw new BadRequestException("invalid.uuid.path.object"); } @@ -71,7 +73,7 @@ TblContact tblContact = contactRepository .findByUuid(contactUuid) - .orElseThrow(() -> new NotFoundException("contact.uuid.not.existing")); + .orElseThrow(() -> new NotFoundException(Constants.CONTACT_UUID_NOT_EXISTING)); TblAddress addressToSave = addressMapper.toTblAddress(addressDto); addressToSave.setUuid(UUID.randomUUID()); @@ -91,10 +93,10 @@ public AddressDto updateAddress(UUID contactUuid, AddressDto addressDto) { TblContact contact = contactRepository.findByUuid(contactUuid) - .orElseThrow(() -> new NotFoundException("contact.uuid.not.existing")); + .orElseThrow(() -> new NotFoundException(Constants.CONTACT_UUID_NOT_EXISTING)); TblAddress address = addressRepository.findByUuid(addressDto.getUuid()) - .orElseThrow(() -> new NotFoundException("address.uuid.not.existing")); + .orElseThrow(() -> new NotFoundException(Constants.ADDRESS_UUID_NOT_EXISTING)); TblAddress addressToSave = addressMapper.toTblAddress(addressDto); addressToSave.setTblContact(contact); @@ -109,13 +111,12 @@ return addressMapper.toAddressDto(savedAddress); } - @Transactional public void deleteAddress(UUID contactUuid, UUID addressUuid) { TblContact tblContact = contactRepository.findByUuid(contactUuid) - .orElseThrow(() -> new NotFoundException("contact.uuid.not.existing")); + .orElseThrow(() -> new NotFoundException(Constants.CONTACT_UUID_NOT_EXISTING)); TblAddress tblAddress = addressRepository.findByTblContactAndUuid(tblContact, addressUuid) - .orElseThrow(() -> new NotFoundException("address.uuid.not.existing")); + .orElseThrow(() -> new NotFoundException(Constants.ADDRESS_UUID_NOT_EXISTING)); addressRepository.delete(tblAddress); }
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/CommunicationTypeService.java b/src/main/java/org/eclipse/openk/contactbasedata/service/CommunicationTypeService.java index b1f9730..e38a7b6 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/service/CommunicationTypeService.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/service/CommunicationTypeService.java
@@ -17,11 +17,13 @@ import lombok.extern.log4j.Log4j2; import org.eclipse.openk.contactbasedata.exceptions.NotFoundException; import org.eclipse.openk.contactbasedata.mapper.CommunicationTypeMapper; -import org.eclipse.openk.contactbasedata.model.*; -import org.eclipse.openk.contactbasedata.repository.*; +import org.eclipse.openk.contactbasedata.model.RefCommunicationType; +import org.eclipse.openk.contactbasedata.repository.CommunicationTypeRepository; import org.eclipse.openk.contactbasedata.viewmodel.CommunicationTypeDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + import java.util.List; import java.util.UUID; import java.util.stream.Collectors; @@ -48,6 +50,7 @@ .collect(Collectors.toList()); } + @Transactional public CommunicationTypeDto insertCommunicationType(CommunicationTypeDto communicationTypeDto) { RefCommunicationType communicationTypeToSave = communicationTypeMapper.toRefCommunicationType(communicationTypeDto); @@ -58,7 +61,7 @@ return communicationTypeMapper.toCommunicationTypeDto(savedCommunicationType); } - + @Transactional public CommunicationTypeDto updateCommunicationType(CommunicationTypeDto communicationTypeDto){ RefCommunicationType communicationTypeUpdated; @@ -74,7 +77,7 @@ return communicationTypeMapper.toCommunicationTypeDto(communicationTypeUpdated); } - + @Transactional public void removeCommunicationType(UUID uuid) { RefCommunicationType existingCommunicationType = communicationTypeRepository.findByUuid(uuid) .orElseThrow( () -> new NotFoundException("communication.type.uuid.not.existing"));
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/CompanyService.java b/src/main/java/org/eclipse/openk/contactbasedata/service/CompanyService.java index 9957faf..3f8ab69 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/service/CompanyService.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/service/CompanyService.java
@@ -134,14 +134,15 @@ // TODO: Move to Mapper TblCommunication tblComm = cpMap.get(dto.getContactUuid()).getContact() .getCommunications().stream() - .filter(comm -> comm.getRefCommunicationType().getId() == 1L) + .filter(comm -> comm.getRefCommunicationType().isTypeEmail()) .findFirst().orElse(null); -// TODO: exchange constant 1L with DB-Solution + dto.setEmail( tblComm == null ? "" : tblComm.getCommunicationData() ); } private void setFromCompanyDto( TblCompany destTblCompany, CompanyDto sourceDto ) { destTblCompany.getContact().setNote(sourceDto.getContactNote()); + destTblCompany.getContact().setAnonymized(sourceDto.getContactAnonymized()); } }
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/ContactAnonymizerService.java b/src/main/java/org/eclipse/openk/contactbasedata/service/ContactAnonymizerService.java new file mode 100644 index 0000000..b71207e --- /dev/null +++ b/src/main/java/org/eclipse/openk/contactbasedata/service/ContactAnonymizerService.java
@@ -0,0 +1,177 @@ +/* + ******************************************************************************* + * Copyright (c) 2019 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ******************************************************************************* + */ +package org.eclipse.openk.contactbasedata.service; + +import lombok.extern.log4j.Log4j2; +import org.eclipse.openk.contactbasedata.constants.Constants; +import org.eclipse.openk.contactbasedata.exceptions.InternalServerErrorException; +import org.eclipse.openk.contactbasedata.model.TblContact; +import org.eclipse.openk.contactbasedata.viewmodel.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.util.Date; +import java.util.UUID; + +@Log4j2 +@Service +public class ContactAnonymizerService { + @Autowired + ContactService contactService; + + @Autowired + private CompanyService companyService; + + @Autowired + private ExternalPersonService externalPersonService; + + @Autowired + private InternalPersonService internalPersonService; + + @Autowired + private ContactPersonService contactPersonService; + + @Autowired + private AddressService addressService; + + @Autowired + private CommunicationService communicationService; + + @Transactional + public void anonymize( UUID contactUuid ) { + TblContact tblContact = contactService.findTblContact(contactUuid); + + switch( tblContact.getContactType() ) { + case Constants.CONTACT_TYPE_COMPANY: + anonymizeCompany( tblContact.getUuid() ); + break; + case Constants.CONTACT_TYPE_INTERNAL_PERSON: + anonymizeInternalPerson( tblContact.getUuid() ); + break; + case Constants.CONTACT_TYPE_EXTERNAL_PERSON: + anonymizeExternalPerson( tblContact.getUuid() ); + break; + case Constants.CONTACT_TYPE_CONTACT_PERSON: + anonymizeContactPerson( tblContact.getUuid() ); + break; + default: + log.warn("Invalid Contact Type: "+tblContact.getContactType()+"for contact: "+contactUuid); + throw new InternalServerErrorException("Invalid contact type found"); + } + } + + private void anonymizeCompany( UUID contactUuid ) { + CompanyDto dto = companyService.findCompany(contactUuid); + dto.setCompanyName(Constants.ANONYMOUS_TAG); + dto.setCompanyType(null); + dto.setContactNote(getContactNote()); + dto.setContactAnonymized(true); + companyService.updateCompany(dto); + + // kill 'em all + companyService.findContactPersonsToCompany(contactUuid).stream() + .forEach(contactPersonDto -> anonymizeContactPerson(contactPersonDto.getContactUuid())); + + processDependencies(contactUuid); + } + + private void anonymizeInternalPerson( UUID contactUuid ) { + InternalPersonDto internalPersonDto = internalPersonService.findInternalPerson(contactUuid); + internalPersonDto.setLastName(Constants.ANONYMOUS_TAG); + internalPersonDto.setFirstName(null); + internalPersonDto.setTitle(null); + internalPersonDto.setDepartment(null); + internalPersonDto.setUid(null); + internalPersonDto.setUserRef(null); + internalPersonDto.setSalutationUuid(null); + internalPersonDto.setContactNote(getContactNote()); + internalPersonDto.setContactAnonymized(true); + + internalPersonService.updateInternalPerson(internalPersonDto); + + processDependencies(contactUuid); + } + + private void anonymizeExternalPerson( UUID contactUuid ) { + ExternalPersonDto externalPersonDto = externalPersonService.findExternalPerson(contactUuid); + externalPersonDto.setLastName(Constants.ANONYMOUS_TAG); + externalPersonDto.setFirstName(null); + externalPersonDto.setTitle(null); + // leave personType untouched + externalPersonDto.setSalutationUuid(null); + externalPersonDto.setContactNote(getContactNote()); + externalPersonDto.setContactAnonymized(true); + externalPersonService.updateExternalPerson(externalPersonDto); + + processDependencies(contactUuid); + } + + private void anonymizeContactPerson( UUID contactUuid ) { + ContactPersonDto contactPersonDto = contactPersonService.findContactPerson(contactUuid); + contactPersonDto.setLastName(Constants.ANONYMOUS_TAG); + contactPersonDto.setFirstName(null); + contactPersonDto.setTitle(null); + // leave personType untouched + contactPersonDto.setSalutationUuid(null); + contactPersonDto.setContactNote(getContactNote()); + contactPersonDto.setContactAnonymized(true); + contactPersonService.updateContactPerson(contactPersonDto); + + processDependencies(contactUuid); + } + + private void processDependencies(UUID contactUuid) { + addressService.getAddressesByContactUuid(contactUuid).stream() + .forEach(this::anonymizeAddress); + + communicationService.getCommunicationsByContactUuid(contactUuid).stream() + .forEach(this::anonymizeCommunication); + } + + private void anonymizeAddress( AddressDto addressDto ) { + addressDto.setCommunity(Constants.ANONYMOUS_TAG); + addressDto.setStreet(Constants.ANONYMOUS_TAG); + addressDto.setCommunitySuffix(null); + addressDto.setHousenumber(null); + addressDto.setLatitude(null); + addressDto.setLongitude(null); + addressDto.setNote(null); + addressDto.setPostcode(null); + addressDto.setUrlMap(null); + addressDto.setNote(Constants.ANONYMOUS_TAG); + + addressService.updateAddress(addressDto.getContactUuid(), addressDto); + } + + private void anonymizeCommunication(CommunicationDto communicationDto ) { + communicationDto.setCommunicationData(Constants.ANONYMOUS_TAG); + communicationDto.setCommunicationTypeDescription(null); + communicationDto.setNote(Constants.ANONYMOUS_TAG); + + communicationService.updateCommunication(communicationDto.getContactUuid(), communicationDto); + } + + private static String getContactNote() { + return new StringBuilder() + .append("*** [") + .append(new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(Date.from(Instant.now()))) + .append("] ***") + .toString(); + } + +}
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/ContactPersonService.java b/src/main/java/org/eclipse/openk/contactbasedata/service/ContactPersonService.java index e2bef26..05adbda 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/service/ContactPersonService.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/service/ContactPersonService.java
@@ -114,9 +114,9 @@ private ContactPersonDto setFromTblContactPerson( ContactPersonDto destDto, TblContactPerson srcTblContactPerson ) { TblCommunication tblComm = srcTblContactPerson.getContact() .getCommunications().stream() - .filter(comm -> comm.getRefCommunicationType().getId() == 1L) + .filter(comm -> comm.getRefCommunicationType().isTypeEmail()) .findFirst().orElse(null); -// TODO: exchange constant 1L with DB-Solution + // TODO: Move to Mapper destDto.setEmail(tblComm != null ? tblComm.getCommunicationData() : null ); @@ -153,5 +153,6 @@ } destTblContactPerson.getContact().setNote(sourceDto.getContactNote()); + destTblContactPerson.getContact().setAnonymized(sourceDto.getContactAnonymized()); } }
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/ContactService.java b/src/main/java/org/eclipse/openk/contactbasedata/service/ContactService.java index 4092fb5..aa50605 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/service/ContactService.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/service/ContactService.java
@@ -15,7 +15,10 @@ package org.eclipse.openk.contactbasedata.service; import lombok.extern.log4j.Log4j2; +import org.eclipse.openk.contactbasedata.constants.Constants; +import org.eclipse.openk.contactbasedata.exceptions.NotFoundException; import org.eclipse.openk.contactbasedata.mapper.ContactMapper; +import org.eclipse.openk.contactbasedata.model.TblContact; import org.eclipse.openk.contactbasedata.model.VwDetailedContact; import org.eclipse.openk.contactbasedata.repository.ContactRepository; import org.eclipse.openk.contactbasedata.repository.DetailedContactRepository; @@ -27,6 +30,7 @@ import java.time.Instant; import java.util.Date; +import java.util.UUID; @Log4j2 @Service @@ -38,6 +42,10 @@ @Autowired private ContactMapper contactMapper; + public TblContact findTblContact(UUID contactUuid ) { + return contactRepository.findByUuid( contactUuid ).orElseThrow( () -> new NotFoundException(Constants.CONTACT_UUID_NOT_EXISTING)); + } + public Page<VwDetailedContact> findDetailedContacts( SearchContactsFilterParams searchContactsFilterParams, Pageable pageable) {
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/ExternalPersonService.java b/src/main/java/org/eclipse/openk/contactbasedata/service/ExternalPersonService.java index daf04e4..d822078 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/service/ExternalPersonService.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/service/ExternalPersonService.java
@@ -124,5 +124,6 @@ } destTblExternalPerson.getContact().setNote(sourceDto.getContactNote()); + destTblExternalPerson.getContact().setAnonymized(sourceDto.getContactAnonymized()); } }
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/InternalPersonService.java b/src/main/java/org/eclipse/openk/contactbasedata/service/InternalPersonService.java index c10b9d6..ef5f4aa 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/service/InternalPersonService.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/service/InternalPersonService.java
@@ -135,5 +135,6 @@ } destTblInternalPerson.getContact().setNote(sourceDto.getContactNote()); + destTblInternalPerson.getContact().setAnonymized(sourceDto.getContactAnonymized()); } }
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/util/SearchContactsFilterParams.java b/src/main/java/org/eclipse/openk/contactbasedata/service/util/SearchContactsFilterParams.java index 61a11e5..802b4ed 100644 --- a/src/main/java/org/eclipse/openk/contactbasedata/service/util/SearchContactsFilterParams.java +++ b/src/main/java/org/eclipse/openk/contactbasedata/service/util/SearchContactsFilterParams.java
@@ -1,3 +1,17 @@ +/* + ******************************************************************************* + * Copyright (c) 2019 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + ******************************************************************************* + */ package org.eclipse.openk.contactbasedata.service.util; import lombok.Data;