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

            if (_Config.TemporaryExposureKeyCountMin > args.Keys.Length || args.Keys.Length > _Config.TemporaryExposureKeyCountMax)
            {
                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());
        }
    }
}
Beispiel #2
0
        private async Task InnerExecuteAsync(byte[] signature, byte[] body)
        {
            _bodyBytes = body;

            if ((signature?.Length ?? 0) != UniversalConstants.PostKeysSignatureByteCount)
            {
                _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, UniversalConstants.BucketIdByteCount);

            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.ExecuteAsync(writeArgs);

            _dbContext.SaveAndCommit();
            _logger.WriteDbWriteCommitted();

            if (filterResults.Items.Length != 0)
            {
                _logger.WriteTekCountAdded(filterResults.Items.Length);
            }
        }