private async Task <ActionResult> CreatePackageInternal() { // Get the user var user = GetCurrentUser(); using (var packageToPush = ReadPackageFromRequest()) { if (packageToPush.Metadata.MinClientVersion > typeof(Manifest).Assembly.GetName().Version) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, String.Format( CultureInfo.CurrentCulture, Strings.UploadPackage_MinClientVersionOutOfRange, packageToPush.Metadata.MinClientVersion))); } // Ensure that the user can push packages for this partialId. var packageRegistration = PackageService.FindPackageRegistrationById(packageToPush.Metadata.Id); if (packageRegistration != null) { if (!packageRegistration.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } // Check if a particular Id-Version combination already exists. We eventually need to remove this check. string normalizedVersion = packageToPush.Metadata.Version.ToNormalizedString(); bool packageExists = packageRegistration.Packages.Any( p => String.Equals( p.NormalizedVersion, normalizedVersion, StringComparison.OrdinalIgnoreCase)); if (packageExists) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Conflict, String.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified, packageToPush.Metadata.Id, packageToPush.Metadata.Version.ToNormalizedStringSafe()))); } } var package = PackageService.CreatePackage(packageToPush, user, commitChanges: false); AutoCuratePackage.Execute(package, packageToPush, commitChanges: false); EntitiesContext.SaveChanges(); using (Stream uploadStream = packageToPush.GetStream()) { await PackageFileService.SavePackageFileAsync(package, uploadStream); } } return(new HttpStatusCodeResult(HttpStatusCode.Created)); }
private async Task <ActionResult> CreatePackageInternal() { // Get the user var user = GetCurrentUser(); using (var packageToPush = ReadPackageFromRequest()) { // Ensure that the user can push packages for this partialId. var packageRegistration = PackageService.FindPackageRegistrationById(packageToPush.Metadata.Id); if (packageRegistration != null) { if (!packageRegistration.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } // Check if a particular Id-Version combination already exists. We eventually need to remove this check. string normalizedVersion = packageToPush.Metadata.Version.ToNormalizedString(); bool packageExists = packageRegistration.Packages.Any( p => String.Equals( p.NormalizedVersion, normalizedVersion, StringComparison.OrdinalIgnoreCase)); if (packageExists) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Conflict, String.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified, packageToPush.Metadata.Id, packageToPush.Metadata.Version.ToNormalizedStringSafe()))); } } var package = PackageService.CreatePackage(packageToPush, user, commitChanges: true); using (Stream uploadStream = packageToPush.GetStream()) { await PackageFileService.SavePackageFileAsync(package, uploadStream); } if ( packageToPush.Metadata.Id.Equals(Constants.NuGetCommandLinePackageId, StringComparison.OrdinalIgnoreCase) && package.IsLatestStable) { // If we're pushing a new stable version of NuGet.CommandLine, update the extracted executable. await NugetExeDownloaderService.UpdateExecutableAsync(packageToPush); } } return(new HttpStatusCodeResult(HttpStatusCode.Created)); }
private async Task <ActionResult> CreatePackageInternal() { // Get the user var user = 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)) { NuspecReader nuspec = null; try { nuspec = packageToPush.GetNuspecReader(); } catch (Exception ex) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, Strings.UploadPackage_InvalidNuspec, ex.Message))); } if (nuspec.GetMinClientVersion() > Constants.MaxSupportedMinClientVersion) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, Strings.UploadPackage_MinClientVersionOutOfRange, nuspec.GetMinClientVersion()))); } // Ensure that the user can push packages for this partialId. var packageRegistration = PackageService.FindPackageRegistrationById(nuspec.GetId()); if (packageRegistration != null) { if (!packageRegistration.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } // Check if a particular Id-Version combination already exists. We eventually need to remove this check. string normalizedVersion = nuspec.GetVersion().ToNormalizedString(); bool packageExists = packageRegistration.Packages.Any( p => String.Equals( p.NormalizedVersion, normalizedVersion, StringComparison.OrdinalIgnoreCase)); if (packageExists) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Conflict, String.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified, nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe()))); } } var packageStreamMetadata = new PackageStreamMetadata { HashAlgorithm = Constants.Sha512HashAlgorithmId, Hash = CryptographyService.GenerateHash(packageStream.AsSeekableStream()), Size = packageStream.Length, }; var package = await PackageService.CreatePackageAsync( packageToPush, packageStreamMetadata, user, commitChanges : false); await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false); await EntitiesContext.SaveChangesAsync(); using (Stream uploadStream = packageStream) { uploadStream.Position = 0; await PackageFileService.SavePackageFileAsync(package, uploadStream.AsSeekableStream()); IndexingService.UpdatePackage(package); } MessageService.SendPackageAddedNotice(package, Url.Action("DisplayPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.Version }, protocol: Request.Url.Scheme), Url.Action("ReportMyPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.Version }, protocol: Request.Url.Scheme), Url.Action("Account", "Users", routeValues: null, protocol: Request.Url.Scheme)); 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)); } } }
private async Task <ActionResult> CreatePackageInternal() { // Get the user var user = GetCurrentUser(); using (var packageStream = ReadPackageFromRequest()) { try { using (var packageToPush = new PackageArchiveReader(packageStream, leaveStreamOpen: false)) { NuspecReader nuspec = null; try { nuspec = packageToPush.GetNuspecReader(); } catch (Exception ex) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, Strings.UploadPackage_InvalidNuspec, ex.Message))); } if (nuspec.GetMinClientVersion() > Constants.MaxSupportedMinClientVersion) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, string.Format( CultureInfo.CurrentCulture, Strings.UploadPackage_MinClientVersionOutOfRange, nuspec.GetMinClientVersion()))); } // Ensure that the user can push packages for this partialId. var packageRegistration = PackageService.FindPackageRegistrationById(nuspec.GetId()); if (packageRegistration != null) { if (!packageRegistration.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } // Check if a particular Id-Version combination already exists. We eventually need to remove this check. string normalizedVersion = nuspec.GetVersion().ToNormalizedString(); bool packageExists = packageRegistration.Packages.Any( p => String.Equals( p.NormalizedVersion, normalizedVersion, StringComparison.OrdinalIgnoreCase)); if (packageExists) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Conflict, String.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified, nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe()))); } } var packageStreamMetadata = new PackageStreamMetadata { HashAlgorithm = Constants.Sha512HashAlgorithmId, Hash = CryptographyService.GenerateHash(packageStream.AsSeekableStream()), Size = packageStream.Length, }; var package = await PackageService.CreatePackageAsync(packageToPush, packageStreamMetadata, user, commitChanges : false); await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false); await EntitiesContext.SaveChangesAsync(); using (Stream uploadStream = packageStream) { uploadStream.Position = 0; await PackageFileService.SavePackageFileAsync(package, uploadStream.AsSeekableStream()); IndexingService.UpdatePackage(package); } return(new HttpStatusCodeResult(HttpStatusCode.Created)); } } catch (InvalidDataException ex) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.BadRequest, string.Format(CultureInfo.CurrentCulture, Strings.UploadPackage_InvalidPackage, ex.Message))); } } }
private async Task <ActionResult> CreatePackageInternal() { // Get the user var user = 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 { 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()))); } // Ensure that the user can push packages for this partialId. var packageRegistration = PackageService.FindPackageRegistrationById(nuspec.GetId()); if (packageRegistration == null) { // Check if API key allows pushing a new package id if (!ApiKeyScopeAllows( subject: nuspec.GetId(), requestedActions: NuGetScopes.PackagePush)) { // User cannot push a new package ID as the API key scope does not allow it return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Unauthorized, Strings.ApiKeyNotAuthorized)); } } else { // Is the user allowed to push this Id? if (!packageRegistration.IsOwner(user)) { // Audit that a non-owner tried to push the package await AuditingService.SaveAuditRecord( new FailedAuthenticatedOperationAuditRecord( user.Username, AuditedAuthenticatedOperationAction.PackagePushAttemptByNonOwner, attemptedPackage : new AuditedPackageIdentifier( nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe()))); // User cannot push a package to an ID owned by another user. return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Conflict, string.Format(CultureInfo.CurrentCulture, Strings.PackageIdNotAvailable, nuspec.GetId()))); } // Check if API key allows pushing the current package id if (!ApiKeyScopeAllows( packageRegistration.Id, NuGetScopes.PackagePushVersion, NuGetScopes.PackagePush)) { // User cannot push a package as the API key scope does not allow it return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Unauthorized, Strings.ApiKeyNotAuthorized)); } // Check if a particular Id-Version combination already exists. We eventually need to remove this check. string normalizedVersion = nuspec.GetVersion().ToNormalizedString(); bool packageExists = packageRegistration.Packages.Any( p => string.Equals( p.NormalizedVersion, normalizedVersion, StringComparison.OrdinalIgnoreCase)); if (packageExists) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Conflict, string.Format(CultureInfo.CurrentCulture, Strings.PackageExistsAndCannotBeModified, nuspec.GetId(), nuspec.GetVersion().ToNormalizedStringSafe()))); } } var packageStreamMetadata = new PackageStreamMetadata { HashAlgorithm = Constants.Sha512HashAlgorithmId, Hash = CryptographyService.GenerateHash(packageStream.AsSeekableStream()), Size = packageStream.Length }; var package = await PackageService.CreatePackageAsync( packageToPush, packageStreamMetadata, user, commitChanges : false); await AutoCuratePackage.ExecuteAsync(package, packageToPush, commitChanges : false); using (Stream uploadStream = packageStream) { uploadStream.Position = 0; try { await PackageFileService.SavePackageFileAsync(package, uploadStream.AsSeekableStream()); } catch (InvalidOperationException ex) { ex.Log(); return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Conflict, Strings.UploadPackage_IdVersionConflict)); } } try { await EntitiesContext.SaveChangesAsync(); } catch { // If saving to the DB fails for any reason, we need to delete the package we just saved. await PackageFileService.DeletePackageFileAsync(nuspec.GetId(), nuspec.GetVersion().ToNormalizedString()); throw; } IndexingService.UpdatePackage(package); // Write an audit record await AuditingService.SaveAuditRecord( new PackageAuditRecord(package, AuditedPackageAction.Create, PackageCreatedVia.Api)); // Notify user of push MessageService.SendPackageAddedNotice(package, Url.Action("DisplayPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.Version }, protocol: Request.Url.Scheme), Url.Action("ReportMyPackage", "Packages", routeValues: new { id = package.PackageRegistration.Id, version = package.Version }, protocol: Request.Url.Scheme), Url.Action("Account", "Users", routeValues: null, protocol: Request.Url.Scheme)); 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)); } } }