Ejemplo n.º 1
0
        public virtual async Task <ActionResult> PublishPackage(string id, string version)
        {
            var package = PackageService.FindPackageByIdAndVersionStrict(id, version);

            if (package == null)
            {
                return(new HttpStatusCodeWithBodyResult(
                           HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version)));
            }

            // Check if the current user's scopes allow listing/unlisting the current package ID
            var apiScopeEvaluationResult = EvaluateApiScope(ActionsRequiringPermissions.UnlistOrRelistPackage, package.PackageRegistration, NuGetScopes.PackageUnlist);

            if (!apiScopeEvaluationResult.IsSuccessful())
            {
                return(GetHttpResultFromFailedApiScopeEvaluation(apiScopeEvaluationResult, id, version));
            }

            if (package.PackageRegistration.IsLocked)
            {
                return(new HttpStatusCodeWithBodyResult(
                           HttpStatusCode.Forbidden,
                           string.Format(CultureInfo.CurrentCulture, Strings.PackageIsLocked, package.PackageRegistration.Id)));
            }

            await PackageService.MarkPackageListedAsync(package);

            IndexingService.UpdatePackage(package);
            return(new EmptyResult());
        }
Ejemplo n.º 2
0
        public virtual async Task <ActionResult> PublishPackage(string id, string version)
        {
            var package = PackageService.FindPackageByIdAndVersionStrict(id, version);

            if (package == null)
            {
                return(new HttpStatusCodeWithBodyResult(
                           HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version)));
            }

            // Check if API key allows listing/unlisting the current package id
            User user = GetCurrentUser();

            if (!HasAnyScopeThatAllows(package.PackageRegistration, NuGetScopes.PackageUnlist))
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized));
            }

            if (package.PackageRegistration.IsLocked)
            {
                return(new HttpStatusCodeWithBodyResult(
                           HttpStatusCode.Forbidden,
                           string.Format(CultureInfo.CurrentCulture, Strings.PackageIsLocked, package.PackageRegistration.Id)));
            }

            await PackageService.MarkPackageListedAsync(package);

            IndexingService.UpdatePackage(package);
            return(new EmptyResult());
        }
Ejemplo n.º 3
0
        public virtual async Task <ActionResult> PublishPackage(string id, string version)
        {
            var package = PackageService.FindPackageByIdAndVersionStrict(id, version);

            if (package == null)
            {
                return(new HttpStatusCodeWithBodyResult(
                           HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version)));
            }

            User user = GetCurrentUser();

            if (!package.IsOwner(user))
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "publish")));
            }

            // Check if API key allows listing/unlisting the current package id
            if (!ApiKeyScopeAllows(
                    subject: id,
                    requestedActions: NuGetScopes.PackageUnlist))
            {
                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized));
            }

            await PackageService.MarkPackageListedAsync(package);

            IndexingService.UpdatePackage(package);
            return(new EmptyResult());
        }
