Skip to content

Commit

Permalink
Merge branch 'development' into l10n_development
Browse files Browse the repository at this point in the history
# Conflicts:
#	sormas-api/src/main/resources/captions_ar-SA.properties
  • Loading branch information
obinna-h-n committed Oct 16, 2024
2 parents 535e1dc + 8be6e7e commit 8d8ec14
Show file tree
Hide file tree
Showing 52 changed files with 448 additions and 156 deletions.
20 changes: 18 additions & 2 deletions docs/SERVER_SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Keycloak can be set up in two ways:
**Setup**
* Run `sormas-base/setup/keycloak/keycloak-setup.sh`
* Update `sormas.properties` file in the SORMAS domain with the property `authentication.provider=KEYCLOAK`
* Change in keycloak administration console the client ID for `sormas-stats` and `sormas-ui` from `https` to `http`
### Keycloak as a standalone installation
Expand Down Expand Up @@ -190,9 +190,25 @@ In case Keycloak is set up alongside an already running instance of SORMAS, thes
3. Login to SORMAS and trigger the **Sync Users** button from the **Users** page
4. This will sync users to Keycloak keeping their original password - see [SORMAS Keycloak Service Provider](sormas-keycloak-service-provider/README.md) for more information about this

### Synchronization between SORMAS and Keycloak

The synchronization of users between SORMAS and Keycloak is can be done in two ways:
from SORMAS to Keycloak or from Keycloak to SORMAS depending on how the `AUTH_PROVIDER_TO_SORMAS_USER_SYNC` feature is configured.

By default, the `AUTH_PROVIDER_TO_SORMAS_USER_SYNC` feature is disabled so the synchronization happens from SORMAS to Keycloak.
An automatic synchronization happens when a user is created/changed/deleted in SORMAS,
and there is another way to trigger this manually by an admin on the users page meaning the users are managed in SORMAS.

If the feature is enabled, the synchronization is done from Keycloak to SORMAS.
In order to make this feature work you also need to configure the `authentication.provider.syncedNewUserRole`configuration property in the `sormas.properties` file
to the name of the role that you want to be assigned to the new users coming from Keycloak.

This feature doesn't allow changing the users in SORMAS, except their roles and language, so users will be managed in keycloak.
The synchronization is done automatically each day at night, or manually by an admin on the users page when needed.
### Keycloak configuration
More about the default configuration and how to customize can be found here [Keycloak](sormas-base/doc/keycloak.md)
More about the default configuration and how to customize can be found here [Keycloak](../sormas-base/doc/keycloak.md)
## Web Server Setup
Expand Down
2 changes: 1 addition & 1 deletion sormas-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<parent>
<groupId>de.symeda.sormas</groupId>
<artifactId>sormas-base</artifactId>
<version>1.98.0-SNAPSHOT</version>
<version>1.99.0-SNAPSHOT</version>
<relativePath>../sormas-base</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/

package de.symeda.sormas.api;

