Exemplo n.º 1
0
        protected override async Task Handle(CreatePresenceCheckCommand request, CancellationToken cancellationToken)
        {
            var now      = DateTime.UtcNow;
            var profiles = await repository.GetProfilesByCovidPassAsync(request.CovidPass, cancellationToken);

            if (!profiles.Any())
            {
                throw new DomainException($"No profiles found with {nameof(request.CovidPass)}: '{request.CovidPass}'");
            }

            foreach (var profile in profiles)
            {
                // meeting notes - always create presente check

                //var activeCheck = await context.PresenceChecks.AsNoTracking()
                //    .Where(x => x.ProfileId == profile.Id && now < x.DeadLineCheck
                //        && x.Status != PresenceCheckStatus.OK)
                //    .ToListAsync(cancellationToken);

                if (profile.ActiveQuarantine(now))
                {
                    var check = new PresenceCheck(profile.Id, now, now.Add(request.DeadLineTime), request.Status);
                    profile.AddPresenceCheck(check);
                }
            }

            await context.SaveChangesAsync(cancellationToken);
        }
        protected override async Task Handle(VerifyProfileCommand request, CancellationToken cancellationToken)
        {
            var profile = await repository.GetProfileAsync(request.ProfileId, request.DeviceId, cancellationToken);

            if (profile == null)
            {
                throw new DomainException("Profile not found");
            }

            var now   = DateTime.UtcNow;
            var nonce = await context.PushNonces.SingleOrDefaultAsync(x => x.Id == profile.PushToken &&
                                                                      x.ExpiredOn > DateTime.UtcNow, cancellationToken);

            if (nonce?.Body != request.Nonce)
            {
                throw new DomainException("Nonce not found or expired");
            }

            if (profile.ClientInfo.OperationSystem == Platform.Android)
            {
                var attestation = androidAttestation.ParseAndVerify(request.SignedAttestationStatement);

                if (attestation == null)
                {
                    throw new DomainException("Device isn't attested");
                }
            }

            profile.AssignCovidPass(request.CovidPass);
            profile.AssignPublicKey(request.PublicKey);
            profile.Verify();

            await context.SaveChangesAsync(cancellationToken);
        }
        public async Task <PushNonce> Handle(GeneratePushNonceCommand request, CancellationToken cancellationToken)
        {
            var profile = await repository.GetProfileAsync(request.ProfileId, request.DeviceId, cancellationToken);

            if (profile == null)
            {
                throw new DomainException("Profile not found");
            }

            if (string.IsNullOrEmpty(profile.PushToken))
            {
                throw new DomainException("Push token is required please update profile");
            }

            var instanceInfo = await instanceIdService.GetInstanceInfoAsync(profile.PushToken, cancellationToken);

            if (instanceInfo == null)
            {
                throw new DomainException("Push token is invalid");
            }

            if (instanceInfo.Platform != profile.ClientInfo.OperationSystem || instanceInfo.Application != profile.ClientInfo.Integrator)
            {
                throw new DomainException("Push token is invalid or from wrong platform");
            }

            var pushNonce = await context.PushNonces.SingleOrDefaultAsync(x => x.Id == profile.PushToken, cancellationToken);

            if (pushNonce != null)
            {
                pushNonce.Update(nonceGenerator.Generate(), DateTime.UtcNow, DateTime.UtcNow.Add(request.TokenExpiration));
            }
            else
            {
                pushNonce = new PushNonce(profile.PushToken, nonceGenerator.Generate(), DateTime.UtcNow, DateTime.UtcNow.Add(request.TokenExpiration));
                await context.PushNonces.AddAsync(pushNonce, cancellationToken);
            }

            await context.SaveChangesAsync(cancellationToken);

            var message = new Notification
            {
                Data = new Dictionary <string, object>
                {
                    { "type", "PUSH_NONCE" },
                    { "Nonce", pushNonce.Body }
                },
                Priority         = "high",
                ContentAvailable = true
            };
            var sendNonceCommand = new SendPushNotificationCommand(profile.Id, message);
            await mediator.Send(sendNonceCommand, cancellationToken);

            return(pushNonce);
        }
Exemplo n.º 4
0
        protected override async Task Handle(DeleteLocationsFromContactsCommand request, CancellationToken cancellationToken)
        {
            var contactsWithLocations = await context.Contacts
                                        .Where(x => x.Latitude != null || x.Longitude != null)
                                        .ToListAsync(cancellationToken);

            foreach (var contact in contactsWithLocations)
            {
                contact.ClearLocation();
            }

            await context.SaveChangesAsync(cancellationToken);
        }
Exemplo n.º 5
0
        public static async Task SaveVirusInfoAsync(string virusInfo)
        {
            CoronaContext context = new CoronaContext();

            context.Database.EnsureCreated();
            CoronaVirusSummary coronaVirusSummary = await context.CoronaVirusSummaries.SingleOrDefaultAsync(x => x.Date == DateTime.Today, new CancellationToken());

            if (coronaVirusSummary == null)
            {
                context.CoronaVirusSummaries.Add(new CoronaVirusSummary()
                {
                    Date      = DateTime.Today,
                    VirusInfo = virusInfo
                });
                int num = await context.SaveChangesAsync(new CancellationToken());
            }
            else
            {
                coronaVirusSummary.VirusInfo = virusInfo;
                int num = await context.SaveChangesAsync(new CancellationToken());
            }
        }
