CVE-2020-26230 (published 2020-11-13T19:15Z)

Radar COVID is the official COVID-19 exposure notification app for Spain. In affected versions of Radar COVID, identification and de-anonymization of COVID-19 positive users that upload Radar COVID TEKs to the Radar COVID server is possible. This vulnerability enables the identification and de-anonymization of COVID-19 positive users when using Radar COVID. The vulnerability is caused by the fact that Radar COVID connections to the server (uploading of TEKs to the backend) are only made by COVID-19 positives. Therefore, any on-path observer with the ability to monitor traffic between the app and the server can identify which users had a positive test. Such an adversary can be the mobile network operator (MNO) if the connection is done through a mobile network, the Internet Service Provider (ISP) if the connection is done through the Internet (e.g., a home network), a VPN provider used by the user, the local network operator in the case of enterprise networks, or any eavesdropper with access to the same network (WiFi or Ethernet) as the user as could be the case of public WiFi hotspots deployed at shopping centers, airports, hotels, and coffee shops. The attacker may also de-anonymize the user. For this additional stage to succeed, the adversary needs to correlate Radar COVID traffic to other identifiable information from the victim. This could be achieved by associating the connection to a contract with the name of the victim or by associating Radar COVID traffic to other user-generated flows containing identifiers in the clear (e.g., HTTP cookies or other mobile flows sending unique identifiers like the IMEI or the AAID without encryption). The former can be executed, for instance, by the Internet Service Provider or the MNO. The latter can be executed by any on-path adversary, such as the network provider or even the cloud provider that hosts more than one service accessed by the victim. The farther the adversary is either from the victim (the client) or the end-point (the server), the less likely it may be that the adversary has access to re-identification information. The vulnerability has been mitigated with the injection of dummy traffic from the application to the backend. Dummy traffic is generated by all users independently of whether they are COVID-19 positive or not. The issue was fixed in iOS in version 1.0.8 (uniform distribution), 1.1.0 (exponential distribution), Android in version 1.0.7 (uniform distribution), 1.1.0 (exponential distribution), Backend in version 1.1.2-RELEASE. For more information see the referenced GitHub Security Advisory.