public enum CaseClassificationCalculationMode {

DISABLED(false, false),
MANUAL(true, false),
AUTOMATIC(false, true),
MANUAL_AND_AUTOMATIC(true, true);

private final boolean manualEnabled;
private final boolean automaticEnabled;

CaseClassificationCalculationMode(boolean manualEnabled, boolean automaticEnabled) {
this.manualEnabled = manualEnabled;
this.automaticEnabled = automaticEnabled;
}

public boolean isManualEnabled() {
return manualEnabled;
}

public boolean isAutomaticEnabled() {
return automaticEnabled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ public interface ConfigFacade {

String getSormasStatsUrl();

boolean isFeatureAutomaticCaseClassification();

String getEmailSenderAddress();

String getEmailSenderName();
Expand Down Expand Up @@ -159,4 +157,8 @@ public interface ConfigFacade {
void resetRequestContext();

String[] getAllowedFileExtensions();

CaseClassificationCalculationMode getCaseClassificationCalculationMode(Disease disease);

boolean isAnyCaseClassificationCalculationEnabled();
}
4 changes: 4 additions & 0 deletions sormas-api/src/main/java/de/symeda/sormas/api/Language.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ public enum Language {

EN(new Locale("en"), "M/d/yyyy", "M/d/yyyy h:mm a", "M/d"),
EN_NG(new Locale("en", "NG"), "dd/MM/yyyy", "dd/MM/yyyy h:mm a", "dd/MM"),
EN_GM(new Locale("en", "GM"), "dd/MM/yyyy", "dd/MM/yyyy h:mm", "dd/MM"),
EN_LR(new Locale("en", "LR"), "dd/MM/yyyy", "dd/MM/yyyy h:mm", "dd/MM"),
EN_GH(new Locale("en", "GH"), "dd/MM/yyyy", "dd/MM/yyyy h:mm a", "dd/MM"),
EN_KE(new Locale("en", "KE"), "dd/MM/yyyy", "dd/MM/yyyy h:mm", "dd/MM"),
EN_AF(new Locale("en", "AF"), "dd/MM/yyyy", "dd/MM/yyyy h:mm a", "dd/MM"),
FR(new Locale("fr", "FR"), "dd/MM/yyyy", "dd/MM/yyyy HH:mm", "dd/MM"),
FR_CH(new Locale("fr", "CH"), "dd/MM/yyyy", "dd/MM/yyyy HH:mm", "dd/MM"),
FR_TN(new Locale("fr", "TN"), "dd/MM/yyyy", "dd/MM/yyyy HH:mm", "dd/MM"),
DE(new Locale("de", "DE"), "dd.MM.yyyy", "dd.MM.yyyy HH:mm", "dd.MM"),
DE_CH(new Locale("de", "CH"), "dd.MM.yyyy", "dd.MM.yyyy HH:mm", "dd.MM"),
PT_CV(new Locale("pt", "CV"), "dd/MM/yyyy", "dd/MM/yyyy H:mm", "dd/MM"),
ES_BO(new Locale("es", "BO"), "dd/MM/yyyy", "dd/MM/yyyy H:mm", "dd/MM"),
ES_EC(new Locale("es", "EC"), "dd/MM/yyyy", "dd/MM/yyyy H:mm", "dd/MM"),
ES_CU(new Locale("es", "CU"), "dd/MM/yyyy", "dd/MM/yyyy H:mm", "dd/MM"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ public class ExternalMessageDto extends SormasToSormasShareableDto {

private boolean automaticProcessingPossible;

@Size(max = FieldConstraints.CHARACTER_LIMIT_TEXT, message = Validations.textTooLong)
private String personAdditionalDetails;

public ExternalMessageType getType() {
return type;
}
Expand Down Expand Up @@ -507,4 +510,12 @@ public boolean isAutomaticProcessingPossible() {
public void setAutomaticProcessingPossible(boolean automaticProcessingPossible) {
this.automaticProcessingPossible = automaticProcessingPossible;
}

public String getPersonAdditionalDetails() {
return personAdditionalDetails;
}

public void setPersonAdditionalDetails(String personAdditionalDetails) {
this.personAdditionalDetails = personAdditionalDetails;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,6 @@

package de.symeda.sormas.api.externalmessage.processing;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutableTriple;

import de.symeda.sormas.api.CountryHelper;
import de.symeda.sormas.api.customizableenum.CustomEnumNotFoundException;
import de.symeda.sormas.api.disease.DiseaseVariant;
Expand All @@ -45,6 +34,16 @@
import de.symeda.sormas.api.sample.SampleDto;
import de.symeda.sormas.api.utils.DataHelper;
import de.symeda.sormas.api.utils.DateHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutableTriple;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public final class ExternalMessageMapper {

Expand Down Expand Up @@ -83,7 +82,12 @@ public List<String[]> mapToPerson(PersonDto person) {
person::setNationalHealthId,
person.getNationalHealthId(),
externalMessage.getPersonNationalHealthId(),
PersonDto.NATIONAL_HEALTH_ID)));
PersonDto.NATIONAL_HEALTH_ID),
Mapping.of(
person::setAdditionalDetails,
person.getAdditionalDetails(),
externalMessage.getPersonAdditionalDetails(),
PersonDto.ADDITIONAL_DETAILS)));

if (person.getBirthdateYYYY() != null) {
DataHelper.Pair<Integer, ApproximateAgeType> ageAndAgeType = ApproximateAgeType.ApproximateAgeHelper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,15 @@

package de.symeda.sormas.api.externalmessage.processing.labmessage;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.symeda.sormas.api.Disease;
import de.symeda.sormas.api.FacadeProvider;
import de.symeda.sormas.api.caze.CaseDataDto;
import de.symeda.sormas.api.caze.CaseSelectionDto;
import de.symeda.sormas.api.caze.surveillancereport.ReportingType;
import de.symeda.sormas.api.caze.surveillancereport.SurveillanceReportDto;
import de.symeda.sormas.api.contact.ContactDto;
import de.symeda.sormas.api.contact.SimilarContactDto;
import de.symeda.sormas.api.event.EventCriteria;
import de.symeda.sormas.api.event.EventDto;
import de.symeda.sormas.api.event.EventIndexDto;
import de.symeda.sormas.api.event.EventParticipantCriteria;
import de.symeda.sormas.api.event.EventParticipantDto;
import de.symeda.sormas.api.event.EventParticipantReferenceDto;
import de.symeda.sormas.api.event.SimilarEventParticipantDto;
import de.symeda.sormas.api.event.*;
import de.symeda.sormas.api.externalmessage.ExternalMessageDto;
import de.symeda.sormas.api.externalmessage.ExternalMessageStatus;
import de.symeda.sormas.api.externalmessage.ExternalMessageType;
Expand All @@ -66,6 +49,17 @@
import de.symeda.sormas.api.utils.dataprocessing.ProcessingResult;
import de.symeda.sormas.api.utils.dataprocessing.ProcessingResultStatus;
import de.symeda.sormas.api.utils.dataprocessing.flow.FlowThen;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
* Abstract class defining the flow of processing a lab message allowing to choose between multiple options like create or select a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2677,6 +2677,7 @@ public interface Captions {
String User_associatedOfficer = "User.associatedOfficer";
String User_community = "User.community";
String User_district = "User.district";
String User_externalId = "User.externalId";
String User_hasConsentedToGdpr = "User.hasConsentedToGdpr";
String User_healthFacility = "User.healthFacility";
String User_laboratory = "User.laboratory";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,7 @@ public interface Strings {
String messageSubcontinentsDearchived = "messageSubcontinentsDearchived";
String messageSymptomsHint = "messageSymptomsHint";
String messageSymptomsVisitHint = "messageSymptomsVisitHint";
String messageSyncUsersFromAuthProviderConfigurationError = "messageSyncUsersFromAuthProviderConfigurationError";
String messageSystemFollowUpCanceled = "messageSystemFollowUpCanceled";
String messageSystemFollowUpCanceledByDropping = "messageSystemFollowUpCanceledByDropping";
String messageTaskArchived = "messageTaskArchived";
Expand Down
11 changes: 11 additions & 0 deletions sormas-api/src/main/java/de/symeda/sormas/api/user/UserDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class UserDto extends EntityDto {
public static final String LIMITED_DISEASES = "limitedDiseases";
public static final String LANGUAGE = "language";
public static final String HAS_CONSENTED_TO_GDPR = "hasConsentedToGdpr";
public static final String EXTERNAL_ID = "externalId";
public static final String JURISDICTION_LEVEL = "jurisdictionLevel";

private boolean active = true;
Expand Down Expand Up @@ -107,6 +108,8 @@ public class UserDto extends EntityDto {

private boolean hasConsentedToGdpr;

private String externalId;

private JurisdictionLevel jurisdictionLevel;

public static UserDto build() {
Expand Down Expand Up @@ -278,6 +281,14 @@ public void setHasConsentedToGdpr(boolean hasConsentedToGdpr) {
this.hasConsentedToGdpr = hasConsentedToGdpr;
}

public String getExternalId() {
return externalId;
}

public void setExternalId(String externalId) {
this.externalId = externalId;
}

public JurisdictionLevel getJurisdictionLevel() {
return jurisdictionLevel;
}
Expand Down
1 change: 1 addition & 0 deletions sormas-api/src/main/resources/captions.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2606,6 +2606,7 @@ User.uuid=UUID
User.region=Region
User.district=District
User.community=Community
User.externalId=External ID
userRestrictDiseases=Restrict access to specific diseases
# Vaccination
vaccinationNewVaccination=New vaccination
Expand Down
Binary file modified sormas-api/src/main/resources/doc/SORMAS_Data_Dictionary.xlsx
Binary file not shown.
Binary file modified sormas-api/src/main/resources/doc/SORMAS_User_Roles.xlsx
Binary file not shown.
8 changes: 6 additions & 2 deletions sormas-api/src/main/resources/enum.properties
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ Disease.EVD = Ebola Virus Disease
Disease.GUINEA_WORM = Guinea Worm
Disease.LASSA = Lassa
Disease.MEASLES = Measles
Disease.MONKEYPOX = Monkeypox
Disease.MONKEYPOX = Mpox
Disease.NEW_INFLUENZA = Influenza (New subtype)
Disease.UNDEFINED = Not Yet Defined
Disease.OTHER = Other Epidemic Disease
Expand Down Expand Up @@ -524,7 +524,7 @@ Disease.Short.EVD = EVD
Disease.Short.GUINEA_WORM = Guinea Worm
Disease.Short.LASSA = Lassa
Disease.Short.MEASLES = Measles
Disease.Short.MONKEYPOX = Monkeypox
Disease.Short.MONKEYPOX = Mpox
Disease.Short.NEW_INFLUENZA = New Flu
Disease.Short.UNDEFINED = Undefined
Disease.Short.OTHER = Other
Expand Down Expand Up @@ -873,9 +873,12 @@ KindOfInvolvement.POTENTIALLY_EXPOSED = Potentially exposed
KindOfInvolvement.POTENTIAL_INDEX_CASE = Potential index case

Language.EN = English
Language.EN_GM = English (The Gambia)
Language.EN_LR = English (Liberia)
Language.EN_AF = English (Afghanistan)
Language.EN_NG = English (Nigeria)
Language.EN_GH = English (Ghana)
Language.EN_KE = English (Kenya)
Language.FR = Français
Language.DE = Deutsch
Language.ES_BO = Español (Bolivia)
Expand All @@ -884,6 +887,7 @@ Language.ES_CU = Español (Cuba)
Language.FI = Suomi
Language.IT = Italiano
Language.DE_CH = Deutsch (Schweiz)
Language.PT_CV = Português (Cabo Verde)
Language.IT_CH = Italiano (Svizzera)
Language.FR_CH = Français (Suisse)
Language.PS = Pashto
Expand Down
2 changes: 2 additions & 0 deletions sormas-api/src/main/resources/strings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,8 @@ messageCustomizableEnumValueSaved = Customizable enum value saved
messageExternalEmailAttachmentPassword=Please use this password to open the documents sent to you via email from SORMAS: %s
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.

# Notifications
notificationCaseClassificationChanged = The classification of case %s has changed to %s.
notificationCaseInvestigationDone = The investigation of case %s has been done.
Expand Down
2 changes: 1 addition & 1 deletion sormas-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<artifactId>sormas-base</artifactId>
<groupId>de.symeda.sormas</groupId>
<version>1.97.0-SNAPSHOT</version>
<version>1.99.0-SNAPSHOT</version>
<relativePath>../sormas-base</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
2 changes: 1 addition & 1 deletion sormas-backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<artifactId>sormas-base</artifactId>
<groupId>de.symeda.sormas</groupId>
<version>1.98.0-SNAPSHOT</version>
<version>1.99.0-SNAPSHOT</version>
<relativePath>../sormas-base</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2066,7 +2066,7 @@ private void updateTasksOnCaseChanged(Case newCase, CaseDataDto existingCase) {
@PermitAll
public void onCaseSampleChanged(Case associatedCase) {
// Update case classification if the feature is enabled
if (configFacade.isFeatureAutomaticCaseClassification()) {
if (configFacade.getCaseClassificationCalculationMode(associatedCase.getDisease()).isAutomaticEnabled()) {
if (associatedCase.getCaseClassification() != CaseClassification.NO_CASE) {
Long pathogenTestsCount = pathogenTestService.countByCase(associatedCase);
if (pathogenTestsCount == 0) {
Expand Down Expand Up @@ -2263,7 +2263,7 @@ private void handleClassificationOnCaseChange(CaseDataDto existingDto, Case save
// Update case classification if the feature is enabled
CaseClassification classification = null;
boolean setClassificationInfo = true;
if (configFacade.isFeatureAutomaticCaseClassification()) {
if (configFacade.getCaseClassificationCalculationMode(savedCase.getDisease()).isAutomaticEnabled()) {
if (savedCase.getCaseClassification() != CaseClassification.NO_CASE
|| configFacade.isConfiguredCountry(CountryHelper.COUNTRY_CODE_LUXEMBOURG)) {
// calculate classification
Expand Down
Loading

0 comments on commit 8d8ec14

Please sign in to comment.