Ejemplo n.º 1
0
        public async Task <string> GetPackageHashAsync(
            PackageSource source,
            PackageIdentity package,
            string hashAlgorithmId,
            CancellationToken token)
        {
            if (source.Type != PackageSourceType.PackagesContainer)
            {
                throw new NotSupportedException($"Only the package source type {PackageSourceType.PackagesContainer} is supported.");
            }

            var id         = package.Id.ToLowerInvariant();
            var version    = package.Version.ToNormalizedString().ToLowerInvariant();
            var packageUri = new Uri($"{source.Url.TrimEnd('/')}/{id}.{version}.nupkg");

            using (var packageStream = await _packageDownloader.DownloadAsync(packageUri, token))
            {
                return(CryptographyService.GenerateHash(packageStream, hashAlgorithmId));
            }
        }
Ejemplo n.º 2
0
        private async Task <bool> TryIndexFromSourceAsync(string id, NuGetVersion version)
        {
            var idString      = id.ToLowerInvariant();
            var versionString = version.ToNormalizedString().ToLowerInvariant();

            _logger.LogInformation(
                "Attempting to index package {Id} {Version} from upstream source...",
                idString,
                versionString);

            try
            {
                // See https://github.com/NuGet/NuGet.Client/blob/4eed67e7e159796ae486d2cca406b283e23b6ac8/src/NuGet.Core/NuGet.Protocol/Resources/DownloadResourceV3.cs#L82
                var packageUri = new Uri(_packageBaseAddress, $"{idString}/{versionString}/{idString}.{versionString}.nupkg");

                // TODO: DownloadAsync throws when the package doesn't exist. This could be cleaner.
                using (var stream = await _downloader.DownloadAsync(packageUri, CancellationToken.None))
                {
                    _logger.LogInformation(
                        "Downloaded package {Id} {Version}, indexing...",
                        idString,
                        versionString);

                    var indexingResult = await _indexer.IndexAsync(stream);

                    switch (indexingResult)
                    {
                    case IndexingResult.InvalidPackage:
                        _logger.LogWarning(
                            "Could not index {Id} {Version} as it is an invalid package",
                            idString,
                            versionString);

                        return(false);

                    case IndexingResult.Success:
                    case IndexingResult.PackageAlreadyExists:
                        _logger.LogInformation(
                            "Successfully indexed {Id} {Version}",
                            idString,
                            versionString);

                        return(true);

                    default:
                        _logger.LogError(
                            "Unknown indexing result for {Id} {Version}: {IndexingResult}",
                            idString,
                            versionString,
                            indexingResult);

                        throw new InvalidOperationException($"Unknown indexing result: {indexingResult}");
                    }
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Failed to index package {Id} {Version}", idString, versionString);

                return(false);
            }
        }
Ejemplo n.º 3
0
        public async Task <Stream> DownloadPackageFileToDiskAsync(Package package)
        {
            var packageUri = await GetPackageReadUriAsync(package);

            return(await _packageDownloader.DownloadAsync(packageUri, CancellationToken.None));
        }
        private async Task <bool> HandleAsync(SignatureValidationMessage message, CancellationToken cancellationToken)
        {
            using (_logger.BeginScope("Handling signature validation message for package {PackageId} {PackageVersion}, validation {ValidationId}",
                                      message.PackageId,
                                      message.PackageVersion,
                                      message.ValidationId))
            {
                // Find the signature validation entity that matches this message.
                var validation = await _validatorStateService.GetStatusAsync(message.ValidationId);

                // A signature validation should be queued with ValidatorState == Incomplete.
                if (validation == null)
                {
                    _logger.LogInformation(
                        "Could not find validation entity, requeueing (package: {PackageId} {PackageVersion}, validationId: {ValidationId})",
                        message.PackageId,
                        message.PackageVersion,
                        message.ValidationId);

                    // Message may be retried.
                    return(false);
                }
                else if (validation.State == ValidationStatus.NotStarted)
                {
                    _logger.LogWarning(
                        "Unexpected signature verification status '{ValidatorState}' when 'Incomplete' was expected, requeueing (package id: {PackageId} package version: {PackageVersion} validation id: {ValidationId})",
                        validation.State,
                        message.PackageId,
                        message.PackageVersion,
                        message.ValidationId);

                    // Message may be retried.
                    return(false);
                }
                else if (validation.State != ValidationStatus.Incomplete)
                {
                    _logger.LogWarning(
                        "Terminal signature verification status '{ValidatorState}' when 'Incomplete' was expected, dropping message (package id: {PackageId} package version: {PackageVersion} validation id: {ValidationId})",
                        validation.State,
                        message.PackageId,
                        message.PackageVersion,
                        message.ValidationId);

                    // Consume the message.
                    return(true);
                }

                // Validate package
                using (var packageStream = await _packageDownloader.DownloadAsync(message.NupkgUri, cancellationToken))
                {
                    var result = await _signatureValidator.ValidateAsync(
                        validation.PackageKey,
                        packageStream,
                        message,
                        cancellationToken);

                    validation.State = result.State;

                    // Save any issues if the resulting state is terminal.
                    if (validation.State == ValidationStatus.Failed ||
                        validation.State == ValidationStatus.Succeeded)
                    {
                        validation.ValidatorIssues = validation.ValidatorIssues ?? new List <ValidatorIssue>();
                        foreach (var issue in result.Issues)
                        {
                            validation.ValidatorIssues.Add(new ValidatorIssue
                            {
                                IssueCode = issue.IssueCode,
                                Data      = issue.Serialize(),
                            });
                        }
                    }

                    // Save the .nupkg URL if the resulting state is successful.
                    if (validation.State == ValidationStatus.Succeeded &&
                        result.NupkgUri != null)
                    {
                        validation.NupkgUrl = result.NupkgUri.AbsoluteUri;
                    }
                }

                // The signature validator should do all of the work to bring this validation to its completion.
                if (validation.State != ValidationStatus.Succeeded &&
                    validation.State != ValidationStatus.Failed)
                {
                    _logger.LogError("The signature validator should have set the status 'Succeeded' or 'Failed', not " +
                                     "'{ValidatorState}' (package id: {PackageId} package version: {PackageVersion} validation id: {ValidationId})",
                                     validation.State,
                                     message.PackageId,
                                     message.PackageVersion,
                                     message.ValidationId);

                    return(false);
                }

                // Save the resulting validation status.
                return(await SaveStatusAsync(validation, message));
            }
        }