From 322d5f708b4320943456c6021d3b187ff5457164 Mon Sep 17 00:00:00 2001 From: SergiuPacurariu Date: Wed, 23 Oct 2024 16:08:07 +0300 Subject: [PATCH 1/5] #13093 - Update Data Protection for certain Data Fields --- .../symeda/sormas/api/caze/CaseDataDto.java | 3 + .../de/symeda/sormas/api/event/EventDto.java | 4 + .../de/symeda/sormas/api/i18n/Strings.java | 1 + .../sormas/api/location/LocationDto.java | 6 +- .../symeda/sormas/api/utils/PersonalData.java | 2 + .../sormas/api/utils/SensitiveData.java | 9 +-- .../AnnotationBasedFieldAccessChecker.java | 2 +- .../PersonalDataFieldAccessChecker.java | 42 ++++++++-- .../SensitiveDataFieldAccessChecker.java | 45 +++++++++-- .../src/main/resources/strings.properties | 1 + .../sormas/backend/caze/CaseFacadeEjb.java | 7 +- .../PortHealthInfoFacadeEjb.java | 5 +- .../SurveillanceReportFacadeEjb.java | 5 +- .../ClinicalVisitFacadeEjb.java | 17 ++-- .../backend/common/AbstractBaseEjb.java | 14 ++-- .../backend/contact/ContactFacadeEjb.java | 5 +- .../backend/document/DocumentFacadeEjb.java | 9 ++- .../event/EventParticipantFacadeEjb.java | 5 +- .../immunization/ImmunizationFacadeEjb.java | 7 +- .../sormas/backend/info/EntityColumn.java | 25 +++++- .../ManualMessageLogFacadeEjb.java | 6 +- .../backend/person/PersonFacadeEjb.java | 5 +- .../sample/AdditionalTestFacadeEjb.java | 5 +- .../backend/sample/PathogenTestFacadeEjb.java | 5 +- .../sormas/backend/sample/SampleService.java | 12 ++- .../share/ExternalShareInfoFacadeEjb.java | 6 +- .../sormas/backend/task/TaskFacadeEjb.java | 6 +- .../therapy/PrescriptionFacadeEjb.java | 15 ++-- .../backend/therapy/TreatmentFacadeEjb.java | 15 ++-- .../travelentry/TravelEntryFacadeEjb.java | 5 +- .../sormas/backend/util/Pseudonymizer.java | 65 +++++++++------ .../vaccination/VaccinationFacadeEjb.java | 5 +- .../sormas/backend/visit/VisitFacadeEjb.java | 8 +- .../sormas/ui/action/ActionEditForm.java | 7 +- .../symeda/sormas/ui/caze/CaseDataForm.java | 4 +- .../clinicalcourse/HealthConditionsForm.java | 79 +++++++++++-------- .../sormas/ui/events/EventDataForm.java | 2 +- .../symeda/sormas/ui/task/TaskEditForm.java | 7 +- .../sormas/ui/utils/AbstractEditForm.java | 4 + .../sormas/ui/utils/NullableOptionGroup.java | 10 +++ .../sormas/ui/utils/RichTextAreaCustom.java | 24 ++++++ .../utils/SormasFieldGroupFieldFactory.java | 2 + .../symeda/sormas/ui/utils/VaadinUiUtil.java | 65 +++++++++++++++ 43 files changed, 439 insertions(+), 137 deletions(-) create mode 100644 sormas-ui/src/main/java/de/symeda/sormas/ui/utils/RichTextAreaCustom.java diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java index 8500490afa3..224afe0be89 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseDataDto.java @@ -346,6 +346,7 @@ public class CaseDataDto extends SormasToSormasShareableDto implements IsCase { @Valid @EmbeddedPersonalData @EmbeddedSensitiveData + @SensitiveData private HealthConditionsDto healthConditions; private YesNoUnknown pregnant; @@ -509,7 +510,9 @@ public class CaseDataDto extends SormasToSormasShareableDto implements IsCase { COUNTRY_CODE_GERMANY, COUNTRY_CODE_SWITZERLAND }) private Date quarantineOfficialOrderSentDate; + @SensitiveData private YesNoUnknown postpartum; + @SensitiveData private Trimester trimester; private FollowUpStatus followUpStatus; @SensitiveData diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventDto.java index 6db5fa85872..648098f13be 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/event/EventDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/event/EventDto.java @@ -167,12 +167,16 @@ public class EventDto extends SormasToSormasShareableDto { private InstitutionalPartnerType srcInstitutionalPartnerType; @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String srcInstitutionalPartnerTypeDetails; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String srcFirstName; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String srcLastName; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String srcTelNo; + @SensitiveData @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String srcEmail; @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java index ed87fae2ee3..e77b185d269 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java @@ -1247,6 +1247,7 @@ public interface Strings { String messageCountImmunizationsNotRestored = "messageCountImmunizationsNotRestored"; String messageCountriesArchived = "messageCountriesArchived"; String messageCountriesDearchived = "messageCountriesDearchived"; + String messageCountriesExcludedFromDataProtection = "messageCountriesExcludedFromDataProtection"; String messageCountryArchived = "messageCountryArchived"; String messageCountryDearchived = "messageCountryDearchived"; String messageCountryDearchivingNotPossible = "messageCountryDearchivingNotPossible"; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/location/LocationDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/location/LocationDto.java index 576e6085873..5f146a7bf22 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/location/LocationDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/location/LocationDto.java @@ -101,8 +101,10 @@ public class LocationDto extends PseudonymizableDto { CountryHelper.COUNTRY_CODE_GERMANY, CountryHelper.COUNTRY_CODE_FRANCE }) private String details; - @PersonalData - @SensitiveData + @PersonalData(excludeForCountries = { + CountryHelper.COUNTRY_CODE_LUXEMBOURG }) + @SensitiveData(excludeForCountries = { + CountryHelper.COUNTRY_CODE_LUXEMBOURG }) @Size(max = FieldConstraints.CHARACTER_LIMIT_DEFAULT, message = Validations.textTooLong) private String city; @PersonalData diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/PersonalData.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/PersonalData.java index c96ed3e9295..4d81471a021 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/utils/PersonalData.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/PersonalData.java @@ -27,4 +27,6 @@ public @interface PersonalData { boolean mandatoryField() default false; + + String[] excludeForCountries() default {}; } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/SensitiveData.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/SensitiveData.java index 6ce06fd20d8..9602b676142 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/utils/SensitiveData.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/SensitiveData.java @@ -1,19 +1,16 @@ /* * SORMAS® - Surveillance Outbreak Response Management & Analysis System * Copyright © 2016-2020 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) - * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * along with this program. If not, see . */ package de.symeda.sormas.api.utils; @@ -28,4 +25,6 @@ public @interface SensitiveData { boolean mandatoryField() default false; + + String[] excludeForCountries() default {}; } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/AnnotationBasedFieldAccessChecker.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/AnnotationBasedFieldAccessChecker.java index 402ac5219da..d87b4038db4 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/AnnotationBasedFieldAccessChecker.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/AnnotationBasedFieldAccessChecker.java @@ -22,7 +22,7 @@ public abstract class AnnotationBasedFieldAccessChecker implements FieldAccessChecker { - private final Class fieldAnnotation; + protected final Class fieldAnnotation; private final Class embeddedAnnotation; private final boolean hasRight; private final SpecialAccessCheck specialAccessCheck; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/PersonalDataFieldAccessChecker.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/PersonalDataFieldAccessChecker.java index be838b8a0eb..cc38ed1c6f5 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/PersonalDataFieldAccessChecker.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/PersonalDataFieldAccessChecker.java @@ -18,6 +18,7 @@ package de.symeda.sormas.api.utils.fieldaccess.checkers; import java.lang.reflect.Field; +import java.util.Arrays; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.EmbeddedPersonalData; @@ -25,20 +26,32 @@ public final class PersonalDataFieldAccessChecker extends AnnotationBasedFieldAccessChecker { - private PersonalDataFieldAccessChecker(final boolean hasRight, SpecialAccessCheck specialAccessCheck) { + private final String serverCountry; + + private PersonalDataFieldAccessChecker(final boolean hasRight, SpecialAccessCheck specialAccessCheck, String serverCountry) { super(PersonalData.class, EmbeddedPersonalData.class, hasRight, specialAccessCheck); + this.serverCountry = serverCountry; } - public static PersonalDataFieldAccessChecker inJurisdiction(RightCheck rightCheck, SpecialAccessCheck specialAccessCheck) { - return new PersonalDataFieldAccessChecker<>(rightCheck.check(UserRight.SEE_PERSONAL_DATA_IN_JURISDICTION), specialAccessCheck); + public static PersonalDataFieldAccessChecker inJurisdiction( + RightCheck rightCheck, + SpecialAccessCheck specialAccessCheck, + String serverCountry) { + return new PersonalDataFieldAccessChecker<>(rightCheck.check(UserRight.SEE_PERSONAL_DATA_IN_JURISDICTION), specialAccessCheck, serverCountry); } - public static PersonalDataFieldAccessChecker outsideJurisdiction(RightCheck rightCheck, SpecialAccessCheck specialAccessCheck) { - return new PersonalDataFieldAccessChecker<>(rightCheck.check(UserRight.SEE_PERSONAL_DATA_OUTSIDE_JURISDICTION), specialAccessCheck); + public static PersonalDataFieldAccessChecker outsideJurisdiction( + RightCheck rightCheck, + SpecialAccessCheck specialAccessCheck, + String serverCountry) { + return new PersonalDataFieldAccessChecker<>( + rightCheck.check(UserRight.SEE_PERSONAL_DATA_OUTSIDE_JURISDICTION), + specialAccessCheck, + serverCountry); } public static PersonalDataFieldAccessChecker forcedNoAccess() { - return new PersonalDataFieldAccessChecker<>(false, t -> false); + return new PersonalDataFieldAccessChecker<>(false, t -> false, null); } @Override @@ -46,6 +59,23 @@ protected boolean isAnnotatedFieldMandatory(Field annotatedField) { return annotatedField.getAnnotation(PersonalData.class).mandatoryField(); } + @Override + public boolean isConfiguredForCheck(Field field, boolean withMandatory) { + boolean annotationPresent = field.isAnnotationPresent(fieldAnnotation); + + if (annotationPresent) { + String[] excludeForCountries = field.getAnnotation(PersonalData.class).excludeForCountries(); + if (Arrays.asList(excludeForCountries).contains(serverCountry)) { + return false; + } + } + + if (!annotationPresent || withMandatory) { + return annotationPresent; + } + return !isAnnotatedFieldMandatory(field); + } + public interface RightCheck { boolean check(UserRight userRight); diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/SensitiveDataFieldAccessChecker.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/SensitiveDataFieldAccessChecker.java index fb0c1f68005..d5b716c26a3 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/SensitiveDataFieldAccessChecker.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/SensitiveDataFieldAccessChecker.java @@ -16,6 +16,7 @@ package de.symeda.sormas.api.utils.fieldaccess.checkers; import java.lang.reflect.Field; +import java.util.Arrays; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.EmbeddedSensitiveData; @@ -23,20 +24,35 @@ public final class SensitiveDataFieldAccessChecker extends AnnotationBasedFieldAccessChecker { - private SensitiveDataFieldAccessChecker(final boolean hasRight, SpecialAccessCheck specialAccessCheck) { + private final String serverCountry; + + private SensitiveDataFieldAccessChecker(final boolean hasRight, SpecialAccessCheck specialAccessCheck, String serverCountry) { super(SensitiveData.class, EmbeddedSensitiveData.class, hasRight, specialAccessCheck); + this.serverCountry = serverCountry; } - public static SensitiveDataFieldAccessChecker inJurisdiction(RightCheck rightCheck, SpecialAccessCheck specialAccessCheck) { - return new SensitiveDataFieldAccessChecker<>(rightCheck.check(UserRight.SEE_SENSITIVE_DATA_IN_JURISDICTION), specialAccessCheck); + public static SensitiveDataFieldAccessChecker inJurisdiction( + RightCheck rightCheck, + SpecialAccessCheck specialAccessCheck, + String serverCountry) { + return new SensitiveDataFieldAccessChecker<>( + rightCheck.check(UserRight.SEE_SENSITIVE_DATA_IN_JURISDICTION), + specialAccessCheck, + serverCountry); } - public static SensitiveDataFieldAccessChecker outsideJurisdiction(RightCheck rightCheck, SpecialAccessCheck specialAccessCheck) { - return new SensitiveDataFieldAccessChecker<>(rightCheck.check(UserRight.SEE_SENSITIVE_DATA_OUTSIDE_JURISDICTION), specialAccessCheck); + public static SensitiveDataFieldAccessChecker outsideJurisdiction( + RightCheck rightCheck, + SpecialAccessCheck specialAccessCheck, + String serverCountry) { + return new SensitiveDataFieldAccessChecker<>( + rightCheck.check(UserRight.SEE_SENSITIVE_DATA_OUTSIDE_JURISDICTION), + specialAccessCheck, + serverCountry); } public static SensitiveDataFieldAccessChecker forcedNoAccess() { - return new SensitiveDataFieldAccessChecker<>(false, t -> false); + return new SensitiveDataFieldAccessChecker<>(false, t -> false, null); } @Override @@ -44,6 +60,23 @@ protected boolean isAnnotatedFieldMandatory(Field annotatedField) { return annotatedField.getAnnotation(SensitiveData.class).mandatoryField(); } + @Override + public boolean isConfiguredForCheck(Field field, boolean withMandatory) { + boolean annotationPresent = field.isAnnotationPresent(fieldAnnotation); + + if (annotationPresent) { + String[] excludeForCountries = field.getAnnotation(SensitiveData.class).excludeForCountries(); + if (Arrays.asList(excludeForCountries).contains(serverCountry)) { + return false; + } + } + + if (!annotationPresent || withMandatory) { + return annotationPresent; + } + return !isAnnotatedFieldMandatory(field); + } + public interface RightCheck { boolean check(UserRight userRight); diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index fc1854df695..2a02c9a7230 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -1522,6 +1522,7 @@ messageExternalEmailAttachmentPassword=Please use this password to open the docu messageExternalEmailAttachmentNotAvailableInfo=Attaching documents is disabled because encryption would not be possible. To encrypt documents, the person needs to have either a national health ID specified, or a primary mobile phone number set with SMS sending set up on this system. messagePersonNationalHealthIdInvalid=The entered national health ID does not seem to be correct messageSyncUsersFromAuthProviderConfigurationError=Syncing users from authentication provider is not possible because the configuration is incorrect. Please contact an admin and inform them about this issue. +messageCountriesExcludedFromDataProtection=Countries excluded from data protection for this field: # Notifications notificationCaseClassificationChanged = The classification of case %s has changed to %s. diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java index d72209821be..e0030adea8e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/CaseFacadeEjb.java @@ -4168,7 +4168,8 @@ public List getCaseFollowUpList( private Pseudonymizer createPseudonymizerForDtoWithClinician( @Nullable String pseudonymizedValue, Collection cases) { - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, createSpecialAccessChecker(cases), pseudonymizedValue); + Pseudonymizer pseudonymizer = + Pseudonymizer.getDefault(userService, createSpecialAccessChecker(cases), pseudonymizedValue, configFacade.getCountryCode()); UserRightFieldAccessChecker clinicianViewRightChecker = new UserRightFieldAccessChecker<>(UserRight.CASE_CLINICIAN_VIEW, userService.hasRight(UserRight.CASE_CLINICIAN_VIEW)); @@ -4179,12 +4180,12 @@ private Pseudonymizer createPseudonymizerForDtoWithClinici @PermitAll public Pseudonymizer createSimplePseudonymizer(Collection cases) { - return Pseudonymizer.getDefault(userService, createSpecialAccessChecker(cases)); + return Pseudonymizer.getDefault(userService, createSpecialAccessChecker(cases), configFacade.getCountryCode()); } @PermitAll public Pseudonymizer createSimplePlaceholderPseudonymizer(Collection cases) { - return Pseudonymizer.getDefaultWithPlaceHolder(userService, createSpecialAccessChecker(cases)); + return Pseudonymizer.getDefaultWithPlaceHolder(userService, createSpecialAccessChecker(cases), configFacade.getCountryCode()); } private AnnotationBasedFieldAccessChecker.SpecialAccessCheck createSpecialAccessChecker( diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java index 941f1d44268..e42bb80b028 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/porthealthinfo/PortHealthInfoFacadeEjb.java @@ -7,6 +7,7 @@ import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoDto; import de.symeda.sormas.api.caze.porthealthinfo.PortHealthInfoFacade; +import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.user.UserService; import de.symeda.sormas.backend.util.DtoHelper; import de.symeda.sormas.backend.util.Pseudonymizer; @@ -18,6 +19,8 @@ public class PortHealthInfoFacadeEjb implements PortHealthInfoFacade { private PortHealthInfoService portHealthInfoService; @EJB private UserService userService; + @EJB + private ConfigFacadeEjb.ConfigFacadeEjbLocal configFacade; public static PortHealthInfoDto toDto(PortHealthInfo source) { if (source == null) { @@ -89,7 +92,7 @@ public PortHealthInfoDto getByCaseUuid(String caseUuid) { } private PortHealthInfoDto toPseudonymizedDto(PortHealthInfo portHealthInfo) { - Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService, configFacade.getCountryCode()); PortHealthInfoDto portHealthInfoDto = toDto(portHealthInfo); pseudonymizer.pseudonymizeDto(PortHealthInfoDto.class, portHealthInfoDto, portHealthInfoService.inJurisdictionOrOwned(portHealthInfo), null); return portHealthInfoDto; diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportFacadeEjb.java index 53d7addf02e..4d9bc572eb7 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/caze/surveillancereport/SurveillanceReportFacadeEjb.java @@ -51,6 +51,7 @@ import de.symeda.sormas.backend.caze.CaseFacadeEjb; import de.symeda.sormas.backend.caze.CaseService; import de.symeda.sormas.backend.common.AbstractBaseEjb; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.externalmessage.ExternalMessageFacadeEjb.ExternalMessageFacadeEjbLocal; import de.symeda.sormas.backend.infrastructure.district.DistrictFacadeEjb; import de.symeda.sormas.backend.infrastructure.district.DistrictService; @@ -102,6 +103,8 @@ public class SurveillanceReportFacadeEjb private SormasToSormasCaseFacadeEjbLocal sormasToSormasCaseFacade; @EJB private SpecialCaseAccessService specialCaseAccessService; + @EJB + private ConfigFacadeEjbLocal configFacade; public SurveillanceReportFacadeEjb() { super(); @@ -198,7 +201,7 @@ protected SurveillanceReportReferenceDto toRefDto(SurveillanceReport surveillanc @Override protected Pseudonymizer createPseudonymizer(List surveillanceReports) { List withSpecialAccess = specialCaseAccessService.getSurveillanceReportUuidsWithSpecialAccess(surveillanceReports); - return Pseudonymizer.getDefault(userService, r -> withSpecialAccess.contains(r.getUuid())); + return Pseudonymizer.getDefault(userService, r -> withSpecialAccess.contains(r.getUuid()), configFacade.getCountryCode()); } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitFacadeEjb.java index 4133237fad0..d830f08488d 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/clinicalcourse/ClinicalVisitFacadeEjb.java @@ -42,6 +42,7 @@ import de.symeda.sormas.backend.caze.CaseFacadeEjb.CaseFacadeEjbLocal; import de.symeda.sormas.backend.caze.CaseQueryContext; import de.symeda.sormas.backend.caze.CaseService; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.person.Person; import de.symeda.sormas.backend.symptoms.Symptoms; @@ -78,6 +79,8 @@ public class ClinicalVisitFacadeEjb implements ClinicalVisitFacade { private CaseService caseService; @EJB private SymptomsService symptomsService; + @EJB + private ConfigFacadeEjbLocal configFacade; // private String countPositiveSymptomsQuery; @@ -159,7 +162,7 @@ public List getIndexList(ClinicalVisitCriteria criteria, List results = QueryHelper.getResultList(em, cq, first, max); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService, configFacade.getCountryCode()); pseudonymizer.pseudonymizeDtoCollection(ClinicalVisitIndexDto.class, results, ClinicalVisitIndexDto::getInJurisdiction, null); // Build the query to count positive symptoms @@ -209,7 +212,7 @@ public List getIndexList(ClinicalVisitCriteria criteria, @Override public ClinicalVisitDto getClinicalVisitByUuid(String uuid) { - return convertToDto(service.getByUuid(uuid), Pseudonymizer.getDefault(userService)); + return convertToDto(service.getByUuid(uuid), Pseudonymizer.getDefault(userService, configFacade.getCountryCode())); } @Override @@ -244,7 +247,7 @@ private ClinicalVisitDto saveClinicalVisit(ClinicalVisitDto clinicalVisit, Strin caseFacade.save(caze); } - return convertToDto(entity, Pseudonymizer.getDefault(userService)); + return convertToDto(entity, Pseudonymizer.getDefault(userService, configFacade.getCountryCode())); } /** @@ -286,7 +289,7 @@ public List getAllActiveClinicalVisitsAfter(Date date, Integer private List toPseudonymizedDtos(List entities) { List inJurisdictionIds = service.getInJurisdictionIds(entities); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); List dtos = entities.stream().map(p -> convertToDto(p, pseudonymizer, inJurisdictionIds.contains(p.getId()))).collect(Collectors.toList()); return dtos; @@ -294,7 +297,7 @@ private List toPseudonymizedDtos(List entities) @Override public List getByUuids(List uuids) { - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); return service.getByUuids(uuids).stream().map(t -> convertToDto(t, pseudonymizer)).collect(Collectors.toList()); } @@ -340,7 +343,7 @@ public List getExportList(CaseCriteria criteria, Collect List resultList = QueryHelper.getResultList(em, cq, first, max); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService, configFacade.getCountryCode()); for (ClinicalVisitExportDto exportDto : resultList) { exportDto.setSymptoms(SymptomsFacadeEjb.toSymptomsDto(symptomsService.getById(exportDto.getSymptomsId()))); @@ -382,7 +385,7 @@ private void pseudonymizeDto(ClinicalVisit source, ClinicalVisitDto dto, Pseudon private void restorePseudonymizedDto(ClinicalVisitDto clinicalVisit, ClinicalVisit existingClinicalVisit) { if (existingClinicalVisit != null) { boolean inJurisdiction = caseService.inJurisdictionOrOwned(existingClinicalVisit.getClinicalCourse().getCaze()); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); ClinicalVisitDto existingDto = toDto(existingClinicalVisit); pseudonymizer.restorePseudonymizedValues(ClinicalVisitDto.class, clinicalVisit, existingDto, inJurisdiction); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractBaseEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractBaseEjb.java index 07b968e4974..c6bdfd09d65 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractBaseEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/common/AbstractBaseEjb.java @@ -35,6 +35,8 @@ public abstract class AbstractBaseEjb adoClass; protected Class dtoClass; + @Inject + private ConfigFacadeEjb.ConfigFacadeEjbLocal configFacade; protected AbstractBaseEjb() { } @@ -141,23 +143,25 @@ protected Pseudonymizer createPseudonymizer(ADO ado) { } protected Pseudonymizer createPseudonymizer(List adoList) { - return Pseudonymizer.getDefault(userService); + return Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); } protected Pseudonymizer createGenericPseudonymizer() { - return Pseudonymizer.getDefault(userService); + return Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); } protected Pseudonymizer createGenericPseudonymizer(SpecialAccessCheck specialAccessCheck) { - return Pseudonymizer.getDefault(userService, specialAccessCheck); + return Pseudonymizer.getDefault(userService, specialAccessCheck, configFacade.getCountryCode()); } protected Pseudonymizer createGenericPlaceholderPseudonymizer() { - return Pseudonymizer.getDefault(userService, I18nProperties.getCaption(Captions.inaccessibleValue)); + return Pseudonymizer.getDefault(userService, I18nProperties.getCaption(Captions.inaccessibleValue), configFacade.getCountryCode()); } protected Pseudonymizer createGenericPlaceholderPseudonymizer(SpecialAccessCheck specialAccessCheck) { - return Pseudonymizer.getDefault(userService, specialAccessCheck, I18nProperties.getCaption(Captions.inaccessibleValue)); + Pseudonymizer aDefault = Pseudonymizer + .getDefault(userService, specialAccessCheck, I18nProperties.getCaption(Captions.inaccessibleValue), configFacade.getCountryCode()); + return aDefault; } protected abstract ADO fillOrBuildEntity(@NotNull DTO source, ADO target, boolean checkChangeDate); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java index e09a585e276..a37c6e0de46 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java @@ -161,6 +161,7 @@ import de.symeda.sormas.backend.clinicalcourse.HealthConditionsMapper; import de.symeda.sormas.backend.common.AbstractCoreFacadeEjb; import de.symeda.sormas.backend.common.AbstractDomainObject; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.common.TaskCreationException; import de.symeda.sormas.backend.disease.DiseaseConfigurationFacadeEjb.DiseaseConfigurationFacadeEjbLocal; @@ -291,6 +292,8 @@ public class ContactFacadeEjb private UserRoleFacadeEjb.UserRoleFacadeEjbLocal userRoleFacadeEjb; @EJB private SpecialCaseAccessService specialCaseAccessService; + @EJB + private ConfigFacadeEjbLocal configFacade; @Resource private ManagedScheduledExecutorService executorService; @@ -1725,7 +1728,7 @@ protected List toPseudonymizedDtos(List adoList) { @Override protected Pseudonymizer createPseudonymizer(List contacts) { - return Pseudonymizer.getDefault(userService, createSpecialAccessChecker(contacts)); + return Pseudonymizer.getDefault(userService, createSpecialAccessChecker(contacts), configFacade.getCountryCode()); } private SpecialAccessCheck createSpecialAccessChecker(Collection contacts) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentFacadeEjb.java index ae27dda00f1..7f5fbb42f81 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/document/DocumentFacadeEjb.java @@ -112,7 +112,7 @@ public class DocumentFacadeEjb implements DocumentFacade { @Override public DocumentDto getDocumentByUuid(String uuid) { - return convertToDto(documentService.getByUuid(uuid), Pseudonymizer.getDefault(userService)); + return convertToDto(documentService.getByUuid(uuid), Pseudonymizer.getDefault(userService, configFacade.getCountryCode())); } @Override @@ -157,7 +157,7 @@ public DocumentDto saveDocument(@Valid DocumentDto dto, byte[] content, @Nonnull document.setRelatedEntities(documentRelatedEntitySet); documentService.ensurePersisted(document); - return convertToDto(document, Pseudonymizer.getDefault(userService)); + return convertToDto(document, Pseudonymizer.getDefault(userService, configFacade.getCountryCode())); } catch (Throwable t) { try { documentStorageService.delete(storageReference); @@ -209,9 +209,10 @@ public void deleteDocument(String documentUuid, String relatedEntityUuid, Docume documentService.markAsDeleted(document); } } + @Override public List getDocumentsRelatedToEntity(DocumentRelatedEntityType type, String uuid) { - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); return documentService.getRelatedToEntity(type, uuid).stream().map(d -> convertToDto(d, pseudonymizer)).collect(Collectors.toList()); } @@ -222,7 +223,7 @@ public List getReferencesRelatedToEntity(DocumentRelatedEn @Override public Map> getDocumentsRelatedToEntities(DocumentCriteria criteria, List sortProperties) { - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); List allDocuments = documentService.getRelatedToEntities(criteria.getDocumentRelatedEntityType(), criteria.getEntityUuids(), sortProperties); diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java index 39f4e5766a2..f5526b3588e 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/event/EventParticipantFacadeEjb.java @@ -104,6 +104,7 @@ import de.symeda.sormas.backend.caze.CaseService; import de.symeda.sormas.backend.common.AbstractCoreFacadeEjb; import de.symeda.sormas.backend.common.AbstractDomainObject; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.common.NotificationService; import de.symeda.sormas.backend.common.messaging.MessageContents; @@ -180,6 +181,8 @@ public class EventParticipantFacadeEjb private VaccinationService vaccinationService; @EJB private SpecialCaseAccessService specialCaseAccessService; + @EJB + private ConfigFacadeEjbLocal configFacade; public EventParticipantFacadeEjb() { } @@ -1157,7 +1160,7 @@ public EventParticipant fillOrBuildEntity(@NotNull EventParticipantDto source, E @Override protected Pseudonymizer createPseudonymizer(List eventParticipants) { - return Pseudonymizer.getDefault(userService, createSpecialAccessChecker(eventParticipants)); + return Pseudonymizer.getDefault(userService, createSpecialAccessChecker(eventParticipants), configFacade.getCountryCode()); } private SpecialAccessCheck createSpecialAccessChecker( diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjb.java index f3132958c5b..10265699d6b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/immunization/ImmunizationFacadeEjb.java @@ -41,6 +41,9 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; +import de.symeda.sormas.api.ConfigFacade; +import de.symeda.sormas.backend.common.ConfigFacadeEjb; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -170,6 +173,8 @@ public class ImmunizationFacadeEjb private VaccinationService vaccinationService; @EJB private SpecialCaseAccessService specialCaseAccessService; + @EJB + private ConfigFacadeEjbLocal configFacade; public ImmunizationFacadeEjb() { } @@ -440,7 +445,7 @@ public ImmunizationDto save(@Valid @NotNull ImmunizationDto dto, boolean checkCh @Override protected Pseudonymizer createPseudonymizer(List immunizations) { - return Pseudonymizer.getDefault(userService, getSpecialAccessChecker(immunizations)); + return Pseudonymizer.getDefault(userService, getSpecialAccessChecker(immunizations), configFacade.getCountryCode()); } private SpecialAccessCheck getSpecialAccessChecker(Collection immunizations) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/info/EntityColumn.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/info/EntityColumn.java index 72d898f1a5f..7661514f8fb 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/info/EntityColumn.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/info/EntityColumn.java @@ -18,6 +18,7 @@ import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.Map; @@ -171,7 +172,29 @@ private static String getCaption(FieldData fieldData) { } private static String getDescription(FieldData fieldData) { - return I18nProperties.getPrefixDescription(fieldData.getI18NPrefix(), fieldData.getField().getName(), ""); + String prefixDescription = I18nProperties.getPrefixDescription(fieldData.getI18NPrefix(), fieldData.getField().getName(), ""); + + String[] excludedForCountries = null; + + Field field = fieldData.getField(); + if (field.getAnnotation(PersonalData.class) != null) { + excludedForCountries = field.getAnnotation(PersonalData.class).excludeForCountries(); + + } else { + if (field.getAnnotation(SensitiveData.class) != null) { + excludedForCountries = field.getAnnotation(SensitiveData.class).excludeForCountries(); + } + } + + String description; + if (excludedForCountries != null && excludedForCountries.length > 0) { + description = prefixDescription + I18nProperties.getString(Strings.messageCountriesExcludedFromDataProtection) + " " + + Arrays.toString(excludedForCountries); + } else { + description = prefixDescription; + } + + return description; } private static String getNotNull(FieldData fieldData) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/manualmessagelog/ManualMessageLogFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/manualmessagelog/ManualMessageLogFacadeEjb.java index 68546300739..983a2b33d54 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/manualmessagelog/ManualMessageLogFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/manualmessagelog/ManualMessageLogFacadeEjb.java @@ -35,6 +35,7 @@ import de.symeda.sormas.api.manualmessagelog.ManualMessageLogIndexDto; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.fieldaccess.checkers.AnnotationBasedFieldAccessChecker.SpecialAccessCheck; +import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.specialcaseaccess.SpecialCaseAccessService; import de.symeda.sormas.backend.user.User; import de.symeda.sormas.backend.user.UserService; @@ -55,6 +56,8 @@ public class ManualMessageLogFacadeEjb implements ManualMessageLogFacade { private UserService userService; @EJB private SpecialCaseAccessService specialCaseAccessService; + @EJB + private ConfigFacadeEjb.ConfigFacadeEjbLocal configFacade; @RightsAllowed({ UserRight._SEND_MANUAL_EXTERNAL_MESSAGES, @@ -104,7 +107,7 @@ public List getIndexList(ManualMessageLogCriteria crit @NotNull private Pseudonymizer createPseudonymizerWithPlaceholder(Collection manualMessageLogs) { - return Pseudonymizer.getDefaultWithPlaceHolder(userService, getSpecialAccessChecker(manualMessageLogs)); + return Pseudonymizer.getDefaultWithPlaceHolder(userService, getSpecialAccessChecker(manualMessageLogs), configFacade.getCountryCode()); } private SpecialAccessCheck getSpecialAccessChecker(Collection manualMessageLogs) { @@ -113,7 +116,6 @@ private SpecialAccessCheck getSpecialAccessChecker(Col return i -> specialAccessUuids.contains(i.getUuid()); } - @LocalBean @Stateless public static class ManualMessageLogFacadeEjbLocal extends ManualMessageLogFacadeEjb { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java index 0c9d9f9f17f..2266e8b4f51 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java @@ -134,6 +134,7 @@ import de.symeda.sormas.backend.caze.CaseService; import de.symeda.sormas.backend.common.AbstractBaseEjb; import de.symeda.sormas.backend.common.AbstractDomainObject; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.contact.ContactFacadeEjb; @@ -258,6 +259,8 @@ public class PersonFacadeEjb extends AbstractBaseEjb getIndexPage(PersonCriteria personCriteria, Integer @Override protected Pseudonymizer createPseudonymizer(List persons) { - return Pseudonymizer.getDefault(userService, createSpecialAccessChecker(persons)); + return Pseudonymizer.getDefault(userService, createSpecialAccessChecker(persons), configFacade.getCountryCode()); } private SpecialAccessCheck createSpecialAccessChecker(Collection persons) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestFacadeEjb.java index 6e553c5bd93..394de84a91b 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/AdditionalTestFacadeEjb.java @@ -20,6 +20,7 @@ import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.SortProperty; import de.symeda.sormas.backend.FacadeHelper; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.user.User; import de.symeda.sormas.backend.user.UserService; import de.symeda.sormas.backend.util.DtoHelper; @@ -38,6 +39,8 @@ public class AdditionalTestFacadeEjb implements AdditionalTestFacade { private SampleService sampleService; @EJB private UserService userService; + @EJB + private ConfigFacadeEjbLocal configFacade; @Override public AdditionalTestDto getByUuid(String uuid) { @@ -118,7 +121,7 @@ public List getAllActiveAdditionalTestsAfter(Date date, Integ private List toPseudonymizedDtos(List entities) { List inJurisdictionIds = service.getInJurisdictionIds(entities); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); return entities.stream().map(p -> convertToDto(p, pseudonymizer, inJurisdictionIds.contains(p.getId()))).collect(Collectors.toList()); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestFacadeEjb.java index 4dc4a8cbe50..46a80c89851 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/PathogenTestFacadeEjb.java @@ -60,6 +60,7 @@ import de.symeda.sormas.backend.FacadeHelper; import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.caze.CaseFacadeEjb.CaseFacadeEjbLocal; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.common.CoreAdo; import de.symeda.sormas.backend.common.NotificationService; import de.symeda.sormas.backend.common.messaging.MessageContents; @@ -120,6 +121,8 @@ public class PathogenTestFacadeEjb implements PathogenTestFacade { private CountryService countryService; @EJB private SpecialCaseAccessService specialCaseAccessService; + @EJB + private ConfigFacadeEjbLocal configFacade; @Override public List getAllActiveUuids() { @@ -485,7 +488,7 @@ private static void pseudonymizeDto( } private Pseudonymizer createPseudonymizer(Collection tests) { - return Pseudonymizer.getDefault(userService, createSpecialAccessChecker(tests)); + return Pseudonymizer.getDefault(userService, createSpecialAccessChecker(tests), configFacade.getCountryCode()); } private SpecialAccessCheck createSpecialAccessChecker(Collection tests) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java index 1295c31c7e8..1c7caa51825 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/sample/SampleService.java @@ -87,6 +87,7 @@ import de.symeda.sormas.backend.caze.CaseService; import de.symeda.sormas.backend.common.AbstractDeletableAdoService; import de.symeda.sormas.backend.common.AbstractDomainObject; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.common.DeletableAdo; import de.symeda.sormas.backend.common.JurisdictionFlagsService; @@ -145,6 +146,8 @@ public class SampleService extends AbstractDeletableAdoService protected FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; @EJB private SpecialCaseAccessService specialCaseAccessService; + @EJB + private ConfigFacadeEjbLocal configFacade; public SampleService() { super(Sample.class, DeletableEntityType.SAMPLE); @@ -324,12 +327,15 @@ public SamplePseudonymizer createPseudonymizer(boolean w AnnotationBasedFieldAccessChecker.SpecialAccessCheck specialAccessChecker = createSpecialAccessChecker(samples); Pseudonymizer rootPseudonymizer = withPlaceHolder - ? Pseudonymizer.getDefaultWithPlaceHolder(userService, specialAccessChecker) - : Pseudonymizer.getDefault(userService, specialAccessChecker); + ? Pseudonymizer.getDefaultWithPlaceHolder(userService, specialAccessChecker, configFacade.getCountryCode()) + : Pseudonymizer.getDefault(userService, specialAccessChecker, configFacade.getCountryCode()); Collection cases = samples.stream().map(IsSample::getAssociatedCase).filter(Objects::nonNull).collect(Collectors.toList()); - return new SamplePseudonymizer<>(rootPseudonymizer, caseFacade.createSimplePseudonymizer(cases), Pseudonymizer.getDefault(userService)); + return new SamplePseudonymizer<>( + rootPseudonymizer, + caseFacade.createSimplePseudonymizer(cases), + Pseudonymizer.getDefault(userService, configFacade.getCountryCode())); } private AnnotationBasedFieldAccessChecker.SpecialAccessCheck createSpecialAccessChecker( diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoFacadeEjb.java index 099709e5e4f..056b9582832 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/share/ExternalShareInfoFacadeEjb.java @@ -36,6 +36,7 @@ import de.symeda.sormas.api.share.ExternalShareInfoFacade; import de.symeda.sormas.api.share.ExternalShareStatus; import de.symeda.sormas.backend.caze.Case; +import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.event.Event; import de.symeda.sormas.backend.user.UserFacadeEjb; @@ -57,6 +58,9 @@ public class ExternalShareInfoFacadeEjb implements ExternalShareInfoFacade { @EJB private UserService userService; + @EJB + private ConfigFacadeEjb.ConfigFacadeEjbLocal configFacade; + @Override public List getIndexList(ExternalShareInfoCriteria criteria, Integer first, Integer max) { final CriteriaBuilder cb = em.getCriteriaBuilder(); @@ -78,7 +82,7 @@ public List getIndexList(ExternalShareInfoCriteria criteri List shareInfoList = QueryHelper.getResultList(em, cq, first, max); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService, configFacade.getCountryCode()); return shareInfoList.stream().map(i -> convertToDto(i, pseudonymizer)).collect(Collectors.toList()); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java index 8aa6c858e34..6067f8e63f3 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskFacadeEjb.java @@ -358,10 +358,10 @@ private TaskPseudonymizer createPseudonymizer(boolean with return new TaskPseudonymizer<>( withPlaceHolder - ? Pseudonymizer.getDefaultWithPlaceHolder(userService, specialAccessCheck) - : Pseudonymizer.getDefault(userService, specialAccessCheck), + ? Pseudonymizer.getDefaultWithPlaceHolder(userService, specialAccessCheck, configFacade.getCountryCode()) + : Pseudonymizer.getDefault(userService, specialAccessCheck, configFacade.getCountryCode()), caseFacade.createSimplePseudonymizer(associatedCases), - Pseudonymizer.getDefault(userService)); + Pseudonymizer.getDefault(userService, configFacade.getCountryCode())); } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionFacadeEjb.java index f10a766ad9f..188e78bec4f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/PrescriptionFacadeEjb.java @@ -30,6 +30,7 @@ import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.caze.CaseQueryContext; import de.symeda.sormas.backend.caze.CaseService; +import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.person.Person; import de.symeda.sormas.backend.user.User; @@ -56,6 +57,8 @@ public class PrescriptionFacadeEjb implements PrescriptionFacade { private TherapyService therapyService; @EJB private CaseService caseService; + @EJB + private ConfigFacadeEjbLocal configFacade; @Override public List getIndexList(PrescriptionCriteria criteria) { @@ -87,7 +90,7 @@ public List getIndexList(PrescriptionCriteria criteria) { List indexList = em.createQuery(cq).getResultList(); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService, configFacade.getCountryCode()); pseudonymizer.pseudonymizeDtoCollection(PrescriptionIndexDto.class, indexList, PrescriptionIndexDto::getInJurisdiction, null); return indexList; @@ -95,7 +98,7 @@ public List getIndexList(PrescriptionCriteria criteria) { @Override public PrescriptionDto getPrescriptionByUuid(String uuid) { - return convertToDto(service.getByUuid(uuid), Pseudonymizer.getDefault(userService)); + return convertToDto(service.getByUuid(uuid), Pseudonymizer.getDefault(userService, configFacade.getCountryCode())); } @Override @@ -114,7 +117,7 @@ public PrescriptionDto savePrescription(@Valid PrescriptionDto prescription) { service.ensurePersisted(entity); - return convertToDto(entity, Pseudonymizer.getDefault(userService)); + return convertToDto(entity, Pseudonymizer.getDefault(userService, configFacade.getCountryCode())); } @Override @@ -143,7 +146,7 @@ public List getAllActivePrescriptionsAfter(Date date, Integer b private List toPseudonymizedDtos(List entities) { List inJurisdictionIds = service.getInJurisdictionIds(entities); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); return entities.stream().map(p -> convertToDto(p, pseudonymizer, inJurisdictionIds.contains(p.getId()))).collect(Collectors.toList()); } @@ -202,7 +205,7 @@ public List getExportList(CaseCriteria criteria, Collecti List exportList = QueryHelper.getResultList(em, cq, first, max); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService, configFacade.getCountryCode()); pseudonymizer.pseudonymizeDtoCollection(PrescriptionExportDto.class, exportList, PrescriptionExportDto::getInJurisdiction, null); return exportList; @@ -233,7 +236,7 @@ private void pseudonymizeDto(Prescription source, PrescriptionDto dto, Pseudonym private void restorePseudonymizedDto(PrescriptionDto prescription, Prescription existingPrescription, PrescriptionDto existingPrescriptionDto) { if (existingPrescription != null) { - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); pseudonymizer.restorePseudonymizedValues( PrescriptionDto.class, prescription, diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentFacadeEjb.java index e71060be315..85cf01f177a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/therapy/TreatmentFacadeEjb.java @@ -29,6 +29,7 @@ import de.symeda.sormas.backend.caze.Case; import de.symeda.sormas.backend.caze.CaseQueryContext; import de.symeda.sormas.backend.caze.CaseService; +import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.person.Person; import de.symeda.sormas.backend.user.User; @@ -57,6 +58,8 @@ public class TreatmentFacadeEjb implements TreatmentFacade { private PrescriptionService prescriptionService; @EJB private CaseService caseService; + @EJB + private ConfigFacadeEjb.ConfigFacadeEjbLocal configFacade; @Override public List getIndexList(TreatmentCriteria criteria) { @@ -86,7 +89,7 @@ public List getIndexList(TreatmentCriteria criteria) { List indexList = em.createQuery(cq).getResultList(); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService, configFacade.getCountryCode()); pseudonymizer.pseudonymizeDtoCollection(TreatmentIndexDto.class, indexList, TreatmentIndexDto::getInJurisdiction, null); return indexList; @@ -122,7 +125,7 @@ public List getTreatmentForPrescription(List prescrip List treatmentIndexDtos = em.createQuery(cq).getResultList(); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService, configFacade.getCountryCode()); pseudonymizer.pseudonymizeDtoCollection(TreatmentIndexDto.class, treatmentIndexDtos, TreatmentIndexDto::getInJurisdiction, null); return treatmentIndexDtos; @@ -130,7 +133,7 @@ public List getTreatmentForPrescription(List prescrip @Override public TreatmentDto getTreatmentByUuid(String uuid) { - return convertToDto(service.getByUuid(uuid), Pseudonymizer.getDefault(userService)); + return convertToDto(service.getByUuid(uuid), Pseudonymizer.getDefault(userService, configFacade.getCountryCode())); } @Override @@ -195,7 +198,7 @@ public List getByUuids(List uuids) { private List toPseudonymizedDtos(List entities) { List inJurisdictionIds = service.getInJurisdictionIds(entities); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); return entities.stream().map(p -> convertToDto(p, pseudonymizer, inJurisdictionIds.contains(p.getId()))).collect(Collectors.toList()); } @@ -245,7 +248,7 @@ public List getExportList(CaseCriteria criteria, Collection< List exportList = QueryHelper.getResultList(em, cq, first, max); - Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefaultWithPlaceHolder(userService, configFacade.getCountryCode()); pseudonymizer.pseudonymizeDtoCollection(TreatmentExportDto.class, exportList, TreatmentExportDto::getInJurisdiction, null); return exportList; @@ -276,7 +279,7 @@ private void pseudonymizeDto(Treatment source, TreatmentDto dto, Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService); + Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, configFacade.getCountryCode()); pseudonymizer.restorePseudonymizedValues(TreatmentDto.class, source, existingDto, service.inJurisdictionOrOwned(existingTreatment)); } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/TravelEntryFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/TravelEntryFacadeEjb.java index e311abde4f4..accd4e2dc1f 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/TravelEntryFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/travelentry/TravelEntryFacadeEjb.java @@ -50,6 +50,7 @@ import de.symeda.sormas.backend.caze.CaseFacadeEjb; import de.symeda.sormas.backend.caze.CaseService; import de.symeda.sormas.backend.common.AbstractCoreFacadeEjb; +import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.infrastructure.community.CommunityFacadeEjb; import de.symeda.sormas.backend.infrastructure.community.CommunityService; import de.symeda.sormas.backend.infrastructure.district.DistrictFacadeEjb; @@ -96,6 +97,8 @@ public class TravelEntryFacadeEjb private TravelEntryService travelEntryService; @EJB private SpecialCaseAccessService specialCaseAccessService; + @EJB + private ConfigFacadeEjb.ConfigFacadeEjbLocal configFacade; public TravelEntryFacadeEjb() { } @@ -223,7 +226,7 @@ public long count(TravelEntryCriteria criteria, boolean ignoreUserFilter) { @Override protected Pseudonymizer createPseudonymizer(List travelEntries) { - return Pseudonymizer.getDefault(userService, getSpecialAccessChecker(travelEntries)); + return Pseudonymizer.getDefault(userService, getSpecialAccessChecker(travelEntries), configFacade.getCountryCode()); } private SpecialAccessCheck getSpecialAccessChecker(Collection entries) { diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/util/Pseudonymizer.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/util/Pseudonymizer.java index 48cc1772c09..211cf1729da 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/util/Pseudonymizer.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/util/Pseudonymizer.java @@ -33,48 +33,62 @@ public final class Pseudonymizer extends DtoPseudonymizer { - public static Pseudonymizer getDefault(UserService userService) { - return getDefault(userService::hasRight, noopSpecialAccessCheck()); + public static Pseudonymizer getDefault(UserService userService, String serverCountry) { + return getDefault(userService::hasRight, noopSpecialAccessCheck(), serverCountry); } - public static Pseudonymizer getDefault(UserService userService, SpecialAccessCheck specialAccessCheck) { - return getDefault(userService::hasRight, specialAccessCheck); + public static Pseudonymizer getDefault(UserService userService, SpecialAccessCheck specialAccessCheck, String serverCountry) { + return getDefault(userService::hasRight, specialAccessCheck, serverCountry); } - public static Pseudonymizer getDefault(UserService userService, SpecialAccessCheck specialAccessCheck, String stringValuePlaceholder) { - return getDefault(userService::hasRight, specialAccessCheck, stringValuePlaceholder); + public static Pseudonymizer getDefault( + UserService userService, + SpecialAccessCheck specialAccessCheck, + String stringValuePlaceholder, + String serverCountry) { + return getDefault(userService::hasRight, specialAccessCheck, stringValuePlaceholder, serverCountry); } - public static Pseudonymizer getDefault(UserService userService, String stringValuePlaceholder) { - return getDefault(userService::hasRight, noopSpecialAccessCheck(), stringValuePlaceholder); + public static Pseudonymizer getDefault(UserService userService, String stringValuePlaceholder, String serverCountry) { + return getDefault(userService::hasRight, noopSpecialAccessCheck(), stringValuePlaceholder, serverCountry); } - private static Pseudonymizer getDefault(RightCheck rightCheck, SpecialAccessCheck specialAccessCheck) { + private static Pseudonymizer getDefault(RightCheck rightCheck, SpecialAccessCheck specialAccessCheck, String serverCountry) { return new Pseudonymizer<>( - createDefaultFieldAccessCheckers(true, rightCheck, specialAccessCheck), - createDefaultFieldAccessCheckers(false, rightCheck, specialAccessCheck), + createDefaultFieldAccessCheckers(true, rightCheck, specialAccessCheck, serverCountry), + createDefaultFieldAccessCheckers(false, rightCheck, specialAccessCheck, serverCountry), "", true); } - private static Pseudonymizer getDefault(RightCheck rightCheck, SpecialAccessCheck specialAccessCheck, String stringValuePlaceholder) { + private static Pseudonymizer getDefault( + RightCheck rightCheck, + SpecialAccessCheck specialAccessCheck, + String stringValuePlaceholder, + String serverCountry) { return new Pseudonymizer<>( - createDefaultFieldAccessCheckers(true, rightCheck, specialAccessCheck), - createDefaultFieldAccessCheckers(false, rightCheck, specialAccessCheck), + createDefaultFieldAccessCheckers(true, rightCheck, specialAccessCheck, serverCountry), + createDefaultFieldAccessCheckers(false, rightCheck, specialAccessCheck, serverCountry), stringValuePlaceholder, true); } - public static Pseudonymizer getDefaultWithPlaceHolder(UserService userService) { - return getDefaultWithPlaceHolder(userService, noopSpecialAccessCheck()); + public static Pseudonymizer getDefaultWithPlaceHolder(UserService userService, String serverCountry) { + return getDefaultWithPlaceHolder(userService, noopSpecialAccessCheck(), serverCountry); } - public static Pseudonymizer getDefaultWithPlaceHolder(UserService userService, SpecialAccessCheck specialAccessCheck) { - return getDefaultWithPlaceHolder(userService::hasRight, specialAccessCheck); + public static Pseudonymizer getDefaultWithPlaceHolder( + UserService userService, + SpecialAccessCheck specialAccessCheck, + String serverCountry) { + return getDefaultWithPlaceHolder(userService::hasRight, specialAccessCheck, serverCountry); } - private static Pseudonymizer getDefaultWithPlaceHolder(RightCheck rightCheck, SpecialAccessCheck specialAccessCheck) { - return getDefault(rightCheck, specialAccessCheck, I18nProperties.getCaption(Captions.inaccessibleValue)); + private static Pseudonymizer getDefaultWithPlaceHolder( + RightCheck rightCheck, + SpecialAccessCheck specialAccessCheck, + String serverCountry) { + return getDefault(rightCheck, specialAccessCheck, I18nProperties.getCaption(Captions.inaccessibleValue), serverCountry); } public static Pseudonymizer getDefaultNoCheckers(boolean pseudonymizeMandatoryFields) { @@ -161,13 +175,14 @@ private static boolean isUserInJurisdiction(User user, User currentUser) { private static FieldAccessCheckers createDefaultFieldAccessCheckers( boolean inJurisdiction, final RightCheck rightCheck, - SpecialAccessCheck specialAccessCheck) { + SpecialAccessCheck specialAccessCheck, + String serverCountry) { PersonalDataFieldAccessChecker personalFieldAccessChecker = inJurisdiction - ? PersonalDataFieldAccessChecker.inJurisdiction(rightCheck::hasRight, specialAccessCheck) - : PersonalDataFieldAccessChecker.outsideJurisdiction(rightCheck::hasRight, specialAccessCheck); + ? PersonalDataFieldAccessChecker.inJurisdiction(rightCheck::hasRight, specialAccessCheck, serverCountry) + : PersonalDataFieldAccessChecker.outsideJurisdiction(rightCheck::hasRight, specialAccessCheck, serverCountry); SensitiveDataFieldAccessChecker sensitiveFieldAccessChecker = inJurisdiction - ? SensitiveDataFieldAccessChecker.inJurisdiction(rightCheck::hasRight, specialAccessCheck) - : SensitiveDataFieldAccessChecker.outsideJurisdiction(rightCheck::hasRight, specialAccessCheck); + ? SensitiveDataFieldAccessChecker.inJurisdiction(rightCheck::hasRight, specialAccessCheck, serverCountry) + : SensitiveDataFieldAccessChecker.outsideJurisdiction(rightCheck::hasRight, specialAccessCheck, serverCountry); return FieldAccessCheckers.withCheckers(Arrays.asList(personalFieldAccessChecker, sensitiveFieldAccessChecker)); } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationFacadeEjb.java index d1dee05a51f..4bbc8281817 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/vaccination/VaccinationFacadeEjb.java @@ -71,6 +71,7 @@ import de.symeda.sormas.backend.clinicalcourse.HealthConditions; import de.symeda.sormas.backend.clinicalcourse.HealthConditionsMapper; import de.symeda.sormas.backend.common.AbstractBaseEjb; +import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.contact.Contact; import de.symeda.sormas.backend.contact.ContactService; import de.symeda.sormas.backend.event.Event; @@ -113,6 +114,8 @@ public class VaccinationFacadeEjb private HealthConditionsMapper healthConditionsMapper; @EJB private SpecialCaseAccessService specialCaseAccessService; + @EJB + private ConfigFacadeEjb.ConfigFacadeEjbLocal configFacade; public VaccinationFacadeEjb() { } @@ -397,7 +400,7 @@ protected Pseudonymizer createPseudonymizer(List va SpecialAccessCheck specialAccessCheck = t -> specialAccessUuids.contains(t.getUuid()); - return Pseudonymizer.getDefault(userService, specialAccessCheck); + return Pseudonymizer.getDefault(userService, specialAccessCheck, configFacade.getCountryCode()); } @Override diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java index ea579696a92..8c1eba2a289 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/visit/VisitFacadeEjb.java @@ -87,6 +87,7 @@ import de.symeda.sormas.backend.caze.CaseFacadeEjb.CaseFacadeEjbLocal; import de.symeda.sormas.backend.caze.CaseService; import de.symeda.sormas.backend.common.AbstractBaseEjb; +import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.common.CriteriaBuilderHelper; import de.symeda.sormas.backend.common.NotificationService; import de.symeda.sormas.backend.common.messaging.MessageContents; @@ -137,6 +138,8 @@ public class VisitFacadeEjb extends AbstractBaseEjb getVisitsExportList( if (!resultList.isEmpty()) { - Pseudonymizer pseudonymizer = Pseudonymizer.getDefault(userService, getSpecialAccessChecker(resultList)); + Pseudonymizer pseudonymizer = + Pseudonymizer.getDefault(userService, getSpecialAccessChecker(resultList), configFacade.getCountryCode()); Set userIds = resultList.stream().map(VisitExportDto::getVisitUserId).filter(Objects::nonNull).collect(Collectors.toSet()); Map visitUsers = userIds.isEmpty() ? null @@ -587,7 +591,7 @@ public Visit fillOrBuildEntity(@NotNull VisitDto source, Visit target, boolean c @Override protected Pseudonymizer createPseudonymizer(List visits) { - return Pseudonymizer.getDefault(userService, getSpecialAccessChecker(visits)); + return Pseudonymizer.getDefault(userService, getSpecialAccessChecker(visits), configFacade.getCountryCode()); } private SpecialAccessCheck getSpecialAccessChecker(Collection visits) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/action/ActionEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/action/ActionEditForm.java index e1b6811807d..018be86c216 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/action/ActionEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/action/ActionEditForm.java @@ -41,6 +41,8 @@ import de.symeda.sormas.ui.utils.DateTimeField; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; +import de.symeda.sormas.ui.utils.RichTextAreaCustom; +import de.symeda.sormas.ui.utils.VaadinUiUtil; public class ActionEditForm extends AbstractEditForm { @@ -99,9 +101,12 @@ protected void addFields() { addField(ActionDto.ACTION_MEASURE, TextField.class); TextField title = addField(ActionDto.TITLE, TextField.class); title.addStyleName(SOFT_REQUIRED); - RichTextArea description = addField(ActionDto.DESCRIPTION, RichTextArea.class); + RichTextAreaCustom description = addField(ActionDto.DESCRIPTION, RichTextAreaCustom.class); + description.setNullRepresentation(""); description.setImmediate(true); + VaadinUiUtil.addGdprMessageOnClick(description); + RichTextArea reply = addField(ActionDto.REPLY, RichTextArea.class); reply.setNullRepresentation(""); reply.setImmediate(true); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java index 2f9385b057a..62ff0097a06 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java @@ -949,8 +949,10 @@ protected void addFields() { CssStyles.style(additionalDetails, CssStyles.CAPTION_HIDDEN); addField(CaseDataDto.PREGNANT, NullableOptionGroup.class); + addField(CaseDataDto.POSTPARTUM, NullableOptionGroup.class); addField(CaseDataDto.TRIMESTER, NullableOptionGroup.class); + FieldHelper.setVisibleWhen(getFieldGroup(), CaseDataDto.TRIMESTER, CaseDataDto.PREGNANT, Arrays.asList(YesNoUnknown.YES), true); addField(CaseDataDto.VACCINATION_STATUS); addFields(CaseDataDto.SMALLPOX_VACCINATION_SCAR, CaseDataDto.SMALLPOX_VACCINATION_RECEIVED); @@ -1082,8 +1084,6 @@ protected void addFields() { differentPlaceOfStayJurisdiction.setVisible(false); } - FieldHelper.setVisibleWhen(getFieldGroup(), CaseDataDto.TRIMESTER, CaseDataDto.PREGNANT, Arrays.asList(YesNoUnknown.YES), true); - diseaseField.addValueChangeListener((ValueChangeListener) valueChangeEvent -> { Disease disease = (Disease) valueChangeEvent.getProperty().getValue(); List diseaseVariants = diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java index c377cb9281f..cad1c6f6615 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java @@ -38,13 +38,17 @@ import com.vaadin.v7.ui.TextArea; import de.symeda.sormas.api.clinicalcourse.HealthConditionsDto; +import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.Descriptions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; +import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.YesNoUnknown; import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; +import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.AbstractEditForm; +import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.FieldHelper; public class HealthConditionsForm extends AbstractEditForm { @@ -52,6 +56,7 @@ public class HealthConditionsForm extends AbstractEditForm private static final long serialVersionUID = 1L; private static final String HEALTH_CONDITIONS_HEADINGS_LOC = "healthConditionsHeadingLoc"; + private static final String CONFIDENTIAL_LABEL = "confidentialLabel"; //@formatter:off private static final String HTML_LAYOUT = @@ -66,7 +71,7 @@ public class HealthConditionsForm extends AbstractEditForm CHRONIC_NEUROLOGIC_CONDITION, CARDIOVASCULAR_DISEASE_INCLUDING_HYPERTENSION, OBESITY, CURRENT_SMOKER, FORMER_SMOKER, ASTHMA, SICKLE_CELL_DISEASE)) ) + - loc(OTHER_CONDITIONS); + loc(OTHER_CONDITIONS) + loc(CONFIDENTIAL_LABEL); //@formatter:on public HealthConditionsForm(FieldVisibilityCheckers fieldVisibilityCheckers, UiFieldAccessCheckers fieldAccessCheckers) { @@ -80,39 +85,45 @@ protected void addFields() { healthConditionsHeadingLabel.addStyleName(H3); getContent().addComponent(healthConditionsHeadingLabel, HEALTH_CONDITIONS_HEADINGS_LOC); - addFields( - TUBERCULOSIS, - ASPLENIA, - HEPATITIS, - DIABETES, - HIV, - HIV_ART, - CHRONIC_LIVER_DISEASE, - MALIGNANCY_CHEMOTHERAPY, - CHRONIC_HEART_FAILURE, - CHRONIC_PULMONARY_DISEASE, - CHRONIC_KIDNEY_DISEASE, - CHRONIC_NEUROLOGIC_CONDITION, - DOWN_SYNDROME, - CONGENITAL_SYPHILIS, - IMMUNODEFICIENCY_OTHER_THAN_HIV, - CARDIOVASCULAR_DISEASE_INCLUDING_HYPERTENSION, - OBESITY, - CURRENT_SMOKER, - FORMER_SMOKER, - ASTHMA, - SICKLE_CELL_DISEASE, - IMMUNODEFICIENCY_INCLUDING_HIV); - TextArea otherConditions = addField(OTHER_CONDITIONS, TextArea.class); - otherConditions.setRows(6); - otherConditions.setDescription( - I18nProperties.getPrefixDescription(HealthConditionsDto.I18N_PREFIX, OTHER_CONDITIONS, "") + "\n" - + I18nProperties.getDescription(Descriptions.descGdpr)); - - initializeVisibilitiesAndAllowedVisibilities(); - initializeAccessAndAllowedAccesses(); - - FieldHelper.setVisibleWhen(getFieldGroup(), HIV_ART, HIV, Arrays.asList(YesNoUnknown.YES), true); + if (UiUtil.permitted(UserRight.SEE_SENSITIVE_DATA_IN_JURISDICTION)) { + addFields( + TUBERCULOSIS, + ASPLENIA, + HEPATITIS, + DIABETES, + HIV, + HIV_ART, + CHRONIC_LIVER_DISEASE, + MALIGNANCY_CHEMOTHERAPY, + CHRONIC_HEART_FAILURE, + CHRONIC_PULMONARY_DISEASE, + CHRONIC_KIDNEY_DISEASE, + CHRONIC_NEUROLOGIC_CONDITION, + DOWN_SYNDROME, + CONGENITAL_SYPHILIS, + IMMUNODEFICIENCY_OTHER_THAN_HIV, + CARDIOVASCULAR_DISEASE_INCLUDING_HYPERTENSION, + OBESITY, + CURRENT_SMOKER, + FORMER_SMOKER, + ASTHMA, + SICKLE_CELL_DISEASE, + IMMUNODEFICIENCY_INCLUDING_HIV); + TextArea otherConditions = addField(OTHER_CONDITIONS, TextArea.class); + otherConditions.setRows(6); + otherConditions.setDescription( + I18nProperties.getPrefixDescription(HealthConditionsDto.I18N_PREFIX, OTHER_CONDITIONS, "") + "\n" + + I18nProperties.getDescription(Descriptions.descGdpr)); + + initializeVisibilitiesAndAllowedVisibilities(); + initializeAccessAndAllowedAccesses(); + + FieldHelper.setVisibleWhen(getFieldGroup(), HIV_ART, HIV, Arrays.asList(YesNoUnknown.YES), true); + } else { + Label confidentialLabel = new Label(I18nProperties.getCaption(Captions.inaccessibleValue)); + confidentialLabel.addStyleName(CssStyles.INACCESSIBLE_LABEL); + getContent().addComponent(confidentialLabel, CONFIDENTIAL_LABEL); + } } @Override diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataForm.java index c704207bec8..7d3a92e2013 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataForm.java @@ -454,7 +454,7 @@ protected void addFields() { diseaseVariantDetailsField.setVisible(diseaseVariant != null && diseaseVariant.matchPropertyValue(DiseaseVariant.HAS_DETAILS, true)); }); - setRequired(true, EventDto.EVENT_STATUS, EventDto.UUID, EventDto.EVENT_TITLE, EventDto.REPORT_DATE_TIME, EventDto.REPORTING_USER); + setRequired(true, EventDto.EVENT_STATUS, EventDto.UUID, EventDto.EVENT_TITLE, EventDto.REPORT_DATE_TIME); reportDate.addValidator( new DateComparisonValidator( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskEditForm.java index 6b28f33007c..63d02222c71 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskEditForm.java @@ -63,6 +63,7 @@ import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; import de.symeda.sormas.ui.utils.TaskStatusValidator; +import de.symeda.sormas.ui.utils.VaadinUiUtil; import de.symeda.sormas.ui.utils.components.MultiSelect; @SuppressWarnings("deprecation") @@ -161,7 +162,11 @@ protected void addFields() { TextArea creatorComment = addField(TaskDto.CREATOR_COMMENT, TextArea.class); creatorComment.setRows(2); creatorComment.setImmediate(true); - addField(TaskDto.ASSIGNEE_REPLY, TextArea.class).setRows(4); + VaadinUiUtil.addGdprMessageOnClick(creatorComment); + + TextArea assigneeReply = addField(TaskDto.ASSIGNEE_REPLY, TextArea.class); + assigneeReply.setRows(4); + VaadinUiUtil.addGdprMessageOnClick(assigneeReply); MultiSelect observerUsers = addField(TaskDto.OBSERVER_USERS, MultiSelect.class); observerUsers.addValueChangeListener(e -> { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/AbstractEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/AbstractEditForm.java index 5e91c4022b7..1162f807383 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/AbstractEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/AbstractEditForm.java @@ -564,6 +564,10 @@ protected void initializeAccessAndAllowedAccesses() { if (field instanceof ComboBoxWithPlaceholder) { FieldHelper.setComboInaccessible((ComboBoxWithPlaceholder) field); } + + if (field instanceof NullableOptionGroup) { + ((NullableOptionGroup) field).setInaccessible(); + } } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/NullableOptionGroup.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/NullableOptionGroup.java index 91dd75ae380..69a6fcfb312 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/NullableOptionGroup.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/NullableOptionGroup.java @@ -23,9 +23,13 @@ import org.apache.commons.lang3.ObjectUtils; import com.vaadin.v7.data.Container; +import com.vaadin.v7.data.Item; import com.vaadin.v7.data.util.converter.Converter; import com.vaadin.v7.ui.OptionGroup; +import de.symeda.sormas.api.i18n.Captions; +import de.symeda.sormas.api.i18n.I18nProperties; + public class NullableOptionGroup extends OptionGroup { public NullableOptionGroup() { @@ -79,4 +83,10 @@ public void setRequired(boolean required) { private Object getFirstValue(Set value) { return value.stream().findFirst().orElse(null); } + + public void setInaccessible() { + this.removeAllItems(); + Item item = this.addItem(1); + item.getItemProperty(item.getItemPropertyIds().stream().findFirst().get()).setValue(I18nProperties.getCaption(Captions.inaccessibleValue)); + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/RichTextAreaCustom.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/RichTextAreaCustom.java new file mode 100644 index 00000000000..8f26e2c24b9 --- /dev/null +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/RichTextAreaCustom.java @@ -0,0 +1,24 @@ +package de.symeda.sormas.ui.utils; + +import com.vaadin.event.FieldEvents; +import com.vaadin.v7.ui.RichTextArea; + +public class RichTextAreaCustom extends RichTextArea { + + public void addFocusListener(FieldEvents.FocusListener listener) { + addListener(FieldEvents.FocusEvent.EVENT_ID, FieldEvents.FocusEvent.class, listener, FieldEvents.FocusListener.focusMethod); + } + + public void removeFocusListener(FieldEvents.FocusListener listener) { + removeListener(FieldEvents.FocusEvent.EVENT_ID, FieldEvents.FocusEvent.class, listener); + + } + + public void addBlurListener(FieldEvents.BlurListener listener) { + addListener(FieldEvents.BlurEvent.EVENT_ID, FieldEvents.BlurEvent.class, listener, FieldEvents.BlurListener.blurMethod); + } + + public void removeBlurListener(FieldEvents.BlurListener listener) { + removeListener(FieldEvents.BlurEvent.EVENT_ID, FieldEvents.BlurEvent.class, listener); + } +} diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java index ad062f3b4b8..d8109192d5e 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java @@ -179,6 +179,8 @@ public T createField(Class type, Class fieldType) { return (T) new UserField(); } else if (CheckBoxTree.class.isAssignableFrom(fieldType)) { return (T) new CheckBoxTree<>(); + } else if (RichTextAreaCustom.class.isAssignableFrom(fieldType)) { + return (T) new RichTextAreaCustom(); } return super.createField(type, fieldType); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/VaadinUiUtil.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/VaadinUiUtil.java index a4de6114cdf..84509ae6295 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/VaadinUiUtil.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/VaadinUiUtil.java @@ -21,6 +21,7 @@ import java.math.RoundingMode; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.UnaryOperator; @@ -43,12 +44,15 @@ import com.vaadin.v7.data.Item; import com.vaadin.v7.data.util.GeneratedPropertyContainer; import com.vaadin.v7.data.util.PropertyValueGenerator; +import com.vaadin.v7.ui.AbstractField; import com.vaadin.v7.ui.Grid; +import com.vaadin.v7.ui.TextArea; import com.vaadin.v7.ui.renderers.HtmlRenderer; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; +import de.symeda.sormas.api.user.UserDto; public final class VaadinUiUtil { @@ -632,4 +636,65 @@ public static void showWarningPopup(String message) { popupWindow.addCloseListener(e -> popupWindow.close()); popupWindow.setWidth(400, Unit.PIXELS); } + + public static void addGdprMessageOnClick(TextArea textArea) { + AtomicBoolean gdprMessageTriggered = new AtomicBoolean(false); + Window subWindowGdpR = VaadinUiUtil.createPopupWindow(); + + textArea.addFocusListener(i -> { + showGdprWindow(textArea, gdprMessageTriggered, subWindowGdpR); + }); + + textArea.addBlurListener(blurEvent -> { + if (gdprMessageTriggered.get() && subWindowGdpR.getParent() == null) { + gdprMessageTriggered.set(false); + } + }); + } + + public static void addGdprMessageOnClick(RichTextAreaCustom richTextArea) { + AtomicBoolean gdprMessageTriggered = new AtomicBoolean(false); + Window subWindowGdpR = VaadinUiUtil.createPopupWindow(); + + richTextArea.addValueChangeListener(event -> { + if (!gdprMessageTriggered.get()) { + showGdprWindow(richTextArea, gdprMessageTriggered, subWindowGdpR); + subWindowGdpR.focus(); + gdprMessageTriggered.set(true); + } + }); + } + + private static void showGdprWindow(AbstractField textArea, AtomicBoolean gdprMessageTriggered, Window subWindowGdpR) { + if (!gdprMessageTriggered.get()) { + gdprMessageTriggered.set(true); + subWindowGdpR.setCaption(I18nProperties.getPrefixCaption(UserDto.I18N_PREFIX, UserDto.HAS_CONSENTED_TO_GDPR)); + VerticalLayout subContentGdpr = new VerticalLayout(); + subWindowGdpR.setContent(subContentGdpr); + subWindowGdpR.center(); + subWindowGdpR.setWidth("40%"); + subWindowGdpR.setModal(true); + subWindowGdpR.setClosable(true); + + Label textGdpr = new Label(); + textGdpr.setWidth("80%"); + textGdpr.setSizeFull(); + textGdpr.setValue(I18nProperties.getString(Strings.messageGdpr)); + subContentGdpr.addComponent(textGdpr); + + HorizontalLayout buttonLayout = new HorizontalLayout(); + buttonLayout.setMargin(false); + buttonLayout.setSpacing(true); + buttonLayout.setWidth(100, Unit.PERCENTAGE); + Button buttonGdpr = ButtonHelper.createButton(I18nProperties.getCaption(Captions.actionConfirm), event -> { + subWindowGdpR.close(); + textArea.focus(); + }, ValoTheme.BUTTON_PRIMARY); + buttonLayout.addComponent(buttonGdpr); + subContentGdpr.addComponent(buttonLayout); + buttonLayout.setComponentAlignment(buttonGdpr, Alignment.BOTTOM_RIGHT); + buttonLayout.setExpandRatio(buttonGdpr, 0); + UI.getCurrent().addWindow(subWindowGdpR); + } + } } From 946919913eb78e58fda6c63f3d7b29e0db8fe9c5 Mon Sep 17 00:00:00 2001 From: SergiuPacurariu Date: Fri, 25 Oct 2024 14:30:58 +0300 Subject: [PATCH 2/5] #13093 - Update Data Protection for certain Data Fields --- .../fieldaccess/UiFieldAccessCheckers.java | 25 +++++----- .../PseudonymizedFieldAccessChecker.java | 48 +++++++++++++++---- .../ActivityAsCase/ActivityAsCaseField.java | 5 +- .../symeda/sormas/ui/caze/CaseController.java | 9 ++-- .../symeda/sormas/ui/caze/CaseDataForm.java | 4 +- .../symeda/sormas/ui/caze/CaseInfoLayout.java | 7 +-- .../maternalhistory/MaternalHistoryForm.java | 5 +- .../porthealthinfo/PortHealthInfoForm.java | 5 +- .../SurveillanceReportForm.java | 10 +--- .../SurveillanceReportList.java | 4 +- .../ui/clinicalcourse/ClinicalCourseForm.java | 5 +- .../ui/clinicalcourse/ClinicalVisitForm.java | 6 ++- .../ui/clinicalcourse/ClinicalVisitGrid.java | 5 +- .../sormas/ui/contact/ContactDataForm.java | 4 +- .../ui/environment/EnvironmentDataForm.java | 5 +- .../symeda/sormas/ui/epidata/EpiDataForm.java | 5 +- .../sormas/ui/events/EventDataForm.java | 4 +- .../ui/events/EventParticipantEditForm.java | 4 +- .../SuperordinateEventComponent.java | 8 +--- .../sormas/ui/exposure/ExposuresField.java | 5 +- ...ciansReportCaseImmunizationsComponent.java | 18 +++---- .../hospitalization/HospitalizationForm.java | 4 +- .../components/form/ImmunizationDataForm.java | 4 +- .../ui/person/PersonContactDetailsField.java | 6 ++- .../sormas/ui/person/PersonCreateForm.java | 2 +- .../sormas/ui/person/PersonEditForm.java | 9 ++-- .../sormas/ui/samples/PathogenTestForm.java | 7 +-- .../EnvironmentSampleEditForm.java | 2 +- .../samples/humansample/SampleDataView.java | 11 ++--- .../samples/humansample/SampleEditForm.java | 8 +--- .../ui/selfreport/SelfReportDataForm.java | 5 +- .../de/symeda/sormas/ui/task/TaskGrid.java | 2 +- .../sormas/ui/therapy/PrescriptionForm.java | 5 +- .../sormas/ui/therapy/PrescriptionGrid.java | 5 +- .../sormas/ui/therapy/TreatmentForm.java | 5 +- .../sormas/ui/therapy/TreatmentGrid.java | 5 +- .../ui/travelentry/TravelEntryDataForm.java | 3 +- .../FieldAccessColumnStyleGenerator.java | 11 ++++- .../sormas/ui/utils/FieldAccessHelper.java | 19 ++++++++ .../ui/vaccination/list/VaccinationList.java | 6 +-- .../symeda/sormas/ui/visit/VisitEditForm.java | 5 +- 41 files changed, 173 insertions(+), 142 deletions(-) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/UiFieldAccessCheckers.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/UiFieldAccessCheckers.java index 26c1b2e5c9f..555e1913608 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/UiFieldAccessCheckers.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/UiFieldAccessCheckers.java @@ -48,41 +48,44 @@ public static UiFieldAccessCheckers getNoop() { return new UiFieldAccessCheckers<>(); } - public static UiFieldAccessCheckers getDefault(boolean isPseudonymized) { + public static UiFieldAccessCheckers getDefault(boolean isPseudonymized, String serverCountry) { UiFieldAccessCheckers fieldAccessCheckers = new UiFieldAccessCheckers<>(); - fieldAccessCheckers.add(PseudonymizedFieldAccessChecker.forPersonalData(isPseudonymized)) - .add(PseudonymizedFieldAccessChecker.forSensitiveData(isPseudonymized)); + fieldAccessCheckers.add(PseudonymizedFieldAccessChecker.forPersonalData(isPseudonymized, serverCountry)) + .add(PseudonymizedFieldAccessChecker.forSensitiveData(isPseudonymized, serverCountry)); return fieldAccessCheckers; } - public static UiFieldAccessCheckers forPersonalData(boolean isPseudonymized) { + public static UiFieldAccessCheckers forPersonalData(boolean isPseudonymized, String serverCountry) { UiFieldAccessCheckers fieldAccessCheckers = new UiFieldAccessCheckers<>(); - fieldAccessCheckers.add(PseudonymizedFieldAccessChecker.forPersonalData(isPseudonymized)); + fieldAccessCheckers.add(PseudonymizedFieldAccessChecker.forPersonalData(isPseudonymized, serverCountry)); return fieldAccessCheckers; } - public static UiFieldAccessCheckers forSensitiveData(boolean isPseudonymized) { + public static UiFieldAccessCheckers forSensitiveData(boolean isPseudonymized, String serverCountry) { UiFieldAccessCheckers fieldAccessCheckers = new UiFieldAccessCheckers<>(); - fieldAccessCheckers.add(PseudonymizedFieldAccessChecker.forSensitiveData(isPseudonymized)); + fieldAccessCheckers.add(PseudonymizedFieldAccessChecker.forSensitiveData(isPseudonymized, serverCountry)); return fieldAccessCheckers; } - public static UiFieldAccessCheckers forDataAccessLevel(PseudonymizableDataAccessLevel accessLevel, boolean isPseudonymized) { + public static UiFieldAccessCheckers forDataAccessLevel( + PseudonymizableDataAccessLevel accessLevel, + boolean isPseudonymized, + String serverCountry) { switch (accessLevel) { case ALL: case NONE: - return getDefault(isPseudonymized); + return getDefault(isPseudonymized, serverCountry); case PERSONAL: - return forSensitiveData(isPseudonymized); + return forSensitiveData(isPseudonymized, serverCountry); case SENSITIVE: - return forPersonalData(isPseudonymized); + return forPersonalData(isPseudonymized, serverCountry); default: throw new IllegalArgumentException(accessLevel.name()); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/PseudonymizedFieldAccessChecker.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/PseudonymizedFieldAccessChecker.java index 28605b139fa..c88550f853c 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/PseudonymizedFieldAccessChecker.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/fieldaccess/checkers/PseudonymizedFieldAccessChecker.java @@ -17,6 +17,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.util.Arrays; import de.symeda.sormas.api.utils.EmbeddedPersonalData; import de.symeda.sormas.api.utils.EmbeddedSensitiveData; @@ -24,15 +25,16 @@ import de.symeda.sormas.api.utils.SensitiveData; import de.symeda.sormas.api.utils.fieldaccess.FieldAccessChecker; -public final class PseudonymizedFieldAccessChecker implements FieldAccessChecker { +public abstract class PseudonymizedFieldAccessChecker implements FieldAccessChecker { private final WrappedFieldAccessChecker wrapped; - public PseudonymizedFieldAccessChecker( + private PseudonymizedFieldAccessChecker( Class annotation, Class embeddedAnnotation, - boolean isPseudonymized) { - this.wrapped = new WrappedFieldAccessChecker(annotation, embeddedAnnotation, isPseudonymized); + boolean isPseudonymized, + String serverCountry) { + this.wrapped = new WrappedFieldAccessChecker(annotation, embeddedAnnotation, isPseudonymized, serverCountry); } @Override @@ -56,24 +58,52 @@ public boolean hasRight(T object) { private final class WrappedFieldAccessChecker extends AnnotationBasedFieldAccessChecker { + private final String serverCountry; + private WrappedFieldAccessChecker( Class annotation, Class embeddedAnnotation, - boolean isPseudonymized) { + boolean isPseudonymized, + String serverCountry) { super(annotation, embeddedAnnotation, !isPseudonymized, t -> false); + this.serverCountry = serverCountry; } @Override protected boolean isAnnotatedFieldMandatory(Field annotatedField) { return false; } + + @Override + public boolean isConfiguredForCheck(Field field, boolean withMandatory) { + if (isExcludedForCountry(field, serverCountry)) { + return false; + } + return super.isConfiguredForCheck(field, withMandatory); + } } - public static PseudonymizedFieldAccessChecker forPersonalData(boolean isPseudonymized) { - return new PseudonymizedFieldAccessChecker<>(PersonalData.class, EmbeddedPersonalData.class, isPseudonymized); + protected abstract boolean isExcludedForCountry(Field field, String serverCountry); + + public static PseudonymizedFieldAccessChecker forPersonalData(boolean isPseudonymized, String serverCountry) { + return new PseudonymizedFieldAccessChecker<>(PersonalData.class, EmbeddedPersonalData.class, isPseudonymized, serverCountry) { + + @Override + protected boolean isExcludedForCountry(Field field, String serverCountry) { + return field.getAnnotation(PersonalData.class) != null + && Arrays.asList(field.getAnnotation(PersonalData.class).excludeForCountries()).contains(serverCountry); + } + }; } - public static PseudonymizedFieldAccessChecker forSensitiveData(boolean isPseudonymized) { - return new PseudonymizedFieldAccessChecker<>(SensitiveData.class, EmbeddedSensitiveData.class, isPseudonymized); + public static PseudonymizedFieldAccessChecker forSensitiveData(boolean isPseudonymized, String serverCountry) { + return new PseudonymizedFieldAccessChecker<>(SensitiveData.class, EmbeddedSensitiveData.class, isPseudonymized, serverCountry) { + + @Override + protected boolean isExcludedForCountry(Field field, String serverCountry) { + return field.getAnnotation(SensitiveData.class) != null + && Arrays.asList(field.getAnnotation(SensitiveData.class).excludeForCountries()).contains(serverCountry); + } + }; } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/ActivityAsCase/ActivityAsCaseField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/ActivityAsCase/ActivityAsCaseField.java index 95f37cd7415..fbfc08b132e 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/ActivityAsCase/ActivityAsCaseField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/ActivityAsCase/ActivityAsCaseField.java @@ -31,6 +31,7 @@ import com.vaadin.v7.ui.Label; import com.vaadin.v7.ui.Table; +import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.activityascase.ActivityAsCaseDto; import de.symeda.sormas.api.activityascase.ActivityAsCaseType; import de.symeda.sormas.api.event.TypeOfPlace; @@ -80,7 +81,9 @@ protected void updateColumns() { .setVisibleColumns(ACTION_COLUMN_ID, COLUMN_ACTIVITY_AS_CASE_TYPE, COLUMN_TYPE_OF_PLACE, COLUMN_DATE, COLUMN_ADDRESS, COLUMN_DESCRIPTION); table.setCellStyleGenerator( - FieldAccessCellStyleGenerator.withFieldAccessCheckers(ActivityAsCaseDto.class, UiFieldAccessCheckers.forSensitiveData(isPseudonymized))); + FieldAccessCellStyleGenerator.withFieldAccessCheckers( + ActivityAsCaseDto.class, + UiFieldAccessCheckers.forSensitiveData(isPseudonymized, FacadeProvider.getConfigFacade().getCountryLocale()))); for (Object columnId : table.getVisibleColumns()) { if (!columnId.equals(ACTION_COLUMN_ID)) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java index f6f1a2cb389..92d01dd0a56 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseController.java @@ -110,7 +110,6 @@ import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.ValidationRuntimeException; import de.symeda.sormas.api.utils.YesNoUnknown; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.uuid.HasUuid; import de.symeda.sormas.api.visit.VisitDto; import de.symeda.sormas.ui.ControllerProvider; @@ -141,6 +140,7 @@ import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DeleteRestoreHandlers; import de.symeda.sormas.ui.utils.DetailSubComponentWrapper; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; import de.symeda.sormas.ui.utils.VaadinUiUtil; import de.symeda.sormas.ui.utils.ViewMode; @@ -1298,8 +1298,7 @@ public CommitDiscardWrapperComponent getSymptomsEditComponent(fina person, SymptomsContext.CASE, viewMode, - UiFieldAccessCheckers - .forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(caseDataDto.isInJurisdiction()), caseDataDto.isPseudonymized())); + FieldAccessHelper.getFieldAccessCheckers(caseDataDto)); symptomsForm.setValue(caseDataDto.getSymptoms()); CommitDiscardWrapperComponent editView = @@ -1381,9 +1380,7 @@ public DetailSubComponentWrapper getExternalDataComponent(final String caseUuid, CaseDataDto caseDataDto = findCase(caseUuid); - CaseExternalDataForm caseExternalDataForm = new CaseExternalDataForm( - UiFieldAccessCheckers - .forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(caseDataDto.isInJurisdiction()), caseDataDto.isPseudonymized())); + CaseExternalDataForm caseExternalDataForm = new CaseExternalDataForm(FieldAccessHelper.getFieldAccessCheckers(caseDataDto)); caseExternalDataForm.setValue(caseDataDto); DetailSubComponentWrapper wrapper = new DetailSubComponentWrapper(() -> null); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java index b9e57040952..b2f181ee080 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java @@ -118,7 +118,6 @@ import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.ExtendedReduced; import de.symeda.sormas.api.utils.YesNoUnknown; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; import de.symeda.sormas.api.utils.fieldvisibility.checkers.CountryFieldVisibilityChecker; import de.symeda.sormas.api.utils.fieldvisibility.checkers.FeatureTypeFieldVisibilityChecker; @@ -135,6 +134,7 @@ import de.symeda.sormas.ui.utils.ConfirmationComponent; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateComparisonValidator; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.InfrastructureFieldsHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; @@ -327,7 +327,7 @@ public CaseDataForm( .add(new CountryFieldVisibilityChecker(FacadeProvider.getConfigFacade().getCountryLocale())) .add(new UserRightFieldVisibilityChecker(UiUtil::permitted)) .add(new FeatureTypeFieldVisibilityChecker(FacadeProvider.getFeatureConfigurationFacade().getActiveServerFeatureConfigurations())), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); this.caseUuid = caseUuid; this.person = person; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseInfoLayout.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseInfoLayout.java index fd7a689f335..529827e3de6 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseInfoLayout.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseInfoLayout.java @@ -32,11 +32,11 @@ import de.symeda.sormas.api.symptoms.SymptomsDto; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.DataHelper; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.ui.AbstractInfoLayout; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.DateFormatHelper; +import de.symeda.sormas.ui.utils.FieldAccessHelper; @SuppressWarnings("serial") public class CaseInfoLayout extends AbstractInfoLayout { @@ -49,10 +49,7 @@ public CaseInfoLayout(CaseDataDto caseDto) { } public CaseInfoLayout(CaseDataDto caseDto, boolean isTravelEntry) { - super( - CaseDataDto.class, - UiFieldAccessCheckers - .forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(caseDto.isInJurisdiction()), caseDto.isPseudonymized())); + super(CaseDataDto.class, FieldAccessHelper.getFieldAccessCheckers(caseDto)); this.caseDto = caseDto; this.isTravelEntry = isTravelEntry; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/maternalhistory/MaternalHistoryForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/maternalhistory/MaternalHistoryForm.java index 9bfc0a029ed..75a24f1bb71 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/maternalhistory/MaternalHistoryForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/maternalhistory/MaternalHistoryForm.java @@ -18,10 +18,9 @@ import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto; import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; import de.symeda.sormas.api.utils.YesNoUnknown; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.AbstractEditForm; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; import de.symeda.sormas.ui.utils.ViewMode; @@ -55,7 +54,7 @@ public MaternalHistoryForm(ViewMode viewMode, boolean isPseudonymized, boolean i MaternalHistoryDto.I18N_PREFIX, true, new FieldVisibilityCheckers(), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); this.viewMode = viewMode; } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java index 52abe79dec9..2fecf46b4c4 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/porthealthinfo/PortHealthInfoForm.java @@ -24,13 +24,12 @@ import de.symeda.sormas.api.infrastructure.pointofentry.PointOfEntryReferenceDto; import de.symeda.sormas.api.utils.DataHelper; import de.symeda.sormas.api.utils.YesNoUnknown; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateComparisonValidator; import de.symeda.sormas.ui.utils.DateTimeField; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; @@ -83,7 +82,7 @@ public PortHealthInfoForm(PointOfEntryDto pointOfEntry, String pointOfEntryDetai PortHealthInfoDto.I18N_PREFIX, false, FieldVisibilityCheckers.withCountry(FacadeProvider.getConfigFacade().getCountryLocale()), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), pseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, pseudonymized)); this.pointOfEntry = pointOfEntry; this.pointOfEntryDetails = pointOfEntryDetails; this.pseudonymized = pseudonymized; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportForm.java index dfd24c9a6b2..880ee52d8d6 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/surveillancereport/SurveillanceReportForm.java @@ -24,10 +24,9 @@ import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.infrastructure.facility.FacilityTypeGroup; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.ComboBoxHelper; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.InfrastructureFieldsHelper; public class SurveillanceReportForm extends AbstractEditForm { @@ -46,12 +45,7 @@ public class SurveillanceReportForm extends AbstractEditForm { @@ -19,7 +18,7 @@ public ClinicalCourseForm(boolean isPseudonymized, boolean inJurisdiction) { ClinicalCourseDto.I18N_PREFIX, true, FieldVisibilityCheckers.withCountry(FacadeProvider.getConfigFacade().getCountryLocale()), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); } @Override diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/ClinicalVisitForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/ClinicalVisitForm.java index 36b9e4926a0..ce80ece4dbe 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/ClinicalVisitForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/ClinicalVisitForm.java @@ -6,6 +6,7 @@ import com.vaadin.v7.ui.TextField; import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.clinicalcourse.ClinicalVisitDto; import de.symeda.sormas.api.i18n.Descriptions; import de.symeda.sormas.api.i18n.I18nProperties; @@ -36,7 +37,10 @@ public ClinicalVisitForm(boolean create, Disease disease, PersonDto person, bool ClinicalVisitDto.I18N_PREFIX, false, new FieldVisibilityCheckers(), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + UiFieldAccessCheckers.forDataAccessLevel( + UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), + isPseudonymized, + FacadeProvider.getConfigFacade().getCountryLocale())); if (create) { hideValidationUntilNextCommit(); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/ClinicalVisitGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/ClinicalVisitGrid.java index 1318e7b3e78..fbebeec4aa3 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/ClinicalVisitGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/ClinicalVisitGrid.java @@ -66,8 +66,9 @@ public ClinicalVisitGrid(CaseReferenceDto caseRef, boolean isPseudonymized, bool } setCellStyleGenerator( - FieldAccessCellStyleGenerator - .withFieldAccessCheckers(ClinicalVisitIndexDto.class, UiFieldAccessCheckers.forSensitiveData(isPseudonymized))); + FieldAccessCellStyleGenerator.withFieldAccessCheckers( + ClinicalVisitIndexDto.class, + UiFieldAccessCheckers.forSensitiveData(isPseudonymized, FacadeProvider.getConfigFacade().getCountryLocale()))); addItemClickListener(e -> { if (ACTION_BTN_ID.equals(e.getPropertyId()) || e.isDoubleClick()) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataForm.java index 5b0fe16c52c..e76a5f9ad9b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataForm.java @@ -81,7 +81,6 @@ import de.symeda.sormas.api.utils.Diseases.DiseasesConfiguration; import de.symeda.sormas.api.utils.ExtendedReduced; import de.symeda.sormas.api.utils.YesNoUnknown; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.UiUtil; @@ -90,6 +89,7 @@ import de.symeda.sormas.ui.utils.ButtonHelper; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateComparisonValidator; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.LayoutUtil; import de.symeda.sormas.ui.utils.NullableOptionGroup; @@ -204,7 +204,7 @@ public ContactDataForm(Disease disease, ViewMode viewMode, boolean isPseudonymiz FieldVisibilityCheckers.withDisease(disease) .andWithCountry(FacadeProvider.getConfigFacade().getCountryLocale()) .andWithFeatureType(FacadeProvider.getFeatureConfigurationFacade().getActiveServerFeatureConfigurations()), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); this.viewMode = viewMode; this.disease = disease; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/environment/EnvironmentDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/environment/EnvironmentDataForm.java index 154a0bedbd4..96fed8d8d73 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/environment/EnvironmentDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/environment/EnvironmentDataForm.java @@ -30,13 +30,12 @@ import de.symeda.sormas.api.user.JurisdictionLevel; import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.user.UserRight; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.location.LocationEditForm; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.CheckBoxTree; import de.symeda.sormas.ui.utils.CssStyles; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.ResizableTextAreaWrapper; import de.symeda.sormas.ui.utils.UserField; @@ -71,7 +70,7 @@ public EnvironmentDataForm(boolean isPseudonymized, boolean inJurisdiction, bool EnvironmentDto.I18N_PREFIX, false, FieldVisibilityCheckers.withCountry(FacadeProvider.getConfigFacade().getCountryLocale()), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized), + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized), isEditAllowed); addFields(); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/epidata/EpiDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/epidata/EpiDataForm.java index 21f396a0e1f..81fa1fe4cd6 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/epidata/EpiDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/epidata/EpiDataForm.java @@ -44,12 +44,11 @@ import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; import de.symeda.sormas.api.utils.YesNoUnknown; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.ActivityAsCase.ActivityAsCaseField; import de.symeda.sormas.ui.exposure.ExposuresField; import de.symeda.sormas.ui.utils.AbstractEditForm; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; import de.symeda.sormas.ui.utils.components.MultilineLabel; @@ -98,7 +97,7 @@ public EpiDataForm( EpiDataDto.I18N_PREFIX, false, FieldVisibilityCheckers.withDisease(disease).andWithCountry(FacadeProvider.getConfigFacade().getCountryLocale()), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized), + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized), isEditAllowed); this.disease = disease; this.parentClass = parentClass; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataForm.java index 7d3a92e2013..6fdfd864d4b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventDataForm.java @@ -79,13 +79,13 @@ import de.symeda.sormas.api.utils.YesNoUnknown; import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.location.LocationEditForm; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.CheckBoxTree; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateComparisonValidator; import de.symeda.sormas.ui.utils.DateTimeField; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; import de.symeda.sormas.ui.utils.PhoneNumberValidator; @@ -197,7 +197,7 @@ private static UiFieldAccessCheckers createFieldAccessCheckers( boolean withPersonalAndSensitive) { if (withPersonalAndSensitive) { - return UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized); + return FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized); } return UiFieldAccessCheckers.getNoop(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantEditForm.java index 0ceb8e3094d..4b4a439cd83 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/EventParticipantEditForm.java @@ -32,10 +32,10 @@ import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; import de.symeda.sormas.api.location.LocationDto; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.AbstractEditForm; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.UserField; @@ -63,7 +63,7 @@ public EventParticipantEditForm(EventDto event, boolean isPseudonymized, boolean EventParticipantDto.I18N_PREFIX, false, FieldVisibilityCheckers.withDisease(event.getDisease()), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); this.event = event; addFields(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventLink/SuperordinateEventComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventLink/SuperordinateEventComponent.java index 6c51364f2ad..71cdf0688e1 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventLink/SuperordinateEventComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/events/eventLink/SuperordinateEventComponent.java @@ -33,13 +33,13 @@ import de.symeda.sormas.api.i18n.Strings; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.DataHelper; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.ui.AbstractInfoLayout; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.ButtonHelper; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateFormatHelper; +import de.symeda.sormas.ui.utils.FieldAccessHelper; public class SuperordinateEventComponent extends VerticalLayout { @@ -129,11 +129,7 @@ private class SuperordinateEventInfoLayout extends AbstractInfoLayout private final EventDto superordinateEvent; public SuperordinateEventInfoLayout(EventDto superordinateEvent) { - super( - EventDto.class, - UiFieldAccessCheckers.forDataAccessLevel( - UiUtil.getPseudonymizableDataAccessLevel(superordinateEvent.isInJurisdiction()), - superordinateEvent.isPseudonymized())); + super(EventDto.class, FieldAccessHelper.getFieldAccessCheckers(superordinateEvent)); this.superordinateEvent = superordinateEvent; setSpacing(true); setMargin(false); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java index 3bdde88a1e1..4b02af90252 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/exposure/ExposuresField.java @@ -32,6 +32,7 @@ import com.vaadin.v7.ui.Table; import de.symeda.sormas.api.EntityDto; +import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.caze.CaseDataDto; import de.symeda.sormas.api.contact.ContactDto; import de.symeda.sormas.api.contact.ContactReferenceDto; @@ -112,7 +113,9 @@ protected void updateColumns() { COLUMN_DESCRIPTION); } table.setCellStyleGenerator( - FieldAccessCellStyleGenerator.withFieldAccessCheckers(ExposureDto.class, UiFieldAccessCheckers.forSensitiveData(isPseudonymized))); + FieldAccessCellStyleGenerator.withFieldAccessCheckers( + ExposureDto.class, + UiFieldAccessCheckers.forSensitiveData(isPseudonymized, FacadeProvider.getConfigFacade().getCountryLocale()))); for (Object columnId : table.getVisibleColumns()) { if (columnId.equals(ACTION_COLUMN_ID)) { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/physiciansreport/PhysiciansReportCaseImmunizationsComponent.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/physiciansreport/PhysiciansReportCaseImmunizationsComponent.java index ee1f9f9e4bf..bc2c86116a7 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/physiciansreport/PhysiciansReportCaseImmunizationsComponent.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/externalmessage/physiciansreport/PhysiciansReportCaseImmunizationsComponent.java @@ -57,6 +57,7 @@ import de.symeda.sormas.ui.utils.DateFormatHelper; import de.symeda.sormas.ui.utils.DeletableUtils; import de.symeda.sormas.ui.utils.DirtyCheckPopup; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.vaccination.VaccinationEditForm; public class PhysiciansReportCaseImmunizationsComponent extends CommitDiscardWrapperComponent { @@ -210,18 +211,11 @@ private void handleEditVaccination(VaccinationDto vaccination, CaseDataDto caze) VaccinationListItem collapsedComponent = vaccinationList.getItemByVaccination(vaccination); currentVaccinationEditComponent = ControllerProvider.getVaccinationController() - .getVaccinationEditComponent( - vaccination, - caze.getDisease(), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(caze.isInJurisdiction()), caze.isPseudonymized()), - false, - (v) -> { - if (!vaccinationsToCreate.contains(v)) { - vaccinationsToUpdate.add(v); - } - }, - true, - UiUtil.permitted(UserRight.IMMUNIZATION_DELETE)); + .getVaccinationEditComponent(vaccination, caze.getDisease(), FieldAccessHelper.getFieldAccessCheckers(caze), false, (v) -> { + if (!vaccinationsToCreate.contains(v)) { + vaccinationsToUpdate.add(v); + } + }, true, UiUtil.permitted(UserRight.IMMUNIZATION_DELETE)); currentVaccinationEditComponent.getDiscardButton().setCaption(I18nProperties.getCaption(Captions.actionCancel)); currentVaccinationEditComponent.getButtonsPanel() diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/hospitalization/HospitalizationForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/hospitalization/HospitalizationForm.java index 716ba30ac49..7f00d8bdc11 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/hospitalization/HospitalizationForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/hospitalization/HospitalizationForm.java @@ -50,12 +50,12 @@ import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.DateComparator; import de.symeda.sormas.api.utils.YesNoUnknown; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateComparisonValidator; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; import de.symeda.sormas.ui.utils.OutbreakFieldVisibilityChecker; @@ -100,7 +100,7 @@ public HospitalizationForm(CaseDataDto caze, ViewMode viewMode, boolean isPseudo false, FieldVisibilityCheckers.withCountry(FacadeProvider.getConfigFacade().getCountryLocale()) .add(new OutbreakFieldVisibilityChecker(viewMode)), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized), + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized), isEditAllowed); this.caze = caze; this.viewMode = viewMode; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/form/ImmunizationDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/form/ImmunizationDataForm.java index af1e2f96a19..fbe86c47094 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/form/ImmunizationDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/immunization/components/form/ImmunizationDataForm.java @@ -66,7 +66,6 @@ import de.symeda.sormas.api.infrastructure.facility.FacilityType; import de.symeda.sormas.api.infrastructure.facility.FacilityTypeGroup; import de.symeda.sormas.api.utils.YesNoUnknown; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.SearchSpecificLayout; @@ -78,6 +77,7 @@ import de.symeda.sormas.ui.utils.ComboBoxWithPlaceholder; import de.symeda.sormas.ui.utils.ConfirmationComponent; import de.symeda.sormas.ui.utils.DateComparisonValidator; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.InfrastructureFieldsHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; @@ -139,7 +139,7 @@ public ImmunizationDataForm(boolean isPseudonymized, boolean inJurisdiction, Cas ImmunizationDto.I18N_PREFIX, false, FieldVisibilityCheckers.withCountry(FacadeProvider.getConfigFacade().getCountryLocale()), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); this.relatedCase = relatedCase; this.actionCallback = actionCallback; addFields(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonContactDetailsField.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonContactDetailsField.java index 66c471fd9da..491cd82be6a 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonContactDetailsField.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonContactDetailsField.java @@ -11,6 +11,7 @@ import com.vaadin.v7.data.Property; import com.vaadin.v7.ui.Table; +import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; @@ -161,8 +162,9 @@ protected void updateColumns() { table.setColumnExpandRatio(ACTION_COLUMN_ID, 0); table.setCellStyleGenerator( - FieldAccessCellStyleGenerator - .withFieldAccessCheckers(PersonContactDetailDto.class, UiFieldAccessCheckers.forSensitiveData(isPseudonymized))); + FieldAccessCellStyleGenerator.withFieldAccessCheckers( + PersonContactDetailDto.class, + UiFieldAccessCheckers.forSensitiveData(isPseudonymized, FacadeProvider.getConfigFacade().getCountryLocale()))); table.setColumnExpandRatio(COLUMN_PRIMARY, 0); table.setColumnExpandRatio(COLUMN_OWNER, 0); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonCreateForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonCreateForm.java index 075fc55ed00..9f6cab9751c 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonCreateForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonCreateForm.java @@ -111,7 +111,7 @@ public PersonCreateForm( PersonDto.I18N_PREFIX, false, FieldVisibilityCheckers.withCountry(FacadeProvider.getConfigFacade().getCountryLocale()), - UiFieldAccessCheckers.getDefault(false)); + UiFieldAccessCheckers.getDefault(false, FacadeProvider.getConfigFacade().getCountryLocale())); this.showHomeAddressForm = showHomeAddressForm; this.showPresentCondition = showPresentCondition; this.showSymptomsOnsetDate = showSymptomsOnsetDate; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonEditForm.java index d3af772d3bc..4367a571630 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/person/PersonEditForm.java @@ -78,17 +78,16 @@ import de.symeda.sormas.api.person.Salutation; import de.symeda.sormas.api.utils.DataHelper.Pair; import de.symeda.sormas.api.utils.DateHelper; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; import de.symeda.sormas.api.utils.fieldvisibility.checkers.CountryFieldVisibilityChecker; import de.symeda.sormas.api.utils.luxembourg.LuxembourgNationalHealthIdValidator; import de.symeda.sormas.ui.ControllerProvider; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.location.LocationEditForm; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.ApproximateAgeValidator; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateComparisonValidator; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.OutbreakFieldVisibilityChecker; import de.symeda.sormas.ui.utils.ResizableTextAreaWrapper; @@ -202,7 +201,7 @@ public PersonEditForm( FieldVisibilityCheckers.withDisease(disease) .add(new OutbreakFieldVisibilityChecker(viewMode)) .add(new CountryFieldVisibilityChecker(FacadeProvider.getConfigFacade().getCountryLocale())), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized), + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized), isEditAllowed); this.personContext = personContext; @@ -233,7 +232,7 @@ public PersonEditForm( FieldVisibilityCheckers.withDisease(disease) .add(new OutbreakFieldVisibilityChecker(viewMode)) .add(new CountryFieldVisibilityChecker(FacadeProvider.getConfigFacade().getCountryLocale())), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); this.personContext = personContext; this.disease = disease; @@ -256,7 +255,7 @@ public PersonEditForm(boolean isEditAllowed, boolean isPseudonymized, boolean in false, new FieldVisibilityCheckers().add(new OutbreakFieldVisibilityChecker(ViewMode.NORMAL)) .add(new CountryFieldVisibilityChecker(FacadeProvider.getConfigFacade().getCountryLocale())), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized), + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized), isEditAllowed); CssStyles.style(CssStyles.H3, occupationHeader, addressHeader, addressesHeader, contactInformationHeader); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/PathogenTestForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/PathogenTestForm.java index d2b201c05e5..281313c0b50 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/PathogenTestForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/PathogenTestForm.java @@ -58,14 +58,13 @@ import de.symeda.sormas.api.sample.PathogenTestType; import de.symeda.sormas.api.sample.SampleDto; import de.symeda.sormas.api.sample.SamplePurpose; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateComparisonValidator; import de.symeda.sormas.ui.utils.DateFormatHelper; import de.symeda.sormas.ui.utils.DateTimeField; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldConfiguration; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; @@ -158,9 +157,7 @@ public PathogenTestForm(boolean create, int caseSampleCount, boolean isPseudonym PathogenTestDto.I18N_PREFIX, false, FieldVisibilityCheckers.withDisease(null).andWithCountry(FacadeProvider.getConfigFacade().getCountryLocale()), - UiFieldAccessCheckers.forDataAccessLevel( - UiUtil.getPseudonymizableDataAccessLevel(create || inJurisdiction), // Jurisdiction doesn't matter for creation forms - !create && isPseudonymized)); // Pseudonymization doesn't matter for creation forms + FieldAccessHelper.getFieldAccessCheckers(create || inJurisdiction, !create && isPseudonymized));// Jurisdiction doesn't matter for creation forms // Pseudonymization doesn't matter for creation forms this.caseSampleCount = caseSampleCount; this.create = create; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/environmentsample/EnvironmentSampleEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/environmentsample/EnvironmentSampleEditForm.java index 530e5d69aea..799b3380fb1 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/environmentsample/EnvironmentSampleEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/environmentsample/EnvironmentSampleEditForm.java @@ -117,7 +117,7 @@ public EnvironmentSampleEditForm(boolean isPseudonymized, boolean isCreate) { EnvironmentSampleDto.I18N_PREFIX, false, FieldVisibilityCheckers.getNoop(), - UiFieldAccessCheckers.getDefault(isPseudonymized)); + UiFieldAccessCheckers.getDefault(isPseudonymized, FacadeProvider.getConfigFacade().getCountryLocale())); this.isCreate = isCreate; addFields(); addValueChangeListener(e -> defaultValueChangeListener((EnvironmentSampleDto) e.getProperty().getValue())); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/humansample/SampleDataView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/humansample/SampleDataView.java index cca12f46ed6..0544db8e6c4 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/humansample/SampleDataView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/humansample/SampleDataView.java @@ -37,7 +37,6 @@ import de.symeda.sormas.api.sample.SampleDto; import de.symeda.sormas.api.sample.SampleReferenceDto; import de.symeda.sormas.api.user.UserRight; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.ui.AbstractInfoLayout; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.UiUtil; @@ -52,6 +51,7 @@ import de.symeda.sormas.ui.utils.CommitDiscardWrapperComponent; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DetailSubComponentWrapper; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.LayoutWithSidePanel; import de.symeda.sormas.ui.utils.components.sidecomponent.SideComponentLayout; @@ -201,8 +201,7 @@ private AbstractInfoLayout getDependentSideComponent(SampleDto sample disease = contactDto.getDisease(); - final ContactInfoLayout contactInfoLayout = - new ContactInfoLayout(contactDto, UiFieldAccessCheckers.getDefault(contactDto.isPseudonymized())); + final ContactInfoLayout contactInfoLayout = new ContactInfoLayout(contactDto, FieldAccessHelper.getFieldAccessCheckers(contactDto)); contactInfoLayout.addStyleName(CssStyles.SIDE_COMPONENT); return (AbstractInfoLayout) contactInfoLayout; @@ -216,10 +215,8 @@ private AbstractInfoLayout getDependentSideComponent(SampleDto sample disease = eventDto.getDisease(); - final EventParticipantInfoLayout eventParticipantInfoLayout = new EventParticipantInfoLayout( - eventParticipantDto, - eventDto, - UiFieldAccessCheckers.getDefault(eventParticipantDto.isPseudonymized())); + final EventParticipantInfoLayout eventParticipantInfoLayout = + new EventParticipantInfoLayout(eventParticipantDto, eventDto, FieldAccessHelper.getFieldAccessCheckers(eventParticipantDto)); eventParticipantInfoLayout.addStyleName(CssStyles.SIDE_COMPONENT); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/humansample/SampleEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/humansample/SampleEditForm.java index f2f6cabaa40..8e5073026a7 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/humansample/SampleEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/samples/humansample/SampleEditForm.java @@ -41,12 +41,12 @@ import de.symeda.sormas.api.sample.SampleDto; import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.user.UserRight; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.samples.AbstractSampleForm; import de.symeda.sormas.ui.utils.DateComparisonValidator; import de.symeda.sormas.ui.utils.DateFormatHelper; import de.symeda.sormas.ui.utils.DateTimeField; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; public class SampleEditForm extends AbstractSampleForm { @@ -62,11 +62,7 @@ public class SampleEditForm extends AbstractSampleForm { private Label laboratorySampleHeadingLabel; public SampleEditForm(boolean isPseudonymized, boolean inJurisdiction, Disease disease) { - super( - SampleDto.class, - SampleDto.I18N_PREFIX, - disease, - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + super(SampleDto.class, SampleDto.I18N_PREFIX, disease, FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); testsToBeRemovedOnCommit = new ArrayList(); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/selfreport/SelfReportDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/selfreport/SelfReportDataForm.java index fc9861b1581..870f42355e0 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/selfreport/SelfReportDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/selfreport/SelfReportDataForm.java @@ -49,14 +49,13 @@ import de.symeda.sormas.api.user.JurisdictionLevel; import de.symeda.sormas.api.user.UserReferenceDto; import de.symeda.sormas.api.user.UserRight; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; import de.symeda.sormas.api.utils.fieldvisibility.checkers.CountryFieldVisibilityChecker; import de.symeda.sormas.api.utils.luxembourg.LuxembourgNationalHealthIdValidator; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.location.LocationEditForm; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.CssStyles; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.PhoneNumberValidator; import de.symeda.sormas.ui.utils.ValidationUtils; @@ -95,7 +94,7 @@ public SelfReportDataForm(Disease disease, boolean inJurisdiction, boolean isPse SelfReportDto.I18N_PREFIX, true, FieldVisibilityCheckers.withDisease(disease).add(new CountryFieldVisibilityChecker(FacadeProvider.getConfigFacade().getCountryLocale())), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); } @Override diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGrid.java index c723f40551b..a20d3560303 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/task/TaskGrid.java @@ -166,7 +166,7 @@ public TaskGrid(TaskCriteria criteria) { getColumn(TaskIndexDto.CONTEXT_REFERENCE).setStyleGenerator(new FieldAccessColumnStyleGenerator<>(task -> { boolean isInJurisdiction = task.getTaskJurisdictionFlagsDto().getInJurisdiction(); - return UiFieldAccessCheckers.getDefault(!isInJurisdiction).hasRight(); + return UiFieldAccessCheckers.getDefault(!isInJurisdiction, FacadeProvider.getConfigFacade().getCountryLocale()).hasRight(); })); addItemClickListener(new ShowDetailsListener<>(TaskIndexDto.CONTEXT_REFERENCE, false, this::navigateToData)); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/PrescriptionForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/PrescriptionForm.java index ce174d85b2e..80bba42de13 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/PrescriptionForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/PrescriptionForm.java @@ -17,11 +17,10 @@ import de.symeda.sormas.api.therapy.PrescriptionDto; import de.symeda.sormas.api.therapy.TreatmentRoute; import de.symeda.sormas.api.therapy.TreatmentType; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.DateComparisonValidator; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; @@ -43,7 +42,7 @@ public PrescriptionForm(boolean create, boolean readOnly, boolean isPseudonymize PrescriptionDto.I18N_PREFIX, false, new FieldVisibilityCheckers(), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); addFields(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/PrescriptionGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/PrescriptionGrid.java index f4c18f9d98b..fb60dd7c797 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/PrescriptionGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/PrescriptionGrid.java @@ -96,8 +96,9 @@ public Class getType() { I18nProperties.getPrefixCaption(PrescriptionIndexDto.I18N_PREFIX, column.getPropertyId().toString(), column.getHeaderCaption())); setCellStyleGenerator( - FieldAccessCellStyleGenerator - .withFieldAccessCheckers(PrescriptionIndexDto.class, UiFieldAccessCheckers.forSensitiveData(isPseudonymized))); + FieldAccessCellStyleGenerator.withFieldAccessCheckers( + PrescriptionIndexDto.class, + UiFieldAccessCheckers.forSensitiveData(isPseudonymized, FacadeProvider.getConfigFacade().getCountryLocale()))); } addItemClickListener(e -> { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/TreatmentForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/TreatmentForm.java index e91756f128b..ecf5bd9d10e 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/TreatmentForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/TreatmentForm.java @@ -13,11 +13,10 @@ import de.symeda.sormas.api.therapy.TreatmentDto; import de.symeda.sormas.api.therapy.TreatmentRoute; import de.symeda.sormas.api.therapy.TreatmentType; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.DateTimeField; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; @@ -38,7 +37,7 @@ public TreatmentForm(boolean create, boolean isPseudonymized, boolean inJurisdic TreatmentDto.I18N_PREFIX, true, new FieldVisibilityCheckers(), - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); setWidth(680, Unit.PIXELS); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/TreatmentGrid.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/TreatmentGrid.java index 6172746f547..13d534355bd 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/TreatmentGrid.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/therapy/TreatmentGrid.java @@ -67,8 +67,9 @@ public TreatmentGrid( I18nProperties.getPrefixCaption(TreatmentIndexDto.I18N_PREFIX, column.getPropertyId().toString(), column.getHeaderCaption())); setCellStyleGenerator( - FieldAccessCellStyleGenerator - .withFieldAccessCheckers(TreatmentIndexDto.class, UiFieldAccessCheckers.forSensitiveData(isPseudonymized))); + FieldAccessCellStyleGenerator.withFieldAccessCheckers( + TreatmentIndexDto.class, + UiFieldAccessCheckers.forSensitiveData(isPseudonymized, FacadeProvider.getConfigFacade().getCountryLocale()))); } addItemClickListener(e -> { diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryDataForm.java index a5b7c5979ee..3c0f0d024d9 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/travelentry/TravelEntryDataForm.java @@ -52,6 +52,7 @@ import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateComparisonValidator; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.InfrastructureFieldsHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; @@ -439,7 +440,7 @@ private static UiFieldAccessCheckers createFieldAccessCheckers( boolean inJurisdiction, boolean withPersonalAndSensitive) { if (withPersonalAndSensitive) { - return UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized); + return FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized); } return UiFieldAccessCheckers.getNoop(); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FieldAccessColumnStyleGenerator.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FieldAccessColumnStyleGenerator.java index 7ab5f9338ac..d602b942a3a 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FieldAccessColumnStyleGenerator.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FieldAccessColumnStyleGenerator.java @@ -19,6 +19,7 @@ import com.vaadin.ui.StyleGenerator; +import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.pseudonymization.Pseudonymizable; @@ -28,12 +29,18 @@ public class FieldAccessColumnStyleGenerator implements StyleGenerator { public static FieldAccessColumnStyleGenerator getDefault(Class beanType, String columnId) { - return forFieldAccessCheckers(beanType, columnId, UiFieldAccessCheckers.getDefault(true)); + return forFieldAccessCheckers( + beanType, + columnId, + UiFieldAccessCheckers.getDefault(true, FacadeProvider.getConfigFacade().getCountryLocale())); } public static FieldAccessColumnStyleGenerator forSensitiveData(Class beanType, String columnId) { - return forFieldAccessCheckers(beanType, columnId, UiFieldAccessCheckers.forSensitiveData(true)); + return forFieldAccessCheckers( + beanType, + columnId, + UiFieldAccessCheckers.forSensitiveData(true, FacadeProvider.getConfigFacade().getCountryLocale())); } private static FieldAccessColumnStyleGenerator forFieldAccessCheckers( diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FieldAccessHelper.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FieldAccessHelper.java index 0c4ea358aa3..fe9a895990a 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FieldAccessHelper.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/FieldAccessHelper.java @@ -17,12 +17,31 @@ import java.util.stream.Stream; +import de.symeda.sormas.api.FacadeProvider; import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; +import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; +import de.symeda.sormas.api.utils.pseudonymization.PseudonymizableDto; +import de.symeda.sormas.ui.UiUtil; public class FieldAccessHelper { public static boolean isAllInaccessible(String... values) { return Stream.of(values).allMatch(v -> I18nProperties.getCaption(Captions.inaccessibleValue).equals(v)); } + + public static UiFieldAccessCheckers getFieldAccessCheckers(boolean inJurisdiction, boolean isPseudonymized) { + return UiFieldAccessCheckers.forDataAccessLevel( + UiUtil.getPseudonymizableDataAccessLevel(inJurisdiction), + isPseudonymized, + FacadeProvider.getConfigFacade().getCountryLocale()); + } + + public static UiFieldAccessCheckers getFieldAccessCheckers(T dto) { + return UiFieldAccessCheckers.forDataAccessLevel( + UiUtil.getPseudonymizableDataAccessLevel(dto.isInJurisdiction()), + dto.isPseudonymized(), + FacadeProvider.getConfigFacade().getCountryLocale()); + } + } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationList.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationList.java index 81f86a48f2e..4dc5127e504 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationList.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/vaccination/list/VaccinationList.java @@ -26,11 +26,11 @@ import de.symeda.sormas.api.i18n.Captions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.user.UserRight; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.vaccination.VaccinationListEntryDto; import de.symeda.sormas.ui.ControllerProvider; import de.symeda.sormas.ui.SormasUI; import de.symeda.sormas.ui.UiUtil; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.PaginationList; public class VaccinationList extends PaginationList { @@ -88,9 +88,7 @@ protected void drawDisplayedEntries() { .edit( FacadeProvider.getVaccinationFacade().getByUuid(listEntry.getVaccination().getUuid()), listEntry.getVaccination().getDisease(), - UiFieldAccessCheckers.forDataAccessLevel( - UiUtil.getPseudonymizableDataAccessLevel(vaccination.isInJurisdiction()), - vaccination.isPseudonymized()), + FieldAccessHelper.getFieldAccessCheckers(vaccination.isInJurisdiction(), vaccination.isPseudonymized()), true, v -> SormasUI.refreshView(), deleteCallback(), diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitEditForm.java index 6f4d7259a62..f8db4394dac 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/visit/VisitEditForm.java @@ -42,13 +42,12 @@ import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.api.symptoms.SymptomsContext; import de.symeda.sormas.api.utils.DateHelper; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.visit.VisitDto; import de.symeda.sormas.api.visit.VisitStatus; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.symptoms.SymptomsForm; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.DateTimeField; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; @@ -82,7 +81,7 @@ public VisitEditForm( VisitDto.I18N_PREFIX, false, null, - UiFieldAccessCheckers.forDataAccessLevel(UiUtil.getPseudonymizableDataAccessLevel(create || inJurisdiction), !create && isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(create || inJurisdiction, !create && isPseudonymized)); if (create) { hideValidationUntilNextCommit(); } From bc38f97deb038a25024be307eeb2498d92cff7ca Mon Sep 17 00:00:00 2001 From: SergiuPacurariu Date: Tue, 29 Oct 2024 14:48:26 +0200 Subject: [PATCH 3/5] #13093 - Update Data Protection for certain Data Fields --- .../symeda/sormas/api/caze/CaseExportDto.java | 1 + .../symeda/sormas/api/contact/ContactDto.java | 1 + .../de/symeda/sormas/api/i18n/Captions.java | 13 ++ .../api/vaccination/VaccinationDto.java | 1 + .../src/main/resources/captions.properties | 15 ++ sormas-api/src/main/resources/enum.properties | 15 -- .../{EntityColumn.java => EntityColumns.java} | 210 +++++++++++------- .../sormas/backend/info/InfoFacadeEjb.java | 48 ++-- .../java/de/symeda/sormas/ui/AboutView.java | 9 +- .../sormas/ui/action/ActionEditForm.java | 3 +- .../clinicalcourse/HealthConditionsForm.java | 6 +- .../sormas/ui/utils/RichTextAreaCustom.java | 24 -- .../utils/SormasFieldGroupFieldFactory.java | 5 +- .../symeda/sormas/ui/utils/VaadinUiUtil.java | 3 +- 14 files changed, 200 insertions(+), 154 deletions(-) rename sormas-backend/src/main/java/de/symeda/sormas/backend/info/{EntityColumn.java => EntityColumns.java} (51%) delete mode 100644 sormas-ui/src/main/java/de/symeda/sormas/ui/utils/RichTextAreaCustom.java diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseExportDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseExportDto.java index 16265e06647..347b398bfdb 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseExportDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/caze/CaseExportDto.java @@ -263,6 +263,7 @@ public class CaseExportDto extends AbstractUuidDto implements IsCase { private String vaccineBatchNumber; private String vaccineUniiCode; private String vaccineAtcCode; + @SensitiveData private HealthConditionsDto healthConditions; private int numberOfPrescriptions; private int numberOfTreatments; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java index fc7e25b832b..615d81675fc 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/contact/ContactDto.java @@ -312,6 +312,7 @@ public class ContactDto extends SormasToSormasShareableDto implements IsContact @Valid private EpiDataDto epiData; @Valid + @SensitiveData private HealthConditionsDto healthConditions; private YesNoUnknown returningTraveler; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java index de514090097..78f72bdf467 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java @@ -1076,6 +1076,19 @@ public interface Captions { String edit = "edit"; String endDateTime = "endDateTime"; String endOfProcessingDate = "endOfProcessingDate"; + String EntityColumn_CAPTION = "EntityColumn.CAPTION"; + String EntityColumn_DATA_PROTECTION = "EntityColumn.DATA_PROTECTION"; + String EntityColumn_DESCRIPTION = "EntityColumn.DESCRIPTION"; + String EntityColumn_DISEASES = "EntityColumn.DISEASES"; + String EntityColumn_ENTITY = "EntityColumn.ENTITY"; + String EntityColumn_EXCLUSIVE_COUNTRIES = "EntityColumn.EXCLUSIVE_COUNTRIES"; + String EntityColumn_FIELD = "EntityColumn.FIELD"; + String EntityColumn_FIELD_ID = "EntityColumn.FIELD_ID"; + String EntityColumn_IGNORED_COUNTRIES = "EntityColumn.IGNORED_COUNTRIES"; + String EntityColumn_NEW_DISEASE = "EntityColumn.NEW_DISEASE"; + String EntityColumn_OUTBREAKS = "EntityColumn.OUTBREAKS"; + String EntityColumn_REQUIRED = "EntityColumn.REQUIRED"; + String EntityColumn_TYPE = "EntityColumn.TYPE"; String Environment = "Environment"; String Environment_description = "Environment.description"; String Environment_environmentMedia = "Environment.environmentMedia"; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/vaccination/VaccinationDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/vaccination/VaccinationDto.java index 8e82f5a4397..2954ad1a01f 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/vaccination/VaccinationDto.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/vaccination/VaccinationDto.java @@ -69,6 +69,7 @@ public class VaccinationDto extends PseudonymizableDto { @DependingOnFeatureType(featureType = FeatureType.IMMUNIZATION_MANAGEMENT, properties = @FeatureProperty(property = FeatureTypeProperty.REDUCED, value = "true"), hide = true) + @SensitiveData private HealthConditionsDto healthConditions; @NotNull(message = Validations.validReportDateTime) private Date reportDate; diff --git a/sormas-api/src/main/resources/captions.properties b/sormas-api/src/main/resources/captions.properties index a2fdb57909f..ec5a44f2864 100644 --- a/sormas-api/src/main/resources/captions.properties +++ b/sormas-api/src/main/resources/captions.properties @@ -1134,6 +1134,21 @@ DocumentTemplate.documentUploadWarning=Document upload warning DocumentTemplate.fileTooBig=The documents were successfully generated, but at least one document could not be uploaded to its entity because its file size exceeds the specified file size limit of %dMB DocumentTemplate.notUploaded=Documents could not be uploaded to the following entities: +# Entity columns +EntityColumn.ENTITY = Entity +EntityColumn.FIELD_ID = Field ID +EntityColumn.FIELD = Field +EntityColumn.TYPE = Type +EntityColumn.DATA_PROTECTION = Data protection +EntityColumn.CAPTION = Caption +EntityColumn.DESCRIPTION = Description +EntityColumn.REQUIRED = Required +EntityColumn.NEW_DISEASE = New disease +EntityColumn.DISEASES = Diseases +EntityColumn.OUTBREAKS = Outbreaks +EntityColumn.IGNORED_COUNTRIES = Ignored countries +EntityColumn.EXCLUSIVE_COUNTRIES = Exclusive countries + # Environment Environment=Environment Environment.uuid=Environment ID diff --git a/sormas-api/src/main/resources/enum.properties b/sormas-api/src/main/resources/enum.properties index 35fa86fe9f5..5fad41403f0 100644 --- a/sormas-api/src/main/resources/enum.properties +++ b/sormas-api/src/main/resources/enum.properties @@ -2181,21 +2181,6 @@ MeansOfImmunization.RECOVERY = Recovery MeansOfImmunization.VACCINATION_RECOVERY = Vaccination/Recovery MeansOfImmunization.OTHER = Other -#EntityColumn -EntityColumn.ENTITY = Entity -EntityColumn.FIELD_ID = Field ID -EntityColumn.FIELD = Field -EntityColumn.TYPE = Type -EntityColumn.DATA_PROTECTION = Data protection -EntityColumn.CAPTION = Caption -EntityColumn.DESCRIPTION = Description -EntityColumn.REQUIRED = Required -EntityColumn.NEW_DISEASE = New disease -EntityColumn.DISEASES = Diseases -EntityColumn.OUTBREAKS = Outbreaks -EntityColumn.IGNORED_COUNTRIES = Ignored countries -EntityColumn.EXCLUSIVE_COUNTRIES = Exclusive countries - #EnumColumn EnumColumn.TYPE = Type EnumColumn.VALUE = Value diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/info/EntityColumn.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/info/EntityColumns.java similarity index 51% rename from sormas-backend/src/main/java/de/symeda/sormas/backend/info/EntityColumn.java rename to sormas-backend/src/main/java/de/symeda/sormas/backend/info/EntityColumns.java index 7661514f8fb..4dce653489a 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/info/EntityColumn.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/info/EntityColumns.java @@ -21,8 +21,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.Date; +import java.util.List; import java.util.Map; import java.util.function.Function; +import java.util.stream.Collectors; import javax.validation.constraints.NotNull; @@ -42,80 +44,73 @@ import de.symeda.sormas.api.utils.PersonalData; import de.symeda.sormas.api.utils.SensitiveData; -public enum EntityColumn { - - ENTITY(256 * 30, EntityColumn::getEntity, false, true, true), - FIELD_ID(256 * 30, EntityColumn::getFieldId, false, true, false), - FIELD(256 * 30, EntityColumn::getFieldName, false, true, false), - TYPE(256 * 30, EntityColumn::getFieldType, true, true, false), - DATA_PROTECTION(256 * 30, EntityColumn::getDataProtection, false, true, false), - CAPTION(256 * 30, EntityColumn::getCaption, false, true, false), - DESCRIPTION(256 * 60, EntityColumn::getDescription, true, true, false), - REQUIRED(256 * 10, EntityColumn::getNotNull, false, true, false), - NEW_DISEASE(256 * 8, EntityColumn::getNewDisease, false, true, false), - DISEASES(256 * 45, EntityColumn::getDiseases, true, true, false), - OUTBREAKS(256 * 10, EntityColumn::getOutbreaks, false, true, false), - IGNORED_COUNTRIES(256 * 20, EntityColumn::getIgnoredCountries, false, false, false), - EXCLUSIVE_COUNTRIES(256 * 20, EntityColumn::getExclusiveCountries, false, false, false); - - private final int width; - private final Function getValueFromField; - private final boolean hasDefaultStyle; - private final boolean isDataProtectionColumn; - private final boolean isColumnForAllFieldsSheet; - - EntityColumn( - int width, - Function getValueFromField, - boolean hasDefaultStyle, - boolean isDataProtectionColumn, - boolean isColumnForAllFieldsSheet) { - - this.width = width; - this.getValueFromField = getValueFromField; - this.hasDefaultStyle = hasDefaultStyle; - this.isDataProtectionColumn = isDataProtectionColumn; - this.isColumnForAllFieldsSheet = isColumnForAllFieldsSheet; +public class EntityColumns { + + private final EntityColumn ENTITY = new EntityColumn("ENTITY", 256 * 30, this::getEntity, false, false, false, true); + private final EntityColumn FIELD_ID = new EntityColumn("FIELD_ID", 256 * 30, EntityColumns::getFieldId, false, true, true, true); + private final EntityColumn FIELD = new EntityColumn("FIELD", 256 * 30, this::getFieldName, false, true, true, true); + private final EntityColumn TYPE = new EntityColumn("TYPE", 256 * 30, this::getFieldType, true, true, true, true); + private final EntityColumn DATA_PROTECTION = new EntityColumn("DATA_PROTECTION", 256 * 30, this::getDataProtection, false, true, true, true); + private final EntityColumn CAPTION = new EntityColumn("CAPTION", 256 * 30, this::getCaption, false, true, true, true); + private final EntityColumn DESCRIPTION = new EntityColumn("DESCRIPTION", 256 * 60, this::getDescription, true, true, true, true); + private final EntityColumn REQUIRED = new EntityColumn("REQUIRED", 256 * 10, this::getNotNull, false, true, true, true); + private final EntityColumn NEW_DISEASE = new EntityColumn("NEW_DISEASE", 256 * 8, this::getNewDisease, false, true, true, true); + private final EntityColumn DISEASES = new EntityColumn("DISEASES", 256 * 45, this::getDiseases, true, true, true, true); + private final EntityColumn OUTBREAKS = new EntityColumn("OUTBREAKS", 256 * 10, this::getOutbreaks, false, true, true, true); + private final EntityColumn IGNORED_COUNTRIES = + new EntityColumn("IGNORED_COUNTRIES", 256 * 20, this::getIgnoredCountries, false, true, false, false); + private final EntityColumn EXCLUSIVE_COUNTRIES = + new EntityColumn("EXCLUSIVE_COUNTRIES", 256 * 20, this::getExclusiveCountries, false, true, false, false); + + private final List entityColumns = List.of( + ENTITY, + FIELD_ID, + FIELD, + TYPE, + DATA_PROTECTION, + CAPTION, + DESCRIPTION, + REQUIRED, + NEW_DISEASE, + DISEASES, + OUTBREAKS, + IGNORED_COUNTRIES, + EXCLUSIVE_COUNTRIES); + + private final String serverCountry; + private final boolean isDataProtectionFlow; + + public EntityColumns(final String serverCountry, final boolean isDataProtectionFlow) { + this.serverCountry = serverCountry; + this.isDataProtectionFlow = isDataProtectionFlow; } - public int getWidth() { - return width; - } - - public String getGetValueFromField(FieldData fieldData) { - return getValueFromField.apply(fieldData); - } - - public boolean hasDefaultStyle() { - return hasDefaultStyle; - } + public List getEntityColumns() { - public boolean isDataProtectionColumn() { - return isDataProtectionColumn; - } + if (isDataProtectionFlow) { + return entityColumns.stream().filter(EntityColumn::isDataProtectionColumn).collect(Collectors.toList()); + } - public boolean isColumnForAllFieldsSheet() { - return isColumnForAllFieldsSheet; + return entityColumns.stream().filter(EntityColumn::isDataDictionaryColumn).collect(Collectors.toList()); } - @Override - public String toString() { - return I18nProperties.getEnumCaption(this); + public List getColumnsForAllFieldsSheet() { + return entityColumns.stream().filter(EntityColumn::isColumnForAllFieldsSheet).collect(Collectors.toList()); } - private static String getEntity(FieldData fieldData) { + private String getEntity(FieldData fieldData) { return DataHelper.getHumanClassName(fieldData.getEntityClass()); } - private static String getFieldId(FieldData fieldData) { + public static String getFieldId(FieldData fieldData) { return DataHelper.getHumanClassName(fieldData.getEntityClass()) + "." + fieldData.getField().getName(); } - private static String getFieldName(FieldData fieldData) { + private String getFieldName(FieldData fieldData) { return fieldData.getField().getName(); } - private static String getFieldType(FieldData fieldData) { + private String getFieldType(FieldData fieldData) { Class fieldType = fieldData.getField().getType(); if (fieldType.isEnum()) { // use enum type name - values are added below @@ -153,13 +148,16 @@ private static String getFieldType(FieldData fieldData) { return fieldType.getSimpleName(); } - private static String getDataProtection(FieldData fieldData) { + private String getDataProtection(FieldData fieldData) { Field field = fieldData.getField(); - if (field.getAnnotation(PersonalData.class) != null) { + if (field.getAnnotation(PersonalData.class) != null + && (!isDataProtectionFlow || !Arrays.asList(field.getAnnotation(PersonalData.class).excludeForCountries()).contains(serverCountry))) { return "personal"; } else { - if (field.getAnnotation(SensitiveData.class) != null) { + if (field.getAnnotation(SensitiveData.class) != null + && (!isDataProtectionFlow + || !Arrays.asList(field.getAnnotation(SensitiveData.class).excludeForCountries()).contains(serverCountry))) { return "sensitive"; } } @@ -167,12 +165,16 @@ private static String getDataProtection(FieldData fieldData) { return null; } - private static String getCaption(FieldData fieldData) { + private String getCaption(FieldData fieldData) { return I18nProperties.getPrefixCaption(fieldData.getI18NPrefix(), fieldData.getField().getName(), ""); } - private static String getDescription(FieldData fieldData) { - String prefixDescription = I18nProperties.getPrefixDescription(fieldData.getI18NPrefix(), fieldData.getField().getName(), ""); + private String getDescription(FieldData fieldData) { + String fieldDescription = I18nProperties.getPrefixDescription(fieldData.getI18NPrefix(), fieldData.getField().getName(), ""); + + if (isDataProtectionFlow) { + return fieldDescription; + } String[] excludedForCountries = null; @@ -180,24 +182,23 @@ private static String getDescription(FieldData fieldData) { if (field.getAnnotation(PersonalData.class) != null) { excludedForCountries = field.getAnnotation(PersonalData.class).excludeForCountries(); - } else { - if (field.getAnnotation(SensitiveData.class) != null) { - excludedForCountries = field.getAnnotation(SensitiveData.class).excludeForCountries(); - } + } else if (field.getAnnotation(SensitiveData.class) != null) { + excludedForCountries = field.getAnnotation(SensitiveData.class).excludeForCountries(); + } String description; if (excludedForCountries != null && excludedForCountries.length > 0) { - description = prefixDescription + I18nProperties.getString(Strings.messageCountriesExcludedFromDataProtection) + " " + description = fieldDescription + I18nProperties.getString(Strings.messageCountriesExcludedFromDataProtection) + " " + Arrays.toString(excludedForCountries); } else { - description = prefixDescription; + description = fieldDescription; } return description; } - private static String getNotNull(FieldData fieldData) { + private String getNotNull(FieldData fieldData) { if (fieldData.getField().getAnnotation(NotNull.class) == null) { return null; } @@ -205,11 +206,11 @@ private static String getNotNull(FieldData fieldData) { return Boolean.TRUE.toString(); } - private static String getNewDisease(FieldData fieldData) { + private String getNewDisease(FieldData fieldData) { return null; } - private static String getDiseases(FieldData fieldData) { + private String getDiseases(FieldData fieldData) { Diseases diseases = fieldData.getField().getAnnotation(Diseases.class); if (diseases == null) { return "All"; @@ -224,7 +225,7 @@ private static String getDiseases(FieldData fieldData) { } } - private static String getOutbreaks(FieldData fieldData) { + private String getOutbreaks(FieldData fieldData) { if (fieldData.getField().getAnnotation(Outbreaks.class) == null) { return null; } @@ -232,7 +233,7 @@ private static String getOutbreaks(FieldData fieldData) { return Boolean.TRUE.toString(); } - private static String getIgnoredCountries(FieldData fieldData) { + private String getIgnoredCountries(FieldData fieldData) { HideForCountries hideForCountries = fieldData.getField().getAnnotation(HideForCountries.class); if (hideForCountries == null) { return null; @@ -248,7 +249,7 @@ private static String getIgnoredCountries(FieldData fieldData) { return hideForCountriesString.toString(); } - private static String getExclusiveCountries(FieldData fieldData) { + private String getExclusiveCountries(FieldData fieldData) { HideForCountriesExcept hideForCountriesExcept = fieldData.getField().getAnnotation(HideForCountriesExcept.class); if (hideForCountriesExcept == null) { return null; @@ -263,4 +264,63 @@ private static String getExclusiveCountries(FieldData fieldData) { return hideForCountriesExceptString.toString(); } + + public class EntityColumn { + + private final String name; + private final int width; + private final Function getValueFromField; + private final boolean hasDefaultStyle; + private final boolean isDataDictionaryColumn; + private final boolean isDataProtectionColumn; + private final boolean isColumnForAllFieldsSheet; + + EntityColumn( + String name, + int width, + Function getValueFromField, + boolean hasDefaultStyle, + boolean isDataDictionaryColumn, + boolean isDataProtectionColumn, + boolean isColumnForAllFieldsSheet) { + + this.name = name; + this.width = width; + this.getValueFromField = getValueFromField; + this.hasDefaultStyle = hasDefaultStyle; + this.isDataDictionaryColumn = isDataDictionaryColumn; + this.isDataProtectionColumn = isDataProtectionColumn; + this.isColumnForAllFieldsSheet = isColumnForAllFieldsSheet; + } + + public int getWidth() { + return width; + } + + public String getGetValueFromField(FieldData fieldData) { + return getValueFromField.apply(fieldData); + } + + public boolean hasDefaultStyle() { + return hasDefaultStyle; + } + + public boolean isDataDictionaryColumn() { + return isDataDictionaryColumn; + } + + public boolean isDataProtectionColumn() { + return isDataProtectionColumn; + } + + public boolean isColumnForAllFieldsSheet() { + return isColumnForAllFieldsSheet; + } + + @Override + public String toString() { + return I18nProperties.getPrefixCaption("EntityColumn", name); + } + + } } diff --git a/sormas-backend/src/main/java/de/symeda/sormas/backend/info/InfoFacadeEjb.java b/sormas-backend/src/main/java/de/symeda/sormas/backend/info/InfoFacadeEjb.java index 44caabb4c59..3e0c1fa8ff5 100644 --- a/sormas-backend/src/main/java/de/symeda/sormas/backend/info/InfoFacadeEjb.java +++ b/sormas-backend/src/main/java/de/symeda/sormas/backend/info/InfoFacadeEjb.java @@ -27,7 +27,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -41,7 +40,6 @@ import javax.ejb.Stateless; import org.apache.commons.lang3.reflect.TypeUtils; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.CellCopyPolicy; import org.apache.poi.ss.usermodel.CellStyle; @@ -110,6 +108,7 @@ import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal; import de.symeda.sormas.backend.disease.DiseaseConfigurationFacadeEjb.DiseaseConfigurationFacadeEjbLocal; import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal; +import de.symeda.sormas.backend.info.EntityColumns.EntityColumn; import de.symeda.sormas.backend.user.UserService; import de.symeda.sormas.backend.util.XssfHelper; @@ -170,35 +169,17 @@ public class InfoFacadeEjb implements InfoFacade { @EJB private FeatureConfigurationFacadeEjbLocal featureConfigurationFacade; - private static EnumSet getColumnsForDataDictionary() { - EnumSet enumSet = EnumSet.allOf(EntityColumn.class); - enumSet.remove(EntityColumn.ENTITY); - return enumSet; - } - @Override public boolean isGenerateDataProtectionDictionaryAllowed() { return userService.hasRight(UserRight.EXPORT_DATA_PROTECTION_DATA) && getDataProtectionFile().exists(); } - private static EnumSet getColumnsForDataProtectionDictionary() { - EnumSet enumSet = EnumSet.allOf(EntityColumn.class); - return enumSet.stream() - .filter(EntityColumn::isDataProtectionColumn) - .collect(Collectors.toCollection(() -> EnumSet.noneOf(EntityColumn.class))); - } - - private static EnumSet getColumnsForAllFieldsSheet(EnumSet enumSet) { - return enumSet.stream() - .filter(column -> !column.isColumnForAllFieldsSheet()) - .collect(Collectors.toCollection(() -> EnumSet.noneOf(EntityColumn.class))); - } - @Override public String generateDataDictionary() throws IOException { + EntityColumns entityColumns = new EntityColumns(configFacade.getCountryLocale(), false); return generateDataDictionary( DATA_DICTIONARY_ENTITIES, - getColumnsForDataDictionary(), + entityColumns, new VisibilityChecks((c, f) -> true, FieldVisibilityCheckers.getNoop()), Collections.emptyList(), Collections.emptyMap(), @@ -218,6 +199,8 @@ public String generateDataProtectionDictionary() throws IOException { .filter(e -> isVisibleByFeatureConfiguration(e.getEntityClass(), featureConfigurations)) .collect(Collectors.toList()); + EntityColumns entityColumns = new EntityColumns(configFacade.getCountryLocale(), true); + try (XSSFWorkbook dataProtectionInputWorkbook = new XSSFWorkbook(getDataProtectionFile())) { XSSFSheet dataProtectionSheet = dataProtectionInputWorkbook.getSheetAt(0); @@ -226,7 +209,7 @@ public String generateDataProtectionDictionary() throws IOException { Map> dataProtectionData = getDataProtectionCellData(dataProtectionSheet); return generateDataDictionary( entities, - getColumnsForDataProtectionDictionary(), + entityColumns, new VisibilityChecks( (dtoClass, field) -> fieldVisibilityCheckers.isVisible(dtoClass, field) && isVisibleByFeatureConfiguration(field.getType(), featureConfigurations), @@ -235,14 +218,15 @@ && isVisibleByFeatureConfiguration(field.getType(), featureConfigurations), dataProtectionData, true); - } catch (InvalidFormatException e) { + } catch (Exception e) { + e.printStackTrace(); throw new IOException(e); } } private String generateDataDictionary( List entities, - EnumSet entityColumns, + EntityColumns entityColumns, VisibilityChecks visibilityChecks, List extraColumns, Map> extraCells, @@ -256,7 +240,7 @@ private String generateDataDictionary( workbook, defaultCellStyle, entities, - entityColumns, + entityColumns.getColumnsForAllFieldsSheet(), visibilityChecks.fieldVisibilityPredicate, extraColumns, extraCells); @@ -266,7 +250,7 @@ private String generateDataDictionary( workbook, defaultCellStyle, entities, - getColumnsForAllFieldsSheet(entityColumns), + entityColumns.getEntityColumns(), visibilityChecks, extraColumns, extraCells, @@ -468,7 +452,7 @@ private void createEntitySheets( XSSFWorkbook workbook, CellStyle defaultCellStyle, List entityInfoList, - EnumSet entityColumns, + List entityColumns, VisibilityChecks visibilityChecks, List extraColumns, Map> extraCells, @@ -491,7 +475,7 @@ private void createAllFieldsSheet( XSSFWorkbook workbook, CellStyle defaultCellStyle, List entityInfoList, - EnumSet entityColumns, + List entityColumns, BiPredicate, Field> fieldVisibilityPredicate, List extraColumns, Map> extraCells) { @@ -529,7 +513,7 @@ private void createEntitySheet( XSSFWorkbook workbook, CellStyle defaultCellStyle, EntityInfo entityInfo, - EnumSet entityColumns, + List entityColumns, VisibilityChecks visibilityChecks, List extraColumns, Map> extraCells, @@ -620,7 +604,7 @@ private XSSFCell createCellsForRow(EntityColumn c, XSSFRow row, FieldData fieldD } private void copyCellsFromExtraCells(XSSFRow row, FieldData fieldData, Map> extraCells) { - String fieldId = EntityColumn.FIELD_ID.getGetValueFromField(fieldData); + String fieldId = EntityColumns.getFieldId(fieldData); if (extraCells.containsKey(fieldId)) { extraCells.get(fieldId).forEach(extraCell -> { XSSFCell newCell = row.createCell(row.getLastCellNum()); @@ -631,7 +615,7 @@ private void copyCellsFromExtraCells(XSSFRow row, FieldData fieldData, Map entityColumns, List extraColumns) { + private void buildHeader(XSSFSheet sheet, List entityColumns, List extraColumns) { XSSFRow headerRow = sheet.createRow(0); entityColumns.forEach(column -> { int colIndex = Math.max(headerRow.getLastCellNum(), 0); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/AboutView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/AboutView.java index bb03f41e445..2413fb29510 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/AboutView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/AboutView.java @@ -348,8 +348,13 @@ private String getCustomDocumentsPath() { public void attachDataProtectionDictionaryDownloader(AbstractComponent target) { new FileDownloader(new StreamResource(() -> new DownloadUtil.DelayedInputStream((out) -> { - String documentPath = FacadeProvider.getInfoFacade().generateDataProtectionDictionary(); - IOUtils.copy(Files.newInputStream(new File(documentPath).toPath()), out); + try { + String documentPath = FacadeProvider.getInfoFacade().generateDataProtectionDictionary(); + IOUtils.copy(Files.newInputStream(new File(documentPath).toPath()), out); + } catch (Exception e) { + e.printStackTrace(); + } + }, (e) -> { }), DownloadUtil.createFileNameWithCurrentDate(ExportEntityName.DATA_PROTECTION_DICTIONARY, ".xlsx"))).extend(target); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/action/ActionEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/action/ActionEditForm.java index 018be86c216..69a354b2339 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/action/ActionEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/action/ActionEditForm.java @@ -41,7 +41,6 @@ import de.symeda.sormas.ui.utils.DateTimeField; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; -import de.symeda.sormas.ui.utils.RichTextAreaCustom; import de.symeda.sormas.ui.utils.VaadinUiUtil; public class ActionEditForm extends AbstractEditForm { @@ -101,7 +100,7 @@ protected void addFields() { addField(ActionDto.ACTION_MEASURE, TextField.class); TextField title = addField(ActionDto.TITLE, TextField.class); title.addStyleName(SOFT_REQUIRED); - RichTextAreaCustom description = addField(ActionDto.DESCRIPTION, RichTextAreaCustom.class); + RichTextArea description = addField(ActionDto.DESCRIPTION, RichTextArea.class); description.setNullRepresentation(""); description.setImmediate(true); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java index cad1c6f6615..944c89a10e9 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java @@ -85,7 +85,7 @@ protected void addFields() { healthConditionsHeadingLabel.addStyleName(H3); getContent().addComponent(healthConditionsHeadingLabel, HEALTH_CONDITIONS_HEADINGS_LOC); - if (UiUtil.permitted(UserRight.SEE_SENSITIVE_DATA_IN_JURISDICTION)) { + if (displayFieldsAllowed()) { addFields( TUBERCULOSIS, ASPLENIA, @@ -137,4 +137,8 @@ protected F addFieldToLayout(CustomLayout layout, String prope return super.addFieldToLayout(layout, propertyId, field); } + + private boolean displayFieldsAllowed() { + return UiUtil.permitted(UserRight.SEE_SENSITIVE_DATA_IN_JURISDICTION); + } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/RichTextAreaCustom.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/RichTextAreaCustom.java deleted file mode 100644 index 8f26e2c24b9..00000000000 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/RichTextAreaCustom.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.symeda.sormas.ui.utils; - -import com.vaadin.event.FieldEvents; -import com.vaadin.v7.ui.RichTextArea; - -public class RichTextAreaCustom extends RichTextArea { - - public void addFocusListener(FieldEvents.FocusListener listener) { - addListener(FieldEvents.FocusEvent.EVENT_ID, FieldEvents.FocusEvent.class, listener, FieldEvents.FocusListener.focusMethod); - } - - public void removeFocusListener(FieldEvents.FocusListener listener) { - removeListener(FieldEvents.FocusEvent.EVENT_ID, FieldEvents.FocusEvent.class, listener); - - } - - public void addBlurListener(FieldEvents.BlurListener listener) { - addListener(FieldEvents.BlurEvent.EVENT_ID, FieldEvents.BlurEvent.class, listener, FieldEvents.BlurListener.blurMethod); - } - - public void removeBlurListener(FieldEvents.BlurListener listener) { - removeListener(FieldEvents.BlurEvent.EVENT_ID, FieldEvents.BlurEvent.class, listener); - } -} diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java index d8109192d5e..ac2b992d67e 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/SormasFieldGroupFieldFactory.java @@ -15,6 +15,7 @@ import com.vaadin.v7.ui.DateField; import com.vaadin.v7.ui.Field; import com.vaadin.v7.ui.OptionGroup; +import com.vaadin.v7.ui.RichTextArea; import de.symeda.sormas.api.Disease; import de.symeda.sormas.api.FacadeProvider; @@ -179,8 +180,8 @@ public T createField(Class type, Class fieldType) { return (T) new UserField(); } else if (CheckBoxTree.class.isAssignableFrom(fieldType)) { return (T) new CheckBoxTree<>(); - } else if (RichTextAreaCustom.class.isAssignableFrom(fieldType)) { - return (T) new RichTextAreaCustom(); + } else if (RichTextArea.class.isAssignableFrom(fieldType)) { + return (T) new RichTextArea(); } return super.createField(type, fieldType); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/VaadinUiUtil.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/VaadinUiUtil.java index 84509ae6295..6f53c037eb8 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/VaadinUiUtil.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/VaadinUiUtil.java @@ -46,6 +46,7 @@ import com.vaadin.v7.data.util.PropertyValueGenerator; import com.vaadin.v7.ui.AbstractField; import com.vaadin.v7.ui.Grid; +import com.vaadin.v7.ui.RichTextArea; import com.vaadin.v7.ui.TextArea; import com.vaadin.v7.ui.renderers.HtmlRenderer; @@ -652,7 +653,7 @@ public static void addGdprMessageOnClick(TextArea textArea) { }); } - public static void addGdprMessageOnClick(RichTextAreaCustom richTextArea) { + public static void addGdprMessageOnClick(RichTextArea richTextArea) { AtomicBoolean gdprMessageTriggered = new AtomicBoolean(false); Window subWindowGdpR = VaadinUiUtil.createPopupWindow(); From 0591b1103f399db8274225e7058277f069606911 Mon Sep 17 00:00:00 2001 From: SergiuPacurariu Date: Tue, 29 Oct 2024 17:51:16 +0200 Subject: [PATCH 4/5] #13093 - Update Data Protection for certain Data Fields - changes after review --- .../java/de/symeda/sormas/ui/AboutView.java | 9 +- .../symeda/sormas/ui/caze/CaseDataForm.java | 4 +- .../clinicalcourse/HealthConditionsForm.java | 93 ++++++++++--------- .../sormas/ui/utils/AbstractEditForm.java | 3 + 4 files changed, 54 insertions(+), 55 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/AboutView.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/AboutView.java index 2413fb29510..bb03f41e445 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/AboutView.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/AboutView.java @@ -348,13 +348,8 @@ private String getCustomDocumentsPath() { public void attachDataProtectionDictionaryDownloader(AbstractComponent target) { new FileDownloader(new StreamResource(() -> new DownloadUtil.DelayedInputStream((out) -> { - try { - String documentPath = FacadeProvider.getInfoFacade().generateDataProtectionDictionary(); - IOUtils.copy(Files.newInputStream(new File(documentPath).toPath()), out); - } catch (Exception e) { - e.printStackTrace(); - } - + String documentPath = FacadeProvider.getInfoFacade().generateDataProtectionDictionary(); + IOUtils.copy(Files.newInputStream(new File(documentPath).toPath()), out); }, (e) -> { }), DownloadUtil.createFileNameWithCurrentDate(ExportEntityName.DATA_PROTECTION_DICTIONARY, ".xlsx"))).extend(target); } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java index b2f181ee080..f17aa0c7c42 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java @@ -1022,6 +1022,8 @@ protected void addFields() { } }); + addField(CaseDataDto.HEALTH_CONDITIONS, HealthConditionsForm.class).setCaption(null); + // Set initial visibilities & accesses initializeVisibilitiesAndAllowedVisibilities(); initializeAccessAndAllowedAccesses(); @@ -1206,8 +1208,6 @@ protected void addFields() { List medicalInformationFields = Arrays.asList(CaseDataDto.PREGNANT, CaseDataDto.VACCINATION_STATUS, CaseDataDto.SMALLPOX_VACCINATION_RECEIVED); - addField(CaseDataDto.HEALTH_CONDITIONS, HealthConditionsForm.class).setCaption(null); - for (String medicalInformationField : medicalInformationFields) { if (getFieldGroup().getField(medicalInformationField).isVisible()) { Label medicalInformationCaptionLabel = new Label(I18nProperties.getString(Strings.headingMedicalInformation)); diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java index 944c89a10e9..c99568bef0b 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java @@ -31,6 +31,7 @@ import static de.symeda.sormas.ui.utils.LayoutUtil.locs; import java.util.Arrays; +import java.util.List; import com.vaadin.ui.CustomLayout; import com.vaadin.ui.Label; @@ -42,11 +43,9 @@ import de.symeda.sormas.api.i18n.Descriptions; import de.symeda.sormas.api.i18n.I18nProperties; import de.symeda.sormas.api.i18n.Strings; -import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.YesNoUnknown; import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; -import de.symeda.sormas.ui.UiUtil; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.FieldHelper; @@ -56,7 +55,7 @@ public class HealthConditionsForm extends AbstractEditForm private static final long serialVersionUID = 1L; private static final String HEALTH_CONDITIONS_HEADINGS_LOC = "healthConditionsHeadingLoc"; - private static final String CONFIDENTIAL_LABEL = "confidentialLabel"; + private static final String CONFIDENTIAL_LABEL_LOC = "confidentialLabel"; //@formatter:off private static final String HTML_LAYOUT = @@ -70,10 +69,33 @@ public class HealthConditionsForm extends AbstractEditForm CHRONIC_HEART_FAILURE, CHRONIC_PULMONARY_DISEASE, CHRONIC_KIDNEY_DISEASE, CHRONIC_NEUROLOGIC_CONDITION, CARDIOVASCULAR_DISEASE_INCLUDING_HYPERTENSION, OBESITY, CURRENT_SMOKER, FORMER_SMOKER, ASTHMA, SICKLE_CELL_DISEASE)) - ) + - loc(OTHER_CONDITIONS) + loc(CONFIDENTIAL_LABEL); + ) + loc(OTHER_CONDITIONS) + loc(CONFIDENTIAL_LABEL_LOC); //@formatter:on + private static final List fieldsList = List.of( + TUBERCULOSIS, + ASPLENIA, + HEPATITIS, + DIABETES, + HIV, + HIV_ART, + CHRONIC_LIVER_DISEASE, + MALIGNANCY_CHEMOTHERAPY, + CHRONIC_HEART_FAILURE, + CHRONIC_PULMONARY_DISEASE, + CHRONIC_KIDNEY_DISEASE, + CHRONIC_NEUROLOGIC_CONDITION, + DOWN_SYNDROME, + CONGENITAL_SYPHILIS, + IMMUNODEFICIENCY_OTHER_THAN_HIV, + CARDIOVASCULAR_DISEASE_INCLUDING_HYPERTENSION, + OBESITY, + CURRENT_SMOKER, + FORMER_SMOKER, + ASTHMA, + SICKLE_CELL_DISEASE, + IMMUNODEFICIENCY_INCLUDING_HIV); + public HealthConditionsForm(FieldVisibilityCheckers fieldVisibilityCheckers, UiFieldAccessCheckers fieldAccessCheckers) { super(HealthConditionsDto.class, I18N_PREFIX, true, fieldVisibilityCheckers, fieldAccessCheckers); } @@ -85,45 +107,18 @@ protected void addFields() { healthConditionsHeadingLabel.addStyleName(H3); getContent().addComponent(healthConditionsHeadingLabel, HEALTH_CONDITIONS_HEADINGS_LOC); - if (displayFieldsAllowed()) { - addFields( - TUBERCULOSIS, - ASPLENIA, - HEPATITIS, - DIABETES, - HIV, - HIV_ART, - CHRONIC_LIVER_DISEASE, - MALIGNANCY_CHEMOTHERAPY, - CHRONIC_HEART_FAILURE, - CHRONIC_PULMONARY_DISEASE, - CHRONIC_KIDNEY_DISEASE, - CHRONIC_NEUROLOGIC_CONDITION, - DOWN_SYNDROME, - CONGENITAL_SYPHILIS, - IMMUNODEFICIENCY_OTHER_THAN_HIV, - CARDIOVASCULAR_DISEASE_INCLUDING_HYPERTENSION, - OBESITY, - CURRENT_SMOKER, - FORMER_SMOKER, - ASTHMA, - SICKLE_CELL_DISEASE, - IMMUNODEFICIENCY_INCLUDING_HIV); - TextArea otherConditions = addField(OTHER_CONDITIONS, TextArea.class); - otherConditions.setRows(6); - otherConditions.setDescription( - I18nProperties.getPrefixDescription(HealthConditionsDto.I18N_PREFIX, OTHER_CONDITIONS, "") + "\n" - + I18nProperties.getDescription(Descriptions.descGdpr)); - - initializeVisibilitiesAndAllowedVisibilities(); - initializeAccessAndAllowedAccesses(); - - FieldHelper.setVisibleWhen(getFieldGroup(), HIV_ART, HIV, Arrays.asList(YesNoUnknown.YES), true); - } else { - Label confidentialLabel = new Label(I18nProperties.getCaption(Captions.inaccessibleValue)); - confidentialLabel.addStyleName(CssStyles.INACCESSIBLE_LABEL); - getContent().addComponent(confidentialLabel, CONFIDENTIAL_LABEL); - } + addFields(fieldsList); + + TextArea otherConditions = addField(OTHER_CONDITIONS, TextArea.class); + otherConditions.setRows(6); + otherConditions.setDescription( + I18nProperties.getPrefixDescription(HealthConditionsDto.I18N_PREFIX, OTHER_CONDITIONS, "") + "\n" + + I18nProperties.getDescription(Descriptions.descGdpr)); + + FieldHelper.setVisibleWhen(getFieldGroup(), HIV_ART, HIV, Arrays.asList(YesNoUnknown.YES), true); + + initializeVisibilitiesAndAllowedVisibilities(); + initializeAccessAndAllowedAccesses(); } @Override @@ -138,7 +133,13 @@ protected F addFieldToLayout(CustomLayout layout, String prope return super.addFieldToLayout(layout, propertyId, field); } - private boolean displayFieldsAllowed() { - return UiUtil.permitted(UserRight.SEE_SENSITIVE_DATA_IN_JURISDICTION); + public void setInaccessible() { + fieldsList.stream().forEach(field -> { + getContent().getComponent(field).setVisible(false); + }); + getContent().getComponent(OTHER_CONDITIONS).setVisible(false); + Label confidentialLabel = new Label(I18nProperties.getCaption(Captions.inaccessibleValue)); + confidentialLabel.addStyleName(CssStyles.INACCESSIBLE_LABEL); + getContent().addComponent(confidentialLabel, CONFIDENTIAL_LABEL_LOC); } } diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/AbstractEditForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/AbstractEditForm.java index 1162f807383..d5db8ba4ae1 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/AbstractEditForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/utils/AbstractEditForm.java @@ -45,6 +45,7 @@ import de.symeda.sormas.api.i18n.Strings; import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; +import de.symeda.sormas.ui.clinicalcourse.HealthConditionsForm; import de.symeda.sormas.ui.utils.components.NotBlankTextValidator; public abstract class AbstractEditForm extends AbstractForm implements FieldGroup.CommitHandler {// implements DtoEditForm { @@ -568,6 +569,8 @@ protected void initializeAccessAndAllowedAccesses() { if (field instanceof NullableOptionGroup) { ((NullableOptionGroup) field).setInaccessible(); } + if (field instanceof HealthConditionsForm) + ((HealthConditionsForm) field).setInaccessible(); } } From 7fe877008a9df56b773fe9dd8337340ef9d89403 Mon Sep 17 00:00:00 2001 From: SergiuPacurariu Date: Wed, 30 Oct 2024 10:37:25 +0200 Subject: [PATCH 5/5] #13093 - Update Data Protection for certain Data Fields - fix after merge with development --- .../AefiInvestigationDataForm.java | 3 ++- .../components/form/AefiDataForm.java | 5 ++--- .../components/information/AefiPersonInfo.java | 11 ++--------- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/AefiInvestigationDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/AefiInvestigationDataForm.java index 1ba7beb0475..416e6fba5a4 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/AefiInvestigationDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/AefiInvestigationDataForm.java @@ -60,6 +60,7 @@ import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateTimeField; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; import de.symeda.sormas.ui.utils.UserField; @@ -294,7 +295,7 @@ public AefiInvestigationDataForm(boolean isCreateAction, boolean isPseudonymized AefiInvestigationDto.I18N_PREFIX, false, FieldVisibilityCheckers.withCountry(FacadeProvider.getConfigFacade().getCountryLocale()), - UiFieldAccessCheckers.forDataAccessLevel(UserProvider.getCurrent().getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); this.isCreateAction = isCreateAction; this.actionCallback = actionCallback; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/components/form/AefiDataForm.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/components/form/AefiDataForm.java index 78ee9dcb888..4b1411c561a 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/components/form/AefiDataForm.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/components/form/AefiDataForm.java @@ -47,14 +47,13 @@ import de.symeda.sormas.api.i18n.Validations; import de.symeda.sormas.api.immunization.ImmunizationDto; import de.symeda.sormas.api.utils.YesNoUnknown; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; -import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.adverseeventsfollowingimmunization.components.fields.vaccines.AefiVaccinationsField; import de.symeda.sormas.ui.utils.AbstractEditForm; import de.symeda.sormas.ui.utils.ButtonHelper; import de.symeda.sormas.ui.utils.CssStyles; import de.symeda.sormas.ui.utils.DateTimeField; +import de.symeda.sormas.ui.utils.FieldAccessHelper; import de.symeda.sormas.ui.utils.FieldHelper; import de.symeda.sormas.ui.utils.NullableOptionGroup; import de.symeda.sormas.ui.utils.UserField; @@ -127,7 +126,7 @@ public AefiDataForm(boolean isCreateAction, boolean isPseudonymized, boolean inJ AefiDto.I18N_PREFIX, false, FieldVisibilityCheckers.withCountry(FacadeProvider.getConfigFacade().getCountryLocale()), - UiFieldAccessCheckers.forDataAccessLevel(UserProvider.getCurrent().getPseudonymizableDataAccessLevel(inJurisdiction), isPseudonymized)); + FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)); this.isCreateAction = isCreateAction; this.actionCallback = actionCallback; diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/components/information/AefiPersonInfo.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/components/information/AefiPersonInfo.java index 3f378ccf0b0..c8bc7373e0a 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/components/information/AefiPersonInfo.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/adverseeventsfollowingimmunization/components/information/AefiPersonInfo.java @@ -1,17 +1,14 @@ /* * SORMAS® - Surveillance Outbreak Response Management & Analysis System * Copyright © 2016-2024 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) - * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. - * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -31,10 +28,10 @@ import de.symeda.sormas.api.person.PersonDto; import de.symeda.sormas.api.user.UserRight; import de.symeda.sormas.api.utils.DataHelper; -import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; import de.symeda.sormas.ui.AbstractInfoLayout; import de.symeda.sormas.ui.UserProvider; import de.symeda.sormas.ui.utils.CssStyles; +import de.symeda.sormas.ui.utils.FieldAccessHelper; @SuppressWarnings("serial") public class AefiPersonInfo extends AbstractInfoLayout { @@ -46,11 +43,7 @@ public class AefiPersonInfo extends AbstractInfoLayout { private Disease disease; public AefiPersonInfo(PersonDto personDto, Disease disease) { - super( - PersonDto.class, - UiFieldAccessCheckers.forDataAccessLevel( - UserProvider.getCurrent().getPseudonymizableDataAccessLevel(personDto.isInJurisdiction()), - personDto.isPseudonymized())); + super(PersonDto.class, FieldAccessHelper.getFieldAccessCheckers(personDto)); this.personDto = personDto; this.disease = disease;