public async Task <IActionResult> UploadDiagnosisKeys()
        {
            var requestBody = String.Empty;

            try
            {
                _logger.LogInformation("UploadDiagnosisKeys endpoint called");
                TemporaryExposureKeyBatchDto parameters = await GetRequestParameters();

                await _addTemporaryExposureKeyService.CreateKeysInDatabase(parameters, KeySource.SmitteStopApiVersion3);

                _logger.LogInformation("Keys uploaded successfully");
                return(Ok());
            }
            catch (JsonException je)
            {
                _logger.LogError($"Incorrect JSON format: { je}  [Deserialized request]: {requestBody}");
                return(BadRequest($"Incorrect JSON format: {je.Message}"));
            }
            catch (ArgumentException ae)
            {
                _logger.LogError("Incorrect input format: " + ae);
                return(BadRequest("Incorrect input format: " + ae.Message));
            }
            catch (SqlException e)
            {
                _logger.LogError("Error occurred when uploading keys to the database." + e);
                return(StatusCode(500, "Error occurred when uploading keys to the database."));
            }
            catch (Exception e)
            {
                _logger.LogError("Error uploading keys:" + e);
                return(StatusCode(500));
            }
        }
        public void MapDtoWithSharingTrue_ToEntity_ShouldHaveSharingTrue()
        {
            //Arrange
            var dto = new TemporaryExposureKeyBatchDto()
            {
                keys = new List <TemporaryExposureKeyDto>
                {
                    new TemporaryExposureKeyDto()
                    {
                    },
                    new TemporaryExposureKeyDto()
                    {
                    }
                },
                isSharingAllowed = true
            };
            var mapper = new ExposureKeyMapper(_epochConverter);

            //Act
            var entities = mapper.FromDtoToEntity(dto);

            //Assert
            entities.Should().NotBeNull();
            entities.Should().NotBeEmpty();
            entities.Select(ent => ent.SharingConsentGiven).Should().AllBeEquivalentTo(true);
        }
        private void ValidateRegions(TemporaryExposureKeyBatchDto parameter)
        {
            var originCountry = _countryRepository.GetApiOriginCountry();

            if (!parameter.keys.Any())
            {
                return;
            }
            if (parameter.regions == null)
            {
                throw new ArgumentException("Regions array is null.");
            }

            var expectedRegionCode = originCountry.Code;
            var regions            = parameter.regions;

            if (regions.Count == 1 && regions.Any(r => r.ToLower() == expectedRegionCode.ToLower()))
            {
                return;
            }

            var regionsString = string.Join(",", parameter.regions);

            throw new ArgumentException(
                      $"Incorrect regions: {regionsString}. Expected single value: {expectedRegionCode}");
        }
 private void ValidateKeyDataLength(TemporaryExposureKeyBatchDto parameter)
 {
     if (parameter.keys.Any(x => x.key.Length != TemporaryExposureKeyDto.KeyLength))
     {
         parameter.keys = GetKeysWithValidSize(parameter.keys, _logger);
     }
 }
        public async Task TestCreateKeysInDatabase()
        {
            var addTemporaryExposureKeyService = CreateTestObject();
            var parameters = new TemporaryExposureKeyBatchDto
            {
                appPackageName   = string.Empty,
                visitedCountries = new List <string>
                {
                    "CR",
                    "PL",
                    "DK"
                },
                regions = new List <string>
                {
                    "dk"
                },
            };

            await addTemporaryExposureKeyService.CreateKeysInDatabase(parameters);

            _temporaryExposureKeyRepositoryMock.Verify(mock =>
                                                       mock.AddTemporaryExposureKeys(It.Is <IList <TemporaryExposureKey> >(keys =>
                                                                                                                           keys.All(key => key.KeySource == KeySource.SmitteStopApiVersion2))));

            _temporaryExposureKeyRepositoryMock.Verify(mock =>
                                                       mock.AddTemporaryExposureKeys(It.Is <IList <TemporaryExposureKey> >(keys =>
                                                                                                                           keys.All(key => key.VisitedCountries.Any(country => country.Country.Code.ToLower() == "dk") == false))));
        }
