Esempio n. 1
0
        /// <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();
            }
        }
Esempio n. 3
0
        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();
            }
        }
Esempio n. 6
0
        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();
            }
        }
Esempio n. 7
0
        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));
        }
Esempio n. 8
0
        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));
        }
Esempio n. 9
0
        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);
        }
Esempio n. 11
0
        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();
            }
        }
Esempio n. 13
0
        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);
            }
        }
Esempio n. 14
0
        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);
            }
        }
Esempio n. 16
0
        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();
                }
            }
        }
Esempio n. 18
0
 private async Task RemoveUserDataInUserTable(User user)
 {
     user.SetAccountAsDeleted();
     await _userRepository.CommitChangesAsync();
 }
Esempio n. 19
0
        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();
        }