Skip to content

Commit 230943b

Browse files
authored
Merge pull request #13910 from SORMAS-Foundation/bugfix-13704-pre-existing-conditions-visibility-roles
Fixes issue where HealthConditionsForm fields are not accessible to u…
2 parents ba1aaf7 + fbf98d7 commit 230943b

8 files changed

Lines changed: 90 additions & 37 deletions

File tree

sormas-backend/src/test/java/de/symeda/sormas/backend/caze/CaseFacadeEjbPseudonymizationTest.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ public void testUpdateGpsCoordinatesWithPseudonymizedData() {
436436
/**
437437
* Expected to save the updated data because, it is a really rare edge case that is not handled at the moment.
438438
* Probably won't be a need to handle it.
439-
*
439+
*
440440
* @see de.symeda.sormas.api.utils.pseudonymization.valuepseudonymizers.LongitudePseudonymizer#isValuePseudonymized(Double)
441441
* and
442442
* @see de.symeda.sormas.api.utils.pseudonymization.valuepseudonymizers.LatitudePseudonymizer#isValuePseudonymized(Double)
@@ -445,6 +445,53 @@ public void testUpdateGpsCoordinatesWithPseudonymizedData() {
445445
assertThat(savedCase.getReportLon(), is(22.234));
446446
}
447447

448+
@Test
449+
public void testOtherConditionsHiddenWithoutSensitiveDataRight() {
450+
// A user without SEE_SENSITIVE_DATA_IN_JURISDICTION must not see otherConditions,
451+
// regardless of jurisdiction — it is @SensitiveData and pseudonymized on the backend.
452+
loginWith(nationalAdmin);
453+
UserRoleReferenceDto noSensitiveDataRole = creator.createUserRoleWithRequiredRights(
454+
"ContactPersonNoSensitive",
455+
JurisdictionLevel.DISTRICT,
456+
UserRight.CASE_VIEW,
457+
UserRight.PERSON_VIEW,
458+
UserRight.CLINICAL_COURSE_VIEW,
459+
UserRight.SEE_PERSONAL_DATA_IN_JURISDICTION);
460+
461+
UserDto contactPerson =
462+
creator.createUser(rdcf1.region.getUuid(), rdcf1.district.getUuid(), rdcf1.facility.getUuid(), "Contact", "Person", noSensitiveDataRole);
463+
464+
// Create case with otherConditions set at creation time
465+
CaseDataDto caze = creator.createCase(
466+
user1.toReference(),
467+
createPerson().toReference(),
468+
Disease.CORONAVIRUS,
469+
CaseClassification.NOT_CLASSIFIED,
470+
InvestigationStatus.PENDING,
471+
new Date(),
472+
rdcf1,
473+
c -> {
474+
c.setRegion(rdcf1.region);
475+
c.setDistrict(rdcf1.district);
476+
c.setCommunity(rdcf1.community);
477+
c.setReportingUser(user1.toReference());
478+
c.getHealthConditions().setOtherConditions("Sensitive pre-existing condition");
479+
});
480+
481+
// user without sensitive data right: healthConditions is @SensitiveData so the entire field is pseudonymized (null),
482+
// and isPseudonymized=true because sensitive data was hidden
483+
loginWith(contactPerson);
484+
CaseDataDto result = getCaseFacade().getCaseDataByUuid(caze.getUuid());
485+
assertThat(result.isPseudonymized(), is(true));
486+
assertThat(result.getHealthConditions(), is(nullValue()));
487+
488+
// nationalAdmin has all rights including SEE_SENSITIVE_DATA: otherConditions must be visible
489+
loginWith(nationalAdmin);
490+
CaseDataDto resultWithRight = getCaseFacade().getCaseDataByUuid(caze.getUuid());
491+
assertThat(resultWithRight.isPseudonymized(), is(false));
492+
assertThat(resultWithRight.getHealthConditions().getOtherConditions(), is("Sensitive pre-existing condition"));
493+
}
494+
448495
@Test
449496
public void testSpecialCaseAccessOutsideJurisdiction() {
450497

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseCreateForm.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,8 +549,10 @@ private void hideAndFillJurisdictionFields() {
549549
getContent().getComponent(PLACE_OF_STAY_HEADING_LOC).setVisible(false);
550550
differentPlaceOfStayJurisdiction.setVisible(false);
551551
responsibleRegionCombo.setVisible(false);
552+
responsibleRegionCombo.setRequired(false);
552553
responsibleRegionCombo.setValue(FacadeProvider.getRegionFacade().getDefaultInfrastructureReference());
553554
responsibleDistrictCombo.setVisible(false);
555+
responsibleDistrictCombo.setRequired(false);
554556
responsibleDistrictCombo.setValue(FacadeProvider.getDistrictFacade().getDefaultInfrastructureReference());
555557
responsibleCommunityCombo.setVisible(false);
556558
responsibleCommunityCombo.setValue(FacadeProvider.getCommunityFacade().getDefaultInfrastructureReference());

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataForm.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@
133133
import de.symeda.sormas.api.utils.DateHelper;
134134
import de.symeda.sormas.api.utils.ExtendedReduced;
135135
import de.symeda.sormas.api.utils.YesNoUnknown;
136-
import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers;
137136
import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers;
138137
import de.symeda.sormas.api.utils.fieldvisibility.checkers.CountryFieldVisibilityChecker;
139138
import de.symeda.sormas.api.utils.fieldvisibility.checkers.FeatureTypeFieldVisibilityChecker;
@@ -369,6 +368,8 @@ public class CaseDataForm extends AbstractEditForm<CaseDataDto> {
369368
private final Disease disease;
370369
private final SymptomsDto symptoms;
371370
private final boolean caseFollowUpEnabled;
371+
private final boolean isPseudonymized;
372+
private final boolean inJurisdiction;
372373
private DateField dfFollowUpUntil;
373374
private CheckBox cbOverwriteFollowUpUntil;
374375
private Field<?> quarantine;
@@ -425,6 +426,8 @@ public CaseDataForm(
425426
this.disease = disease;
426427
this.symptoms = symptoms;
427428
this.caseFollowUpEnabled = UiUtil.enabled(FeatureType.CASE_FOLLOWUP);
429+
this.isPseudonymized = isPseudonymized;
430+
this.inJurisdiction = inJurisdiction;
428431
setCustomizableFieldsMetadata(customizableFieldsMetadata);
429432
setCustomizableFieldsValues(customizableFieldsValues);
430433

@@ -1119,8 +1122,9 @@ protected void addFields() {
11191122
disease,
11201123
FieldVisibilityCheckers.withDisease(disease)
11211124
.add(new CountryFieldVisibilityChecker(FacadeProvider.getConfigFacade().getCountryLocale())),
1122-
UiFieldAccessCheckers.getDefault(true, FacadeProvider.getConfigFacade().getCountryLocale()),
1123-
new PersonReferenceDto(person.getUuid()))).setCaption(null);
1125+
FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized),
1126+
new PersonReferenceDto(person.getUuid())))
1127+
.setCaption(null);
11241128

11251129
//diagnosis criteria
11261130
if ((FacadeProvider.getConfigFacade().isConfiguredCountry(CountryHelper.COUNTRY_CODE_LUXEMBOURG)) && disease == Disease.TUBERCULOSIS) {

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseDataView.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,13 +259,13 @@ protected void initView(String params) {
259259
layout.addSidePanelComponent(new SideComponentLayout(specialAccessListComponent), SPECIAL_ACCESSES_LOC);
260260
}
261261

262-
if (UiUtil.permitted(FeatureType.SELF_REPORTING)) {
262+
if (UiUtil.permitted(FeatureType.SELF_REPORTING, UserRight.SELF_REPORT_VIEW)) {
263263
SelfReportListComponent selfReportListComponent =
264264
new SelfReportListComponent(SelfReportType.CASE, new SelfReportCriteria().setCaze(new CaseReferenceDto(caze.getUuid())));
265265
SelfReportListComponentLayout selfReportListComponentLayout = new SelfReportListComponentLayout(selfReportListComponent);
266266
layout.addSidePanelComponent(selfReportListComponentLayout, SELF_REPORT_LOC);
267267
}
268-
if (UiUtil.permitted(FeatureType.SURVEYS)) {
268+
if (UiUtil.permitted(FeatureType.SURVEYS, UserRight.SURVEY_VIEW)) {
269269
SurveyListComponentLayout surveyList = new SurveyListComponentLayout(
270270
caze.toReference(),
271271
caze.getDisease(),

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseFilterForm.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ public void addMoreFilters(CustomLayout moreFiltersContainer) {
455455
moreFiltersContainer.addComponent(buildWeekAndDateFilter(isExternalShareEnabled), WEEK_AND_DATE_FILTER);
456456

457457
moreFiltersContainer.addComponent(buildBirthdayRangeFilter(), BIRTHDATE_RANGE_FILTER);
458-
if (UiUtil.enabled(FeatureType.SURVEYS)) {
458+
if (UiUtil.enabled(FeatureType.SURVEYS) && UiUtil.permitted(UserRight.SURVEY_VIEW)) {
459459
buildSurveyFilters(moreFiltersContainer);
460460
}
461461
}
@@ -862,15 +862,19 @@ private HorizontalLayout buildBirthdayRangeFilter() {
862862

863863
private void buildSurveyFilters(CustomLayout layout) {
864864

865-
ComboBox surveyCombo = addField(layout, FieldConfiguration.withCaptionAndPixelSized(CaseCriteria.SURVEY, I18nProperties.getString(Strings.promptSurvey), 200));
865+
ComboBox surveyCombo =
866+
addField(layout, FieldConfiguration.withCaptionAndPixelSized(CaseCriteria.SURVEY, I18nProperties.getString(Strings.promptSurvey), 200));
866867
FieldHelper.updateItems(surveyCombo, FacadeProvider.getSurveyFacade().getAllAsReference());
867-
addField(layout,
868+
addField(
869+
layout,
868870
FieldConfiguration
869871
.withCaptionAndPixelSized(CaseCriteria.SURVEY_RESPONSE_STATUS, I18nProperties.getString(Strings.promptSurveyResponseStatus), 200));
870-
addField(layout,
872+
addField(
873+
layout,
871874
FieldConfiguration
872875
.withCaptionAndPixelSized(CaseCriteria.SURVEY_ASSIGNED_FROM, I18nProperties.getString(Strings.promptSurveyAssignedFrom), 200));
873-
addField(layout,
876+
addField(
877+
layout,
874878
FieldConfiguration
875879
.withCaptionAndPixelSized(CaseCriteria.SURVEY_ASSIGNED_TO, I18nProperties.getString(Strings.promptSurveyAssignedTo), 200));
876880

sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import com.vaadin.ui.Label;
5252
import com.vaadin.v7.data.fieldgroup.FieldGroup;
5353
import com.vaadin.v7.ui.AbstractSelect;
54-
import com.vaadin.v7.ui.AbstractTextField;
5554
import com.vaadin.v7.ui.ComboBox;
5655
import com.vaadin.v7.ui.Field;
5756
import com.vaadin.v7.ui.TextArea;
@@ -66,13 +65,11 @@
6665
import de.symeda.sormas.api.i18n.I18nProperties;
6766
import de.symeda.sormas.api.i18n.Strings;
6867
import de.symeda.sormas.api.person.PersonReferenceDto;
69-
import de.symeda.sormas.api.user.UserRight;
7068
import de.symeda.sormas.api.utils.DateHelper;
7169
import de.symeda.sormas.api.utils.YesNoUnknown;
7270
import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers;
7371
import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers;
7472
import de.symeda.sormas.ui.ControllerProvider;
75-
import de.symeda.sormas.ui.UiUtil;
7673
import de.symeda.sormas.ui.utils.AbstractEditForm;
7774
import de.symeda.sormas.ui.utils.CssStyles;
7875
import de.symeda.sormas.ui.utils.FieldHelper;
@@ -328,16 +325,6 @@ protected void addFields() {
328325

329326
FieldHelper.setVisibleWhen(getFieldGroup(), Arrays.asList(MALARIA_INFECTED_YEAR), MALARIA, Arrays.asList(YesNoUnknown.YES), true);
330327
}
331-
if (UiUtil.permitted(UserRight.SEE_SENSITIVE_DATA_IN_JURISDICTION, UserRight.SEE_SENSITIVE_DATA_OUTSIDE_JURISDICTION)) {
332-
Field<?> other = getField(OTHER_CONDITIONS);
333-
if (other != null) {
334-
other.setReadOnly(false);
335-
other.setEnabled(true);
336-
if (other instanceof AbstractTextField) {
337-
((AbstractTextField) other).setInputPrompt("");
338-
}
339-
}
340-
}
341328
}
342329

343330
/**

sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataForm.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@
8787
import de.symeda.sormas.api.utils.Diseases.DiseasesConfiguration;
8888
import de.symeda.sormas.api.utils.ExtendedReduced;
8989
import de.symeda.sormas.api.utils.YesNoUnknown;
90-
import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers;
9190
import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers;
9291
import de.symeda.sormas.api.utils.fieldvisibility.checkers.CountryFieldVisibilityChecker;
9392
import de.symeda.sormas.ui.ControllerProvider;
@@ -182,6 +181,8 @@ public class ContactDataForm extends AbstractEditForm<ContactDto> {
182181
private final ViewMode viewMode;
183182
private final Disease disease;
184183
private final boolean diseaseHasFollowUp;
184+
private final boolean isPseudonymized;
185+
private final boolean inJurisdiction;
185186
private OptionGroup contactProximities;
186187
private ComboBox region;
187188
private ComboBox district;
@@ -222,6 +223,8 @@ public ContactDataForm(Disease disease, ViewMode viewMode, boolean isPseudonymiz
222223
this.viewMode = viewMode;
223224
this.disease = disease;
224225
this.diseaseHasFollowUp = FacadeProvider.getDiseaseConfigurationFacade().hasFollowUp(disease);
226+
this.isPseudonymized = isPseudonymized;
227+
this.inJurisdiction = inJurisdiction;
225228
addFields();
226229
}
227230

@@ -545,7 +548,7 @@ protected void addFields() {
545548
disease,
546549
FieldVisibilityCheckers.withDisease(disease)
547550
.add(new CountryFieldVisibilityChecker(FacadeProvider.getConfigFacade().getCountryLocale())),
548-
UiFieldAccessCheckers.getDefault(true, FacadeProvider.getConfigFacade().getCountryLocale())));
551+
FieldAccessHelper.getFieldAccessCheckers(inJurisdiction, isPseudonymized)));
549552
clinicalCourseForm.setCaption(null);
550553

551554
Label generalCommentLabel = new Label(I18nProperties.getPrefixCaption(ContactDto.I18N_PREFIX, ContactDto.ADDITIONAL_DETAILS));

sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactDataView.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
*/
1515
package de.symeda.sormas.ui.contact;
1616

17+
import java.util.List;
18+
1719
import com.vaadin.server.Page;
1820
import com.vaadin.shared.ui.ContentMode;
1921
import com.vaadin.ui.Button;
@@ -74,8 +76,6 @@
7476
import de.symeda.sormas.ui.utils.components.sidecomponent.SideComponentLayout;
7577
import de.symeda.sormas.ui.vaccination.list.VaccinationListComponent;
7678

77-
import java.util.List;
78-
7979
public class ContactDataView extends AbstractContactView implements HasName {
8080

8181
private static final long serialVersionUID = -1L;
@@ -220,13 +220,16 @@ protected void initView(String params) {
220220
layout.addSidePanelComponent(taskList, TASKS_LOC);
221221
}
222222

223-
if (!(FacadeProvider.getConfigFacade().isConfiguredCountry(CountryHelper.COUNTRY_CODE_LUXEMBOURG) && List.of(Disease.INVASIVE_MENINGOCOCCAL_INFECTION, Disease.MEASLES).contains(contactDto.getDisease()))) {
223+
if (!(FacadeProvider.getConfigFacade().isConfiguredCountry(CountryHelper.COUNTRY_CODE_LUXEMBOURG)
224+
&& List.of(Disease.INVASIVE_MENINGOCOCCAL_INFECTION, Disease.MEASLES).contains(contactDto.getDisease()))) {
224225
if (UiUtil.permitted(UserRight.SAMPLE_VIEW)) {
225226
SampleListComponent sampleList = new SampleListComponent(
226-
new SampleCriteria().contact(getContactRef()).disease(contactDto.getDisease()).sampleAssociationType(SampleAssociationType.CONTACT),
227-
this::showUnsavedChangesPopup,
228-
editAllowed,
229-
SampleAssociationType.CONTACT);
227+
new SampleCriteria().contact(getContactRef())
228+
.disease(contactDto.getDisease())
229+
.sampleAssociationType(SampleAssociationType.CONTACT),
230+
this::showUnsavedChangesPopup,
231+
editAllowed,
232+
SampleAssociationType.CONTACT);
230233
SampleListComponentLayout sampleListComponentLayout = new SampleListComponentLayout(sampleList, null);
231234
layout.addSidePanelComponent(sampleListComponentLayout, SAMPLES_LOC);
232235
}
@@ -310,10 +313,13 @@ protected void initView(String params) {
310313
layout.addSidePanelComponent(new SideComponentLayout(externalEmailSideComponent), EXTERNAL_EMAILS_LOC);
311314
}
312315

313-
SelfReportListComponent selfReportListComponent =
314-
new SelfReportListComponent(SelfReportType.CONTACT, new SelfReportCriteria().setContact(new ContactReferenceDto(contactDto.getUuid())));
315-
SelfReportListComponentLayout selfReportListComponentLayout = new SelfReportListComponentLayout(selfReportListComponent);
316-
layout.addSidePanelComponent(selfReportListComponentLayout, SELF_REPORT_LOC);
316+
if (UiUtil.permitted(FeatureType.SELF_REPORTING, UserRight.SELF_REPORT_VIEW)) {
317+
SelfReportListComponent selfReportListComponent = new SelfReportListComponent(
318+
SelfReportType.CONTACT,
319+
new SelfReportCriteria().setContact(new ContactReferenceDto(contactDto.getUuid())));
320+
SelfReportListComponentLayout selfReportListComponentLayout = new SelfReportListComponentLayout(selfReportListComponent);
321+
layout.addSidePanelComponent(selfReportListComponentLayout, SELF_REPORT_LOC);
322+
}
317323

318324
final boolean deleted = FacadeProvider.getContactFacade().isDeleted(uuid);
319325
layout.disableIfNecessary(deleted, contactEditAllowed);

0 commit comments

Comments
 (0)