Пример #6
0
        public async Task <IList <TemporaryExposureKey> > GetFilteredKeysEntitiesFromDTO(
            TemporaryExposureKeyBatchDto parameters)
        {
            var incomingKeys = _exposureKeyMapper.FromDtoToEntity(parameters);

            incomingKeys = await FilterDuplicateKeysAsync(incomingKeys);

            return(incomingKeys);
        }
Пример #7
0
        public async Task CreateKeysInDatabase(TemporaryExposureKeyBatchDto parameters, KeySource apiVersion)
        {
            var newTemporaryExposureKeys = await GetFilteredKeysEntitiesFromDTO(parameters);

            if (newTemporaryExposureKeys.Any())
            {
                await CreateNewKeysInDatabase(parameters, newTemporaryExposureKeys, apiVersion);
            }
        }
Пример #8
0
 public void ValidateParameterAndThrowIfIncorrect(TemporaryExposureKeyBatchDto parameter, KeyValidationConfiguration configuration)
 {
     ValidateKeyDuplication(parameter);
     ValidateKeyDataLength(parameter);
     ValidateRollingStartDate(parameter, configuration);
     ValidateRollingDurationSpan(parameter);
     ValidateRegions(parameter);
     ValidateVisitedCountries(parameter);
     ValidatePackageNames(parameter, configuration);
 }
 List <TemporaryExposureKey> IExposureKeyMapper.FromDtoToEntity(TemporaryExposureKeyBatchDto dto)
 {
     return(dto.keys.Select(key => new TemporaryExposureKey()
     {
         CreatedOn = DateTime.UtcNow,
         RollingStartNumber = key.rollingStart.ToUnixEpoch(),
         KeyData = key.key,
         RollingPeriod = (long)(key.rollingDurationSpan.TotalMinutes / 10.0d),
         TransmissionRiskLevel = key.transmissionRiskLevel,
         DaysSinceOnsetOfSymptoms = key.daysSinceOnsetOfSymptoms
     }).ToList());
 }
 public List <TemporaryExposureKey> FromDtoToEntity(TemporaryExposureKeyBatchDto dto)
 {
     return(dto.keys.Select(key => new TemporaryExposureKey()
     {
         CreatedOn = DateTime.UtcNow,
         RollingStartNumber = _epochConverter.ConvertToEpoch(key.rollingStart),
         KeyData = key.key,
         RollingPeriod = (long)(key.rollingDurationSpan.TotalMinutes / 10.0d),
         TransmissionRiskLevel = key.transmissionRiskLevel,
         DaysSinceOnsetOfSymptoms = key.daysSinceOnsetOfSymptoms,
         SharingConsentGiven = dto.sharingConsentGiven
     }).ToList());
 }
        private void ValidateKeyCount(TemporaryExposureKeyBatchDto parameter, KeyValidationConfiguration configuration)
        {
            //The period of time covered by the data file exceeds 14 days
            if (parameter.keys.Count <= configuration.OutdatedKeysDayOffset)
            {
                return;
            }

            var errorMessage =
                $"Incorrect key count. Given key count: {parameter.keys.Count}. Expected: {configuration.OutdatedKeysDayOffset}";

            throw new ArgumentException(errorMessage);
        }
Пример #12
0
        private void ValidateKeyDuplication(TemporaryExposureKeyBatchDto parameter)
        {
            var duplicatedKeys = GetDuplicatedKeys(parameter.keys.Select(k => k.key).ToList());

            if (!duplicatedKeys.Any())
            {
                return;
            }

            var stringOfDuplicatedKeys = string.Join(", ", duplicatedKeys.Select(key => BitConverter.ToString(key).Replace("-", "")));
            var errorMessage           = $"Duplicate key values. Duplicated keys: {stringOfDuplicatedKeys}";

            throw new ArgumentException(errorMessage);
        }
