diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/config/WSBaseConfig.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/config/WSBaseConfig.java index ebdb4d83..f6b6924f 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/config/WSBaseConfig.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/config/WSBaseConfig.java @@ -36,14 +36,14 @@ import org.dpppt.backend.sdk.ws.controller.GaenController; import org.dpppt.backend.sdk.ws.filter.ResponseWrapperFilter; import org.dpppt.backend.sdk.ws.insertmanager.InsertManager; -import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.FakeKeysFilter; -import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.IOSLegacyProblemRPLT144Filter; -import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.InvalidRollingPeriodFilter; -import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.KeysNotMatchingJWTFilter; -import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.NoBase64Filter; -import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.OldAndroid0RPFilter; +import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.NonFakeKeysFilter; +import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.ValidRollingPeriodFilter; +import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.KeysMatchingJWTFilter; +import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.Base64Filter; import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.RollingStartNumberAfterDayAfterTomorrowFilter; -import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.RollingStartNumberBeforeRetentionDay; +import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.RollingStartNumberInRetentionPeriodFilter; +import org.dpppt.backend.sdk.ws.insertmanager.insertionmodifier.IOSLegacyProblemRPLT144Modifier; +import org.dpppt.backend.sdk.ws.insertmanager.insertionmodifier.OldAndroid0RPModifier; import org.dpppt.backend.sdk.ws.interceptor.HeaderInjector; import org.dpppt.backend.sdk.ws.security.KeyVault; import org.dpppt.backend.sdk.ws.security.NoValidateRequest; @@ -195,32 +195,33 @@ public ProtoSignature gaenSigner() { @Bean public InsertManager insertManager() { var manager = new InsertManager(gaenDataService(), gaenValidationUtils()); - manager.addFilter(new NoBase64Filter(gaenValidationUtils())); - manager.addFilter(new KeysNotMatchingJWTFilter(gaenRequestValidator, gaenValidationUtils())); + manager.addFilter(new Base64Filter(gaenValidationUtils())); + manager.addFilter(new KeysMatchingJWTFilter(gaenRequestValidator, gaenValidationUtils())); manager.addFilter(new RollingStartNumberAfterDayAfterTomorrowFilter()); - manager.addFilter(new RollingStartNumberBeforeRetentionDay(gaenValidationUtils())); - manager.addFilter(new FakeKeysFilter()); - manager.addFilter(new InvalidRollingPeriodFilter()); + manager.addFilter(new RollingStartNumberInRetentionPeriodFilter(gaenValidationUtils())); + manager.addFilter(new NonFakeKeysFilter()); + manager.addFilter(new ValidRollingPeriodFilter()); return manager; } + @ConditionalOnProperty( - value="ws.app.gaen.insertfilter.android0rpfilter", + value="ws.app.gaen.insertmanager.android0rpmodifier", havingValue = "true", matchIfMissing = false) - @Bean public OldAndroid0RPFilter oldAndroid0RPFilter(InsertManager manager){ - var androidFilter = new OldAndroid0RPFilter(); - manager.addFilter(androidFilter); - return androidFilter; + @Bean public OldAndroid0RPModifier oldAndroid0RPModifier(InsertManager manager){ + var androidModifier = new OldAndroid0RPModifier(); + manager.addModifier(androidModifier); + return androidModifier; } @ConditionalOnProperty( - value="ws.app.gaen.insertfilter.iosrplt144filter", + value="ws.app.gaen.insertmanager.iosrplt144modifier", havingValue = "true", matchIfMissing = false) - @Bean public IOSLegacyProblemRPLT144Filter iosLegacyProblemRPLT144(InsertManager manager){ - var iosFilter = new IOSLegacyProblemRPLT144Filter(); - manager.addFilter(iosFilter); - return iosFilter; + @Bean public IOSLegacyProblemRPLT144Modifier iosLegacyProblemRPLT144(InsertManager manager){ + var iosModifier = new IOSLegacyProblemRPLT144Modifier(); + manager.addModifier(iosModifier); + return iosModifier; } diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/controller/GaenController.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/controller/GaenController.java index 7a51e101..e3c3d7a2 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/controller/GaenController.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/controller/GaenController.java @@ -35,7 +35,7 @@ import org.dpppt.backend.sdk.utils.UTCInstant; import org.dpppt.backend.sdk.ws.insertmanager.InsertException; import org.dpppt.backend.sdk.ws.insertmanager.InsertManager; -import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.NoBase64Filter.KeyIsNotBase64Exception; +import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.Base64Filter.KeyIsNotBase64Exception; import org.dpppt.backend.sdk.ws.security.ValidateRequest; import org.dpppt.backend.sdk.ws.security.ValidateRequest.ClaimIsBeforeOnsetException; import org.dpppt.backend.sdk.ws.security.ValidateRequest.InvalidDateException; diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/InsertManager.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/InsertManager.java index 3d98e89d..704cd43d 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/InsertManager.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/InsertManager.java @@ -7,7 +7,8 @@ import org.dpppt.backend.sdk.model.gaen.GaenKey; import org.dpppt.backend.sdk.semver.Version; import org.dpppt.backend.sdk.utils.UTCInstant; -import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.InsertionFilter; +import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.KeyInsertionFilter; +import org.dpppt.backend.sdk.ws.insertmanager.insertionmodifier.KeyInsertionModifier; import org.dpppt.backend.sdk.ws.util.ValidationUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,16 +16,19 @@ /** * The insertion manager is responsible for inserting keys uploaded by clients * into the database. To make sure we only have valid keys in the database, a - * list of {@Link InsertionFilter} is applied to the given list of keys. The - * remaining keys are then inserted into the database. If any of the filters - * throws an {@Link InsertException} the process of insertions is aborted and - * the exception is propagated back to the caller, which is responsible for - * handling the exception. + * list of {@link KeyInsertionModifier} is applied, and then a list of + * {@Link KeyInsertionFilter} is applied to the given list of keys. The + * remaining keys are then inserted into the database. If any of the modifiers + * filters throws an {@Link InsertException} the process of insertions is + * aborted and the exception is propagated back to the caller, which is + * responsible for handling the exception. * */ public class InsertManager { - private final List filterList = new ArrayList<>(); + private final List filterList = new ArrayList<>(); + private final List modifierList = new ArrayList<>(); + private final GAENDataService dataService; private final ValidationUtils validationUtils; @@ -35,13 +39,17 @@ public InsertManager(GAENDataService dataService, ValidationUtils validationUtil this.validationUtils = validationUtils; } - public void addFilter(InsertionFilter filter) { - filterList.add(filter); + public void addFilter(KeyInsertionFilter filter) { + this.filterList.add(filter); + } + + public void addModifier(KeyInsertionModifier modifier) { + this.modifierList.add(modifier); } /** * Inserts the keys into the database. The additional parameters are supplied to - * the configured filters. + * the configured modifiers and filters. * * @param keys the list of keys from the client * @param header request header from client @@ -71,7 +79,11 @@ public void insertIntoDatabase(List keys, String header, Object princip var osVersion = extractOsVersion(headerParts[4]); var appVersion = extractAppVersion(headerParts[1], headerParts[2]); - for (InsertionFilter filter : filterList) { + for (KeyInsertionModifier modifier : modifierList) { + internalKeys = modifier.modify(now, internalKeys, osType, osVersion, appVersion, principal); + } + + for (KeyInsertionFilter filter : filterList) { internalKeys = filter.filter(now, internalKeys, osType, osVersion, appVersion, principal); } diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/README.md b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/README.md index dc5276b7..acb9b257 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/README.md +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/README.md @@ -1,30 +1,26 @@ # Insert-Manager ## Idea -The Insert-Manager was introduced to reduce logic in controllers. The idea is to provide a second abstraction layer next to the `DataServices` to provide for possible generic validation and normalization. The Insert-Manager holds a list of `InsertionFilter`, which provide some code, to either filter for invalid data or alter incoming data. Each filter can decide to either skip respective keys, or throw a `InsertException`. Throwing an exception aborts the current insert request, and throws to the controller. Inside the controller the exception can be mapped to a respective error message and http status code. +The Insert-Manager was introduced to reduce logic in controllers. The idea is to provide a second abstraction layer next to the `DataServices` to provide for possible generic validation and normalization. For this there are two mechanisems: modifiers and filters -The current default only handles `KeyIsNotBase64Exception` and ignores all other exceptions (since there are none). +The Insert-Manager holds a list of `KeyInsertionFilter`, which provide some code, to either filter for invalid data data. Each filter can decide to either skip respective keys, or throw a `InsertException`. Throwing an exception aborts the current insert request, and throws to the controller. Inside the controller the exception can be mapped to a respective error message and http status code. -During construction, instances of `GAENDataService` and `ValidationUtils` are needed. Further, any filter can be added to the list with `addFilter(InsertionFilter filter)`. Ideally, this happens inside the [`WSBaseConfig`](../config/WSBaseConfig.java), where default filters are added right after constructing the `InsertManager`. To allow for conditional `InsertionFilters` refer to the following snippet: +Additionally the Insert-Manager can be configured to hold a list of `KeyInsertModifier`. Modifiers are can be used to modify incoming keys before inserting into the database. (for example to fix buggy clients) -```java -@ConditionalOnProperty( -value="ws.app.gaen.ioslegacy", -havingValue = "true", -matchIfMissing = true) -@Bean public IOSLegacyProblemRPLT144 iosLegacyProblemRPLT144(InsertManager manager){ - var iosFilter = new IOSLegacyProblemRPLT144(); - manager.addFilter(iosFilter); - return iosFilter; -} -``` +Encapsulating the logic into smaller pieces of code, should allow for easier and better reviews of the respective filters and modifiers. Further, for each filter or modifier an extensive documentation can be provided, without cluttering the code with too many comments. -This looks for a property, either supplied via a `application.properties` file, or via `java` arguments (e.g. `java -D w.app.gaen.ioslegacy`) and constructs and inserts the respective filter bean into the filter chain. For further `SpringBoot` `Conditional` annotations have a look at ["Spring Boot Conditionals"](https://reflectoring.io/spring-boot-conditionals/) +## Valid Keys +A valid key is defined as follows: +- Base64 Encoded key +- Non Fake +- Rolling Period in [1..144] +- Rolling start number inside the configured retention period +- Rolling start number not too far in the future, more precisely not after the day after tomorrow at time of insertion +- Key date must honor the onset date which is given by the healt authority -Encapsulating the logic into smaller pieces of code, should allow for easier and better reviews of the respective filters. Further, for each filter an extensive documentation can be provided, without cluttering the code with too many comments. -## InsertionFilter Interface -The `InsertionFilter` interface has the following signature: +## KeyInsertionFilter Interface +The `KeyInsertionFilter` interface has the following signature: ```java public List filter(UTCInstant now, List content, OSType osType, Version osVersion, Version appVersion, Object principal) throws InsertException; @@ -32,6 +28,16 @@ public List filter(UTCInstant now, List content, OSType osType It gets a `now` object representing _the time the request started_ from the controller , a list of keys, some OS and app related information taken from the `UserAgent` (c.f. `InsertManager@exctractOS` and following) and a possible principal object, representing a authenticated state (e.g. a `JWT`). The function is marked to throw a `InsertException` to stop the inserting process. +## KeyInsertionModifier Interface +The `KeyInsertionModifier` interface has the following signature: + +```java +public List modify(UTCInstant now, List content, OSType osType, Version osVersion, Version appVersion, Object principal) throws InsertException; +``` + +It gets a `now` object representing _the time the request started_ from the controller , a list of keys, some OS and app related information taken from the `UserAgent` (c.f. `InsertManager@exctractOS` and following) and a possible principal object, representing a authenticated state (e.g. a `JWT`). The function is marked to throw a `InsertException` to stop the inserting process. + + ## InsertException An `InsertException` can be thrown inside an implementation of the `InsertionFilter` interface to mark an insert as "unrecoverable" and abort it. Such "unrecoverable" states might be patterns in the uploaded model, which allows for packet sniffing and/or information gathering. @@ -44,32 +50,54 @@ Looking at the `WSBaseConfig`, we can see that during construction of the `Inser @Bean public InsertManager insertManager() { var manager = new InsertManager(gaenDataService(), gaenValidationUtils()); - manager.addFilter(new NoBase64Filter(gaenValidationUtils())); - manager.addFilter(new KeysNotMatchingJWTFilter(gaenRequestValidator, gaenValidationUtils())); - manager.addFilter(new RollingStartNumberAfterDayAfterTomorrow()); - manager.addFilter(new RollingStartNumberBeforeRetentionDay(gaenValidationUtils())); - manager.addFilter(new FakeKeysFilter()); - manager.addFilter(new InvalidRollingPeriodFilter()); + manager.addFilter(new Base64Filter(gaenValidationUtils())); + manager.addFilter(new KeysMatchingJWTFilter(gaenRequestValidator, gaenValidationUtils())); + manager.addFilter(new RollingStartNumberAfterDayAfterTomorrowFilter()); + manager.addFilter(new RollingStartNumberInRetentionPeriodFilter(gaenValidationUtils())); + manager.addFilter(new NonFakeKeysFilter()); + manager.addFilter(new ValidRollingPeriodFilter()); return manager; } ``` -- `NoBase64Filter` +- `Base64Filter` > This filter validates that the key actually is a correctly encoded base64 string. Since we are using 16 bytes of key data, those can be represented with exactly 24 characters. The validation of the length is already done during model validation and is assumed to be correct when reaching the filter. This filter _throws_ a `KeyIsNotBase64Exception` if any of the keys is wrongly encoded. Every key submitted _MUST_ have correct base64 encoding -- `KeysNotMatchingJWTFilter`: +- `KeysMatchingJWTFilter`: > This filter compares the supplied keys with information found in the JWT token. During the `exposed` request, the onset date, which will be set by the health authority and inserted as a claim into the JWT is the lower bound for allowed key dates. For the `exposednextday` the JWT contains the previously submitted and checked `delayedKeyDate`, which is compared to the actual supplied key. - `RollingStartNumberAfterDayAfterTomorrowFilter`: > Representing the maximum allowed time skew. Any key which is further in the future as the day after tomorrow is considered to be _maliciously_ or faulty (for example because of wrong date time settings) uploaded and is hence filtered out. -- `RollingStartNumberBeforeRetentionDay`: - > Any key which was valid earlier than `RetentionPeriod` is considered to be outdated and not saved in the database. The key would be removed during the next database clean anyways. -- `FakeKeysFilter` - > Any key which has the `fake` flag is not inserted. -- `InvalidRollingPeriodFilter`: +- `RollingStartNumberInRetentionPeriodFilter`: + > Only keys with key date in the configured retention period are inserted into the datbase. Any key which was valid earlier than `RetentionPeriod` is considered to be outdated and not saved in the database. The key would be removed during the next database clean anyways. +- `NonFakeKeysFilter` + > Only keys that are non-fake are inserted into the database, more precicely keys that have the fake flag set to `0`. +- `ValidRollingPeriodFilter`: > The `RollingPeriod` represents the 10 minutes interval of the key's validity. Negative numbers are not possible, hence any key having a negative rolling period is considered to be _maliciously_ uploaded. Further, according to [Apple/Googles documentation](https://github.com/google/exposure-notifications-server/blob/main/docs/server_functional_requirements.md) values must be in [1..144] -## Additonal Filters -- `IOSLegacyProblemRPLT144Filter` - > This filter makes sure, that rolling period is always set to 144. Default value according to EN is 144, so just set it to that. This allows to check for the Google-TEKs also on iOS. Because the Rolling Proximity Identifier is based on the TEK and the unix epoch, this should work. The only downside is that iOS will not be able to optimize verification of the TEKs, because it will have to consider each TEK for a whole day. -- `OldAndroid0RPFilter`: - > Some early builds of Google's Exposure Notification API returned TEKs with rolling period set to '0'. According to the specification, this is invalid and will cause both Android and iOS to drop/ignore the key. To mitigate ignoring TEKs from these builds alltogether, the rolling period is increased to '144' (one full day). This should not happen anymore and can be removed in the near future. Until then we are going to log whenever this happens to be able to monitor this problem. \ No newline at end of file +## Additonal Modifiers +- `IOSLegacyProblemRPLT144FModifier` + > This modifier makes sure, that rolling period is always set to 144. Default value according to EN is 144, so just set it to that. This allows to check for the Google-TEKs also on iOS. Because the Rolling Proximity Identifier is based on the TEK and the unix epoch, this should work. The only downside is that iOS will not be able to optimize verification of the TEKs, because it will have to consider each TEK for a whole day. +- `OldAndroid0RPModifier`: + > Some early builds of Google's Exposure Notification API returned TEKs with rolling period set to '0'. According to the specification, this is invalid and will cause both Android and iOS to drop/ignore the key. To mitigate ignoring TEKs from these builds alltogether, the rolling period is increased to '144' (one full day). This should not happen anymore and can be removed in the near future. Until then we are going to log whenever this happens to be able to monitor this problem. + + + +## Configuration +During construction, instances of `GAENDataService` and `ValidationUtils` are needed. Further, any filter or modifier can be added to the list with `addFilter(KeyInsertionFilter filter)` or `addModifier(KeyInsertionModifier)`. Ideally, this happens inside the [`WSBaseConfig`](../config/WSBaseConfig.java), where default filters are added right after constructing the `InsertManager`. + +To allow for conditional `KeyInsertionFilters` or `KeyInsertionModifiers` refer to the following snippet: + +```java +@ConditionalOnProperty( +value="ws.app.gaen.insertmanager.iosrplt144modifier", +havingValue = "true", +matchIfMissing = false) +@Bean public IOSLegacyProblemRPLT144Modifier iosLegacyProblemRPLT144(InsertManager manager){ + var iosModifier = new IOSLegacyProblemRPLT144Modifier(); + manager.addModifier(iosModifier); + return iosModifier; +} +``` + +This looks for a property, either supplied via a `application.properties` file, or via `java` arguments (e.g. `java -D ws.app.gaen.insertmanager.iosrplt144modifier`) and constructs and inserts the respective modifier bean into the modifier chain. For further `SpringBoot` `Conditional` annotations have a look at ["Spring Boot Conditionals"](https://reflectoring.io/spring-boot-conditionals/) + diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/NoBase64Filter.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/Base64Filter.java similarity index 93% rename from dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/NoBase64Filter.java rename to dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/Base64Filter.java index 63c9b98b..685c9431 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/NoBase64Filter.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/Base64Filter.java @@ -15,11 +15,11 @@ * if any of the keys is not valid Base64, as this is a client error. * */ -public class NoBase64Filter implements InsertionFilter { +public class Base64Filter implements KeyInsertionFilter { private final ValidationUtils validationUtils; - public NoBase64Filter(ValidationUtils validationUtils) { + public Base64Filter(ValidationUtils validationUtils) { this.validationUtils = validationUtils; } diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/InsertionFilter.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/KeyInsertionFilter.java similarity index 97% rename from dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/InsertionFilter.java rename to dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/KeyInsertionFilter.java index 9262dbad..fc64160e 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/InsertionFilter.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/KeyInsertionFilter.java @@ -13,7 +13,7 @@ * Interface for filters than can be configured in the {@link InsertManager} * */ -public interface InsertionFilter { +public interface KeyInsertionFilter { /** * The {@link InsertManager} goes through all configured filters and calls them diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/KeysNotMatchingJWTFilter.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/KeysMatchingJWTFilter.java similarity index 94% rename from dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/KeysNotMatchingJWTFilter.java rename to dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/KeysMatchingJWTFilter.java index a46d83a4..bbe4c707 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/KeysNotMatchingJWTFilter.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/KeysMatchingJWTFilter.java @@ -24,12 +24,12 @@ * supplied key. * */ -public class KeysNotMatchingJWTFilter implements InsertionFilter { +public class KeysMatchingJWTFilter implements KeyInsertionFilter { private final ValidateRequest validateRequest; private final ValidationUtils validationUtils; - public KeysNotMatchingJWTFilter(ValidateRequest validateRequest, ValidationUtils utils) { + public KeysMatchingJWTFilter(ValidateRequest validateRequest, ValidationUtils utils) { this.validateRequest = validateRequest; this.validationUtils = utils; } diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/FakeKeysFilter.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/NonFakeKeysFilter.java similarity index 74% rename from dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/FakeKeysFilter.java rename to dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/NonFakeKeysFilter.java index 6a4137cd..da269471 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/FakeKeysFilter.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/NonFakeKeysFilter.java @@ -9,14 +9,15 @@ import org.dpppt.backend.sdk.ws.insertmanager.OSType; /** - * Filters out fake keys from fake upload requests. Fake keys are never inserted - * into the database. + * Filters out fake keys from fake upload requests. Only Non-Fake keys are + * inserted into the database. * */ -public class FakeKeysFilter implements InsertionFilter { +public class NonFakeKeysFilter implements KeyInsertionFilter { /** - * Loops through the list of given keys and checks the fake flag. + * Loops through the list of given keys and checks the fake flag. Only return + * keys that have fake flag set to 0 */ @Override public List filter(UTCInstant now, List content, OSType osType, Version osVersion, diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/RollingStartNumberAfterDayAfterTomorrowFilter.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/RollingStartNumberAfterDayAfterTomorrowFilter.java index bb704f23..159bd6df 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/RollingStartNumberAfterDayAfterTomorrowFilter.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/RollingStartNumberAfterDayAfterTomorrowFilter.java @@ -15,7 +15,7 @@ * too far in the future. * */ -public class RollingStartNumberAfterDayAfterTomorrowFilter implements InsertionFilter { +public class RollingStartNumberAfterDayAfterTomorrowFilter implements KeyInsertionFilter { /** * Loops through all the keys and converts the rolling start number to a diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/RollingStartNumberBeforeRetentionDay.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/RollingStartNumberInRetentionPeriodFilter.java similarity index 64% rename from dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/RollingStartNumberBeforeRetentionDay.java rename to dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/RollingStartNumberInRetentionPeriodFilter.java index 4e46d748..13ab8c22 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/RollingStartNumberBeforeRetentionDay.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/RollingStartNumberInRetentionPeriodFilter.java @@ -11,26 +11,25 @@ import org.dpppt.backend.sdk.ws.util.ValidationUtils; /** - * Checks if a key is before the configured retention period. If a key is before - * the retention period it is filtered out, as it will not be relevant for the + * Checks if a key is in the configured retention period. If a key is before the + * retention period it is filtered out, as it will not be relevant for the * system anymore. * - * @author alig - * */ -public class RollingStartNumberBeforeRetentionDay implements InsertionFilter { +public class RollingStartNumberInRetentionPeriodFilter implements KeyInsertionFilter { private final ValidationUtils validationUtils; - public RollingStartNumberBeforeRetentionDay(ValidationUtils validationUtils) { + public RollingStartNumberInRetentionPeriodFilter(ValidationUtils validationUtils) { this.validationUtils = validationUtils; } /** - * Loops throug all the keys and converts the rolling start number to a - * timstamp. Using - * {@link ValidationUtils#isBeforeRetention(UTCInstant, UTCInstant)} all keys - * that are before the retention period are filtered out. + * Loops through all the keys and converts the rolling start number to a + * timestamp. Using + * {@link ValidationUtils#isBeforeRetention(UTCInstant, UTCInstant)} only keys + * are accepted that are not before the retention period. Keys before the + * retention period are filtered out. */ @Override public List filter(UTCInstant now, List content, OSType osType, Version osVersion, diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/InvalidRollingPeriodFilter.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/ValidRollingPeriodFilter.java similarity index 93% rename from dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/InvalidRollingPeriodFilter.java rename to dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/ValidRollingPeriodFilter.java index 249221be..11c5e030 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/InvalidRollingPeriodFilter.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/ValidRollingPeriodFilter.java @@ -16,7 +16,7 @@ * >EN documentation * */ -public class InvalidRollingPeriodFilter implements InsertionFilter { +public class ValidRollingPeriodFilter implements KeyInsertionFilter { /** * Loop through given keys and filter out keys which have rolling period < 1 or diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/IOSLegacyProblemRPLT144Filter.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionmodifier/IOSLegacyProblemRPLT144Modifier.java similarity index 72% rename from dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/IOSLegacyProblemRPLT144Filter.java rename to dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionmodifier/IOSLegacyProblemRPLT144Modifier.java index 21add1da..91a37e7a 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/IOSLegacyProblemRPLT144Filter.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionmodifier/IOSLegacyProblemRPLT144Modifier.java @@ -1,4 +1,4 @@ -package org.dpppt.backend.sdk.ws.insertmanager.insertionfilters; +package org.dpppt.backend.sdk.ws.insertmanager.insertionmodifier; import java.util.List; @@ -8,7 +8,7 @@ import org.dpppt.backend.sdk.ws.insertmanager.OSType; /** - * This filter makes sure, that rolling period is always set to 144. Default + * This key modifier makes sure, that rolling period is always set to 144. Default * value according to EN is 144, so just set it to that. This allows to check * for the Google-TEKs also on iOS. Because the Rolling Proximity Identifier is * based on the TEK and the unix epoch, this should work. The only downside is @@ -16,10 +16,10 @@ * will have to consider each TEK for a whole day. * */ -public class IOSLegacyProblemRPLT144Filter implements InsertionFilter { +public class IOSLegacyProblemRPLT144Modifier implements KeyInsertionModifier { @Override - public List filter(UTCInstant now, List content, OSType osType, Version osVersion, + public List modify(UTCInstant now, List content, OSType osType, Version osVersion, Version appVersion, Object principal) { for (GaenKey key : content) { key.setRollingPeriod(144); diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionmodifier/KeyInsertionModifier.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionmodifier/KeyInsertionModifier.java new file mode 100644 index 00000000..3d5b6899 --- /dev/null +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionmodifier/KeyInsertionModifier.java @@ -0,0 +1,37 @@ +package org.dpppt.backend.sdk.ws.insertmanager.insertionmodifier; + +import java.util.List; + +import org.dpppt.backend.sdk.model.gaen.GaenKey; +import org.dpppt.backend.sdk.semver.Version; +import org.dpppt.backend.sdk.utils.UTCInstant; +import org.dpppt.backend.sdk.ws.insertmanager.InsertException; +import org.dpppt.backend.sdk.ws.insertmanager.InsertManager; +import org.dpppt.backend.sdk.ws.insertmanager.OSType; + +/** + * Interface for key modifiers than can be configured in the {@link InsertManager} + * + */ +public interface KeyInsertionModifier { + + /** + * The {@link InsertManager} goes through all configured key modifiers and calls them + * with a list of {@link GaenKey} where the modifieres are applied before inserting + * into the database. + * + * @param now current timestamp + * @param content the list of new gaen keys for modification + * @param osType the os type of the client which uploaded the keys + * @param osVersion the os version of the client which uploaded the keys + * @param appVersion the app version of the client which uploaded the keys + * @param principal the authorization context which belongs to the uploaded + * keys. Depending on the configured system, this could be a + * JWT token for example. + * @return + * @throws InsertException + */ + public List modify(UTCInstant now, List content, OSType osType, Version osVersion, + Version appVersion, Object principal) throws InsertException; + +} \ No newline at end of file diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/OldAndroid0RPFilter.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionmodifier/OldAndroid0RPModifier.java similarity index 86% rename from dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/OldAndroid0RPFilter.java rename to dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionmodifier/OldAndroid0RPModifier.java index a68964c9..202e38a2 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionfilters/OldAndroid0RPFilter.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/main/java/org/dpppt/backend/sdk/ws/insertmanager/insertionmodifier/OldAndroid0RPModifier.java @@ -1,9 +1,8 @@ -package org.dpppt.backend.sdk.ws.insertmanager.insertionfilters; +package org.dpppt.backend.sdk.ws.insertmanager.insertionmodifier; import java.util.List; import org.dpppt.backend.sdk.model.gaen.GaenKey; - import org.dpppt.backend.sdk.semver.Version; import org.dpppt.backend.sdk.utils.UTCInstant; import org.dpppt.backend.sdk.ws.insertmanager.OSType; @@ -19,8 +18,9 @@ * the near future. Until then we are going to log whenever this happens to be * able to monitor this problem. */ -public class OldAndroid0RPFilter implements InsertionFilter { - private static final Logger logger = LoggerFactory.getLogger(OldAndroid0RPFilter.class); +public class OldAndroid0RPModifier implements KeyInsertionModifier { + + private static final Logger logger = LoggerFactory.getLogger(OldAndroid0RPModifier.class); /** * Loop through all the given keys and check if the rolling period is equal to @@ -28,7 +28,7 @@ public class OldAndroid0RPFilter implements InsertionFilter { * iOS client, an error log is printed. */ @Override - public List filter(UTCInstant now, List content, OSType osType, Version osVersion, + public List modify(UTCInstant now, List content, OSType osType, Version osVersion, Version appVersion, Object principal) { for (GaenKey gaenKey : content) { if (gaenKey.getRollingPeriod().equals(0)) { diff --git a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/test/java/org/dpppt/backend/sdk/ws/insertmanager/InsertManagerTest.java b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/test/java/org/dpppt/backend/sdk/ws/insertmanager/InsertManagerTest.java index 67f840bd..be48aeba 100644 --- a/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/test/java/org/dpppt/backend/sdk/ws/insertmanager/InsertManagerTest.java +++ b/dpppt-backend-sdk/dpppt-backend-sdk-ws/src/test/java/org/dpppt/backend/sdk/ws/insertmanager/InsertManagerTest.java @@ -10,7 +10,7 @@ import org.dpppt.backend.sdk.model.gaen.GaenKey; import org.dpppt.backend.sdk.semver.Version; import org.dpppt.backend.sdk.utils.UTCInstant; -import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.OldAndroid0RPFilter; +import org.dpppt.backend.sdk.ws.insertmanager.insertionmodifier.OldAndroid0RPModifier; import org.dpppt.backend.sdk.ws.util.ValidationUtils; import org.junit.Test; import org.slf4j.LoggerFactory; @@ -74,13 +74,13 @@ public void wrongHeaderShouldNotFail() throws Exception { @Test public void iosRP0ShouldLog() throws Exception { - Logger logger = (Logger)LoggerFactory.getLogger(OldAndroid0RPFilter.class); + Logger logger = (Logger)LoggerFactory.getLogger(OldAndroid0RPModifier.class); var appender = new TestAppender(); appender.setContext(logger.getLoggerContext()); appender.start(); logger.addAppender(appender); InsertManager manager = new InsertManager(new MockDataSource(), new ValidationUtils(16, Duration.ofDays(14), Duration.ofHours(2).toMillis())); - manager.addFilter(new OldAndroid0RPFilter()); + manager.addModifier(new OldAndroid0RPModifier()); var key = new GaenKey("POSTMAN+POSTMAN+", (int)UTCInstant.now().get10MinutesSince1970(), 0, 0); try { manager.insertIntoDatabase(List.of(key), "org.dpppt.testrunner;1.0.0;1;iOS;29", null, UTCInstant.now());