Пример #1
0
        /// <summary>
        /// This method does a simple validation of keys that might be obtained from the operating system.
        /// Some actions by user, may cause wrond TEKs being generated and obtained from OS, e.g., manually changing the date.
        /// Xamarin representation of TEKs does not take care of such things so we do it in this method.
        /// The method will return a list with only valid keys.
        ///
        /// These are the factors that make a key upload invalid according to Apple at
        /// https://developer.apple.com/documentation/exposurenotification/setting_up_an_exposure_notification_server:
        ///  1. RollingStart is not unique for each of the user's keys
        ///  2. There are gaps in the key validity periods for a user
        ///		(they say "gaps in ENIntervalNumber", but I think this is a more correct way of saying what they mean)
        ///  3. There are keys with overlapping validity periods
        ///  4. The period of time covered exceeds 14 days
        ///  5. RollingPeriod is not 1 day
        /// </summary>
        /// <param name="temporaryExposureKeys"></param>
        /// <returns></returns>
        public static List <ExposureKeyModel> CreateAValidListOfTemporaryExposureKeys(IEnumerable <ExposureKeyModel> temporaryExposureKeys)
        {
            List <ExposureKeyModel> validListOfTeks = temporaryExposureKeys.ToList();

            // Satisfy criterion 1. If there are several keys with the same RollingStart, keep only 1

            int i = 0;

            while (i < validListOfTeks.Count)
            {
                ExposureKeyModel leftTek = validListOfTeks[i];

                // Remove all duplicates to the right of the key at i

                int j = validListOfTeks.Count - 1;
                while (j > i)
                {
                    ExposureKeyModel rightTek = validListOfTeks[j];

                    if (leftTek.RollingStart == rightTek.RollingStart)
                    {
                        validListOfTeks.RemoveAt(j);
                    }
                    j--;
                }

                i++;
            }

            // Satisfy criterion 2. Iterate backwards in time and if the next key is not 1 day before the previous key
            // take what we have iterated over so far

            // Sort from newest to oldest
            validListOfTeks.Sort((x, y) => y.RollingStart.CompareTo(x.RollingStart));
            for (int k = 0; k < validListOfTeks.Count - 1; k++)
            {
                if (validListOfTeks[k + 1].RollingStart != validListOfTeks[k].RollingStart.AddDays(-1))
                {
                    validListOfTeks = validListOfTeks.Take(k + 1).ToList();
                    break;
                }
            }

            // Criterion 3 will be satisfied. We now have unique RollingStarts and each key is 1 day from the next. Criterion 3 will
            // then be satisfied when we satisfy criterion 5 below

            // Satisfy criterion 4. If we have more than 14 keys, only take 14
            if (validListOfTeks.Count > 14)
            {
                validListOfTeks = validListOfTeks.Take(14).ToList();
            }

            // Satisfy criterion 5 by setting RollingDuration to 1 day
            foreach (ExposureKeyModel tek in validListOfTeks)
            {
                tek.RollingDuration = new TimeSpan(1, 0, 0, 0);
            }

            return(validListOfTeks);
        }
Пример #2
0
 private bool TeksAreEqual(ExposureKeyModel tek1, ExposureKeyModel tek2)
 {
     return
         (tek1.Key == tek2.Key &&
          tek1.RollingDuration == tek2.RollingDuration &&
          tek1.RollingStart == tek2.RollingStart &&
          tek1.TransmissionRiskLevel == tek2.TransmissionRiskLevel);
 }
Пример #3
0
 // True iff. container contains a key with same value as the given tek. Not looking at object addresses
 private bool ContainsTek(ExposureKeyModel tek, IEnumerable <ExposureKeyModel> teks)
 {
     foreach (ExposureKeyModel containedTek in teks)
     {
         if (TeksAreEqual(containedTek, tek))
         {
             return(true);
         }
     }
     return(false);
 }
Пример #4
0
        public void createAValidListOfTemporaryExposureKeys_HaveDateGap_OnlyNewestShouldBeKept()
        {
            // Create keys
            ExposureKeyModel tek1 = new ExposureKeyModel(new byte[1], june1, TimeSpan.FromDays(1), RiskLevel.Medium);
            ExposureKeyModel tek2 = new ExposureKeyModel(new byte[2], june1.AddDays(1), TimeSpan.FromDays(1), RiskLevel.Medium);
            ExposureKeyModel tek3 = new ExposureKeyModel(new byte[3], june1.AddDays(3), TimeSpan.FromDays(1), RiskLevel.Medium);

            // Process a list of copies
            IEnumerable <ExposureKeyModel> temporaryExposureKeys = new List <ExposureKeyModel>()
            {
                CopyTek(tek1), CopyTek(tek2), CopyTek(tek3)
            };
            IEnumerable <ExposureKeyModel> processedKeys = UploadDiagnosisKeysHelper.CreateAValidListOfTemporaryExposureKeys(temporaryExposureKeys);

            // Only tek3 should be left
            Assert.Single(processedKeys);
            Assert.True(ContainsTek(tek3, processedKeys));
        }
