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)))); }
public async Task <IList <TemporaryExposureKey> > GetFilteredKeysEntitiesFromDTO( TemporaryExposureKeyBatchDto parameters) { var incomingKeys = _exposureKeyMapper.FromDtoToEntity(parameters); incomingKeys = await FilterDuplicateKeysAsync(incomingKeys); return(incomingKeys); }
public async Task CreateKeysInDatabase(TemporaryExposureKeyBatchDto parameters, KeySource apiVersion) { var newTemporaryExposureKeys = await GetFilteredKeysEntitiesFromDTO(parameters); if (newTemporaryExposureKeys.Any()) { await CreateNewKeysInDatabase(parameters, newTemporaryExposureKeys, apiVersion); } }
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); }
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); }
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); }
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" }, }; }
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."); } }