Пример #13
0
        private async Task CreateNewKeysInDatabase(TemporaryExposureKeyBatchDto parameters, IList <TemporaryExposureKey> newTemporaryExposureKeys, KeySource apiVersion)
        {
            var origin = _countryRepository.FindByIsoCode(parameters.regions[0]);

            foreach (var key in newTemporaryExposureKeys)
            {
                key.Origin     = origin;
                key.KeySource  = apiVersion;
                key.ReportType = ReportType.CONFIRMED_TEST;
            }

            var visitedCountries = parameters.visitedCountries.FindAll(countryCode => countryCode.ToLower() != origin.Code.ToLower());
            await _temporaryExposureKeyRepository.AddTemporaryExposureKeysAsync(newTemporaryExposureKeys);

            await CreateKeyCountryRelationships(visitedCountries, newTemporaryExposureKeys);
        }
        private void ValidateRollingStartDateIntervals(TemporaryExposureKeyBatchDto parameter)
        {
            //Any ENIntervalNumber values from the same user are not unique
            var rollingStartGroupsHavingMoreThan1Key =
                parameter.keys.GroupBy(k => k.rollingStart).Where(group => group.Count() > 1).ToList();

            if (!rollingStartGroupsHavingMoreThan1Key.Any())
            {
                return;
            }

            var rollingStartDates = rollingStartGroupsHavingMoreThan1Key.Select(group => @group.Key);
            var errorMessage      =
                $"Incorrect intervals. Dates having more than one key: {string.Join(", ", rollingStartDates)}";

            throw new ArgumentException(errorMessage);
        }