Severity: LOW
CVSS v2 base score: 2.6 (AV:N/AC:H/Au:N/C:P/I:N/A:N)
CVSS v3 base score: 5.3, MEDIUM (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-200
cwe_name: Exposure of Sensitive Information to an Unauthorized Actor
description: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
extended_description: 
	   There are many different kinds of mistakes that introduce information exposures. The severity of the error can range widely, depending on the context in which the product operates, the type of sensitive information that is revealed, and the benefits it may provide to an attacker.  Some kinds of sensitive information include:
       
         private, personal information, such as personal messages, financial data, health records, geographic location, or contact details
         system status and environment, such as the operating system and installed packages
		 business secrets and intellectual property
		 network status and configuration
		 the product's own code or internal state
         metadata, e.g. logging of connections or message headers
		 indirect information, such as a discrepancy between two internal operations that can be observed by an outsider
       
	    Information might be sensitive to different parties, each of which may have their own expectations for whether the information should be protected.  These parties include:
               
                  the product's own users
                  people or organizations whose information is created or used by the product, even if they are not direct product users
		  the product's administrators, including the admins of the system(s) and/or networks on which the product operates
                  the developer
               
	    Information exposures can occur in different ways:
               
                  the code explicitly inserts sensitive information into resources or messages that are intentionally made accessible to unauthorized actors, but should not contain the information - i.e., the information should have been "scrubbed" or "sanitized"
                  a different weakness or mistake indirectly inserts the sensitive information into resources, such as a web script error revealing the full system path of the program.
                  the code manages resources that intentionally contain sensitive information, but the resources are unintentionally made accessible to unauthorized actors. In this case, the information exposure is resultant - i.e., a different weakness enabled the access to the information in the first place.
               
	    It is common practice to describe any loss of confidentiality as an "information exposure," but this can lead to overuse of CWE-200 in CWE mapping. From the CWE perspective, loss of confidentiality is a technical impact that can arise from dozens of different weaknesses, such as insecure file permissions or out-of-bounds read.  CWE-200 and its lower-level descendants are intended to cover the mistakes that occur in behaviors that explicitly manage, store, transfer, or cleanse sensitive information.
         
         

Fix information:
repo_url: https://github.com/RadarCOVID/radar-covid-backend-dp3t-server
commit_details: repo_url: https://github.com/RadarCOVID/radar-covid-backend-dp3t-server
author: mapalomar
author_date: 2020-10-09 23:04:38+02:00
msg: [MAPR] Setted responses retention time on fake requests
repository: repo_url: https://github.com/RadarCOVID/radar-covid-backend-dp3t-server
repo_name: RadarCOVID/radar-covid-backend-dp3t-server
description: DP^3T Radar COVID fork
repo_language: Java
owner: RadarCOVID
file_changes: filename: CHANGELOG.md
change_type: ModificationType.MODIFY
diff: @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
 
 ## [Unrelease]
 
+### Added
+
+- Setted responses retention time on fake requests
+- Added aspect configuration
+
+### Fixed
+
+- Fixed messages in aspects.
+
 ## [1.1.2.RELEASE] - 2020-10-09
 
 ### Added

programming_language: Markdown
filename: application.yml
change_type: ModificationType.MODIFY
diff: @@ -133,3 +133,10 @@ application:
     validation:
       url: ${TAN_VALIDATION_URL:}
       enabled: ${TAN_VALIDATION_ENABLED:false}
+  response:
+    retention:
+      enabled: ${RESPONSE_RETENTION_ENABLED:false}
+      time:
+        exposed: ${RESPONSE_RETENTION_TIME_EXPOSED:1000} # milliseconds
+  log:
+    enabled: ${LOGGABLE_ENABLED:false}
\ No newline at end of file

programming_language: Shell
filename: GaenController.java
change_type: ModificationType.MODIFY
diff: @@ -10,6 +10,7 @@
 package org.dpppt.backend.sdk.ws.controller;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
+
 import io.jsonwebtoken.Jwts;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -20,6 +21,7 @@
 import org.dpppt.backend.sdk.data.gaen.GAENDataService;
 import org.dpppt.backend.sdk.model.gaen.*;
 import org.dpppt.backend.sdk.ws.radarcovid.annotation.Loggable;
+import org.dpppt.backend.sdk.ws.radarcovid.annotation.ResponseRetention;
 import org.dpppt.backend.sdk.ws.security.ValidateRequest;
 import org.dpppt.backend.sdk.ws.security.ValidateRequest.InvalidDateException;
 import org.dpppt.backend.sdk.ws.security.signature.ProtoSignature;
@@ -100,6 +102,7 @@ public GaenController(GAENDataService dataService, FakeKeyService fakeKeyService
 
 	@PostMapping(value = "/exposed")
 	@Loggable
+	@ResponseRetention(time = "application.response.retention.time.exposed")
 	@Transactional
 	@Operation(description = "Send exposed keys to server - includes a fix for the fact that GAEN doesn't give access to the current day's exposed key")
 	@ApiResponses(value = {

programming_language: Java
filename: ResponseRetention.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020 Gobierno de España
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ */
+package org.dpppt.backend.sdk.ws.radarcovid.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Documented
+@Retention(value=RetentionPolicy.RUNTIME)
+@Target(value={ElementType.CONSTRUCTOR, ElementType.METHOD})
+public @interface ResponseRetention {
+
+	/**
+	 * Environment property with response retention time, in milliseconds
+	 */
+	String time();
+}

programming_language: Java
filename: ResponseRetentionAspectConfiguration.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2020 Gobierno de España
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ */
+package org.dpppt.backend.sdk.ws.radarcovid.config;
+
+import java.util.Arrays;
+
+import org.apache.commons.lang3.math.NumberUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.dpppt.backend.sdk.ws.radarcovid.annotation.ResponseRetention;
+import org.dpppt.backend.sdk.ws.radarcovid.exception.RadarCovidServerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+
+/**
+ * Aspect in charge of controlling the minimum response time of a service.
+ */
+@Configuration
+@ConditionalOnProperty(name = "application.response.retention.enabled", havingValue = "true", matchIfMissing = true)
+public class ResponseRetentionAspectConfiguration {
+
+	private static final Logger log = LoggerFactory.getLogger("org.dpppt.backend.sdk.ws.radarcovid.annotation.ResponseRetention");
+	
+	@Autowired
+	private Environment environment;
+	
+    @Aspect
+    @Component
+    public class ControllerTimeResponseControlAspect {
+
+        @Pointcut("@annotation(responseRetention)")
+        public void annotationPointCutDefinition(ResponseRetention responseRetention){
+        }
+        
+		@Around("execution(@org.dpppt.backend.sdk.ws.radarcovid.annotation.ResponseRetention * *..controller..*(..)) && annotationPointCutDefinition(responseRetention)")
+        public Object logAround(ProceedingJoinPoint joinPoint, ResponseRetention responseRetention) throws Throwable {
+
+        	log.debug("************************* INIT TIME RESPONSE CONTROL *********************************");
+            long start = System.currentTimeMillis();
+            try {
+                String className = joinPoint.getSignature().getDeclaringTypeName();
+                String methodName = joinPoint.getSignature().getName();
+                Object result = joinPoint.proceed();
+                long elapsedTime = System.currentTimeMillis() - start;
+                long responseRetentionTimeMillis = getTimeMillis(responseRetention.time());
+                log.debug("Controller : Controller {}.{} () execution time : {} ms", className, methodName, elapsedTime);
+                if (elapsedTime < responseRetentionTimeMillis) {
+                	Thread.sleep(responseRetentionTimeMillis - elapsedTime);
+                }
+                elapsedTime = System.currentTimeMillis() - start;
+                log.debug("Controller : Controller {}.{} () NEW execution time : {} ms", className, methodName, elapsedTime);
+                log.debug("************************* END TIME RESPONSE CONTROL **********************************");
+                return result;
+
+            } catch (IllegalArgumentException e) {
+				log.error("Controller : Illegal argument {} in {} ()", Arrays.toString(joinPoint.getArgs()),
+						joinPoint.getSignature().getName());
+				log.debug("************************* END TIME RESPONSE CONTROL **********************************");
+                throw e;
+            }
+        }
+        
+		private long getTimeMillis(String timeMillisString) {
+			String stringValue = environment.getProperty(timeMillisString);
+			if (NumberUtils.isCreatable(stringValue)) {
+				return Long.parseLong(stringValue);
+			} else {
+				throw new RadarCovidServerException(HttpStatus.INTERNAL_SERVER_ERROR,
+						"Invalid timeMillisString value \"" + timeMillisString + "\" - not found or cannot parse into long");
+			}
+		}
+    }
+
+}

programming_language: Java
filename: RadarCovidServerException.java
change_type: ModificationType.ADD
diff: @@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 Gobierno de España
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ */
+package org.dpppt.backend.sdk.ws.radarcovid.exception;
+
+import org.springframework.http.HttpStatus;
+
+
+public class RadarCovidServerException extends RuntimeException {
+
+    private final HttpStatus httpStatus;
+
+    /**
+     * The Constructor for the Exception class.
+     *
+     * @param httpStatus the state of the server
+     * @param message    the message
+     */
+    public RadarCovidServerException(HttpStatus httpStatus, String message) {
+        super(message);
+        this.httpStatus = httpStatus;
+    }
+
+	public HttpStatus getHttpStatus() {
+		return httpStatus;
+	}
+    
+}

programming_language: Java
filename: application.yaml
change_type: ModificationType.MODIFY
diff: @@ -133,3 +133,10 @@ application:
     validation:
       url: ${TAN_VALIDATION_URL:}
       enabled: ${TAN_VALIDATION_ENABLED:false}
+  response:
+    retention:
+      enabled: ${RESPONSE_RETENTION_ENABLED:true}
+      time:
+        exposed: ${RESPONSE_RETENTION_TIME_EXPOSED:1000} # milliseconds
+  log:
+    enabled: ${LOGGABLE_ENABLED:true}
\ No newline at end of file

programming_language: Shell
repo_url: https://github.com/RadarCOVID/radar-covid-ios
commit_details: repo_url: https://github.com/RadarCOVID/radar-covid-ios
author: noel
author_date: 2020-10-30 05:31:39-04:00
msg: chore: release 1.1.0
repository: repo_url: https://github.com/RadarCOVID/radar-covid-ios
repo_name: RadarCOVID/radar-covid-ios
description: Native iOS app using DP^3T iOS sdk to handle Exposure Notification framework from Apple
repo_language: Swift
owner: RadarCOVID
repo_url: https://github.com/RadarCOVID/radar-covid-android
commit_details: repo_url: https://github.com/RadarCOVID/radar-covid-android
author: Oscar Rodriguez
author_date: 2020-10-08 10:27:13+02:00
msg: *Added exponential interval for fake request
repository: repo_url: https://github.com/RadarCOVID/radar-covid-android
repo_name: RadarCOVID/radar-covid-android
description: Native Android app using DP^3T Android sdk to handle Exposure Notifications API from Google
repo_language: Kotlin
owner: RadarCOVID
file_changes: filename: RadarCovidApplication.kt
change_type: ModificationType.MODIFY
diff: @@ -14,6 +14,7 @@ import dagger.android.AndroidInjector
 import dagger.android.support.DaggerApplication
 import es.gob.radarcovid.common.base.broadcast.ExposureStatusChangeBroadcastReceiver
 import es.gob.radarcovid.common.di.component.DaggerApplicationComponent
+import es.gob.radarcovid.datamanager.repository.PreferencesRepository
 import es.gob.radarcovid.features.worker.FakeInfectionReportWorker
 import io.reactivex.rxjava3.plugins.RxJavaPlugins
 import okhttp3.CertificatePinner
@@ -29,6 +30,9 @@ class RadarCovidApplication : DaggerApplication() {
     @Inject
     lateinit var certificatePinner: CertificatePinner
 
+    @Inject
+    lateinit var preferencesRepository: PreferencesRepository
+
     @Inject
     @Named("userAgent")
     lateinit var userAgent: String
@@ -47,7 +51,7 @@ class RadarCovidApplication : DaggerApplication() {
         DP3T.setCertificatePinner(certificatePinner)
         DP3T.setUserAgent(userAgent)
 
-        FakeInfectionReportWorker.start(this)
+        FakeInfectionReportWorker.start(this, preferencesRepository)
 
         registerReceiver(ExposureStatusChangeBroadcastReceiver(), DP3T.getUpdateIntentFilter())
 

programming_language: Scala
filename: PreferencesRepository.kt
change_type: ModificationType.MODIFY
diff: @@ -57,4 +57,8 @@ interface PreferencesRepository {
 
     fun getHealingTime(): HealingTime
 
+    fun getTDummy(): Long
+
+    fun setTDummy(time: Long)
+
 }
\ No newline at end of file

programming_language: Swift
filename: PreferencesRepositoryImpl.kt
change_type: ModificationType.MODIFY
diff: @@ -36,6 +36,7 @@ class PreferencesRepositoryImpl @Inject constructor(@Named("applicationContext")
         private const val KEY_REGIONS = "key_regions"
         private const val KEY_LANGUAGES = "key_languages"
         private const val KEY_HEALING_TIME = "key_healing_time"
+        private const val KEY_T_DUMMY = "KEY_T_DUMMY"
     }
 
     private val preferences = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE)
@@ -167,4 +168,12 @@ class PreferencesRepositoryImpl @Inject constructor(@Named("applicationContext")
         return Gson().fromJson(healingTimeJson, HealingTime::class.java)
     }
 
+    override fun getTDummy(): Long {
+        return preferences.getLong(KEY_T_DUMMY, -1)
+    }
+
+    override fun setTDummy(time: Long) {
+        preferences.edit().putLong(KEY_T_DUMMY, time).apply()
+    }
+
 }
\ No newline at end of file

programming_language: Scala
filename: FakeInfectionReportWorker.kt
change_type: ModificationType.MODIFY
diff: @@ -13,12 +13,21 @@ package es.gob.radarcovid.features.worker
 import android.content.Context
 import androidx.work.*
 import dagger.android.HasAndroidInjector
+import es.gob.radarcovid.datamanager.repository.PreferencesRepository
 import es.gob.radarcovid.datamanager.usecase.ReportFakeInfectionUseCase
 import org.dpppt.android.sdk.BuildConfig
 import org.dpppt.android.sdk.DP3T
+import java.security.SecureRandom
 import java.util.concurrent.TimeUnit
 import javax.inject.Inject
-import kotlin.random.Random
+
+
+private const val FACTOR_HOUR_MILLIS = 60 * 60 * 1000L
+private const val FACTOR_DAY_MILLIS: Long = 24 * FACTOR_HOUR_MILLIS
+private const val MAX_DELAY_HOURS: Long = 48
+private val SAMPLING_RATE =
+    if (BuildConfig.DEBUG) 1.0f else 0.2f
+private const val KEY_T_DUMMY = "KEY_T_DUMMY"
 
 class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters) :
     Worker(context, workerParams) {
@@ -31,43 +40,93 @@ class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters
 
     companion object {
 
+        private var clock: Clock = ClockImpl()
+
         private const val TAG = "FakeInfectionReportWorker"
 
-        fun start(context: Context) {
-            start(context, getRandomDelay(), ExistingWorkPolicy.KEEP)
+        fun start(context: Context, preferencesRepository: PreferencesRepository) {
+            var tDummy: Long = preferencesRepository.getTDummy()
+            if (tDummy == -1L) {
+                tDummy = clock.currentTimeMillis() + clock.syncInterval()
+                preferencesRepository.setTDummy(tDummy)
+            }
+            start(context, tDummy, ExistingWorkPolicy.KEEP)
         }
 
         private fun start(
             context: Context,
-            delayInMinutes: Long,
+            tDummy: Long,
             existingWorkPolicy: ExistingWorkPolicy
         ) {
+
+            val now = clock.currentTimeMillis()
+            val executionDelay = 0L.coerceAtLeast(tDummy - now)
+            val executionDelayDays =
+                executionDelay / FACTOR_DAY_MILLIS
+
             val constraints = Constraints.Builder()
                 .setRequiredNetworkType(NetworkType.CONNECTED)
                 .build()
             val work =
                 OneTimeWorkRequest
                     .Builder(FakeInfectionReportWorker::class.java)
-                    .setInitialDelay(delayInMinutes, TimeUnit.MINUTES)
+                    .setInitialDelay(executionDelayDays, TimeUnit.MINUTES)
                     .setConstraints(constraints)
+                    .setInputData(Data.Builder().putLong(KEY_T_DUMMY, tDummy).build())
                     .build()
             WorkManager.getInstance(context)
                 .enqueueUniqueWork(TAG, existingWorkPolicy, work)
         }
 
-        private fun getRandomDelay(): Long = Random.nextLong(180, 360)
+        //private fun getRandomDelay(): Long = Random.nextLong(180, 360)
 
     }
 
     @Inject
     lateinit var reportFakeInfectionUseCase: ReportFakeInfectionUseCase
 
+    @Inject
+    lateinit var preferencesRepository: PreferencesRepository
+
     override fun doWork(): Result {
-        if (BuildConfig.DEBUG)
-            DP3T.addWorkerStartedToHistory(applicationContext, TAG)
-        reportFakeInfectionUseCase.reportFakeInfection().subscribe()
-        start(applicationContext, getRandomDelay(), ExistingWorkPolicy.APPEND)
+        val now = clock.currentTimeMillis()
+        var tDummy = inputData.getLong(KEY_T_DUMMY, now)
+        while (tDummy < now) {
+            if (tDummy >= now - FACTOR_HOUR_MILLIS * MAX_DELAY_HOURS) {
+                if (BuildConfig.DEBUG)
+                    DP3T.addWorkerStartedToHistory(applicationContext, TAG)
+                reportFakeInfectionUseCase.reportFakeInfection().subscribe()
+            }
+            tDummy += clock.syncInterval();
+            preferencesRepository.setTDummy(tDummy)
+        }
+
+        start(applicationContext, tDummy, ExistingWorkPolicy.APPEND)
         return Result.success()
     }
-    
+
+    interface Clock {
+        fun syncInterval(): Long
+        fun currentTimeMillis(): Long
+    }
+
+    class ClockImpl : Clock {
+        override fun syncInterval(): Long {
+            val newDelayDays: Double =
+                ExponentialDistribution.sampleFromStandard() / SAMPLING_RATE
+            return (newDelayDays * FACTOR_DAY_MILLIS) as Long
+        }
+
+        override fun currentTimeMillis(): Long {
+            return System.currentTimeMillis()
+        }
+    }
+
+    object ExponentialDistribution {
+        fun sampleFromStandard(): Double {
+            val random = SecureRandom()
+            return -Math.log(1.0 - random.nextDouble())
+        }
+    }
+
 }
\ No newline at end of file

programming_language: Scala
repo_url: https://github.com/RadarCOVID/radar-covid-android
commit_details: repo_url: https://github.com/RadarCOVID/radar-covid-android
author: Oscar Rodriguez
author_date: 2020-10-08 13:06:12+02:00
msg: *changed minutes for milliseconds
repository: repo_url: https://github.com/RadarCOVID/radar-covid-android
repo_name: RadarCOVID/radar-covid-android
description: Native Android app using DP^3T Android sdk to handle Exposure Notifications API from Google
repo_language: Kotlin
owner: RadarCOVID
file_changes: filename: FakeInfectionReportWorker.kt
change_type: ModificationType.MODIFY
diff: @@ -70,7 +70,7 @@ class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters
             val work =
                 OneTimeWorkRequest
                     .Builder(FakeInfectionReportWorker::class.java)
-                    .setInitialDelay(executionDelayDays, TimeUnit.MINUTES)
+                    .setInitialDelay(executionDelayDays, TimeUnit.MILLISECONDS)
                     .setConstraints(constraints)
                     .setInputData(Data.Builder().putLong(KEY_T_DUMMY, tDummy).build())
                     .build()

programming_language: Scala
repo_url: https://github.com/RadarCOVID/radar-covid-backend-dp3t-server
commit_details: repo_url: https://github.com/RadarCOVID/radar-covid-backend-dp3t-server
author: mapalomar
author_date: 2020-10-10 18:43:57+02:00
msg: [MAPR] AOP aspects ordering
repository: repo_url: https://github.com/RadarCOVID/radar-covid-backend-dp3t-server
repo_name: RadarCOVID/radar-covid-backend-dp3t-server
description: DP^3T Radar COVID fork
repo_language: Java
owner: RadarCOVID
file_changes: filename: CHANGELOG.md
change_type: ModificationType.MODIFY
diff: @@ -6,8 +6,9 @@ All notable changes to this project will be documented in this file.
 
 ### Added
 
-- Setted responses retention time on fake requests
-- Added aspect configuration
+- Setted responses retention time on fake requests.
+- Added aspect configuration.
+- AOP aspects ordering.
 
 ### Fixed
 
@@ -19,14 +20,14 @@ All notable changes to this project will be documented in this file.
 
 - Updated DP3T release: 1.1.2
 - Environment description in README.md file.
-- Added license
+- Added license.
 - Added CODE_OF_CONDUCT.md file.
 - Added CHANGELOG.md file.
 
 ### Changed
 
 - Max keys are now 30.
-- Updated TestContainers version
+- Updated TestContainers version.
 
 ### Deleted
 

programming_language: Markdown
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -27,6 +27,23 @@
     </properties>
 
     <profiles>
+        <profile>
+            <id>aws-metrics</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.springframework.cloud</groupId>
+                    <artifactId>spring-cloud-starter-aws</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.springframework.cloud</groupId>
+                    <artifactId>spring-cloud-aws-actuator</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>io.micrometer</groupId>
+                    <artifactId>micrometer-registry-cloudwatch2</artifactId>
+                </dependency>
+            </dependencies>
+        </profile>
         <profile>
             <id>radarcovid-local</id>
             <properties>
@@ -38,12 +55,24 @@
             <properties>
                 <build.profile.id>radarcovid-pre</build.profile.id>
             </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.springframework.cloud</groupId>
+                    <artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
+                </dependency>
+            </dependencies>
         </profile>
         <profile>
             <id>radarcovid-pro</id>
             <properties>
                 <build.profile.id>radarcovid-pro</build.profile.id>
             </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.springframework.cloud</groupId>
+                    <artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
+                </dependency>
+            </dependencies>
         </profile>
     </profiles>
 
@@ -61,10 +90,6 @@
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-cloud-connectors</artifactId>
 		</dependency>
-		<dependency>
-			<groupId>org.springframework.cloud</groupId>
-			<artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
-		</dependency>
         <dependency>
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-test</artifactId>

programming_language: HTML
filename: application.yml
change_type: ModificationType.MODIFY
diff: @@ -32,7 +32,13 @@ cloud:
     stack:
       auto: ${CLOUD.AWS.STACK.AUTO:false}
 
-management.endpoints.enabled-by-default: false
+management:
+  endpoints.enabled-by-default: false
+  metrics:
+    export:
+      cloudwatch:
+        namespace: dpppt
+        batch-size: 20
 
 server:
   error.whitelabel.enabled: true
@@ -62,8 +68,13 @@ logging:
     com.amazonaws: error
     org.dpppt.backend.sdk.data.gaen.fakekeyservice: info
     org.dpppt.backend.sdk.ws.radarcovid: debug
+    org.dpppt.backend.sdk.ws.radarcovid.annotation: info
+    org.dpppt.backend.sdk.ws.radarcovid.config: info
     org.dpppt.backend.sdk.ws.security.gaen: debug
     org.dpppt: info
+    com.zaxxer.hikari.pool.HikariPool: debug
+    com.zaxxer.hikari.HikariConfig: debug
+    com.zaxxer.hikari: debug
   pattern:
     console: '[%-5level] [%X{X-B3-TraceId:-},%X{X-Amz-Cf-Id:-}] - %c{1} - %msg%n'
 
@@ -138,5 +149,7 @@ application:
       enabled: ${RESPONSE_RETENTION_ENABLED:false}
       time:
         exposed: ${RESPONSE_RETENTION_TIME_EXPOSED:1000} # milliseconds
+        exposednextday: ${RESPONSE_RETENTION_TIME_EXPOSEDNEXTDAY:1000} # milliseconds
+
   log:
     enabled: ${LOGGABLE_ENABLED:false}
\ No newline at end of file

programming_language: Shell
filename: GaenController.java
change_type: ModificationType.MODIFY
diff: @@ -191,6 +191,7 @@ public GaenController(GAENDataService dataService, FakeKeyService fakeKeyService
 
 	@PostMapping(value = "/exposednextday")
 	@Loggable
+	@ResponseRetention(time = "application.response.retention.time.exposednextday")
 	@Transactional
 	@Operation(description = "Allows the client to send the last exposed key of the infection to the backend server. The JWT must come from a previous call to /exposed")
 	@ApiResponses(value = {

programming_language: Java
filename: ControllerLoggerAspectConfiguration.java
change_type: ModificationType.MODIFY
diff: @@ -17,6 +17,7 @@
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -40,6 +41,7 @@ public class ControllerLoggerAspectConfiguration {
     private static final Logger log = LoggerFactory.getLogger("org.dpppt.backend.sdk.ws.radarcovid.annotation.Loggable");
 
     @Aspect
+    @Order(1)
     @Component
     public class ControllerLoggerAspect {
         @Before("execution(@org.dpppt.backend.sdk.ws.radarcovid.annotation.Loggable * *..controller..*(..))")

programming_language: Java
filename: MethodLoggerAspectConfiguration.java
change_type: ModificationType.MODIFY
diff: @@ -17,6 +17,7 @@
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 
 import java.util.Arrays;
@@ -31,6 +32,7 @@ public class MethodLoggerAspectConfiguration {
     private static final Logger log = LoggerFactory.getLogger("org.dpppt.backend.sdk.ws.radarcovid.annotation.Loggable");
 
     @Aspect
+    @Order(2)
     @Component
     public class MethodLoggerAspect {
         @Before("execution(@org.dpppt.backend.sdk.ws.radarcovid.annotation.Loggable * *..business.impl..*(..))")

programming_language: Java
filename: ResponseRetentionAspectConfiguration.java
change_type: ModificationType.MODIFY
diff: @@ -23,6 +23,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
 import org.springframework.core.env.Environment;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Component;
@@ -40,6 +41,7 @@ public class ResponseRetentionAspectConfiguration {
 	private Environment environment;
 	
     @Aspect
+    @Order(0)
     @Component
     public class ControllerTimeResponseControlAspect {
 

programming_language: Java
filename: application.yaml
change_type: ModificationType.MODIFY
diff: @@ -62,6 +62,8 @@ logging:
     com.amazonaws: error
     org.dpppt.backend.sdk.data.gaen.fakekeyservice: info
     org.dpppt.backend.sdk.ws.radarcovid: debug
+    org.dpppt.backend.sdk.ws.radarcovid.config: info
+    org.dpppt.backend.sdk.ws.radarcovid.annotation: info
     org.dpppt.backend.sdk.ws.security.gaen: debug
     org.dpppt: info
   pattern:
@@ -138,5 +140,7 @@ application:
       enabled: ${RESPONSE_RETENTION_ENABLED:true}
       time:
         exposed: ${RESPONSE_RETENTION_TIME_EXPOSED:1000} # milliseconds
+        exposednextday: ${RESPONSE_RETENTION_TIME_EXPOSEDNEXTDAY:1000} # milliseconds
+
   log:
     enabled: ${LOGGABLE_ENABLED:true}
\ No newline at end of file

programming_language: Shell
filename: pom.xml
change_type: ModificationType.MODIFY
diff: @@ -12,514 +12,529 @@
          xmlns="http://maven.apache.org/POM/4.0.0"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                              http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+	<modelVersion>4.0.0</modelVersion>
 
-    <groupId>org.dpppt</groupId>
-    <artifactId>dpppt-backend-sdk</artifactId>
-    <packaging>pom</packaging>
-    <version>1.0.0-SNAPSHOT</version>
-    <name>DP3T Backend SDK</name>
+	<groupId>org.dpppt</groupId>
+	<artifactId>dpppt-backend-sdk</artifactId>
+	<packaging>pom</packaging>
+	<version>1.0.0-SNAPSHOT</version>
+	<name>DP3T Backend SDK</name>
 
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 
-        <java-version>11</java-version>
-        <maven.compiler.source>${java-version}</maven.compiler.source>
-        <maven.compiler.target>${java-version}</maven.compiler.target>
+		<java-version>11</java-version>
+		<maven.compiler.source>${java-version}</maven.compiler.source>
+		<maven.compiler.target>${java-version}</maven.compiler.target>
 
-        <spring-boot-version>2.2.9.RELEASE</spring-boot-version>
-        <spring-cloud-version>Hoxton.SR8</spring-cloud-version>
-        <spring-cloud-starter-aws.version>2.2.4.RELEASE</spring-cloud-starter-aws.version>
-        <spring-framework-version>5.2.8.RELEASE</spring-framework-version>
+		<spring-boot-version>2.2.9.RELEASE</spring-boot-version>
+		<spring-cloud-version>Hoxton.SR8</spring-cloud-version>
+		<spring-cloud-starter-aws.version>2.2.4.RELEASE</spring-cloud-starter-aws.version>
+		<spring-framework-version>5.2.8.RELEASE</spring-framework-version>
 
-        <itCoverageAgent></itCoverageAgent>
-        <aspectj-version>1.9.6</aspectj-version>
-        <build-helper-maven-plugin.version>1.9.1</build-helper-maven-plugin.version>
-        <jackson-version>2.11.1</jackson-version>
-        <jsonwebtoken-version>0.11.2</jsonwebtoken-version>
-        <postgresql-version>42.2.13</postgresql-version>
-        <protobuf-java-version>3.12.1</protobuf-java-version>
-        <snakeyaml-version>1.26</snakeyaml-version>
-        <springdoc-openapi-version>1.4.0</springdoc-openapi-version>
-        <tomcat-version>9.0.36</tomcat-version>
+		<itCoverageAgent></itCoverageAgent>
+		<aspectj-version>1.9.6</aspectj-version>
+		<build-helper-maven-plugin.version>1.9.1</build-helper-maven-plugin.version>
+		<jackson-version>2.11.1</jackson-version>
+		<jsonwebtoken-version>0.11.2</jsonwebtoken-version>
+		<micrometer-registry-cloudwatch2.version>1.5.5</micrometer-registry-cloudwatch2.version>
+		<postgresql-version>42.2.13</postgresql-version>
+		<protobuf-java-version>3.12.1</protobuf-java-version>
+		<snakeyaml-version>1.26</snakeyaml-version>
+		<springdoc-openapi-version>1.4.0</springdoc-openapi-version>
+		<tomcat-version>9.0.36</tomcat-version>
 
-        <sonar.host.url>https://sonarcloud.io</sonar.host.url>
-        <!--suppress UnresolvedMavenProperty -->
-        <sonar.organization>${env.SONAR_ORGANIZATION}</sonar.organization>
-        <!--suppress UnresolvedMavenProperty -->
-        <sonar.login>${env.SONAR_TOKEN}</sonar.login>
-        <sonar.coverage.jacoco.xmlReportPaths>
-            ${project.basedir}/../dpppt-backend-sdk-report/target/site/jacoco-aggregate/jacoco.xml
-        </sonar.coverage.jacoco.xmlReportPaths>
-    </properties>
+		<sonar.host.url>https://sonarcloud.io</sonar.host.url>
+		<!--suppress UnresolvedMavenProperty -->
+		<sonar.organization>${env.SONAR_ORGANIZATION}</sonar.organization>
+		<!--suppress UnresolvedMavenProperty -->
+		<sonar.login>${env.SONAR_TOKEN}</sonar.login>
+		<sonar.coverage.jacoco.xmlReportPaths>
+			${project.basedir}/../dpppt-backend-sdk-report/target/site/jacoco-aggregate/jacoco.xml
+		</sonar.coverage.jacoco.xmlReportPaths>
+	</properties>
 
-    <modules>
-        <module>dpppt-backend-sdk-model</module>
-        <module>dpppt-backend-sdk-data</module>
-        <module>dpppt-backend-sdk-ws</module>
-        <module>dpppt-backend-sdk-report</module>
-    </modules>
+	<modules>
+		<module>dpppt-backend-sdk-model</module>
+		<module>dpppt-backend-sdk-data</module>
+		<module>dpppt-backend-sdk-ws</module>
+		<module>dpppt-backend-sdk-report</module>
+	</modules>
 
-    <dependencies>
+	<dependencies>
 
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context</artifactId>
-        </dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-context</artifactId>
+		</dependency>
 
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
-        </dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
 
-        <!-- Apache Commons -->
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <version>2.7</version>
-        </dependency>
+		<!-- Apache Commons -->
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>2.7</version>
+		</dependency>
 
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
 
-        <!-- Logging -->
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-logging</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>jcl-over-slf4j</artifactId>
-        </dependency>
+		<!-- Logging -->
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-logging</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>jcl-over-slf4j</artifactId>
+		</dependency>
 
-        <dependency>
-            <groupId>com.google.protobuf</groupId>
-            <artifactId>protobuf-java</artifactId>
-            <version>${protobuf-java-version}</version>
-        </dependency>
+		<dependency>
+			<groupId>com.google.protobuf</groupId>
+			<artifactId>protobuf-java</artifactId>
+			<version>${protobuf-java-version}</version>
+		</dependency>
 
-    </dependencies>
+	</dependencies>
 
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>org.springframework.boot</groupId>
-                <artifactId>spring-boot-dependencies</artifactId>
-                <type>pom</type>
-                <version>${spring-boot-version}</version>
-                <scope>import</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.springframework.cloud</groupId>
-                <artifactId>spring-cloud-dependencies</artifactId>
-                <type>pom</type>
-                <version>${spring-cloud-version}</version>
-                <scope>import</scope>
-            </dependency>
-            <dependency>
-		<groupId>org.springframework.cloud</groupId>
-		<artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
-		<version>${spring-cloud-starter-aws.version}</version>
-	    </dependency>   
-            <dependency>
-                <groupId>org.springframework</groupId>
-                <artifactId>spring-core</artifactId>
-                <version>${spring-framework-version}</version>
-                <exclusions>
-                    <exclusion>
-                        <groupId>commons-logging</groupId>
-                        <artifactId>commons-logging</artifactId>
-                    </exclusion>
-                </exclusions>
-            </dependency>
-            <dependency>
-                <groupId>io.jsonwebtoken</groupId>
-                <artifactId>jjwt-api</artifactId>
-                <version>${jsonwebtoken-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>io.jsonwebtoken</groupId>
-                <artifactId>jjwt-jackson</artifactId>
-                <version>${jsonwebtoken-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>io.jsonwebtoken</groupId>
-                <artifactId>jjwt-impl</artifactId>
-                <version>${jsonwebtoken-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.postgresql</groupId>
-                <artifactId>postgresql</artifactId>
-                <version>${postgresql-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.springdoc</groupId>
-                <artifactId>springdoc-openapi-webmvc-core</artifactId>
-                <version>${springdoc-openapi-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.springdoc</groupId>
-                <artifactId>springdoc-openapi-ui</artifactId>
-                <version>${springdoc-openapi-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.springdoc</groupId>
-                <artifactId>springdoc-openapi-security</artifactId>
-                <version>${springdoc-openapi-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.yaml</groupId>
-                <artifactId>snakeyaml</artifactId>
-                <version>${snakeyaml-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.tomcat.embed</groupId>
-                <artifactId>tomcat-embed-core</artifactId>
-                <version>${tomcat-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.tomcat.embed</groupId>
-                <artifactId>tomcat-embed-el</artifactId>
-                <version>${tomcat-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.tomcat.embed</groupId>
-                <artifactId>tomcat-embed-websocket</artifactId>
-                <version>${tomcat-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>com.fasterxml.jackson.core</groupId>
-                <artifactId>jackson-annotations</artifactId>
-                <version>${jackson-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>com.fasterxml.jackson.core</groupId>
-                <artifactId>jackson-core</artifactId>
-                <version>${jackson-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>com.fasterxml.jackson.core</groupId>
-                <artifactId>jackson-databind</artifactId>
-                <version>${jackson-version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.springframework.cloud</groupId>
-                <artifactId>spring-cloud-starter-circuitbreaker-spring-retry</artifactId>
-                <version>1.0.3.RELEASE</version>
-            </dependency>
-            <dependency>
-                <groupId>org.springframework.cloud</groupId>
-                <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
-                <version>1.0.3.RELEASE</version>
-            </dependency>
-            <dependency>
-                <groupId>joda-time</groupId>
-                <artifactId>joda-time</artifactId>
-                <version>2.10.6</version>
-            </dependency>
-            <dependency>
-                <groupId>org.aspectj</groupId>
-                <artifactId>aspectjrt</artifactId>
-                <version>${aspectj-version}</version>
-                <scope>compile</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.aspectj</groupId>
-                <artifactId>aspectjweaver</artifactId>
-                <version>${aspectj-version}</version>
-                <scope>compile</scope>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-dependencies</artifactId>
+				<type>pom</type>
+				<version>${spring-boot-version}</version>
+				<scope>import</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-dependencies</artifactId>
+				<type>pom</type>
+				<version>${spring-cloud-version}</version>
+				<scope>import</scope>
+			</dependency>
 
-    <!--
-        <repositories>
-            <repository>
-                <id>spring-snapshots</id>
-                <name>Spring Snapshots</name>
-                <url>https://repo.spring.io/snapshot</url>
-                <snapshots>
-                    <enabled>true</enabled>
-                </snapshots>
-            </repository>
-        </repositories>
-    -->
+			<dependency>
+				<groupId>org.springframework</groupId>
+				<artifactId>spring-core</artifactId>
+				<version>${spring-framework-version}</version>
+				<exclusions>
+					<exclusion>
+						<groupId>commons-logging</groupId>
+						<artifactId>commons-logging</artifactId>
+					</exclusion>
+				</exclusions>
+			</dependency>
 
-    <build>
+			<!-- AWS -->
+			<dependency>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-aws-actuator</artifactId>
+				<version>${spring-cloud-starter-aws.version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
+				<version>${spring-cloud-starter-aws.version}</version>
+			</dependency>
+			<dependency>
+				<groupId>io.micrometer</groupId>
+				<artifactId>micrometer-registry-cloudwatch2</artifactId>
+				<version>${micrometer-registry-cloudwatch2.version}</version>
+			</dependency>
 
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>${java-version}</source>
-                    <target>${java-version}</target>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-enforcer-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>enforce-versions</id>
-                        <goals>
-                            <goal>enforce</goal>
-                        </goals>
-                        <configuration>
-                            <rules>
-                                <requireJavaVersion>
-                                    <version>${java-version}</version>
-                                </requireJavaVersion>
-                                <bannedDependencies>
-                                    <excludes>
-                                        <exclude>log4j:log4j</exclude>
-                                        <exclude>commons-logging:commons-logging</exclude>
-                                        <exclude>org.apache.logging.log4j:log4j-core</exclude>
-                                    </excludes>
-                                </bannedDependencies>
-                            </rules>
-                            <fail>true</fail>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <groupId>org.jacoco</groupId>
-                <artifactId>jacoco-maven-plugin</artifactId>
-                <executions>
-                    <!-- set arg line property for surefire -->
-                    <execution>
-                        <id>prepare-agent</id>
-                        <goals>
-                            <goal>prepare-agent</goal>
-                        </goals>
-                        <configuration>
-                            <propertyName>surefireArgLine</propertyName>
-                        </configuration>
-                    </execution>
-                    <!-- set arg line property for failsafe -->
-                    <execution>
-                        <id>prepare-agent-integration</id>
-                        <goals>
-                            <goal>prepare-agent-integration</goal>
-                        </goals>
-                        <configuration>
-                            <propertyName>failsafeArgLine</propertyName>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>prepare-unit-tests</id>
-                        <goals>
-                            <goal>prepare-agent</goal>
-                        </goals>
-                        <!--<configuration>-->
-                        <!--<destFile>${sonar.jacoco.reportPath}</destFile>-->
-                        <!--</configuration>-->
-                    </execution>
+			<dependency>
+				<groupId>io.jsonwebtoken</groupId>
+				<artifactId>jjwt-api</artifactId>
+				<version>${jsonwebtoken-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>io.jsonwebtoken</groupId>
+				<artifactId>jjwt-jackson</artifactId>
+				<version>${jsonwebtoken-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>io.jsonwebtoken</groupId>
+				<artifactId>jjwt-impl</artifactId>
+				<version>${jsonwebtoken-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.postgresql</groupId>
+				<artifactId>postgresql</artifactId>
+				<version>${postgresql-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.springdoc</groupId>
+				<artifactId>springdoc-openapi-webmvc-core</artifactId>
+				<version>${springdoc-openapi-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.springdoc</groupId>
+				<artifactId>springdoc-openapi-ui</artifactId>
+				<version>${springdoc-openapi-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.springdoc</groupId>
+				<artifactId>springdoc-openapi-security</artifactId>
+				<version>${springdoc-openapi-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.yaml</groupId>
+				<artifactId>snakeyaml</artifactId>
+				<version>${snakeyaml-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.apache.tomcat.embed</groupId>
+				<artifactId>tomcat-embed-core</artifactId>
+				<version>${tomcat-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.apache.tomcat.embed</groupId>
+				<artifactId>tomcat-embed-el</artifactId>
+				<version>${tomcat-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.apache.tomcat.embed</groupId>
+				<artifactId>tomcat-embed-websocket</artifactId>
+				<version>${tomcat-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>com.fasterxml.jackson.core</groupId>
+				<artifactId>jackson-annotations</artifactId>
+				<version>${jackson-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>com.fasterxml.jackson.core</groupId>
+				<artifactId>jackson-core</artifactId>
+				<version>${jackson-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>com.fasterxml.jackson.core</groupId>
+				<artifactId>jackson-databind</artifactId>
+				<version>${jackson-version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-starter-circuitbreaker-spring-retry</artifactId>
+				<version>1.0.3.RELEASE</version>
+			</dependency>
+			<dependency>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
+				<version>1.0.3.RELEASE</version>
+			</dependency>
+			<dependency>
+				<groupId>joda-time</groupId>
+				<artifactId>joda-time</artifactId>
+				<version>2.10.6</version>
+			</dependency>
+			<dependency>
+				<groupId>org.aspectj</groupId>
+				<artifactId>aspectjrt</artifactId>
+				<version>${aspectj-version}</version>
+				<scope>compile</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.aspectj</groupId>
+				<artifactId>aspectjweaver</artifactId>
+				<version>${aspectj-version}</version>
+				<scope>compile</scope>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
 
-                    <!-- prepare agent for measuring integration tests -->
-                    <execution>
-                        <id>prepare-agent-coverage</id>
-                        <goals>
-                            <goal>prepare-agent</goal>
-                        </goals>
-                        <phase>pre-integration-test</phase>
-                        <configuration>
-                            <!--<destFile>${sonar.jacoco.itReportPath}</destFile>-->
-                            <propertyName>itCoverageAgent</propertyName>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <forkCount>1</forkCount>
-                </configuration>
-            </plugin>
+	<!--
+		<repositories>
+			<repository>
+				<id>spring-snapshots</id>
+				<name>Spring Snapshots</name>
+				<url>https://repo.spring.io/snapshot</url>
+				<snapshots>
+					<enabled>true</enabled>
+				</snapshots>
+			</repository>
+		</repositories>
+	-->
+
+	<build>
+
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>${java-version}</source>
+					<target>${java-version}</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-enforcer-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>enforce-versions</id>
+						<goals>
+							<goal>enforce</goal>
+						</goals>
+						<configuration>
+							<rules>
+								<requireJavaVersion>
+									<version>${java-version}</version>
+								</requireJavaVersion>
+								<bannedDependencies>
+									<excludes>
+										<exclude>log4j:log4j</exclude>
+										<exclude>commons-logging:commons-logging</exclude>
+										<exclude>org.apache.logging.log4j:log4j-core</exclude>
+									</excludes>
+								</bannedDependencies>
+							</rules>
+							<fail>true</fail>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.jacoco</groupId>
+				<artifactId>jacoco-maven-plugin</artifactId>
+				<executions>
+					<!-- set arg line property for surefire -->
+					<execution>
+						<id>prepare-agent</id>
+						<goals>
+							<goal>prepare-agent</goal>
+						</goals>
+						<configuration>
+							<propertyName>surefireArgLine</propertyName>
+						</configuration>
+					</execution>
+					<!-- set arg line property for failsafe -->
+					<execution>
+						<id>prepare-agent-integration</id>
+						<goals>
+							<goal>prepare-agent-integration</goal>
+						</goals>
+						<configuration>
+							<propertyName>failsafeArgLine</propertyName>
+						</configuration>
+					</execution>
+					<execution>
+						<id>prepare-unit-tests</id>
+						<goals>
+							<goal>prepare-agent</goal>
+						</goals>
+						<!--<configuration>-->
+						<!--<destFile>${sonar.jacoco.reportPath}</destFile>-->
+						<!--</configuration>-->
+					</execution>
+
+					<!-- prepare agent for measuring integration tests -->
+					<execution>
+						<id>prepare-agent-coverage</id>
+						<goals>
+							<goal>prepare-agent</goal>
+						</goals>
+						<phase>pre-integration-test</phase>
+						<configuration>
+							<!--<destFile>${sonar.jacoco.itReportPath}</destFile>-->
+							<propertyName>itCoverageAgent</propertyName>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<configuration>
+					<forkCount>1</forkCount>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-failsafe-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>integration-tests</id>
+						<goals>
+							<goal>integration-test</goal>
+							<goal>verify</goal>
+						</goals>
+						<configuration>
+							<argLine>${itCoverageAgent}</argLine>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>build-helper-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>add-classes</id>
+						<phase>generate-sources</phase>
+						<goals>
+							<goal>add-source</goal>
+						</goals>
+						<configuration>
+							<sources>
+								<source>${project.build.directory}/generated-sources</source>
+							</sources>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-help-plugin</artifactId>
+				<inherited>false</inherited>
+				<executions>
+					<execution>
+						<id>show-profiles</id>
+						<phase>clean</phase>
+						<goals>
+							<goal>active-profiles</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
 
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-failsafe-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>integration-tests</id>
-                        <goals>
-                            <goal>integration-test</goal>
-                            <goal>verify</goal>
-                        </goals>
-                        <configuration>
-                            <argLine>${itCoverageAgent}</argLine>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>build-helper-maven-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>add-classes</id>
-                        <phase>generate-sources</phase>
-                        <goals>
-                            <goal>add-source</goal>
-                        </goals>
-                        <configuration>
-                            <sources>
-                                <source>${project.build.directory}/generated-sources</source>
-                            </sources>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-help-plugin</artifactId>
-                <inherited>false</inherited>
-                <executions>
-                    <execution>
-                        <id>show-profiles</id>
-                        <phase>clean</phase>
-                        <goals>
-                            <goal>active-profiles</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            
 			<plugin>
 				<groupId>pl.project13.maven</groupId>
 				<artifactId>git-commit-id-plugin</artifactId>
 				<executions>
-				  <execution>
-					<id>retrieve-git-info</id>
-					<phase>prepare-package</phase>
-					<goals>
-					  <goal>revision</goal>
-					</goals>
-				  </execution>
+					<execution>
+						<id>retrieve-git-info</id>
+						<phase>prepare-package</phase>
+						<goals>
+							<goal>revision</goal>
+						</goals>
+					</execution>
 				</executions>
 				<configuration>
-				  <injectAllReactorProjects>true</injectAllReactorProjects>
-				  <runOnlyOnce>true</runOnlyOnce>
-				  <skipPoms>false</skipPoms>
-				  <dateFormat>yyyyMMddHHmmss</dateFormat>
-				  <dateFormatTimeZone>UTC</dateFormatTimeZone>
-				  <failOnNoGitDirectory>false</failOnNoGitDirectory>
+					<injectAllReactorProjects>true</injectAllReactorProjects>
+					<runOnlyOnce>true</runOnlyOnce>
+					<skipPoms>false</skipPoms>
+					<dateFormat>yyyyMMddHHmmss</dateFormat>
+					<dateFormatTimeZone>UTC</dateFormatTimeZone>
+					<failOnNoGitDirectory>false</failOnNoGitDirectory>
 				</configuration>
-			  </plugin>
-			  <plugin>
+			</plugin>
+			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-jar-plugin</artifactId>
 				<configuration>
-				  <archive>
-					<manifestEntries>
-					  <Last-Commit-Id>${git.commit.id}</Last-Commit-Id>
-					  <Last-Commit-Time>${git.commit.time}</Last-Commit-Time>
-					  <Reproducible-Build>true</Reproducible-Build>
-					</manifestEntries>
-				  </archive>
+					<archive>
+						<manifestEntries>
+							<Last-Commit-Id>${git.commit.id}</Last-Commit-Id>
+							<Last-Commit-Time>${git.commit.time}</Last-Commit-Time>
+							<Reproducible-Build>true</Reproducible-Build>
+						</manifestEntries>
+					</archive>
 				</configuration>
-			  </plugin>
-			  <plugin>
+			</plugin>
+			<plugin>
 				<groupId>io.github.zlika</groupId>
 				<artifactId>reproducible-build-maven-plugin</artifactId>
 				<version>0.12</version>
 				<executions>
-				  <execution>
-					<id>strip-jaxb</id>
-					<goals>
-					  <goal>strip-jaxb</goal>
-					</goals>
-				  </execution>
-				  <execution>
-					<id>strip-jar</id>
-					<goals>
-					  <goal>strip-jar</goal>
-					</goals>
+					<execution>
+						<id>strip-jaxb</id>
+						<goals>
+							<goal>strip-jaxb</goal>
+						</goals>
+					</execution>
+					<execution>
+						<id>strip-jar</id>
+						<goals>
+							<goal>strip-jar</goal>
+						</goals>
+						<configuration>
+							<zipDateTime>${git.commit.time}</zipDateTime>
+							<!-- Set custom date/time format pattern, "yyyyMMddHHmmss" by default -->
+							<!-- <zipDateTimeFormatPattern>yyyyMMddHHmmss</zipDateTimeFormatPattern> -->
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-compiler-plugin</artifactId>
+					<version>3.8.1</version>
 					<configuration>
-					  <zipDateTime>${git.commit.time}</zipDateTime>
-					  <!-- Set custom date/time format pattern, "yyyyMMddHHmmss" by default -->
-					  <!-- <zipDateTimeFormatPattern>yyyyMMddHHmmss</zipDateTimeFormatPattern> -->
+						<source>${java-version}</source>
+						<target>${java-version}</target>
+						<compilerArgs>
+							<arg>-parameters</arg>
+						</compilerArgs>
 					</configuration>
-				  </execution>
-				</executions>
-			  </plugin>
-        </plugins>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-compiler-plugin</artifactId>
-                    <version>3.8.1</version>
-                    <configuration>
-                        <source>${java-version}</source>
-                        <target>${java-version}</target>
-                        <compilerArgs>
-                            <arg>-parameters</arg>
-                        </compilerArgs>
-                    </configuration>
-                </plugin>
-                <plugin>
-                    <groupId>org.jacoco</groupId>
-                    <artifactId>jacoco-maven-plugin</artifactId>
-                    <version>0.8.5</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.sonarsource.scanner.maven</groupId>
-                    <artifactId>sonar-maven-plugin</artifactId>
-                    <version>3.7.0.1746</version>
-                </plugin>
-                <plugin>
-                    <groupId>com.github.os72</groupId>
-                    <artifactId>protoc-jar-maven-plugin</artifactId>
-                    <version>3.11.4</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.codehaus.mojo</groupId>
-                    <artifactId>build-helper-maven-plugin</artifactId>
-                    <version>3.2.0</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-help-plugin</artifactId>
-                    <version>3.2.0</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-failsafe-plugin</artifactId>
-                    <version>2.22.2</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-surefire-plugin</artifactId>
-                    <version>2.22.2</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-enforcer-plugin</artifactId>
-                    <version>3.0.0-M3</version>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-    </build>
-    <!--
-        <distributionManagement>
-            <repository>
-                <id>github</id>
-                <name>GitHub Packages</name>
-                <url>https://maven.pkg.github.com/DP-3T/dp3t-sdk-backend</url>
-            </repository>
-        </distributionManagement>
-    -->
+				</plugin>
+				<plugin>
+					<groupId>org.jacoco</groupId>
+					<artifactId>jacoco-maven-plugin</artifactId>
+					<version>0.8.5</version>
+				</plugin>
+				<plugin>
+					<groupId>org.sonarsource.scanner.maven</groupId>
+					<artifactId>sonar-maven-plugin</artifactId>
+					<version>3.7.0.1746</version>
+				</plugin>
+				<plugin>
+					<groupId>com.github.os72</groupId>
+					<artifactId>protoc-jar-maven-plugin</artifactId>
+					<version>3.11.4</version>
+				</plugin>
+				<plugin>
+					<groupId>org.codehaus.mojo</groupId>
+					<artifactId>build-helper-maven-plugin</artifactId>
+					<version>3.2.0</version>
+				</plugin>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-help-plugin</artifactId>
+					<version>3.2.0</version>
+				</plugin>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-failsafe-plugin</artifactId>
+					<version>2.22.2</version>
+				</plugin>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-surefire-plugin</artifactId>
+					<version>2.22.2</version>
+				</plugin>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-enforcer-plugin</artifactId>
+					<version>3.0.0-M3</version>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+	</build>
+	<!--
+		<distributionManagement>
+			<repository>
+				<id>github</id>
+				<name>GitHub Packages</name>
+				<url>https://maven.pkg.github.com/DP-3T/dp3t-sdk-backend</url>
+			</repository>
+		</distributionManagement>
+	-->
 </project>

programming_language: HTML
repo_url: https://github.com/RadarCOVID/radar-covid-android
commit_details: repo_url: https://github.com/RadarCOVID/radar-covid-android
author: Oscar Rodriguez
author_date: 2020-10-16 15:04:26+02:00
msg: chore: fix build config import
repository: repo_url: https://github.com/RadarCOVID/radar-covid-android
repo_name: RadarCOVID/radar-covid-android
description: Native Android app using DP^3T Android sdk to handle Exposure Notifications API from Google
repo_language: Kotlin
owner: RadarCOVID
file_changes: filename: FakeInfectionReportWorker.kt
change_type: ModificationType.MODIFY
diff: @@ -13,9 +13,9 @@ package es.gob.radarcovid.features.worker
 import android.content.Context
 import androidx.work.*
 import dagger.android.HasAndroidInjector
+import es.gob.radarcovid.BuildConfig
 import es.gob.radarcovid.datamanager.repository.PreferencesRepository
 import es.gob.radarcovid.datamanager.usecase.ReportFakeInfectionUseCase
-import org.dpppt.android.sdk.BuildConfig
 import org.dpppt.android.sdk.DP3T
 import java.security.SecureRandom
 import java.util.concurrent.TimeUnit

programming_language: Scala
repo_url: https://github.com/RadarCOVID/radar-covid-android
commit_details: repo_url: https://github.com/RadarCOVID/radar-covid-android
author: Oscar Rodriguez
author_date: 2020-10-15 18:38:43+02:00
msg: chore: Changed ExistingWorkPolicy to REPLACE in fake request worker
repository: repo_url: https://github.com/RadarCOVID/radar-covid-android
repo_name: RadarCOVID/radar-covid-android
description: Native Android app using DP^3T Android sdk to handle Exposure Notifications API from Google
repo_language: Kotlin
owner: RadarCOVID
file_changes: filename: FakeInfectionReportWorker.kt
change_type: ModificationType.MODIFY
diff: @@ -98,7 +98,7 @@ class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters
             preferencesRepository.setTDummy(tDummy)
         }
 
-        start(applicationContext, tDummy, ExistingWorkPolicy.APPEND)
+        start(applicationContext, tDummy, ExistingWorkPolicy.REPLACE)
         return Result.success()
     }
 

programming_language: Scala
repo_url: https://github.com/RadarCOVID/radar-covid-android
commit_details: repo_url: https://github.com/RadarCOVID/radar-covid-android
author: Alberto Vecina Sánchez
author_date: 2020-09-22 13:10:21+02:00
msg: *[FakeReport] Implemented random fake infection reports
repository: repo_url: https://github.com/RadarCOVID/radar-covid-android
repo_name: RadarCOVID/radar-covid-android
description: Native Android app using DP^3T Android sdk to handle Exposure Notifications API from Google
repo_language: Kotlin
owner: RadarCOVID
file_changes: filename: RadarCovidApplication.kt
change_type: ModificationType.MODIFY
diff: @@ -14,6 +14,7 @@ import dagger.android.AndroidInjector
 import dagger.android.support.DaggerApplication
 import es.gob.radarcovid.common.base.broadcast.ExposureStatusChangeBroadcastReceiver
 import es.gob.radarcovid.common.di.component.DaggerApplicationComponent
+import es.gob.radarcovid.features.worker.FakeInfectionReportWorker
 import io.reactivex.rxjava3.plugins.RxJavaPlugins
 import okhttp3.CertificatePinner
 import org.dpppt.android.sdk.DP3T
@@ -46,6 +47,8 @@ class RadarCovidApplication : DaggerApplication() {
         DP3T.setCertificatePinner(certificatePinner)
         DP3T.setUserAgent(userAgent)
 
+        FakeInfectionReportWorker.start(this)
+
         registerReceiver(ExposureStatusChangeBroadcastReceiver(), DP3T.getUpdateIntentFilter())
 
     }

programming_language: Scala
filename: RepositoryModule.kt
change_type: ModificationType.MODIFY
diff: @@ -31,22 +31,19 @@ class RepositoryModule {
 
     @Provides
     @PerApplication
-    fun providesExposureStatusRepository(repository: ExposureStatusRepositoryImpl): ExposureStatusRepository =
+    fun providesFakeInfectionReportRepository(repository: FakeInfectionReportRepositoryImpl): FakeInfectionReportRepository =
         repository
 
     @Provides
     @PerApplication
-    fun providesDomainRepository(repository: DomainRepositoryImpl): DomainRepository = repository
+    fun providesExposureStatusRepository(repository: ExposureStatusRepositoryImpl): ExposureStatusRepository =
+        repository
 
     @Provides
     @PerApplication
     fun providesPreferencesRepository(repository: PreferencesRepositoryImpl): PreferencesRepository =
         repository
 
-    @Provides
-    @PerApplication
-    fun providesExampleRepository(repository: ExampleRepositoryImpl): ExampleRepository = repository
-
     @Provides
     @PerApplication
     fun providesApiRepository(repository: ApiRepositoryImpl): ApiRepository = repository

programming_language: Markdown
filename: ServicesModule.kt
change_type: ModificationType.MODIFY
diff: @@ -14,11 +14,16 @@ import dagger.Module
 import dagger.android.ContributesAndroidInjector
 import es.gob.radarcovid.common.base.broadcast.ExposureStatusChangeBroadcastReceiver
 import es.gob.radarcovid.common.di.scope.PerService
+import es.gob.radarcovid.features.worker.FakeInfectionReportWorker
 import es.gob.radarcovid.features.worker.HealerWorker
 
 @Module
 abstract class ServicesModule {
 
+    @PerService
+    @ContributesAndroidInjector
+    abstract fun bindsFakeInfectedReportWorker(): FakeInfectionReportWorker
+
     @PerService
     @ContributesAndroidInjector
     abstract fun bindsHealerWorker(): HealerWorker

programming_language: Scala
filename: DomainRepositoryImpl.kt
change_type: ModificationType.DELETE
diff: @@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2020 Gobierno de España
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * SPDX-License-Identifier: MPL-2.0
- */
-
-package es.gob.radarcovid.datamanager.repository
-
-import es.gob.radarcovid.models.domain.ExposureInfo
-import javax.inject.Inject
-
-class DomainRepositoryImpl @Inject constructor() : DomainRepository {
-
-    override var exposureInfo: ExposureInfo? = null
-
-}
\ No newline at end of file

programming_language: unknown
filename: ExampleRepository.kt
change_type: ModificationType.DELETE
diff: @@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2020 Gobierno de España
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * SPDX-License-Identifier: MPL-2.0
- */
-
-package es.gob.radarcovid.datamanager.repository
-
-import org.funktionale.either.Either
-
-interface ExampleRepository {
-
-    fun exampleRequest(): Either<Throwable, String>
-
-}
\ No newline at end of file

programming_language: unknown
filename: ExampleRepositoryImpl.kt
change_type: ModificationType.DELETE
diff: @@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2020 Gobierno de España
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * SPDX-License-Identifier: MPL-2.0
- */
-
-package es.gob.radarcovid.datamanager.repository
-
-import es.gob.radarcovid.common.base.BaseRepository
-import es.gob.radarcovid.datamanager.api.ApiInterface
-import org.funktionale.either.Either
-import javax.inject.Inject
-
-class ExampleRepositoryImpl @Inject constructor(private val apiInterface: ApiInterface) :
-    BaseRepository(), ExampleRepository {
-
-    override fun exampleRequest(): Either<Throwable, String> = callService {
-        apiInterface.test()
-    }
-
-}
\ No newline at end of file

programming_language: unknown
filename: FakeInfectionReportRepository.kt
change_type: ModificationType.RENAME
diff: @@ -10,10 +10,10 @@
 
 package es.gob.radarcovid.datamanager.repository
 
-import es.gob.radarcovid.models.domain.ExposureInfo
+import io.reactivex.rxjava3.core.Completable
 
-interface DomainRepository {
+interface FakeInfectionReportRepository {
 
-    var exposureInfo: ExposureInfo?
+    fun notifyFakeInfected(authCode: String): Completable
 
 }
\ No newline at end of file

programming_language: Scala
filename: FakeInfectionReportRepositoryImpl.kt
change_type: ModificationType.ADD
diff: @@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020 Gobierno de España
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
+package es.gob.radarcovid.datamanager.repository
+
+import android.content.Context
+import es.gob.radarcovid.BuildConfig
+import io.reactivex.rxjava3.core.Completable
+import org.dpppt.android.sdk.DP3T
+import org.dpppt.android.sdk.models.ExposeeAuthMethodAuthorization
+import javax.inject.Inject
+import javax.inject.Named
+
+class FakeInfectionReportRepositoryImpl @Inject constructor(
+    @Named("applicationContext") private val context: Context
+) : FakeInfectionReportRepository {
+
+    override fun notifyFakeInfected(authCode: String): Completable =
+        Completable.create {
+            if (BuildConfig.isMock) {
+                it.onComplete()
+            } else {
+                DP3T.sendFakeInfectedRequest(context,
+                    ExposeeAuthMethodAuthorization("Bearer $authCode"),
+                    { it.onComplete() },
+                    { it.onError(Exception("Error notifying fake infection")) }
+                )
+            }
+        }
+
+}
\ No newline at end of file

programming_language: Scala
filename: ReportFakeInfectionUseCase.kt
change_type: ModificationType.ADD
diff: @@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020 Gobierno de España
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
+package es.gob.radarcovid.datamanager.usecase
+
+import es.gob.radarcovid.datamanager.repository.ApiRepository
+import es.gob.radarcovid.datamanager.repository.FakeInfectionReportRepository
+import es.gob.radarcovid.models.request.RequestVerifyCode
+import es.gob.radarcovid.models.response.ResponseToken
+import io.reactivex.rxjava3.core.Completable
+import io.reactivex.rxjava3.core.Observable
+import javax.inject.Inject
+
+class ReportFakeInfectionUseCase @Inject constructor(
+    private val fakeInfectionReportRepository: FakeInfectionReportRepository,
+    private val apiRepository: ApiRepository
+) {
+
+    companion object {
+
+        const val FAKE_REPORT_CODE: String = "112358132134"
+        
+    }
+
+
+    fun reportFakeInfection(): Completable =
+        getFakeVerifyToken().flatMapCompletable {
+            fakeInfectionReportRepository.notifyFakeInfected(it.token)
+        }.concatWith {
+            it.onComplete()
+        }
+
+    private fun getFakeVerifyToken(): Observable<ResponseToken> {
+        return Observable.create { emitter ->
+            val result = apiRepository.verifyCode(RequestVerifyCode(null, FAKE_REPORT_CODE))
+
+            if (result.isLeft()) {
+                emitter.onError(result.left().get())
+            } else {
+                emitter.onNext(result.right().get())
+                emitter.onComplete()
+            }
+
+        }
+    }
+
+}
\ No newline at end of file

programming_language: Scala
filename: ReportInfectedUseCase.kt
change_type: ModificationType.MODIFY
diff: @@ -14,6 +14,7 @@ import es.gob.radarcovid.common.base.utils.JwtTokenUtils
 import es.gob.radarcovid.datamanager.repository.ApiRepository
 import es.gob.radarcovid.datamanager.repository.ContactTracingRepository
 import es.gob.radarcovid.datamanager.repository.PreferencesRepository
+import es.gob.radarcovid.models.exception.GenericRequestException
 import es.gob.radarcovid.models.request.RequestVerifyCode
 import es.gob.radarcovid.models.response.ResponseToken
 import io.reactivex.rxjava3.core.Completable
@@ -28,17 +29,18 @@ class ReportInfectedUseCase @Inject constructor(
     private val jwtTokenUtils: JwtTokenUtils
 ) {
 
-    fun reportInfected(reportCode: String): Completable {
-
-        return getVerifyToken(reportCode).flatMapCompletable {
-            contactTracingRepository.notifyInfected(it.token, jwtTokenUtils.getOnset(it.token))
-        }.concatWith {
-            preferencesRepository.setInfectionReportDate(Date())
-            it.onComplete()
+    fun reportInfected(reportCode: String): Completable =
+        if (reportCode == ReportFakeInfectionUseCase.FAKE_REPORT_CODE) {
+            Completable.create { it.onError(GenericRequestException()) }
+        } else {
+            getVerifyToken(reportCode).flatMapCompletable {
+                contactTracingRepository.notifyInfected(it.token, jwtTokenUtils.getOnset(it.token))
+            }.concatWith {
+                preferencesRepository.setInfectionReportDate(Date())
+                it.onComplete()
+            }
         }
 
-    }
-
     private fun getVerifyToken(reportCode: String): Observable<ResponseToken> {
         return Observable.create { emitter ->
             val result = apiRepository.verifyCode(RequestVerifyCode(null, reportCode))

programming_language: Scala
filename: FakeInfectionReportWorker.kt
change_type: ModificationType.ADD
diff: @@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2020 Gobierno de España
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ */
+
+package es.gob.radarcovid.features.worker
+
+import android.content.Context
+import androidx.work.*
+import dagger.android.HasAndroidInjector
+import es.gob.radarcovid.datamanager.usecase.ReportFakeInfectionUseCase
+import org.dpppt.android.sdk.BuildConfig
+import org.dpppt.android.sdk.DP3T
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+import kotlin.random.Random
+
+class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters) :
+    Worker(context, workerParams) {
+
+    init {
+        (context.applicationContext as? HasAndroidInjector)
+            ?.androidInjector()
+            ?.inject(this)
+    }
+
+    companion object {
+
+        private const val TAG = "FakeInfectionReportWorker"
+
+        fun start(context: Context) {
+            start(context, getRandomDelay(), ExistingWorkPolicy.KEEP)
+        }
+
+        private fun start(
+            context: Context,
+            delayInMinutes: Long,
+            existingWorkPolicy: ExistingWorkPolicy
+        ) {
+            val constraints = Constraints.Builder()
+                .setRequiredNetworkType(NetworkType.CONNECTED)
+                .build()
+            val work =
+                OneTimeWorkRequest
+                    .Builder(FakeInfectionReportWorker::class.java)
+                    .setInitialDelay(delayInMinutes, TimeUnit.MINUTES)
+                    .setConstraints(constraints)
+                    .build()
+            WorkManager.getInstance(context)
+                .enqueueUniqueWork(TAG, existingWorkPolicy, work)
+        }
+
+        private fun getRandomDelay(): Long = Random.nextLong(180, 360)
+
+    }
+
+    @Inject
+    lateinit var reportFakeInfectionUseCase: ReportFakeInfectionUseCase
+
+    override fun doWork(): Result {
+        if (BuildConfig.DEBUG)
+            DP3T.addWorkerStartedToHistory(applicationContext, TAG)
+        reportFakeInfectionUseCase.reportFakeInfection().subscribe()
+        start(applicationContext, getRandomDelay(), ExistingWorkPolicy.APPEND)
+        return Result.success()
+    }
+    
+}
\ No newline at end of file

programming_language: Scala
repo_url: https://github.com/RadarCOVID/radar-covid-android
commit_details: repo_url: https://github.com/RadarCOVID/radar-covid-android
author: Oscar Rodriguez
author_date: 2020-10-14 18:46:39+02:00
msg: chore: fix execution delay
repository: repo_url: https://github.com/RadarCOVID/radar-covid-android
repo_name: RadarCOVID/radar-covid-android
description: Native Android app using DP^3T Android sdk to handle Exposure Notifications API from Google
repo_language: Kotlin
owner: RadarCOVID
file_changes: filename: FakeInfectionReportWorker.kt
change_type: ModificationType.MODIFY
diff: @@ -61,8 +61,6 @@ class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters
 
             val now = clock.currentTimeMillis()
             val executionDelay = 0L.coerceAtLeast(tDummy - now)
-            val executionDelayDays =
-                executionDelay / FACTOR_DAY_MILLIS
 
             val constraints = Constraints.Builder()
                 .setRequiredNetworkType(NetworkType.CONNECTED)
@@ -70,7 +68,7 @@ class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters
             val work =
                 OneTimeWorkRequest
                     .Builder(FakeInfectionReportWorker::class.java)
-                    .setInitialDelay(executionDelayDays, TimeUnit.MILLISECONDS)
+                    .setInitialDelay(executionDelay, TimeUnit.MILLISECONDS)
                     .setConstraints(constraints)
                     .setInputData(Data.Builder().putLong(KEY_T_DUMMY, tDummy).build())
                     .build()
@@ -90,6 +88,7 @@ class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters
         val now = clock.currentTimeMillis()
         var tDummy = inputData.getLong(KEY_T_DUMMY, now)
         while (tDummy < now) {
+            // only do request if it was planned to do in the last 48h
             if (tDummy >= now - FACTOR_HOUR_MILLIS * MAX_DELAY_HOURS) {
                 if (BuildConfig.DEBUG)
                     DP3T.addWorkerStartedToHistory(applicationContext, TAG)

programming_language: Scala
repo_url: https://github.com/RadarCOVID/radar-covid-android
commit_details: repo_url: https://github.com/RadarCOVID/radar-covid-android
author: Oscar Rodriguez
author_date: 2020-10-08 11:22:28+02:00
msg: *Code fix
repository: repo_url: https://github.com/RadarCOVID/radar-covid-android
repo_name: RadarCOVID/radar-covid-android
description: Native Android app using DP^3T Android sdk to handle Exposure Notifications API from Google
repo_language: Kotlin
owner: RadarCOVID
file_changes: filename: FakeInfectionReportWorker.kt
change_type: ModificationType.MODIFY
diff: @@ -20,7 +20,7 @@ import org.dpppt.android.sdk.DP3T
 import java.security.SecureRandom
 import java.util.concurrent.TimeUnit
 import javax.inject.Inject
-
+import kotlin.math.ln
 
 private const val FACTOR_HOUR_MILLIS = 60 * 60 * 1000L
 private const val FACTOR_DAY_MILLIS: Long = 24 * FACTOR_HOUR_MILLIS
@@ -78,8 +78,6 @@ class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters
                 .enqueueUniqueWork(TAG, existingWorkPolicy, work)
         }
 
-        //private fun getRandomDelay(): Long = Random.nextLong(180, 360)
-
     }
 
     @Inject
@@ -114,7 +112,7 @@ class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters
         override fun syncInterval(): Long {
             val newDelayDays: Double =
                 ExponentialDistribution.sampleFromStandard() / SAMPLING_RATE
-            return (newDelayDays * FACTOR_DAY_MILLIS) as Long
+            return (newDelayDays * FACTOR_DAY_MILLIS).toLong()
         }
 
         override fun currentTimeMillis(): Long {
@@ -125,7 +123,7 @@ class FakeInfectionReportWorker(context: Context, workerParams: WorkerParameters
     object ExponentialDistribution {
         fun sampleFromStandard(): Double {
             val random = SecureRandom()
-            return -Math.log(1.0 - random.nextDouble())
+            return -ln(1.0 - random.nextDouble())
         }
     }
 

programming_language: Scala