public ApiController( IEntitiesContext entitiesContext, IPackageService packageService, IPackageFileService packageFileService, IUserService userService, INuGetExeDownloaderService nugetExeDownloaderService, IContentService contentService, IIndexingService indexingService, ISearchService searchService, IAutomaticallyCuratePackageCommand autoCuratePackage, IStatusService statusService, IMessageService messageService, AuditingService auditingService, IGalleryConfigurationService configurationService) { EntitiesContext = entitiesContext; PackageService = packageService; PackageFileService = packageFileService; UserService = userService; NugetExeDownloaderService = nugetExeDownloaderService; ContentService = contentService; StatisticsService = null; IndexingService = indexingService; SearchService = searchService; AutoCuratePackage = autoCuratePackage; StatusService = statusService; MessageService = messageService; AuditingService = auditingService; ConfigurationService = configurationService; }
private async Task <HttpStatusCodeWithBodyResult> VerifyPackageKeyInternalAsync(User user, Credential credential, string id, string version) { // Verify that the user has permission to push for the specific Id \ version combination. var package = PackageService.FindPackageByIdAndVersion(id, version, semVerLevelKey: SemVerLevelKey.SemVer2); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } // Write an audit record await AuditingService.SaveAuditRecordAsync( new PackageAuditRecord(package, AuditedPackageAction.Verify)); string[] requestedActions; if (CredentialTypes.IsPackageVerificationApiKey(credential.Type)) { requestedActions = new[] { NuGetScopes.PackageVerify }; } else { requestedActions = new[] { NuGetScopes.PackagePush, NuGetScopes.PackagePushVersion }; } var apiScopeEvaluationResult = EvaluateApiScope(ActionsRequiringPermissions.VerifyPackage, package.PackageRegistration, requestedActions); if (!apiScopeEvaluationResult.IsSuccessful()) { return(GetHttpResultFromFailedApiScopeEvaluation(apiScopeEvaluationResult, id, version)); } return(null); }
private async Task <HttpStatusCodeWithBodyResult> VerifyPackageKeyInternalAsync(User user, Credential credential, string id, string version) { // Verify that the user has permission to push for the specific Id \ version combination. var package = PackageService.FindPackageByIdAndVersion(id, version, semVerLevelKey: SemVerLevelKey.SemVer2); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } // Write an audit record await AuditingService.SaveAuditRecordAsync( new PackageAuditRecord(package, AuditedPackageAction.Verify)); if (CredentialTypes.IsPackageVerificationApiKey(credential.Type)) { // Secure path: verify that verification key matches package scope. if (!HasAnyScopeThatAllows(package.PackageRegistration, NuGetScopes.PackageVerify)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } } else { // Insecure path: verify that API key is legacy or matches package scope. if (!HasAnyScopeThatAllows(package.PackageRegistration, NuGetScopes.PackagePush, NuGetScopes.PackagePushVersion)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } } return(null); }
public AuthenticationService( IEntitiesContext entities, IAppConfiguration config, IDiagnosticsService diagnostics, AuditingService auditing, IEnumerable <Authenticator> providers, ICredentialBuilder credentialBuilder, ICredentialValidator credentialValidator, IDateTimeProvider dateTimeProvider) { if (entities == null) { throw new ArgumentNullException(nameof(entities)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } if (diagnostics == null) { throw new ArgumentNullException(nameof(diagnostics)); } if (auditing == null) { throw new ArgumentNullException(nameof(auditing)); } if (providers == null) { throw new ArgumentNullException(nameof(providers)); } if (credentialBuilder == null) { throw new ArgumentNullException(nameof(credentialBuilder)); } if (credentialValidator == null) { throw new ArgumentNullException(nameof(credentialValidator)); } if (dateTimeProvider == null) { throw new ArgumentNullException(nameof(dateTimeProvider)); } InitCredentialFormatters(); Entities = entities; _config = config; Auditing = auditing; _trace = diagnostics.SafeGetSource("AuthenticationService"); Authenticators = providers.ToDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase); _credentialBuilder = credentialBuilder; _credentialValidator = credentialValidator; _dateTimeProvider = dateTimeProvider; }
public static bool WroteRecord <T>(this AuditingService self, Func <T, bool> predicate) where T : AuditRecord { TestAuditingService testService = self as TestAuditingService; if (testService != null) { return(testService.Records.OfType <T>().Any(predicate)); } return(false); }
public UserService( IAppConfiguration config, IEntityRepository <User> userRepository, IEntityRepository <Credential> credentialRepository, AuditingService auditing) : this() { Config = config; UserRepository = userRepository; CredentialRepository = credentialRepository; Auditing = auditing; }
public AuthenticationService(IEntitiesContext entities, IAppConfiguration config, IDiagnosticsService diagnostics, AuditingService auditing, IEnumerable <Authenticator> providers) { _credentialFormatters = new Dictionary <string, Func <string, string> >(StringComparer.OrdinalIgnoreCase) { { "password", _ => Strings.CredentialType_Password }, { "apikey", _ => Strings.CredentialType_ApiKey }, { "external", FormatExternalCredentialType } }; Entities = entities; _config = config; Auditing = auditing; _trace = diagnostics.SafeGetSource("AuthenticationService"); Authenticators = providers.ToDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase); }
public PackageDeleteService( IEntityRepository <Package> packageRepository, IEntityRepository <PackageDelete> packageDeletesRepository, IEntitiesContext entitiesContext, IPackageService packageService, IIndexingService indexingService, IPackageFileService packageFileService, AuditingService auditingService) { _packageRepository = packageRepository; _packageDeletesRepository = packageDeletesRepository; _entitiesContext = entitiesContext; _packageService = packageService; _indexingService = indexingService; _packageFileService = packageFileService; _auditingService = auditingService; }
public PackageService( IEntityRepository <PackageRegistration> packageRegistrationRepository, IEntityRepository <Package> packageRepository, IEntityRepository <PackageOwnerRequest> packageOwnerRequestRepository, IIndexingService indexingService, IPackageNamingConflictValidator packageNamingConflictValidator, AuditingService auditingService) { if (packageRegistrationRepository == null) { throw new ArgumentNullException(nameof(packageRegistrationRepository)); } if (packageRepository == null) { throw new ArgumentNullException(nameof(packageRepository)); } if (packageOwnerRequestRepository == null) { throw new ArgumentNullException(nameof(packageOwnerRequestRepository)); } if (indexingService == null) { throw new ArgumentNullException(nameof(indexingService)); } if (packageNamingConflictValidator == null) { throw new ArgumentNullException(nameof(packageNamingConflictValidator)); } if (auditingService == null) { throw new ArgumentNullException(nameof(auditingService)); } _packageRegistrationRepository = packageRegistrationRepository; _packageRepository = packageRepository; _packageOwnerRequestRepository = packageOwnerRequestRepository; _indexingService = indexingService; _packageNamingConflictValidator = packageNamingConflictValidator; _auditingService = auditingService; }
public ApiController( IEntitiesContext entitiesContext, IPackageService packageService, IPackageFileService packageFileService, IUserService userService, INuGetExeDownloaderService nugetExeDownloaderService, IContentService contentService, IIndexingService indexingService, ISearchService searchService, IAutomaticallyCuratePackageCommand autoCuratePackage, IStatusService statusService, IStatisticsService statisticsService, IMessageService messageService, AuditingService auditingService, IGalleryConfigurationService configurationService) : this(entitiesContext, packageService, packageFileService, userService, nugetExeDownloaderService, contentService, indexingService, searchService, autoCuratePackage, statusService, messageService, auditingService, configurationService) { StatisticsService = statisticsService; }
private async Task <ActionResult> CreatePackageInternal() { var policyResult = await SecurityPolicyService.EvaluateAsync(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 { 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. var id = nuspec.GetId(); var 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))); } // Check if a particular Id-Version combination already exists. We eventually need to remove this check. string normalizedVersion = 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, id, nuspec.GetVersion().ToNormalizedStringSafe()))); } } var packageStreamMetadata = new PackageStreamMetadata { HashAlgorithm = Constants.Sha512HashAlgorithmId, Hash = CryptographyService.GenerateHash(packageStream.AsSeekableStream()), 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)); } } }
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)); } } }
public static bool WroteRecordOfType <T>(this AuditingService self) where T : AuditRecord { return(WroteRecord <T>(self, _ => true)); }
public TestPackageDeleteService(IEntityRepository <Package> packageRepository, IEntityRepository <PackageDelete> packageDeletesRepository, IEntitiesContext entitiesContext, IPackageService packageService, IIndexingService indexingService, IPackageFileService packageFileService, AuditingService auditingService) : base(packageRepository, packageDeletesRepository, entitiesContext, packageService, indexingService, packageFileService, auditingService) { }
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)) { // 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 can not push this package 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); } // 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)); } } }