Exemplo n.º 6
0
        protected override async Task Handle(ConvertContactsTimestampCommand request, CancellationToken cancellationToken)
        {
            var contacts = await context.Contacts.ToListAsync(cancellationToken);

            foreach (var contact in contacts)
            {
                if (contact.Timestamp.HasValue)
                {
                    var creationDate = convertService.UnixTimeStampToDateTime(contact.Timestamp.Value).Date;
                    contact.SetCreationDate(creationDate);
                }
            }

            await context.SaveChangesAsync(cancellationToken);
        }
        protected override async Task Handle(DeleteOldProfilesCommand request, CancellationToken cancellationToken)
        {
            var treshold = DateTime.UtcNow.Add(-request.Interval);

            var expiredProfiles = await context.Profiles
                                  .Where(x => x.CreatedOn.HasValue && x.CreatedOn.Value <= treshold)
                                  .ToListAsync(cancellationToken);

            if (expiredProfiles.Any())
            {
                var builder = new StringBuilder();
                expiredProfiles.ForEach(x => builder.Append($"{x.CovidPass};"));
                log.LogInformation($"deleting profiles with covid passes {builder}");

                context.Profiles.RemoveRange(expiredProfiles);
                await context.SaveChangesAsync(cancellationToken);
            }
        }
        protected override async Task Handle(UpdatePresenceCheckCommand request, CancellationToken cancellationToken)
        {
            var profile = await repository.GetProfileAsync(request.ProfileId, request.DeviceId, request.CovidPass, cancellationToken);

            if (profile == null)
            {
                throw new DomainException("Profile not found");
            }
            var nonceQuery = new RetrieveNonceQuery(profile.CovidPass);
            var nonceCache = await mediator.Send(nonceQuery, cancellationToken);

            if (nonceCache == null)
            {
                throw new DomainException("Invalid nonce");
            }

            if (nonceCache.Nonce != request.Nonce)
            {
                throw new DomainException("Invalid nonce");
            }

            var now = DateTime.UtcNow;
            var pendingSuspectedPresenceCheck = await context.PresenceChecks
                                                .Where(x => x.ProfileId == profile.Id)
                                                .Where(x => x.Status == PresenceCheckStatus.SUSPECTED)
                                                .Where(x => x.CreatedOn <= now && now <= x.DeadLineCheck)
                                                .FirstOrDefaultAsync(cancellationToken);

            if (pendingSuspectedPresenceCheck == null)
            {
                throw new DomainException("There is no active check for given covid pass");
            }

            var newStatus = request.Status switch
            {
                Contracts.Requests.PresenceCheckStatus.OK => PresenceCheckStatus.OK,
                Contracts.Requests.PresenceCheckStatus.LEFT => PresenceCheckStatus.LEFT,
                _ => PresenceCheckStatus.SUSPECTED
            };

            pendingSuspectedPresenceCheck.UpdateStatus(newStatus);
            await context.SaveChangesAsync(cancellationToken);
        }
    }
        protected override async Task Handle(VerifyProfileCommand request, CancellationToken cancellationToken)
        {
            var profile = await repository.GetProfileAsync(request.ProfileId, request.DeviceId, cancellationToken);

            if (profile == null)
            {
                throw new DomainException("Profile not found");
            }

            var now   = DateTime.UtcNow;
            var nonce = await context.PushNonces.SingleOrDefaultAsync(x => x.Id == profile.PushToken &&
                                                                      x.ExpiredOn > DateTime.UtcNow, cancellationToken);

            if (nonce?.Body != request.Nonce)
            {
                throw new DomainException("Nonce not found or expired");
            }

            if (profile.ClientInfo.OperationSystem == Platform.Android)
            {
                var attestation = androidAttestation.ParseAndVerify(request.SignedAttestationStatement);

                if (attestation == null || !attestation.BasicIntegrity || !attestation.CtsProfileMatch)
                {
                    throw new DomainException("Device isn't attested");
                }
                var certDigest = new byte[] { 0x80, 0xc0, 0xdc, 0x5c, 0x6f, 0x43, 0xd4, 0x97, 0xc4, 0x5a, 0xed, 0x7e, 0x36, 0x98, 0x8a, 0xbe, 0x48, 0xd5, 0xfd, 0xcc, 0xbb, 0xfa, 0xbb, 0xbf, 0x87, 0x86, 0x93, 0x1e, 0x59, 0xdd, 0x1d, 0xaf };
                if (attestation.ApkPackageName != "sk.nczi.ekarantena" || !certDigest.SequenceEqual(attestation.ApkCertificateDigestSha256))
                {
                    throw new DomainException("Device is not using the legitimate app");
                }
            }

            profile.AssignCovidPass(request.CovidPass);
            profile.AssignPublicKey(request.PublicKey);
            profile.Verify();

            await context.SaveChangesAsync(cancellationToken);
        }
 protected override async Task Handle(DeleteExposureKeysCommand request, CancellationToken cancellationToken)
 {
     context.ExposureKeys.RemoveRange(request.ExposureKeys);
     await context.SaveChangesAsync(cancellationToken);
 }