/// <summary> /// Validates and creates a <see cref="Package"/> entity from a NuGet package archive. /// </summary> /// <param name="nugetPackage">A <see cref="PackageArchiveReader"/> instance from which package metadata can be read.</param> /// <param name="packageStreamMetadata">The <see cref="PackageStreamMetadata"/> instance providing metadata about the package stream.</param> /// <param name="user">The <see cref="User"/> creating the package.</param> /// <param name="commitChanges"><c>True</c> to commit the changes to the data store and notify the indexing service; otherwise <c>false</c>.</param> /// <returns>Returns the created <see cref="Package"/> entity.</returns> /// <exception cref="InvalidPackageException"> /// This exception will be thrown when a package metadata property violates a data validation constraint. /// </exception> public async Task<Package> CreatePackageAsync(PackageArchiveReader nugetPackage, PackageStreamMetadata packageStreamMetadata, User user, bool isVerified, bool commitChanges = true) { PackageMetadata packageMetadata; PackageRegistration packageRegistration; try { packageMetadata = PackageMetadata.FromNuspecReader(nugetPackage.GetNuspecReader()); ValidateNuGetPackageMetadata(packageMetadata); ValidatePackageTitle(packageMetadata); packageRegistration = CreateOrGetPackageRegistration(user, packageMetadata, isVerified); } catch (Exception exception) when (exception is EntityException || exception is PackagingException) { // Wrap the exception for consistency of this API. throw new InvalidPackageException(exception.Message, exception); } var package = CreatePackageFromNuGetPackage(packageRegistration, nugetPackage, packageMetadata, packageStreamMetadata, user); packageRegistration.Packages.Add(package); await UpdateIsLatestAsync(packageRegistration, commitChanges: false); if (commitChanges) { await _packageRegistrationRepository.CommitChangesAsync(); NotifyIndexingService(); } return package; }
public virtual async Task UpdatePackageStreamMetadataAsync( Package package, PackageStreamMetadata metadata, bool commitChanges = true) { if (package == null) { throw new ArgumentNullException(nameof(package)); } if (metadata == null) { throw new ArgumentNullException(nameof(metadata)); } package.Hash = metadata.Hash; package.HashAlgorithm = metadata.HashAlgorithm; package.PackageFileSize = metadata.Size; var now = DateTime.UtcNow; package.LastUpdated = now; /// If the package is available, consider this change as an "edit" so that the package appears for cursors /// on the <see cref="Package.LastEdited"/> field. if (package.PackageStatusKey == PackageStatus.Available) { package.LastEdited = now; } if (commitChanges) { await _packageRepository.CommitChangesAsync(); } }
public async Task SoftDeletePackagesAsync(IEnumerable <Package> packages, User deletedBy, string reason, string signature) { using (var strategy = new SuspendDbExecutionStrategy()) using (var transaction = _entitiesContext.GetDatabase().BeginTransaction()) { // Increase command timeout _entitiesContext.SetCommandTimeout(seconds: 300); // Keep package registrations var packageRegistrations = packages .GroupBy(p => p.PackageRegistration) .Select(g => g.First().PackageRegistration) .ToList(); // Backup the package binaries and remove from main storage // We're doing this early in the process as we need the metadata to still exist in the DB. await BackupPackageBinaries(packages); // Store the soft delete in the database var packageDelete = new PackageDelete { DeletedOn = DateTime.UtcNow, DeletedBy = deletedBy, Reason = reason, Signature = signature }; foreach (var package in packages) { /// We do not call <see cref="IPackageService.MarkPackageUnlistedAsync(Package, bool)"/> here /// because that writes an audit entry. Additionally, the latest bits are already updated by /// the package status change. package.Listed = false; await _packageService.UpdatePackageStatusAsync( package, PackageStatus.Deleted, commitChanges : false); packageDelete.Packages.Add(package); await _auditingService.SaveAuditRecordAsync(CreateAuditRecord(package, package.PackageRegistration, AuditedPackageAction.SoftDelete, reason)); _telemetryService.TrackPackageDelete(package, isHardDelete: false); } _packageDeletesRepository.InsertOnCommit(packageDelete); // Commit changes await _packageRepository.CommitChangesAsync(); await _packageDeletesRepository.CommitChangesAsync(); transaction.Commit(); } // Force refresh the index UpdateSearchIndex(); }
public async Task SoftDeletePackagesAsync(IEnumerable <Package> packages, User deletedBy, string reason, string signature) { List <PackageRegistration> packageRegistrations; // Must suspend the retry execution strategy in order to use transactions. using (EntitiesConfiguration.SuspendRetriableExecutionStrategy()) { using (var transaction = _entitiesContext.GetDatabase().BeginTransaction()) { // Increase command timeout _entitiesContext.SetCommandTimeout(seconds: 300); // Keep package registrations packageRegistrations = packages .GroupBy(p => p.PackageRegistration) .Select(g => g.First().PackageRegistration) .ToList(); // Backup the package binaries and remove from main storage // We're doing this early in the process as we need the metadata to still exist in the DB. await BackupPackageBinaries(packages); // Store the soft delete in the database var packageDelete = new PackageDelete { DeletedOn = DateTime.UtcNow, DeletedBy = deletedBy, Reason = reason, Signature = signature }; foreach (var package in packages) { package.Listed = false; package.Deleted = true; packageDelete.Packages.Add(package); await _auditingService.SaveAuditRecordAsync(CreateAuditRecord(package, package.PackageRegistration, AuditedPackageAction.SoftDelete, reason)); } _packageDeletesRepository.InsertOnCommit(packageDelete); // Commit changes await _packageRepository.CommitChangesAsync(); await _packageDeletesRepository.CommitChangesAsync(); transaction.Commit(); } } // handle in separate transaction because of concurrency check with retry await UpdateIsLatestAsync(packageRegistrations); // Force refresh the index UpdateSearchIndex(); }
public async Task AddPackageOwnerAsync(PackageRegistration package, User user) { package.Owners.Add(user); await _packageRepository.CommitChangesAsync(); var request = FindExistingPackageOwnerRequest(package, user); if (request != null) { _packageOwnerRequestRepository.DeleteOnCommit(request); await _packageOwnerRequestRepository.CommitChangesAsync(); } }
public virtual async Task UpdatePackageStatusAsync( Package package, PackageStatus newPackageStatus, bool commitChanges = true) { if (package == null) { throw new ArgumentNullException(nameof(package)); } if (package.PackageRegistration == null) { throw new ArgumentException($"The {nameof(Package.PackageRegistration)} property must populated on the provided package.", nameof(package)); } // Avoid all of this work if the package status is not changing. if (package.PackageStatusKey != newPackageStatus) { #pragma warning disable CS0612 // Type or member is obsolete package.Deleted = newPackageStatus == PackageStatus.Deleted; #pragma warning restore CS0612 // Type or member is obsolete package.PackageStatusKey = newPackageStatus; package.LastUpdated = DateTime.UtcNow; /// If the package is being made available, consider this change as an "edit" so that the package /// appears for cursors on the <see cref="Package.LastEdited"/> field. if (newPackageStatus == PackageStatus.Available) { package.LastEdited = DateTime.UtcNow; } // If the package is just now becoming available or if it was previously a latest package, then // re-evaluate all of the latest bits. if (newPackageStatus == PackageStatus.Available || package.IsLatest || package.IsLatestStable || package.IsLatestSemVer2 || package.IsLatestStableSemVer2) { await UpdateIsLatestAsync(package.PackageRegistration, commitChanges : false); } } if (commitChanges) { // Even if the package status did not change, commit the changes in the entity context to pick up any // other entity changes. await _packageRepository.CommitChangesAsync(); } }
public async Task AddPackageOwnerAsync(PackageRegistration package, User newOwner) { package.Owners.Add(newOwner); await _packageRepository.CommitChangesAsync(); var request = FindExistingPackageOwnerRequest(package, newOwner); if (request != null) { _packageOwnerRequestRepository.DeleteOnCommit(request); await _packageOwnerRequestRepository.CommitChangesAsync(); } await _auditingService.SaveAuditRecordAsync( new PackageRegistrationAuditRecord(package, AuditedPackageRegistrationAction.AddOwner, newOwner.Username)); }
public async Task <ActionResult> Update(LockPackageViewModel lockPackageViewModel) { int counter = 0; if (lockPackageViewModel != null && lockPackageViewModel.PackageLockStates != null) { var packageIdsFromRequest = lockPackageViewModel.PackageLockStates.Select(x => x.Id).ToList(); var packageRegistrationsFromDb = GetPackageRegistrationsForIds(packageIdsFromRequest); var packageStatesFromRequestDictionary = lockPackageViewModel.PackageLockStates.ToDictionary(x => x.Id); foreach (var packageRegistration in packageRegistrationsFromDb) { if (packageStatesFromRequestDictionary.TryGetValue(packageRegistration.Id, out var packageStateRequest)) { if (packageRegistration.IsLocked != packageStateRequest.IsLocked) { packageRegistration.IsLocked = packageStateRequest.IsLocked; counter++; } } } if (counter > 0) { await _packageRegistrationRepository.CommitChangesAsync(); } } TempData["Message"] = string.Format(CultureInfo.InvariantCulture, $"Lock state was updated for {counter} packages."); return(View(nameof(Index), lockPackageViewModel)); }
private async Task InsertDeleteAccount(User user, User admin) { var accountDelete = new AccountDelete { DeletedOn = DateTime.UtcNow, DeletedAccountKey = user.Key, DeletedByKey = admin.Key, }; _accountDeleteRepository.InsertOnCommit(accountDelete); await _accountDeleteRepository.CommitChangesAsync(); }
public async Task <PackageOwnerRequest> AddPackageOwnershipRequest(PackageRegistration package, User requestingOwner, User newOwner) { if (package == null) { throw new ArgumentNullException(nameof(package)); } if (requestingOwner == null) { throw new ArgumentNullException(nameof(requestingOwner)); } if (newOwner == null) { throw new ArgumentNullException(nameof(newOwner)); } var existingRequest = GetPackageOwnershipRequests(package: package, newOwner: newOwner).FirstOrDefault(); if (existingRequest != null) { return(existingRequest); } var newRequest = new PackageOwnerRequest { PackageRegistrationKey = package.Key, RequestingOwnerKey = requestingOwner.Key, NewOwnerKey = newOwner.Key, ConfirmationCode = CryptographyService.GenerateToken(), RequestDate = DateTime.UtcNow }; _packageOwnerRequestRepository.InsertOnCommit(newRequest); await _packageOwnerRequestRepository.CommitChangesAsync(); return(newRequest); }
public virtual async Task UpdatePackageVerifiedStatusAsync(IReadOnlyCollection <PackageRegistration> packageRegistrationList, bool isVerified) { var packageRegistrationIdSet = new HashSet <string>(packageRegistrationList.Select(prl => prl.Id)); var allPackageRegistrations = _packageRegistrationRepository.GetAll(); var packageRegistrationsToUpdate = allPackageRegistrations .Where(pr => packageRegistrationIdSet.Contains(pr.Id)) .ToList(); if (packageRegistrationsToUpdate.Count > 0) { packageRegistrationsToUpdate .ForEach(pru => pru.IsVerified = isVerified); await _packageRegistrationRepository.CommitChangesAsync(); } }
public async Task PublishPackageAsync(Package package, bool commitChanges = true) { if (package == null) { throw new ArgumentNullException(nameof(package)); } package.Published = DateTime.UtcNow; package.Listed = true; await UpdateIsLatestAsync(package.PackageRegistration, false); if (commitChanges) { await _packageRepository.CommitChangesAsync(); } }
public async Task <Certificate> AddCertificateAsync(HttpPostedFileBase file) { if (file == null) { throw new ArgumentNullException(nameof(file)); } _certificateValidator.Validate(file); using (var certificateFile = CertificateFile.Create(file.InputStream)) { var certificate = GetCertificate(certificateFile.Sha256Thumbprint); if (certificate == null) { await SaveToFileStorageAsync(certificateFile); certificate = new Certificate() { #pragma warning disable CS0618 // Only set the SHA1 thumbprint, for backwards compatibility. Never read it. Sha1Thumbprint = certificateFile.Sha1Thumbprint, #pragma warning restore CS0618 Thumbprint = certificateFile.Sha256Thumbprint, UserCertificates = new List <UserCertificate>() }; _certificateRepository.InsertOnCommit(certificate); await _certificateRepository.CommitChangesAsync(); await _auditingService.SaveAuditRecordAsync( new CertificateAuditRecord(AuditedCertificateAction.Add, certificate.Thumbprint)); _telemetryService.TrackCertificateAdded(certificateFile.Sha256Thumbprint); } return(certificate); } }
public async Task <Package> CreatePackageAsync(PackageArchiveReader nugetPackage, PackageStreamMetadata packageStreamMetadata, User user, bool commitChanges = true) { var packageMetadata = PackageMetadata.FromNuspecReader(nugetPackage.GetNuspecReader()); ValidateNuGetPackageMetadata(packageMetadata); ValidatePackageTitle(packageMetadata); var packageRegistration = CreateOrGetPackageRegistration(user, packageMetadata); var package = CreatePackageFromNuGetPackage(packageRegistration, nugetPackage, packageMetadata, packageStreamMetadata, user); packageRegistration.Packages.Add(package); if (commitChanges) { await _packageRegistrationRepository.CommitChangesAsync(); NotifyIndexingService(); } return(package); }
public async Task <Certificate> AddCertificateAsync(HttpPostedFileBase file) { if (file == null) { throw new ArgumentNullException(nameof(file)); } _certificateValidator.Validate(file); using (var certificateFile = CertificateFile.Create(file.InputStream)) { var certificate = GetCertificate(certificateFile.Sha256Thumbprint); if (certificate == null) { await SaveToFileStorageAsync(certificateFile); certificate = new Certificate() { Sha1Thumbprint = certificateFile.Sha1Thumbprint, Thumbprint = certificateFile.Sha256Thumbprint, UserCertificates = new List <UserCertificate>() }; _certificateRepository.InsertOnCommit(certificate); await _certificateRepository.CommitChangesAsync(); await _auditingService.SaveAuditRecordAsync( new CertificateAuditRecord(AuditedCertificateAction.Add, certificate.Thumbprint)); _telemetryService.TrackCertificateAdded(certificateFile.Sha256Thumbprint); } return(certificate); } }
public async Task <IReadOnlyCollection <Cve> > GetOrCreateCvesByIdAsync(IEnumerable <string> ids, bool commitChanges) { if (ids == null) { throw new ArgumentNullException(nameof(ids)); } var details = _cveRepository.GetAll() .Where(c => ids.Contains(c.CveId)) .ToList(); var addedDetails = new List <Cve>(); foreach (var missingId in ids.Where(i => !details.Any(c => c.CveId == i))) { var detail = new Cve { CveId = missingId, Listed = false, Status = CveStatus.Unknown }; addedDetails.Add(detail); details.Add(detail); } if (addedDetails.Any()) { _cveRepository.InsertOnCommit(addedDetails); if (commitChanges) { await _cveRepository.CommitChangesAsync(); } } return(details); }
public virtual async Task UpdateStatusAsync(SymbolPackage symbolPackage, PackageStatus newPackageStatus, bool commitChanges = true) { if (symbolPackage == null) { throw new ArgumentNullException(nameof(symbolPackage)); } // Avoid all of this work if the package status is not changing. if (symbolPackage.StatusKey != newPackageStatus) { symbolPackage.StatusKey = newPackageStatus; /// If the package is being made available. if (newPackageStatus == PackageStatus.Available) { symbolPackage.Published = DateTime.UtcNow; } if (commitChanges) { await _symbolPackageRepository.CommitChangesAsync(); } } }
private async Task RemoveUserDataInUserTable(User user) { user.SetAccountAsDeleted(); await _userRepository.CommitChangesAsync(); }
public async Task UpdateDeprecation( IReadOnlyCollection <Package> packages, PackageDeprecationStatus status, PackageRegistration alternatePackageRegistration, Package alternatePackage, string customMessage, User user) { if (packages == null || !packages.Any()) { throw new ArgumentException(nameof(packages)); } if (user == null) { throw new ArgumentNullException(nameof(user)); } var shouldDelete = status == PackageDeprecationStatus.NotDeprecated; var deprecations = new List <PackageDeprecation>(); foreach (var package in packages) { var deprecation = package.Deprecations.SingleOrDefault(); if (shouldDelete) { if (deprecation != null) { package.Deprecations.Remove(deprecation); deprecations.Add(deprecation); } } else { if (deprecation == null) { deprecation = new PackageDeprecation { Package = package }; package.Deprecations.Add(deprecation); deprecations.Add(deprecation); } deprecation.Status = status; deprecation.DeprecatedByUser = user; deprecation.AlternatePackageRegistration = alternatePackageRegistration; deprecation.AlternatePackage = alternatePackage; deprecation.CustomMessage = customMessage; } } if (shouldDelete) { _deprecationRepository.DeleteOnCommit(deprecations); } else { _deprecationRepository.InsertOnCommit(deprecations); } await _deprecationRepository.CommitChangesAsync(); }