Пример #5
0
        public void createAValidListOfTemporaryExposureKeys_HaveMultipleWithSameDate_OnlyOneWithEachDateShouldBeKept()
        {
            // Create keys
            ExposureKeyModel tek1 = new ExposureKeyModel(new byte[1], june1, TimeSpan.FromDays(1), RiskLevel.Medium);
            ExposureKeyModel tek2 = new ExposureKeyModel(new byte[2], june1, TimeSpan.FromDays(1), RiskLevel.Medium);
            ExposureKeyModel tek3 = new ExposureKeyModel(new byte[3], june1.AddDays(1), TimeSpan.FromDays(1), RiskLevel.Medium);

            // Process a list of copies
            IEnumerable <ExposureKeyModel> temporaryExposureKeys = new List <ExposureKeyModel>()
            {
                CopyTek(tek1), CopyTek(tek2), CopyTek(tek3)
            };
            IEnumerable <ExposureKeyModel> processedKeys = UploadDiagnosisKeysHelper.CreateAValidListOfTemporaryExposureKeys(temporaryExposureKeys);

            // The only difference should be that tek2 is not contained in the result
            Assert.Equal(2, processedKeys.Count());
            Assert.True(ContainsTek(tek1, processedKeys));
            Assert.True(ContainsTek(tek3, processedKeys));
        }
Пример #6
0
        public void createAValidListOfTemporaryExposureKeys_HaveBadRollingDurations_RollingDurationsShouldBeSetToOneDay()
        {
            // Create keys
            ExposureKeyModel tek1 = new ExposureKeyModel(new byte[1], june1, TimeSpan.FromDays(0), RiskLevel.Medium);
            ExposureKeyModel tek2 = new ExposureKeyModel(new byte[2], june1.AddDays(1), TimeSpan.FromDays(10), RiskLevel.Medium);
            ExposureKeyModel tek3 = new ExposureKeyModel(new byte[3], june1.AddDays(2), TimeSpan.FromDays(-10), RiskLevel.Medium);

            // Process a list of copies
            IEnumerable <ExposureKeyModel> temporaryExposureKeys = new List <ExposureKeyModel>()
            {
                CopyTek(tek1), CopyTek(tek2), CopyTek(tek3)
            };
            IEnumerable <ExposureKeyModel> processedKeys = UploadDiagnosisKeysHelper.CreateAValidListOfTemporaryExposureKeys(temporaryExposureKeys);

            // RollingDurations should be 1 day
            foreach (ExposureKeyModel tek in processedKeys)
            {
                Assert.Equal(TimeSpan.FromDays(1), tek.RollingDuration);
            }
        }
        public async void createAValidListOfTemporaryExposureKeys_HaveDateGap_AllShouldBeKept()
        {
            SystemTime.ResetDateTime();

            // Create keys
            ExposureKeyModel tek1 = new ExposureKeyModel(new byte[1], SystemTime.Now(), TimeSpan.FromDays(1), RiskLevel.Medium);
            ExposureKeyModel tek2 = new ExposureKeyModel(new byte[2], SystemTime.Now().AddDays(-1), TimeSpan.FromDays(1), RiskLevel.Medium);
            ExposureKeyModel tek3 = new ExposureKeyModel(new byte[3], SystemTime.Now().AddDays(-3), TimeSpan.FromDays(1), RiskLevel.Medium);

            // Process a list of copies
            IEnumerable <ExposureKeyModel> temporaryExposureKeys = new List <ExposureKeyModel>()
            {
                CopyTek(tek1), CopyTek(tek2), CopyTek(tek3)
            };
            IEnumerable <ExposureKeyModel> processedKeys = UploadDiagnosisKeysHelper.CreateAValidListOfTemporaryExposureKeys(temporaryExposureKeys);

            // No keys should be filtered out
            Assert.Equal(processedKeys.Count(), temporaryExposureKeys.Count());
            Assert.True(ContainsTek(tek3, processedKeys));
            Assert.False((await _logManager.GetLogs(10)).Any());
        }
        public void createAValidListOfTemporaryExposureKeys_HaveMultipleWithSameDate_AllShouldBeKept()
        {
            SystemTime.ResetDateTime();

            // Create keys
            ExposureKeyModel tek1 = new ExposureKeyModel(new byte[1], SystemTime.Now(), TimeSpan.FromDays(0.7), RiskLevel.Medium);
            ExposureKeyModel tek2 = new ExposureKeyModel(new byte[2], SystemTime.Now(), TimeSpan.FromDays(0.3), RiskLevel.Medium);
            ExposureKeyModel tek3 = new ExposureKeyModel(new byte[3], SystemTime.Now().AddDays(-1), TimeSpan.FromDays(1), RiskLevel.Medium);

            // Process a list of copies
            IEnumerable <ExposureKeyModel> temporaryExposureKeys = new List <ExposureKeyModel>()
            {
                CopyTek(tek1), CopyTek(tek2), CopyTek(tek3)
            };
            IEnumerable <ExposureKeyModel> processedKeys = UploadDiagnosisKeysHelper.CreateAValidListOfTemporaryExposureKeys(temporaryExposureKeys);

            // No keys should be filtered out
            Assert.True(ContainsTek(tek1, processedKeys));
            Assert.True(ContainsTek(tek2, processedKeys));
            Assert.True(ContainsTek(tek3, processedKeys));
        }
