Esempio n. 1
0
        public string[] Validate(PostTeksArgs args)
        {
            if (args == null)
            {
                return new[] { "Null value." }
            }
            ;

            if (_Config.TemporaryExposureKeyCountMin > args.Keys.Length || args.Keys.Length > _Config.TemporaryExposureKeyCountMax) //TODO sensible but hi anti-spam, maximum - e.g. not 14
            {
                return new[] { $"Invalid number of keys - {args.Keys.Length}." }
            }
            ;

            var keyErrors = new List <string>();

            for (var i = 0; i < args.Keys.Length; i++)
            {
                keyErrors.AddRange(_TemporaryExposureKeyValidator.Valid(args.Keys[i]).Select(x => $"Key[{i}] - {x}"));
            }

            return(keyErrors.ToArray());
        }
    }
}
Esempio n. 2
0
        private async Task InnerExecute(byte[] signature, byte[] body)
        {
            _BodyBytes = body;

            if ((signature?.Length ?? 0) != _WorkflowConfig.PostKeysSignatureLength)
            {
                _Logger.WriteSignatureValidationFailed();
                return;
            }

            try
            {
                var argsJson = Encoding.UTF8.GetString(_BodyBytes);
                _ArgsObject = _JsonSerializer.Deserialize <PostTeksArgs>(argsJson);
            }
            catch (Exception e)
            {
                _Logger.WritePostBodyParsingFailed(e);
                return;
            }

            var base64Parser       = new Base64();
            var base64ParserResult = base64Parser.TryParseAndValidate(_ArgsObject.BucketId, _WorkflowConfig.BucketIdLength);

            if (!base64ParserResult.Valid)
            {
                _Logger.WriteBucketIdParsingFailed(_ArgsObject.BucketId, base64ParserResult.Messages);
                return;
            }

            _BucketIdBytes = base64ParserResult.Item;

            var messages = _KeyValidator.Validate(_ArgsObject);

            if (messages.Length > 0)
            {
                _Logger.WriteTekValidationFailed(messages);
                return;
            }

            var teks = _ArgsObject.Keys.Select(Mapper.MapToTek).ToArray();

            foreach (var i in teks)
            {
                i.PublishAfter = _DateTimeProvider.Snapshot;
            }

            messages = new TekListDuplicateValidator().Validate(teks);
            if (messages.Length > 0)
            {
                _Logger.WriteTekDuplicatesFound(messages);
                return;
            }

            //Validation ends, filtering starts

            var filterResult = _TekApplicableWindowFilter.Execute(teks);

            _Logger.WriteApplicableWindowFilterResult(filterResult.Messages);
            teks = filterResult.Items;
            _Logger.WriteValidTekCount(teks.Length);

            var workflow = _DbContext
                           .KeyReleaseWorkflowStates
                           .Include(x => x.Teks)
                           .SingleOrDefault(x => x.BucketId == _BucketIdBytes);

            if (workflow == null)
            {
                _Logger.WriteBucketDoesNotExist(_ArgsObject.BucketId);
                return;
            }

            if (!_SignatureValidator.Valid(signature, workflow.ConfirmationKey, _BodyBytes))
            {
                _Logger.WriteSignatureInvalid(workflow.BucketId, signature);
                return;
            }

            var filterResults = _TekListWorkflowFilter.Filter(teks, workflow);

            _Logger.WriteWorkflowFilterResults(filterResults.Messages);
            _Logger.WriteValidTekCountSecondPass(teks.Length);

            //Run after the filter removes the existing TEKs from the args.
            var allTeks = workflow.Teks.Select(Mapper.MapToTek).Concat(filterResults.Items).ToArray();

            messages = new TekListDuplicateKeyDataValidator().Validate(allTeks);
            if (messages.Length > 0)
            {
                _Logger.WriteTekDuplicatesFoundWholeWorkflow(messages);
                return;
            }

            _Logger.WriteDbWriteStart();
            var writeArgs = new TekWriteArgs
            {
                WorkflowStateEntityEntity = workflow,
                NewItems = filterResults.Items
            };

            await _Writer.Execute(writeArgs);

            _DbContext.SaveAndCommit();
            _Logger.WriteDbWriteCommitted();

            if (filterResults.Items.Length != 0)
            {
                _Logger.WriteTekCountAdded(filterResults.Items.Length);
            }
        }
        private async Task InnerExecute(byte[] signature, byte[] body)
        {
            _Logger.LogDebug("Signature received: {Signature}", signature);

            _BodyBytes = body;

            if ((signature?.Length ?? 0) != _WorkflowConfig.PostKeysSignatureLength)
            {
                _Logger.LogError("Signature is null or incorrect length.");
                return;
            }

            try
            {
                var argsJson = Encoding.UTF8.GetString(_BodyBytes);
                _Logger.LogDebug("Body -\n{ArgsJson}.", argsJson);
                _ArgsObject = _JsonSerializer.Deserialize <PostTeksArgs>(argsJson);
            }
            catch (Exception e)
            {
                _Logger.LogError("Error reading body -\n{E}", e.ToString());
                return;
            }

            var base64Parser       = new Base64();
            var base64ParserResult = base64Parser.TryParseAndValidate(_ArgsObject.BucketId, _WorkflowConfig.BucketIdLength);

            if (!base64ParserResult.Valid)
            {
                _Logger.LogValidationMessages(base64ParserResult.Messages.Select(x => $"BuckedId - {x}").ToArray());
                return;
            }

            _BucketIdBytes = base64ParserResult.Item;

            if (_Logger.LogValidationMessages(_KeyValidator.Validate(_ArgsObject)))
            {
                return;
            }

            var teks = _ArgsObject.Keys.Select(Mapper.MapToTek).ToArray();

            foreach (var i in teks)
            {
                i.PublishAfter = _DateTimeProvider.Snapshot;
            }

            if (_Logger.LogValidationMessages(new TekListDuplicateValidator().Validate(teks)))
            {
                return;
            }

            //Validation ends, filtering starts

            var filterResult = _TekApplicableWindowFilter.Execute(teks);

            teks = filterResult.Items;
            _Logger.LogFilterMessages(filterResult.Messages);
            _Logger.LogInformation("TEKs remaining - Count:{count}.", teks.Length);

            var workflow = _DbContext
                           .KeyReleaseWorkflowStates
                           .Include(x => x.Teks)
                           .SingleOrDefault(x => x.BucketId == _BucketIdBytes);

            if (workflow == null)
            {
                _Logger.LogError("Workflow does not exist - {BucketId}.", _ArgsObject.BucketId);
                return;
            }

            if (!_SignatureValidator.Valid(signature, workflow.ConfirmationKey, _BodyBytes))
            {
                _Logger.LogError("Signature not valid: {Signature}", signature);
                return;
            }

            var filterResults = _TekListWorkflowFilter.Filter(teks, workflow);

            _Logger.LogFilterMessages(filterResults.Messages);
            _Logger.LogInformation("TEKs remaining - Count:{count}.", teks.Length);

            //Run after the filter removes the existing TEKs from the args.
            var allTeks = workflow.Teks.Select(Mapper.MapToTek).Concat(filterResults.Items).ToArray();

            if (_Logger.LogValidationMessages(new TekListDuplicateKeyDataValidator().Validate(allTeks)))
            {
                return;
            }

            _Logger.LogDebug("Writing.");
            var writeArgs = new TekWriteArgs
            {
                WorkflowStateEntityEntity = workflow,
                NewItems = filterResults.Items
            };

            await _Writer.Execute(writeArgs);

            _DbContext.SaveAndCommit();
            _Logger.LogDebug("Committed.");

            if (filterResults.Items.Length != 0)
            {
                _Logger.LogInformation("Teks added - Count:{FilterResultsLength}.", filterResults.Items.Length);
            }
        }