Пример #15
0
        private void ValidatePackageNames(TemporaryExposureKeyBatchDto parameter, KeyValidationConfiguration configuration)
        {
            var packageName = parameter.appPackageName.ToLower();

            if (packageName == configuration.PackageNames.Apple ||
                packageName == configuration.PackageNames.Google)
            {
                return;
            }

            var errorMessage = $"Incorrect package name. Given: {packageName}.";

            errorMessage += $"Expected for {nameof(configuration.PackageNames.Apple)}: {configuration.PackageNames.Apple}";
            errorMessage += $"Expected for {nameof(configuration.PackageNames.Google)}: {configuration.PackageNames.Google}";

            throw new ArgumentException(errorMessage);
        }
        private void ValidateVisitedCountries(TemporaryExposureKeyBatchDto parameter)
        {
            if (parameter.visitedCountries == null)
            {
                return;
            }

            var notFoundVisitedCountries = new List <string>();
            var disabledVisitedCountries = new List <string>();

            foreach (var visitedCountry in parameter.visitedCountries)
            {
                var foundCountry = _countryRepository.FindByIsoCode(visitedCountry);

                if (foundCountry == null)
                {
                    notFoundVisitedCountries.Add(visitedCountry);
                }
                else if (!foundCountry.VisitedCountriesEnabled)
                {
                    disabledVisitedCountries.Add(visitedCountry);
                }
            }

            var errorMessage = string.Empty;

            if (notFoundVisitedCountries.Any())
            {
                errorMessage +=
                    $"ISO codes of countries not found in the database: {string.Join(", ", notFoundVisitedCountries)}. ";
            }
            if (disabledVisitedCountries.Any())
            {
                errorMessage +=
                    $"ISO codes of countries marked as disabled in the database: {string.Join(", ", disabledVisitedCountries)}. ";
            }

            if (notFoundVisitedCountries.Any() || disabledVisitedCountries.Any())
            {
                throw new ArgumentException(errorMessage);
            }
        }
        public void Init()
        {
            SetupMockServices();

            _keyValidationConfiguration = new KeyValidationConfiguration()
            {
                OutdatedKeysDayOffset = 14,
                PackageNames          = new PackageNameConfig()
                {
                    Apple = "com.netcompany.smittestop-exposure-notification", Google = "com.netcompany.smittestop-exposure-notification"
                },
            };

            _exposureKeyValidator = new ExposureKeyValidator(_countryRepositoryMock.Object, _loggerValidator.Object);
            _exposureKeyReader    = new ExposureKeyReader(_exposureKeyValidator, _keyValidationConfiguration, _loggerReader.Object);

            _parameterArgument = new TemporaryExposureKeyBatchDto()
            {
                appPackageName = "com.netcompany.smittestop-exposure-notification",
                platform       = "Android",

                keys = new List <TemporaryExposureKeyDto>()
                {
                    new TemporaryExposureKeyDto()
                    {
                        key                   = new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                        rollingDuration       = "1.00:00:00",
                        rollingStart          = DateTime.UtcNow.Date.AddDays(-1),
                        transmissionRiskLevel = RiskLevel.RISK_LEVEL_MEDIUM_HIGH
                    }
                },
                regions = new List <string>
                {
                    "dk"
                },
                visitedCountries = new List <string>
                {
                    "AT"
                },
                isSharingAllowed = true
            };
        }
        private static void ValidateRollingDurationSpan(TemporaryExposureKeyBatchDto parameter)
        {
            //The TEKRollingPeriod value is not 144
            var minimumValidSpan = TimeSpan.FromMinutes(10);
            var maximumValidSpan = TemporaryExposureKeyDto.OneDayTimeSpan;

            var incorrectRollingDurationSpans = parameter.keys.Where(k =>
                                                                     k.rollingDurationSpan > maximumValidSpan ||
                                                                     k.rollingDurationSpan < minimumValidSpan).ToList();

            if (!incorrectRollingDurationSpans.Any())
            {
                return;
            }

            var spansString  = string.Join(", ", incorrectRollingDurationSpans.Select(key => key.rollingDurationSpan));
            var errorMessage = $"Incorrect spans: {spansString}. Expecting span to be > {minimumValidSpan} and < {maximumValidSpan}";

            throw new ArgumentException(errorMessage);
        }
        public void Init()
        {
            SetupMockServices();
            exposureKeyValidator = new ExposureKeyValidator(countryRepositoryMock.Object);
            parameterArgument    = new TemporaryExposureKeyBatchDto()
            {
                deviceVerificationPayload = "eyJhbGciOiJSUzI1NiIsIng1YyI6WyJNSUlGa3pDQ0JIdWdBd0lCQWdJUkFOY1NramRzNW42K0NBQUFBQUFwYTBjd0RRWUpLb1pJaHZjTkFRRUxCUUF3UWpFTE1Ba0dBMVVFQmhNQ1ZWTXhIakFjQmdOVkJBb1RGVWR2YjJkc1pTQlVjblZ6ZENCVFpYSjJhV05sY3pFVE1CRUdBMVVFQXhNS1IxUlRJRU5CSURGUE1UQWVGdzB5TURBeE1UTXhNVFF4TkRsYUZ3MHlNVEF4TVRFeE1UUXhORGxhTUd3eEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlFd3BEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIRXcxTmIzVnVkR0ZwYmlCV2FXVjNNUk13RVFZRFZRUUtFd3BIYjI5bmJHVWdURXhETVJzd0dRWURWUVFERXhKaGRIUmxjM1F1WVc1a2NtOXBaQzVqYjIwd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUNXRXJCUVRHWkdOMWlaYk45ZWhSZ2lmV0J4cWkyUGRneHcwM1A3VHlKWmZNeGpwNUw3ajFHTmVQSzVIemRyVW9JZDF5Q0l5Qk15eHFnYXpxZ3RwWDVXcHNYVzRWZk1oSmJOMVkwOXF6cXA2SkQrMlBaZG9UVTFrRlJBTVdmTC9VdVp0azdwbVJYZ0dtNWpLRHJaOU54ZTA0dk1ZUXI4OE5xd1cva2ZaMWdUT05JVVQwV3NMVC80NTIyQlJXeGZ3eGMzUUUxK1RLV2tMQ3J2ZWs2V2xJcXlhQzUyVzdNRFI4TXBGZWJ5bVNLVHZ3Zk1Sd3lLUUxUMDNVTDR2dDQ4eUVjOHNwN3dUQUhNL1dEZzhRb3RhcmY4T0JIa25vWjkyWGl2aWFWNnRRcWhST0hDZmdtbkNYaXhmVzB3RVhDdnFpTFRiUXRVYkxzUy84SVJ0ZFhrcFFCOUFnTUJBQUdqZ2dKWU1JSUNWREFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUhBd0V3REFZRFZSMFRBUUgvQkFJd0FEQWRCZ05WSFE0RUZnUVU2REhCd3NBdmI1M2cvQzA3cHJUdnZ3TlFRTFl3SHdZRFZSMGpCQmd3Rm9BVW1OSDRiaERyejV2c1lKOFlrQnVnNjMwSi9Tc3daQVlJS3dZQkJRVUhBUUVFV0RCV01DY0dDQ3NHQVFVRkJ6QUJoaHRvZEhSd09pOHZiMk56Y0M1d2Eya3VaMjl2Wnk5bmRITXhiekV3S3dZSUt3WUJCUVVITUFLR0gyaDBkSEE2THk5d2Eya3VaMjl2Wnk5bmMzSXlMMGRVVXpGUE1TNWpjblF3SFFZRFZSMFJCQll3RklJU1lYUjBaWE4wTG1GdVpISnZhV1F1WTI5dE1DRUdBMVVkSUFRYU1CZ3dDQVlHWjRFTUFRSUNNQXdHQ2lzR0FRUUIxbmtDQlFNd0x3WURWUjBmQkNnd0pqQWtvQ0tnSUlZZWFIUjBjRG92TDJOeWJDNXdhMmt1WjI5dlp5OUhWRk14VHpFdVkzSnNNSUlCQkFZS0t3WUJCQUhXZVFJRUFnU0I5UVNCOGdEd0FIY0E5bHlVTDlGM01DSVVWQmdJTUpSV2p1Tk5FeGt6djk4TUx5QUx6RTd4Wk9NQUFBRnZudXkwWndBQUJBTUFTREJHQWlFQTdlLzBZUnUzd0FGbVdIMjdNMnZiVmNaL21ycCs0cmZZYy81SVBKMjlGNmdDSVFDbktDQ0FhY1ZOZVlaOENDZllkR3BCMkdzSHh1TU9Ia2EvTzQxaldlRit6Z0IxQUVTVVpTNnc3czZ2eEVBSDJLaitLTURhNW9LKzJNc3h0VC9UTTVhMXRvR29BQUFCYjU3c3RKTUFBQVFEQUVZd1JBSWdFWGJpb1BiSnA5cUMwRGoyNThERkdTUk1BVStaQjFFaVZFYmJiLzRVdk5FQ0lCaEhrQnQxOHZSbjl6RHZ5cmZ4eXVkY0hUT1NsM2dUYVlBLzd5VC9CaUg0TUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFESUFjUUJsbWQ4TUVnTGRycnJNYkJUQ3ZwTVhzdDUrd3gyRGxmYWpKTkpVUDRqWUZqWVVROUIzWDRFMnpmNDluWDNBeXVaRnhBcU9SbmJqLzVqa1k3YThxTUowajE5ekZPQitxZXJ4ZWMwbmhtOGdZbExiUW02c0tZN1AwZXhmcjdIdUszTWtQMXBlYzE0d0ZFVWFHcUR3VWJHZ2wvb2l6MzhGWENFK0NXOEUxUUFFVWZ2YlFQVFliS3hZait0Q05sc3MwYlRTb0wyWjJkL2ozQnBMM01GdzB5eFNLL1VUcXlrTHIyQS9NZGhKUW14aStHK01LUlNzUXI2MkFuWmF1OXE2WUZvaSs5QUVIK0E0OFh0SXlzaEx5Q1RVM0h0K2FLb2hHbnhBNXVsMVhSbXFwOEh2Y0F0MzlQOTVGWkdGSmUwdXZseWpPd0F6WHVNdTdNK1BXUmMiLCJNSUlFU2pDQ0F6S2dBd0lCQWdJTkFlTzBtcUdOaXFtQkpXbFF1REFOQmdrcWhraUc5dzBCQVFzRkFEQk1NU0F3SGdZRFZRUUxFeGRIYkc5aVlXeFRhV2R1SUZKdmIzUWdRMEVnTFNCU01qRVRNQkVHQTFVRUNoTUtSMnh2WW1Gc1UybG5iakVUTUJFR0ExVUVBeE1LUjJ4dlltRnNVMmxuYmpBZUZ3MHhOekEyTVRVd01EQXdOREphRncweU1URXlNVFV3TURBd05ESmFNRUl4Q3pBSkJnTlZCQVlUQWxWVE1SNHdIQVlEVlFRS0V4VkhiMjluYkdVZ1ZISjFjM1FnVTJWeWRtbGpaWE14RXpBUkJnTlZCQU1UQ2tkVVV5QkRRU0F4VHpFd2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURRR005RjFJdk4wNXprUU85K3ROMXBJUnZKenp5T1RIVzVEekVaaEQyZVBDbnZVQTBRazI4RmdJQ2ZLcUM5RWtzQzRUMmZXQllrL2pDZkMzUjNWWk1kUy9kTjRaS0NFUFpSckF6RHNpS1VEelJybUJCSjV3dWRnem5kSU1ZY0xlL1JHR0ZsNXlPRElLZ2pFdi9TSkgvVUwrZEVhbHROMTFCbXNLK2VRbU1GKytBY3hHTmhyNTlxTS85aWw3MUkyZE44RkdmY2Rkd3VhZWo0YlhocDBMY1FCYmp4TWNJN0pQMGFNM1Q0SStEc2F4bUtGc2JqemFUTkM5dXpwRmxnT0lnN3JSMjV4b3luVXh2OHZObWtxN3pkUEdIWGt4V1k3b0c5aitKa1J5QkFCazdYckpmb3VjQlpFcUZKSlNQazdYQTBMS1cwWTN6NW96MkQwYzF0Skt3SEFnTUJBQUdqZ2dFek1JSUJMekFPQmdOVkhROEJBZjhFQkFNQ0FZWXdIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUJJR0ExVWRFd0VCL3dRSU1BWUJBZjhDQVFBd0hRWURWUjBPQkJZRUZKalIrRzRRNjgrYjdHQ2ZHSkFib090OUNmMHJNQjhHQTFVZEl3UVlNQmFBRkp2aUIxZG5IQjdBYWdiZVdiU2FMZC9jR1lZdU1EVUdDQ3NHQVFVRkJ3RUJCQ2t3SnpBbEJnZ3JCZ0VGQlFjd0FZWVphSFIwY0RvdkwyOWpjM0F1Y0d0cExtZHZiMmN2WjNOeU1qQXlCZ05WSFI4RUt6QXBNQ2VnSmFBamhpRm9kSFJ3T2k4dlkzSnNMbkJyYVM1bmIyOW5MMmR6Y2pJdlozTnlNaTVqY213d1B3WURWUjBnQkRnd05qQTBCZ1puZ1F3QkFnSXdLakFvQmdnckJnRUZCUWNDQVJZY2FIUjBjSE02THk5d2Eya3VaMjl2Wnk5eVpYQnZjMmwwYjNKNUx6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFHb0ErTm5uNzh5NnBSamQ5WGxRV05hN0hUZ2laL3IzUk5Ha21VbVlIUFFxNlNjdGk5UEVhanZ3UlQyaVdUSFFyMDJmZXNxT3FCWTJFVFV3Z1pRK2xsdG9ORnZoc085dHZCQ09JYXpwc3dXQzlhSjl4anU0dFdEUUg4TlZVNllaWi9YdGVEU0dVOVl6SnFQalk4cTNNRHhyem1xZXBCQ2Y1bzhtdy93SjRhMkc2eHpVcjZGYjZUOE1jRE8yMlBMUkw2dTNNNFR6czNBMk0xajZieWtKWWk4d1dJUmRBdktMV1p1L2F4QlZielltcW13a201ekxTRFc1bklBSmJFTENRQ1p3TUg1NnQyRHZxb2Z4czZCQmNDRklaVVNweHU2eDZ0ZDBWN1N2SkNDb3NpclNtSWF0ai85ZFNTVkRRaWJldDhxLzdVSzR2NFpVTjgwYXRuWnoxeWc9PSJdfQ.eyJub25jZSI6InY1S0FXenU3YXArYnlRbnpnWnB0bGc9PSIsInRpbWVzdGFtcE1zIjoxNTkwOTU3NzYyMDg2LCJhcGtQYWNrYWdlTmFtZSI6ImNvbS5uZXRjb21wYW55LnNtaXR0ZXN0b3BfZXhwb3N1cmVfbm90aWZpY2F0aW9uIiwiYXBrRGlnZXN0U2hhMjU2IjoiTGUzZFRxMk9Bd0gxb2hJU0hUUk43MHc3QjYrZHVQc0JUb3p0cnpSUU5kTT0iLCJjdHNQcm9maWxlTWF0Y2giOnRydWUsImFwa0NlcnRpZmljYXRlRGlnZXN0U2hhMjU2IjpbIlRzSVA1SXZqZFo4VElPUEs4OHg0cUxWLzcwRFhZNHpVLzBmZ2tJUDV6M0k9Il0sImJhc2ljSW50ZWdyaXR5Ijp0cnVlLCJldmFsdWF0aW9uVHlwZSI6IkJBU0lDIn0.f8BgnP7h9JjLoqCU5IUNEX4paRederRGcq_KBccNzLq1JUNqL04Lx6sVW8PCJrWjOYmJd5FSks9wp0Rb85H78mwmE4QJBt90FEOtO-WFWVdVqU-MNfVxXQqfDexusZx2Sk2khVcqeJkWGd7UXHO-DwHaZuhsB15nkhAOBirEVKneZFSUW4dKRRzcXrSGyeOpnhr8YVGwokfidgZbkj0Z_fzfBbQN6ihr9PGknwLYyir04gNvB2k8hPqGmKs3RIB6zzw-nPG4HK1PoBl27GKl-n7nX97FHvRCn5j5XRZOVY5fnA2iDhbXcdYsNPLYs60ndRAE42oQW5xUiNDymIQteg",
                appPackageName            = "com.netcompany.smittestop-exposure-notification",
                platform = "Android",

                keys = new List <TemporaryExposureKeyDto>()
                {
                    new TemporaryExposureKeyDto()
                    {
                        key = new byte[TemporaryExposureKeyDto.KeyLength] {
                            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
                        },
                        rollingDuration       = "1.00:00:00",
                        rollingStart          = DateTime.UtcNow.Date.AddDays(-1),
                        transmissionRiskLevel = RiskLevel.RISK_LEVEL_MEDIUM_HIGH
                    }
                },
                regions = new List <string>()
                {
                    "dk"
                },
                visitedCountries = new List <string>()
                {
                    "AT"
                }
            }
            ;
            configurationArgument = new KeyValidationConfiguration()
            {
                OutdatedKeysDayOffset = 14,
                PackageNames          = new PackageNameConfig()
                {
                    Apple = "com.netcompany.smittestop-exposure-notification", Google = "com.netcompany.smittestop-exposure-notification"
                },
            };
        }