Пример #9
0
 private ExposureKeyModel CopyTek(ExposureKeyModel tek)
 {
     return(new ExposureKeyModel(tek.Key, tek.RollingStart, tek.RollingDuration, tek.TransmissionRiskLevel));
 }
Пример #10
0
        public async void calculateTransmissionRiskbasedOnDateDifference()
        {
            // Create keys with different dates
            ExposureKeyModel tekminus3 = new ExposureKeyModel(new byte[1], june1.AddDays(-3), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tekminus2 = new ExposureKeyModel(new byte[1], june1.AddDays(-2), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tekminus1 = new ExposureKeyModel(new byte[1], june1.AddDays(-1), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek2      = new ExposureKeyModel(new byte[1], june1.AddDays(2), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek3      = new ExposureKeyModel(new byte[1], june1.AddDays(3), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek4      = new ExposureKeyModel(new byte[1], june1.AddDays(4), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek5      = new ExposureKeyModel(new byte[1], june1.AddDays(5), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek6      = new ExposureKeyModel(new byte[1], june1.AddDays(6), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek7      = new ExposureKeyModel(new byte[1], june1.AddDays(7), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek8      = new ExposureKeyModel(new byte[1], june1.AddDays(8), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek9      = new ExposureKeyModel(new byte[1], june1.AddDays(9), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek10     = new ExposureKeyModel(new byte[1], june1.AddDays(10), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek11     = new ExposureKeyModel(new byte[1], june1.AddDays(11), TimeSpan.FromDays(1), RiskLevel.Invalid);
            ExposureKeyModel tek12     = new ExposureKeyModel(new byte[1], june1.AddDays(12), TimeSpan.FromDays(1), RiskLevel.Invalid);


            // Process a list of copies
            IEnumerable <ExposureKeyModel> temporaryExposureKeys = new List <ExposureKeyModel>()
            {
                tek2, tek3, tek4, tek5, tek6, tek7, tek8, tek9, tek10, tek11, tek12
            };
            IEnumerable <ExposureKeyModel> processedKeys = UploadDiagnosisKeysHelper.CreateAValidListOfTemporaryExposureKeys(temporaryExposureKeys);
            List <ExposureKeyModel>        validKeys     = UploadDiagnosisKeysHelper.CreateAValidListOfTemporaryExposureKeys(processedKeys);

            List <ExposureKeyModel> resultKeys = UploadDiagnosisKeysHelper.SetTransmissionRiskLevel(validKeys, MiBaDate);

            for (int i = 1; i < 11; i++)
            {
                if (i == 0)
                {
                    Assert.Equal("Highest", resultKeys[i].TransmissionRiskLevel.ToString());
                }
                if (i > 0 && i < 3)
                {
                    Assert.Equal("VeryHigh", resultKeys[i].TransmissionRiskLevel.ToString());
                }
                if (i > 2 && i < 5)
                {
                    Assert.Equal("High", resultKeys[i].TransmissionRiskLevel.ToString());
                }
                if (i > 4 && i < 9)
                {
                    Assert.Equal("MediumHigh", resultKeys[i].TransmissionRiskLevel.ToString());
                }
                if (i > 8)
                {
                    Assert.Equal("Medium", resultKeys[i].TransmissionRiskLevel.ToString());
                }
            }

            IEnumerable <ExposureKeyModel> negativeDifferenceExposureKeys = new List <ExposureKeyModel>()
            {
                tekminus1, tekminus2, tekminus3
            };
            IEnumerable <ExposureKeyModel> processedNegativeDifferenceExposureKeys = UploadDiagnosisKeysHelper.CreateAValidListOfTemporaryExposureKeys(negativeDifferenceExposureKeys);
            List <ExposureKeyModel>        validNegativeDifferenceExposureKeys     = UploadDiagnosisKeysHelper.CreateAValidListOfTemporaryExposureKeys(processedNegativeDifferenceExposureKeys);
            List <ExposureKeyModel>        resultKeysNegativeDifference            = UploadDiagnosisKeysHelper.SetTransmissionRiskLevel(validNegativeDifferenceExposureKeys, MiBaDate);

            for (int i = 1; i < 11; i++)
            {
                if (i == 0)
                {
                    Assert.Equal("Medium", resultKeysNegativeDifference[i].TransmissionRiskLevel.ToString());
                }
                if (i == 1)
                {
                    Assert.Equal("MediumLow", resultKeysNegativeDifference[i].TransmissionRiskLevel.ToString());
                }
                if (i == 2)
                {
                    Assert.Equal("Low", resultKeysNegativeDifference[i].TransmissionRiskLevel.ToString());
                }
            }
        }