Exemple #1
0
        public async Task SubmitPositiveDiagnosisAsync(SelfDiagnosisSubmissionRequest diagnosis)
        {
            using (var ctx = new ExposureNotificationContext(dbContextOptions))
                using (var transaction = ctx.Database.BeginTransaction())
                {
                    // Ensure the database contains the diagnosis uid
                    var dbDiag = await ctx.Diagnoses.FirstOrDefaultAsync(d => d.DiagnosisUid == diagnosis.DiagnosisUid);

                    // Check that the diagnosis uid exists and that there aren't too many keys associated
                    // already, otherwise it might be someone submitting fake data with a legitimate key
                    if (dbDiag == null || dbDiag.KeyCount > maxKeysPerDiagnosisFile)
                    {
                        throw new InvalidOperationException();
                    }

                    var dbKeys = diagnosis.Keys.Select(k => DbTemporaryExposureKey.FromKey(k)).ToList();

                    // Add the new keys to the db
                    foreach (var dbk in dbKeys)
                    {
                        // Only add key if it doesn't exist already
                        if (!await ctx.TemporaryExposureKeys.AnyAsync(k => k.Base64KeyData == dbk.Base64KeyData))
                        {
                            ctx.TemporaryExposureKeys.Add(dbk);
                        }
                    }

                    // Increment key count
                    dbDiag.KeyCount += diagnosis.Keys.Count();

                    await ctx.SaveChangesAsync();

                    await transaction.CommitAsync();
                }
        }
Exemple #2
0
        public async Task <KeysResponse> GetKeysAsync(ulong since, int skip = 0, int take = 1000)
        {
            using (var ctx = new ExposureNotificationContext(dbContextOptions))
            {
                var oldest = DateTimeOffset.UtcNow.AddDays(-14).ToUnixTimeSeconds();

                var results = await ctx.TemporaryExposureKeys.AsQueryable()
                              .Where(dtk => dtk.Id > since &&
                                     dtk.TimestampSecondsSinceEpoch >= oldest)
                              .OrderBy(dtk => dtk.Id)
                              .Skip(skip)
                              .Take(take)
                              .ToListAsync().ConfigureAwait(false);

                var newestIndex = results
                                  .LastOrDefault()?.Id;

                var keys = results.Select(dtk => dtk.ToKey());

                return(new KeysResponse
                {
                    Latest = newestIndex ?? 0,
                    Keys = keys
                });
            }
        }
Exemple #3
0
 public void DeleteAllKeysAsync()
 {
     using (var ctx = new ExposureNotificationContext(dbContextOptions))
     {
         ctx.TemporaryExposureKeys.RemoveRange(ctx.TemporaryExposureKeys);
         ctx.SaveChanges();
     }
 }
Exemple #4
0
 public Task <List <TemporaryExposureKey> > GetAllKeysAsync()
 {
     using (var ctx = new ExposureNotificationContext(dbContextOptions))
     {
         return(ctx.TemporaryExposureKeys
                .Select(k => k.ToKey())
                .ToListAsync());
     }
 }
Exemple #5
0
        public async Task <int> GetNextBatchAsync(int batchNumber, string region, Func <TemporaryExposureKeyBatch, Task> processBatch)
        {
            region ??= DbTemporaryExposureKey.DefaultRegion;

            var keyCount = 0;

            using (var ctx = new ExposureNotificationContext(dbContextOptions))
                using (var transaction = ctx.Database.BeginTransaction())
                {
                    var keys = await ctx.TemporaryExposureKeys
                               .Where(k => k.Region == region && !k.Processed)
                               .OrderBy(k => k.TimestampMsSinceEpoch)
                               .Take(TemporaryExposureKeyBatches.MaxKeysPerFile)
                               .ToListAsync();

                    var exposureKeys = keys.Select(k => k.ToProtoKey());

                    keyCount = exposureKeys.Count();

                    var f = new TemporaryExposureKeyBatch
                    {
                        Header = new TemporaryExposureKeyBatchHeader
                        {
                            BatchNum       = batchNumber,
                            BatchSize      = keyCount,
                            StartTimestamp = keys.First().TimestampMsSinceEpoch,
                            EndTimestamp   = keys.Last().TimestampMsSinceEpoch,
                            Region         = region
                        }
                    };
                    f.Key.AddRange(exposureKeys);

                    await processBatch(f);

                    // Decide to delete keys or just mark them as processed
                    // Marking as processed is better
                    if (Startup.DeleteKeysFromDbAfterBatching)
                    {
                        ctx.TemporaryExposureKeys.RemoveRange(keys);
                    }
                    else
                    {
                        foreach (var k in keys)
                        {
                            k.Processed = true;
                        }
                    }

                    await ctx.SaveChangesAsync();

                    await transaction.CommitAsync();
                }

            return(keyCount);
        }
Exemple #6
0
        public ExposureNotificationStorage(
            Action <DbContextOptionsBuilder> buildDbContextOpetions = null,
            Action <DbContext> initializeDb = null)
        {
            var dbContextOptionsBuilder = new DbContextOptionsBuilder();

            buildDbContextOpetions?.Invoke(dbContextOptionsBuilder);
            dbContextOptions = dbContextOptionsBuilder.Options;

            using (var ctx = new ExposureNotificationContext(dbContextOptions))
                initializeDb?.Invoke(ctx);
        }
Exemple #7
0
        public async Task AddDiagnosisUidsAsync(IEnumerable <string> diagnosisUids)
        {
            using (var ctx = new ExposureNotificationContext(dbContextOptions))
            {
                foreach (var d in diagnosisUids)
                {
                    if (!(await ctx.Diagnoses.AnyAsync(r => r.DiagnosisUid == d)))
                    {
                        ctx.Diagnoses.Add(new DbDiagnosis(d));
                    }
                }

                await ctx.SaveChangesAsync();
            }
        }
Exemple #8
0
        public async Task RemoveDiagnosisUidsAsync(IEnumerable <string> diagnosisUids)
        {
            using (var ctx = new ExposureNotificationContext(dbContextOptions))
            {
                var toRemove = new List <DbDiagnosis>();

                foreach (var d in diagnosisUids)
                {
                    var existingUid = await ctx.Diagnoses.FindAsync(d);

                    if (existingUid != null)
                    {
                        toRemove.Add(existingUid);
                    }
                }

                ctx.Diagnoses.RemoveRange(toRemove);
                await ctx.SaveChangesAsync();
            }
        }
Exemple #9
0
        public async Task SubmitPositiveDiagnosisAsync(SelfDiagnosisSubmissionRequest diagnosis)
        {
            using (var ctx = new ExposureNotificationContext(dbContextOptions))
            {
                // Ensure the database contains the diagnosis uid
                if (!ctx.Diagnoses.Any(d => d.DiagnosisUid == diagnosis.DiagnosisUid))
                {
                    throw new InvalidOperationException();
                }

                var dbKeys = diagnosis.Keys.Select(k => DbTemporaryExposureKey.FromKey(k)).ToList();

                foreach (var dbk in dbKeys)
                {
                    ctx.TemporaryExposureKeys.Add(dbk);
                }

                await ctx.SaveChangesAsync();
            }
        }
Exemple #10
0
 public Task <bool> CheckIfDiagnosisUidExistsAsync(string diagnosisUid)
 {
     using (var ctx = new ExposureNotificationContext(dbContextOptions))
         return(Task.FromResult(ctx.Diagnoses.Any(d => d.DiagnosisUid.Equals(diagnosisUid))));
 }