Пример #20
0
        private static void ValidateRollingStartDate(TemporaryExposureKeyBatchDto parameter,
                                                     KeyValidationConfiguration configuration)
        {
            var outdatedKeysDate      = DateTime.UtcNow.Date.AddDays(-configuration.OutdatedKeysDayOffset);
            var todaysDateUtcMidnight = DateTime.UtcNow.Date;

            var keysWithInvalidRollingStart =
                parameter.keys.Where(key => key.rollingStart <outdatedKeysDate || key.rollingStart> todaysDateUtcMidnight).ToList();

            if (!keysWithInvalidRollingStart.Any())
            {
                return;
            }

            var invalidRollingStartDates       = keysWithInvalidRollingStart.Select(key => key.rollingStart);
            var invalidRollingStartDatesString = string.Join(", ", invalidRollingStartDates);

            var errorMessage = $"Incorrect start date. Incorrect dates: {invalidRollingStartDatesString}. OutdatedKeysDayOffset from configuration: {configuration.OutdatedKeysDayOffset}";

            throw new ArgumentException(errorMessage);
        }
        public void ValidateParameterAndThrowIfIncorrect(TemporaryExposureKeyBatchDto parameter, KeyValidationConfiguration configuration, ILogger logger)
        {
            var now = DateTime.UtcNow;
            var outdatedKeysDate = DateTime.UtcNow.Date.AddDays(-configuration.OutdatedKeysDayOffset);

            var originCountry = _countryRepository.GetApiOriginCountry();

            //The period of time covered by the data file exceeds 14 days
            if (parameter.keys.Count > configuration.OutdatedKeysDayOffset)
            {
                throw new ArgumentException("Incorrect key count.");
            }
            if (!ValidateForDuplicatedKeys(parameter.keys.Select(k => k.key).ToList()))
            {
                throw new ArgumentException("Duplicate key values.");
            }

            if (parameter.keys.Any(x => x.key.Length != TemporaryExposureKeyDto.KeyLength))
            {
                parameter.keys = GetKeysWithValidSize(parameter.keys, logger);
            }

            if (parameter.keys.Any(k => k.rollingStart < outdatedKeysDate || k.rollingStart > now))
            {
                throw new ArgumentException("Incorrect start date.");
            }

            //The TEKRollingPeriod value is not 144
            if (parameter.keys.Any(k => k.rollingDurationSpan > TemporaryExposureKeyDto.OneDayTimeSpan || k.rollingDurationSpan < TimeSpan.FromMinutes(10)))
            {
                throw new ArgumentException("Incorrect span.");
            }

            //Any ENIntervalNumber values from the same user are not unique
            if (parameter.keys.GroupBy(k => k.rollingStart).Any(group => group.Count() > 1))
            {
                throw new ArgumentException("Incorrect intervals.");
            }

            if (parameter.keys.Any())
            {
                var expectedRegionCode = originCountry.Code;
                if (parameter.regions == null)
                {
                    throw new ArgumentException($"Regions array is null.");
                }

                var regions = parameter.regions;
                if (regions.Count != 1 || regions.All(r => r.ToLower() != expectedRegionCode.ToLower()))
                {
                    var regionsStr = string.Join(",", parameter.regions);
                    throw new ArgumentException($"Incorrect regions: {regionsStr}. Expected single value: {expectedRegionCode}");
                }
            }
            if (parameter.visitedCountries != null)
            {
                foreach (var visitedCountry in parameter.visitedCountries)
                {
                    var countryDb = _countryRepository.FindByIsoCode(visitedCountry);
                    if (countryDb == null || countryDb.VisitedCountriesEnabled == false)
                    {
                        throw new ArgumentException("Incorrect visited countries.");
                    }
                }
            }

            if (configuration.PackageNames.Apple != parameter.appPackageName.ToLower() && configuration.PackageNames.Google != parameter.appPackageName.ToLower())
            {
                throw new ArgumentException("Incorrect package name.");
            }
        }