Ejemplo n.º 4
0
        private async Task <ActionResult> CreatePackageInternal()
        {
            string       id      = null;
            NuGetVersion version = null;

            try
            {
                var policyResult = await SecurityPolicyService.EvaluateUserPoliciesAsync(SecurityPolicyAction.PackagePush, HttpContext);

                if (!policyResult.Success)
                {
                    return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, policyResult.ErrorMessage));
                }

                // Get the user
                var currentUser = GetCurrentUser();

                using (var packageStream = ReadPackageFromRequest())
                {
                    try
                    {
                        using (var archive = new ZipArchive(packageStream, ZipArchiveMode.Read, leaveOpen: true))
                        {
                            var reference = DateTime.UtcNow.AddDays(1); // allow "some" clock skew

                            var entryInTheFuture = archive.Entries.FirstOrDefault(
                                e => e.LastWriteTime.UtcDateTime > reference);

                            if (entryInTheFuture != null)
                            {
                                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                            CultureInfo.CurrentCulture,
                                                                            Strings.PackageEntryFromTheFuture,
                                                                            entryInTheFuture.Name)));
                            }
                        }

                        using (var packageToPush = new PackageArchiveReader(packageStream, leaveStreamOpen: false))
                        {
                            try
                            {
                                await PackageService.EnsureValid(packageToPush);
                            }
                            catch (Exception ex)
                            {
                                ex.Log();

                                var message = Strings.FailedToReadUploadFile;
                                if (ex is InvalidPackageException || ex is InvalidDataException || ex is EntityException)
                                {
                                    message = ex.Message;
                                }

                                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, message));
                            }

                            NuspecReader nuspec;
                            var          errors = ManifestValidator.Validate(packageToPush.GetNuspec(), out nuspec).ToArray();
                            if (errors.Length > 0)
                            {
                                var errorsString = string.Join("', '", errors.Select(error => error.ErrorMessage));
                                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                            CultureInfo.CurrentCulture,
                                                                            errors.Length > 1 ? Strings.UploadPackage_InvalidNuspecMultiple : Strings.UploadPackage_InvalidNuspec,
                                                                            errorsString)));
                            }

                            if (nuspec.GetMinClientVersion() > Constants.MaxSupportedMinClientVersion)
                            {
                                return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format(
                                                                            CultureInfo.CurrentCulture,
                                                                            Strings.UploadPackage_MinClientVersionOutOfRange,
                                                                            nuspec.GetMinClientVersion())));
                            }

                            User owner;

                            // Ensure that the user can push packages for this partialId.
                            id      = nuspec.GetId();
                            version = nuspec.GetVersion();
                            var packageRegistration = PackageService.FindPackageRegistrationById(id);
                            if (packageRegistration == null)
                            {
                                // Check if the current user's scopes allow pushing a new package ID
                                var apiScopeEvaluationResult = EvaluateApiScope(ActionsRequiringPermissions.UploadNewPackageId, new ActionOnNewPackageContext(id, ReservedNamespaceService), NuGetScopes.PackagePush);
                                owner = apiScopeEvaluationResult.Owner;
                                if (!apiScopeEvaluationResult.IsSuccessful())
                                {
                                    // User cannot push a new package ID as the current user's scopes does not allow it
                                    return(GetHttpResultFromFailedApiScopeEvaluationForPush(apiScopeEvaluationResult, id, version));
                                }
                            }
                            else
                            {
                                // Check if the current user's scopes allow pushing a new version of an existing package ID
                                var apiScopeEvaluationResult = EvaluateApiScope(ActionsRequiringPermissions.UploadNewPackageVersion, packageRegistration, NuGetScopes.PackagePushVersion, NuGetScopes.PackagePush);
                                owner = apiScopeEvaluationResult.Owner;
                                if (!apiScopeEvaluationResult.IsSuccessful())
                                {
                                    // User cannot push a package as the current user's scopes does not allow it
                                    await AuditingService.SaveAuditRecordAsync(
                                        new FailedAuthenticatedOperationAuditRecord(
                                            currentUser.Username,
                                            AuditedAuthenticatedOperationAction.PackagePushAttemptByNonOwner,
                                            attemptedPackage : new AuditedPackageIdentifier(
                                                id, version.ToNormalizedStringSafe())));

                                    return(GetHttpResultFromFailedApiScopeEvaluationForPush(apiScopeEvaluationResult, id, version));
                                }

                                if (packageRegistration.IsLocked)
                                {
                                    return(new HttpStatusCodeWithBodyResult(
                                               HttpStatusCode.Forbidden,
                                               string.Format(CultureInfo.CurrentCulture, Strings.PackageIsLocked, packageRegistration.Id)));
                                }

                                var nuspecVersion   = nuspec.GetVersion();
                                var existingPackage = PackageService.FindPackageByIdAndVersionStrict(nuspec.GetId(), nuspecVersion.ToStringSafe());
                                if (existingPackage != null)
                                {
                                    if (existingPackage.PackageStatusKey == PackageStatus.FailedValidation)
                                    {
                                        TelemetryService.TrackPackageReupload(existingPackage);

                                        await PackageDeleteService.HardDeletePackagesAsync(
                                            new[] { existingPackage },
                                            currentUser,
                                            Strings.FailedValidationHardDeleteReason,
                                            Strings.AutomatedPackageDeleteSignature,
                                            deleteEmptyPackageRegistration : false);
                                    }
                                    else
                                    {
                                        return(new HttpStatusCodeWithBodyResult(
                                                   HttpStatusCode.Conflict,
                                                   string.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified,
                                                                 id, nuspecVersion.ToNormalizedStringSafe())));
                                    }
                                }
                            }

                            var packageStreamMetadata = new PackageStreamMetadata
                            {
                                HashAlgorithm = CoreConstants.Sha512HashAlgorithmId,
                                Hash          = CryptographyService.GenerateHash(
                                    packageStream.AsSeekableStream(),
                                    CoreConstants.Sha512HashAlgorithmId),
                                Size = packageStream.Length
                            };

                            var package = await PackageUploadService.GeneratePackageAsync(
                                id,
                                packageToPush,
                                packageStreamMetadata,
                                owner,
                                currentUser);

                            await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false);

                            PackageCommitResult commitResult;
                            using (Stream uploadStream = packageStream)
                            {
                                uploadStream.Position = 0;
                                commitResult          = await PackageUploadService.CommitPackageAsync(
                                    package,
                                    uploadStream.AsSeekableStream());
                            }

                            switch (commitResult)
                            {
                            case PackageCommitResult.Success:
                                break;

                            case PackageCommitResult.Conflict:
                                return(new HttpStatusCodeWithBodyResult(
                                           HttpStatusCode.Conflict,
                                           Strings.UploadPackage_IdVersionConflict));

                            default:
                                throw new NotImplementedException($"The package commit result {commitResult} is not supported.");
                            }

                            IndexingService.UpdatePackage(package);

                            // Write an audit record
                            await AuditingService.SaveAuditRecordAsync(
                                new PackageAuditRecord(package, AuditedPackageAction.Create, PackageCreatedVia.Api));

                            if (!(ConfigurationService.Current.AsynchronousPackageValidationEnabled && ConfigurationService.Current.BlockingAsynchronousPackageValidationEnabled))
                            {
                                // Notify user of push unless async validation in blocking mode is used
                                MessageService.SendPackageAddedNotice(package,
                                                                      Url.Package(package.PackageRegistration.Id, package.NormalizedVersion, relativeUrl: false),
                                                                      Url.ReportPackage(package.PackageRegistration.Id, package.NormalizedVersion, relativeUrl: false),
                                                                      Url.AccountSettings(relativeUrl: false));
                            }

                            TelemetryService.TrackPackagePushEvent(package, currentUser, User.Identity);

                            if (package.SemVerLevelKey == SemVerLevelKey.SemVer2)
                            {
                                return(new HttpStatusCodeWithServerWarningResult(HttpStatusCode.Created, Strings.WarningSemVer2PackagePushed));
                            }

                            return(new HttpStatusCodeResult(HttpStatusCode.Created));
                        }
                    }
                    catch (InvalidPackageException ex)
                    {
                        return(BadRequestForExceptionMessage(ex));
                    }
                    catch (InvalidDataException ex)
                    {
                        return(BadRequestForExceptionMessage(ex));
                    }
                    catch (EntityException ex)
                    {
                        return(BadRequestForExceptionMessage(ex));
                    }
                    catch (FrameworkException ex)
                    {
                        return(BadRequestForExceptionMessage(ex));
                    }
                }
            }
            catch (HttpException ex) when(ex.IsMaxRequestLengthExceeded())
            {
                // ASP.NET throws HttpException when maxRequestLength limit is exceeded.
                return(new HttpStatusCodeWithBodyResult(
                           HttpStatusCode.RequestEntityTooLarge,
                           Strings.PackageFileTooLarge));
            }
            catch (Exception)
            {
                TelemetryService.TrackPackagePushFailureEvent(id, version);
                throw;
            }
        }