public void TrackPackageDeprecateSucceedsWithoutAlternate(PackageDeprecationStatus status, bool hasCustomMessage)
            {
                var service       = CreateService();
                var packages      = fakes.Package.Packages.ToList();
                var allProperties = new List <IDictionary <string, string> >();

                service.TelemetryClient
                .Setup(x => x.TrackMetric(It.IsAny <string>(), It.IsAny <double>(), It.IsAny <IDictionary <string, string> >()))
                .Callback <string, double, IDictionary <string, string> >((_, __, p) => allProperties.Add(p));

                service.TrackPackageDeprecate(packages, status, null, null, hasCustomMessage);

                service.TelemetryClient.Verify(
                    x => x.TrackMetric("PackageDeprecate", packages.Count(), It.IsAny <IDictionary <string, string> >()),
                    Times.Once);

                var properties = Assert.Single(allProperties);

                Assert.Contains(
                    new KeyValuePair <string, string>("PackageDeprecationReason", ((int)status).ToString()),
                    properties);

                Assert.Contains(
                    new KeyValuePair <string, string>("PackageDeprecationAlternatePackageId", null),
                    properties);

                Assert.Contains(
                    new KeyValuePair <string, string>("PackageDeprecationAlternatePackageVersion", null),
                    properties);

                Assert.Contains(
                    new KeyValuePair <string, string>("PackageDeprecationCustomMessage", hasCustomMessage.ToString()),
                    properties);
            }
 public void TrackPackageDeprecate(
     IReadOnlyList <Package> packages,
     PackageDeprecationStatus status,
     PackageRegistration alternateRegistration,
     Package alternatePackage,
     bool hasCustomMessage)
 {
     TrackMetricForPackageVersions(
         Events.PackageDeprecate,
         packages,
         properties =>
     {
         properties.Add(DeprecationReason, ((int)status).ToString());
         properties.Add(DeprecationAlternatePackageId, alternateRegistration?.Id ?? alternatePackage?.Id);
         properties.Add(DeprecationAlternatePackageVersion, alternatePackage?.NormalizedVersion);
         properties.Add(DeprecationCustomMessage, hasCustomMessage.ToString());
     });
 }
Exemple #3
0
 public Task ReturnsSuccessfulWithoutCustomMessage(
     User currentUser,
     User owner,
     bool isLegacy,
     bool hasCriticalBugs,
     bool isOther,
     PackageDeprecationStatus expectedStatus,
     ReturnsSuccessful_AlternatePackage_State alternatePackageState)
 {
     return(AssertSuccessful(
                currentUser,
                owner,
                isLegacy,
                hasCriticalBugs,
                isOther,
                expectedStatus,
                alternatePackageState,
                false));
 }
            private static Mock <DbDataReader> MockDataReader(
                PackageDeprecationStatus deprecationStatus,
                string message                      = null,
                string alternatePackageId           = null,
                string alternatePackageVersionRange = null)
            {
                var dataReaderMock = new Mock <DbDataReader>(MockBehavior.Strict);

                if (deprecationStatus == PackageDeprecationStatus.NotDeprecated)
                {
                    // Simulate that these columns do not exist in the resultset.
                    dataReaderMock.Setup(m => m.GetOrdinal(Db2CatalogProjectionColumnNames.DeprecationStatus)).Throws <IndexOutOfRangeException>();
                }
                else
                {
                    const int ordinalDeprecationStatus = 7;
                    dataReaderMock.Setup(m => m.GetOrdinal(Db2CatalogProjectionColumnNames.DeprecationStatus)).Returns(ordinalDeprecationStatus);
                    dataReaderMock.Setup(m => m.IsDBNull(ordinalDeprecationStatus)).Returns(false);
                    dataReaderMock.Setup(m => m.GetInt32(ordinalDeprecationStatus)).Returns((int)deprecationStatus);

                    const int ordinalDeprecationMessage = 8;
                    dataReaderMock.Setup(m => m.GetOrdinal(Db2CatalogProjectionColumnNames.DeprecationMessage)).Returns(ordinalDeprecationMessage);
                    dataReaderMock.Setup(m => m.IsDBNull(ordinalDeprecationMessage)).Returns(message == null);
                    dataReaderMock.Setup(m => m.GetString(ordinalDeprecationMessage)).Returns(message);

                    const int ordinalAlternatePackageId = 9;
                    dataReaderMock.Setup(m => m.GetOrdinal(Db2CatalogProjectionColumnNames.AlternatePackageId)).Returns(ordinalAlternatePackageId);
                    dataReaderMock.Setup(m => m.IsDBNull(ordinalAlternatePackageId)).Returns(alternatePackageId == null);
                    dataReaderMock.Setup(m => m.GetString(ordinalAlternatePackageId)).Returns(alternatePackageId);

                    const int ordinalAlternatePackageVersionRange = 10;
                    dataReaderMock.Setup(m => m.GetOrdinal(Db2CatalogProjectionColumnNames.AlternatePackageVersion)).Returns(ordinalAlternatePackageVersionRange);
                    dataReaderMock.Setup(m => m.IsDBNull(ordinalAlternatePackageVersionRange)).Returns(alternatePackageVersionRange == null);
                    dataReaderMock.Setup(m => m.GetString(ordinalAlternatePackageVersionRange)).Returns(alternatePackageVersionRange);
                }

                return(dataReaderMock);
            }
Exemple #5
0
        public void DeprecationFieldsAreSetAsExpected(
            PackageDeprecationStatus status,
            bool hasAlternateRegistration,
            bool hasAlternatePackage)
        {
            // Arrange
            var deprecation = new PackageDeprecation
            {
                Status        = status,
                CustomMessage = "hello",
            };

            var alternateRegistrationId = "alternateRegistrationId";

            if (hasAlternateRegistration)
            {
                var registration = new PackageRegistration
                {
                    Id = alternateRegistrationId
                };

                deprecation.AlternatePackageRegistration = registration;
            }

            var alternatePackageRegistrationId = "alternatePackageRegistration";
            var alternatePackageVersion        = "1.0.0-alt";

            if (hasAlternatePackage)
            {
                var alternatePackageRegistration = new PackageRegistration
                {
                    Id = alternatePackageRegistrationId
                };

                var alternatePackage = new Package
                {
                    Version             = alternatePackageVersion,
                    PackageRegistration = alternatePackageRegistration
                };

                deprecation.AlternatePackage = alternatePackage;
            }

            var package = CreateTestPackage("1.0.0");

            var packageKeyToDeprecation = new Dictionary <int, PackageDeprecation>
            {
                { 123, deprecation }
            };

            // Act
            var model = CreateDisplayPackageViewModel(
                package,
                currentUser: null,
                packageKeyToDeprecation: packageKeyToDeprecation,
                readmeHtml: null);

            // Assert
            Assert.Equal(status, model.DeprecationStatus);
            Assert.Equal(deprecation.CustomMessage, model.CustomMessage);

            if (hasAlternatePackage)
            {
                Assert.Equal(alternatePackageRegistrationId, model.AlternatePackageId);
                Assert.Equal(alternatePackageVersion, model.AlternatePackageVersion);
            }
            else if (hasAlternateRegistration)
            {
                Assert.Equal(alternateRegistrationId, model.AlternatePackageId);
                Assert.Null(model.AlternatePackageVersion);
            }
            else
            {
                Assert.Null(model.AlternatePackageId);
                Assert.Null(model.AlternatePackageVersion);
            }

            var versionModel = model.PackageVersions.Single();

            Assert.Equal(status, versionModel.DeprecationStatus);
            Assert.Null(versionModel.AlternatePackageId);
            Assert.Null(versionModel.AlternatePackageVersion);
            Assert.Null(versionModel.CustomMessage);
        }
 public void TrackPackageDeprecate(IReadOnlyList <Package> packages, PackageDeprecationStatus status, PackageRegistration alternateRegistration, Package alternatePackage, bool hasCustomMessage)
 {
     throw new NotImplementedException();
 }
        public void DeprecationFieldsAreSetAsExpected(
            PackageDeprecationStatus status,
            SeverityString_State severity,
            bool hasCves,
            bool hasCwes,
            bool hasAlternateRegistration,
            bool hasAlternatePackage)
        {
            // Arrange
            decimal?cvss;

            switch (severity)
            {
            case SeverityString_State.Critical:
                cvss = (decimal)9.5;
                break;

            case SeverityString_State.High:
                cvss = (decimal)7.5;
                break;

            case SeverityString_State.Medium:
                cvss = (decimal)5;
                break;

            case SeverityString_State.Low:
                cvss = (decimal)2;
                break;

            case SeverityString_State.None:
                cvss = null;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(severity));
            }

            var deprecation = new PackageDeprecation
            {
                CvssRating    = cvss,
                CustomMessage = "hello"
            };

            var cveIds = new[] { "CVE-2019-1111", "CVE-2019-2222" };

            if (hasCves)
            {
                foreach (var cveId in cveIds)
                {
                    var cve = new Cve
                    {
                        CveId = cveId
                    };

                    deprecation.Cves.Add(cve);
                }
            }

            var cweIds = new[] { "CWE-1", "CWE-2" };

            if (hasCwes)
            {
                foreach (var cweId in cweIds)
                {
                    var cwe = new Cwe
                    {
                        CweId = cweId
                    };

                    deprecation.Cwes.Add(cwe);
                }
            }

            var alternateRegistrationId = "alternateRegistrationId";

            if (hasAlternateRegistration)
            {
                var registration = new PackageRegistration
                {
                    Id = alternateRegistrationId
                };

                deprecation.AlternatePackageRegistration = registration;
            }

            var alternatePackageRegistrationId = "alternatePackageRegistration";
            var alternatePackageVersion        = "1.0.0-alt";

            if (hasAlternatePackage)
            {
                var alternatePackageRegistration = new PackageRegistration
                {
                    Id = alternatePackageRegistrationId
                };

                var alternatePackage = new Package
                {
                    Version             = alternatePackageVersion,
                    PackageRegistration = alternatePackageRegistration
                };

                deprecation.AlternatePackage = alternatePackage;
            }

            var package = CreateTestPackage("1.0.0");

            var linkedDeprecation = new PackageDeprecation
            {
                Status = status
            };

            package.Deprecations.Add(linkedDeprecation);

            // Act
            var model = new DisplayPackageViewModel(package, null, deprecation);

            // Assert
            Assert.Equal(status, model.DeprecationStatus);
            Assert.Equal(deprecation.CustomMessage, model.CustomMessage);

            string expectedString;

            switch (severity)
            {
            case SeverityString_State.Critical:
                expectedString = "Critical";
                break;

            case SeverityString_State.High:
                expectedString = "High";
                break;

            case SeverityString_State.Medium:
                expectedString = "Medium";
                break;

            case SeverityString_State.Low:
                expectedString = "Low";
                break;

            case SeverityString_State.None:
                expectedString = null;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(severity));
            }

            Assert.Equal(expectedString, model.Severity);

            if (hasCves)
            {
                Assert.Equal(cveIds, model.CveIds);
            }
            else
            {
                Assert.Empty(model.CveIds);
            }

            if (hasCwes)
            {
                Assert.Equal(cweIds, model.CweIds);
            }
            else
            {
                Assert.Empty(model.CweIds);
            }

            if (hasAlternatePackage)
            {
                Assert.Equal(alternatePackageRegistrationId, model.AlternatePackageId);
                Assert.Equal(alternatePackageVersion, model.AlternatePackageVersion);
            }
            else if (hasAlternateRegistration)
            {
                Assert.Equal(alternateRegistrationId, model.AlternatePackageId);
                Assert.Null(model.AlternatePackageVersion);
            }
            else
            {
                Assert.Null(model.AlternatePackageId);
                Assert.Null(model.AlternatePackageVersion);
            }

            var versionModel = model.PackageVersions.Single();

            Assert.Equal(status, versionModel.DeprecationStatus);
            Assert.Null(versionModel.Severity);
            Assert.Null(versionModel.CveIds);
            Assert.Null(versionModel.CweIds);
            Assert.Null(versionModel.AlternatePackageId);
            Assert.Null(versionModel.AlternatePackageVersion);
            Assert.Null(versionModel.CustomMessage);
        }
Exemple #8
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();
        }
Exemple #9
0
            private async Task AssertSuccessful(
                User currentUser,
                User owner,
                bool isLegacy,
                bool hasCriticalBugs,
                bool isOther,
                PackageDeprecationStatus expectedStatus,
                ReturnsSuccessful_AlternatePackage_State alternatePackageState,
                bool hasCustomMessage)
            {
                // Arrange
                var id = "id";

                var featureFlagService = GetMock <IFeatureFlagService>();

                featureFlagService
                .Setup(x => x.IsManageDeprecationEnabled(currentUser))
                .Returns(true)
                .Verifiable();

                var registration = new PackageRegistration
                {
                    Id = id
                };

                registration.Owners.Add(owner);

                var package = new Package
                {
                    NormalizedVersion   = "2.3.4",
                    PackageRegistration = registration
                };

                var package2 = new Package
                {
                    NormalizedVersion   = "1.0.0",
                    PackageRegistration = registration
                };

                var unselectedPackage = new Package
                {
                    NormalizedVersion   = "1.3.2",
                    PackageRegistration = registration
                };

                var packageService = GetMock <IPackageService>();

                packageService
                .Setup(x => x.FindPackagesById(id, PackageDeprecationFieldsToInclude.DeprecationAndRelationships))
                .Returns(new[] { package, package2, unselectedPackage })
                .Verifiable();

                var alternatePackageId      = alternatePackageState != ReturnsSuccessful_AlternatePackage_State.None ? "altId" : null;
                var alternatePackageVersion = alternatePackageState == ReturnsSuccessful_AlternatePackage_State.Package ? "1.2.3-alt" : null;

                var alternatePackageRegistration = new PackageRegistration
                {
                    Id = alternatePackageId
                };

                var alternatePackage = new Package
                {
                    NormalizedVersion   = alternatePackageVersion,
                    PackageRegistration = alternatePackageRegistration
                };

                if (alternatePackageState == ReturnsSuccessful_AlternatePackage_State.Registration)
                {
                    packageService
                    .Setup(x => x.FindPackageRegistrationById(alternatePackageId))
                    .Returns(alternatePackageRegistration)
                    .Verifiable();
                }
                else if (alternatePackageState == ReturnsSuccessful_AlternatePackage_State.Package)
                {
                    packageService
                    .Setup(x => x.FindPackageByIdAndVersionStrict(alternatePackageId, alternatePackageVersion))
                    .Returns(alternatePackage)
                    .Verifiable();
                }

                var deprecationService = GetMock <IPackageDeprecationService>();

                var customMessage = hasCustomMessage ? "message" : null;

                deprecationService
                .Setup(x => x.UpdateDeprecation(
                           new[] { package, package2 },
                           expectedStatus,
                           alternatePackageState == ReturnsSuccessful_AlternatePackage_State.Registration ? alternatePackageRegistration : null,
                           alternatePackageState == ReturnsSuccessful_AlternatePackage_State.Package ? alternatePackage : null,
                           customMessage,
                           currentUser))
                .Completes()
                .Verifiable();

                var auditingService = GetService <IAuditingService>();

                var controller = GetController <ManageDeprecationJsonApiController>();

                controller.SetCurrentUser(currentUser);

                var packageNormalizedVersions = new[] { package.NormalizedVersion, package2.NormalizedVersion };

                // Act
                var result = await controller.Deprecate(
                    id,
                    packageNormalizedVersions,
                    isLegacy,
                    hasCriticalBugs,
                    isOther,
                    alternatePackageId,
                    alternatePackageVersion,
                    customMessage);

                // Assert
                AssertSuccessResponse(controller);

                if (expectedStatus == PackageDeprecationStatus.NotDeprecated)
                {
                    foreach (var normalizedVersion in packageNormalizedVersions)
                    {
                        auditingService.WroteRecord <PackageAuditRecord>(
                            r => r.Action == AuditedPackageAction.Undeprecate &&
                            r.Reason == PackageUndeprecatedVia.Web &&
                            r.DeprecationRecord == null &&
                            r.Id == id &&
                            r.PackageRecord.NormalizedVersion == normalizedVersion);
                    }
                }
                else
                {
                    foreach (var normalizedVersion in packageNormalizedVersions)
                    {
                        auditingService.WroteRecord <PackageAuditRecord>(
                            r => r.Action == AuditedPackageAction.Deprecate &&
                            r.Reason == PackageDeprecatedVia.Web &&
                            r.DeprecationRecord.Status == (int)expectedStatus &&
                            r.Id == id &&
                            r.PackageRecord.NormalizedVersion == normalizedVersion);
                    }
                }

                featureFlagService.Verify();
                packageService.Verify();
                deprecationService.Verify();
            }
        public void DeprecationFieldsAreSetAsExpected(
            PackageDeprecationStatus status,
            bool hasAlternateRegistration,
            bool hasAlternatePackage)
        {
            // Arrange
            var deprecation = new PackageDeprecation
            {
                CustomMessage = "hello"
            };

            var alternateRegistrationId = "alternateRegistrationId";

            if (hasAlternateRegistration)
            {
                var registration = new PackageRegistration
                {
                    Id = alternateRegistrationId
                };

                deprecation.AlternatePackageRegistration = registration;
            }

            var alternatePackageRegistrationId = "alternatePackageRegistration";
            var alternatePackageVersion        = "1.0.0-alt";

            if (hasAlternatePackage)
            {
                var alternatePackageRegistration = new PackageRegistration
                {
                    Id = alternatePackageRegistrationId
                };

                var alternatePackage = new Package
                {
                    Version             = alternatePackageVersion,
                    PackageRegistration = alternatePackageRegistration
                };

                deprecation.AlternatePackage = alternatePackage;
            }

            var package = CreateTestPackage("1.0.0");

            var linkedDeprecation = new PackageDeprecation
            {
                Status = status
            };

            package.Deprecations.Add(linkedDeprecation);

            // Act
            var model = new DisplayPackageViewModel(package, null, deprecation);

            // Assert
            Assert.Equal(status, model.DeprecationStatus);
            Assert.Equal(deprecation.CustomMessage, model.CustomMessage);

            if (hasAlternatePackage)
            {
                Assert.Equal(alternatePackageRegistrationId, model.AlternatePackageId);
                Assert.Equal(alternatePackageVersion, model.AlternatePackageVersion);
            }
            else if (hasAlternateRegistration)
            {
                Assert.Equal(alternateRegistrationId, model.AlternatePackageId);
                Assert.Null(model.AlternatePackageVersion);
            }
            else
            {
                Assert.Null(model.AlternatePackageId);
                Assert.Null(model.AlternatePackageVersion);
            }

            var versionModel = model.PackageVersions.Single();

            Assert.Equal(status, versionModel.DeprecationStatus);
            Assert.Null(versionModel.AlternatePackageId);
            Assert.Null(versionModel.AlternatePackageVersion);
            Assert.Null(versionModel.CustomMessage);
        }
Exemple #11
0
            private async Task AssertSuccessful(
                User currentUser,
                User owner,
                bool isLegacy,
                bool hasCriticalBugs,
                bool isOther,
                PackageDeprecationStatus expectedStatus,
                ReturnsSuccessful_AlternatePackage_State alternatePackageState,
                bool hasCustomMessage)
            {
                // Arrange
                var id = "id";

                var registration = new PackageRegistration
                {
                    Id = id
                };

                var featureFlagService = GetMock <IFeatureFlagService>();

                featureFlagService
                .Setup(x => x.IsManageDeprecationEnabled(currentUser, registration))
                .Returns(true)
                .Verifiable();

                registration.Owners.Add(owner);

                var package = new Package
                {
                    NormalizedVersion   = "2.3.4",
                    PackageRegistration = registration
                };

                var package2 = new Package
                {
                    NormalizedVersion   = "1.0.0",
                    PackageRegistration = registration
                };

                var unselectedPackage = new Package
                {
                    NormalizedVersion   = "1.3.2",
                    PackageRegistration = registration
                };

                var packageService = GetMock <IPackageService>();

                packageService
                .Setup(x => x.FindPackagesById(id, PackageDeprecationFieldsToInclude.DeprecationAndRelationships))
                .Returns(new[] { package, package2, unselectedPackage })
                .Verifiable();

                string alternatePackageId      = null;
                string alternatePackageVersion = null;
                PackageRegistration alternatePackageRegistration = null;
                Package             alternatePackage             = null;

                if (alternatePackageState != ReturnsSuccessful_AlternatePackage_State.None)
                {
                    var alternateRegistration =
                        alternatePackageState == ReturnsSuccessful_AlternatePackage_State.PackageSameId
                        ? registration
                        : new PackageRegistration
                    {
                        Id = "altId"
                    };

                    alternatePackageId = alternateRegistration.Id;

                    if (alternatePackageState == ReturnsSuccessful_AlternatePackage_State.RegistrationDifferentId)
                    {
                        alternatePackageRegistration = alternateRegistration;
                        packageService
                        .Setup(x => x.FindPackageRegistrationById(alternatePackageId))
                        .Returns(alternateRegistration)
                        .Verifiable();
                    }
                    else if (alternatePackageState == ReturnsSuccessful_AlternatePackage_State.PackageSameId ||
                             alternatePackageState == ReturnsSuccessful_AlternatePackage_State.PackageDifferentId)
                    {
                        alternatePackageVersion = "1.2.3-alt";
                        alternatePackage        = new Package
                        {
                            NormalizedVersion   = alternatePackageVersion,
                            PackageRegistration = alternateRegistration
                        };

                        packageService
                        .Setup(x => x.FindPackageByIdAndVersionStrict(alternatePackageId, alternatePackageVersion))
                        .Returns(alternatePackage)
                        .Verifiable();
                    }
                }

                var deprecationService = GetMock <IPackageDeprecationService>();

                var customMessage = hasCustomMessage ? "<message>" : null;

                deprecationService
                .Setup(x => x.UpdateDeprecation(
                           new[] { package, package2 },
                           expectedStatus,
                           alternatePackageRegistration,
                           alternatePackage,
                           customMessage,
                           currentUser))
                .Completes()
                .Verifiable();

                var service = GetService <PackageDeprecationManagementService>();

                var packageNormalizedVersions = new[] { package.NormalizedVersion, package2.NormalizedVersion };

                // Act
                var result = await InvokeUpdateDeprecation(
                    service,
                    currentUser,
                    id,
                    packageNormalizedVersions,
                    isLegacy,
                    hasCriticalBugs,
                    isOther,
                    alternatePackageId,
                    alternatePackageVersion,
                    customMessage);

                // Assert
                Assert.Null(result);

                featureFlagService.Verify();
                packageService.Verify();
                deprecationService.Verify();
            }
        public async Task UpdateDeprecation(
            IReadOnlyList <Package> packages,
            PackageDeprecationStatus status,
            PackageRegistration alternatePackageRegistration,
            Package alternatePackage,
            string customMessage,
            User user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            if (packages == null || !packages.Any())
            {
                throw new ArgumentException(nameof(packages));
            }

            var registration = packages.First().PackageRegistration;

            if (packages.Select(p => p.PackageRegistrationKey).Distinct().Count() > 1)
            {
                throw new ArgumentException("All packages to deprecate must have the same ID.", nameof(packages));
            }

            using (var strategy = new SuspendDbExecutionStrategy())
                using (var transaction = _entitiesContext.GetDatabase().BeginTransaction())
                {
                    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)
                    {
                        _entitiesContext.Deprecations.RemoveRange(deprecations);
                    }
                    else
                    {
                        _entitiesContext.Deprecations.AddRange(deprecations);
                    }

                    await _entitiesContext.SaveChangesAsync();

                    await _packageUpdateService.UpdatePackagesAsync(packages);

                    transaction.Commit();

                    _telemetryService.TrackPackageDeprecate(
                        packages,
                        status,
                        alternatePackageRegistration,
                        alternatePackage,
                        !string.IsNullOrWhiteSpace(customMessage));

                    foreach (var package in packages)
                    {
                        await _auditingService.SaveAuditRecordAsync(
                            new PackageAuditRecord(
                                package,
                                status == PackageDeprecationStatus.NotDeprecated ? AuditedPackageAction.Undeprecate : AuditedPackageAction.Deprecate,
                                status == PackageDeprecationStatus.NotDeprecated ? PackageUndeprecatedVia.Web : PackageDeprecatedVia.Web));
                    }
                }
        }
Exemple #13
0
            public async Task ReturnsSuccessful(
                User currentUser,
                User owner,
                bool isVulnerable,
                bool isLegacy,
                bool isOther,
                PackageDeprecationStatus expectedStatus,
                ReturnsSuccessful_AlternatePackage_State alternatePackageState,
                bool hasAdditionalData)
            {
                // Arrange
                var id = "id";

                var featureFlagService = GetMock <IFeatureFlagService>();

                featureFlagService
                .Setup(x => x.IsManageDeprecationEnabled(currentUser))
                .Returns(true)
                .Verifiable();

                var registration = new PackageRegistration
                {
                    Id = id
                };

                registration.Owners.Add(owner);

                var package = new Package
                {
                    NormalizedVersion   = "2.3.4",
                    PackageRegistration = registration
                };

                var package2 = new Package
                {
                    NormalizedVersion   = "1.0.0",
                    PackageRegistration = registration
                };

                var unselectedPackage = new Package
                {
                    NormalizedVersion   = "1.3.2",
                    PackageRegistration = registration
                };

                var packageService = GetMock <IPackageService>();

                packageService
                .Setup(x => x.FindPackagesById(id, PackageDeprecationFieldsToInclude.DeprecationAndRelationships))
                .Returns(new[] { package, package2, unselectedPackage })
                .Verifiable();

                var alternatePackageId      = alternatePackageState != ReturnsSuccessful_AlternatePackage_State.None ? "altId" : null;
                var alternatePackageVersion = alternatePackageState == ReturnsSuccessful_AlternatePackage_State.Package ? "1.2.3-alt" : null;

                var alternatePackageRegistration = new PackageRegistration
                {
                    Id = alternatePackageId
                };

                var alternatePackage = new Package
                {
                    NormalizedVersion   = alternatePackageVersion,
                    PackageRegistration = alternatePackageRegistration
                };

                if (alternatePackageState == ReturnsSuccessful_AlternatePackage_State.Registration)
                {
                    packageService
                    .Setup(x => x.FindPackageRegistrationById(alternatePackageId))
                    .Returns(alternatePackageRegistration)
                    .Verifiable();
                }
                else if (alternatePackageState == ReturnsSuccessful_AlternatePackage_State.Package)
                {
                    packageService
                    .Setup(x => x.FindPackageByIdAndVersionStrict(alternatePackageId, alternatePackageVersion))
                    .Returns(alternatePackage)
                    .Verifiable();
                }

                var deprecationService = GetMock <IPackageDeprecationService>();

                var cveIds = hasAdditionalData ? new[] { "CVE-2019-1111", "CVE-2019-22222", "CVE-2019-333333" } : null;
                var cves   = cveIds?.Select(i => new Cve {
                    CveId = i
                }).ToArray() ?? new Cve[0];

                deprecationService
                .Setup(x => x.GetOrCreateCvesByIdAsync(cveIds ?? Enumerable.Empty <string>(), false))
                .CompletesWith(cves)
                .Verifiable();

                var cvss = hasAdditionalData ? (decimal?)5.5 : null;

                var cweIds = hasAdditionalData ? new[] { "CWE-1", "CWE-2", "CWE-3" } : null;
                var cwes   = cweIds?.Select(i => new Cwe {
                    CweId = i
                }).ToArray() ?? new Cwe[0];

                deprecationService
                .Setup(x => x.GetCwesById(cweIds ?? Enumerable.Empty <string>()))
                .Returns(cwes)
                .Verifiable();

                var customMessage = hasAdditionalData ? "message" : null;

                deprecationService
                .Setup(x => x.UpdateDeprecation(
                           new[] { package, package2 },
                           expectedStatus,
                           cves,
                           cvss,
                           cwes,
                           alternatePackageState == ReturnsSuccessful_AlternatePackage_State.Registration ? alternatePackageRegistration : null,
                           alternatePackageState == ReturnsSuccessful_AlternatePackage_State.Package ? alternatePackage : null,
                           customMessage))
                .Completes()
                .Verifiable();

                var controller = GetController <ManageDeprecationJsonApiController>();

                controller.SetCurrentUser(currentUser);

                // Act
                var result = await controller.Deprecate(
                    id,
                    new[] { package.NormalizedVersion, package2.NormalizedVersion },
                    isVulnerable,
                    isLegacy,
                    isOther,
                    cveIds,
                    cvss,
                    cweIds,
                    alternatePackageId,
                    alternatePackageVersion,
                    customMessage);

                // Assert
                AssertSuccessResponse(controller);
                featureFlagService.Verify();
                packageService.Verify();
                deprecationService.Verify();
            }
            private void VerifyDeprecationProjections(
                PackageDeprecationStatus status,
                string alternatePackageId,
                string alternatePackageVersionRange)
            {
                // Arrange
                string customMessage = null;

                Mock <DbDataReader> dataReaderMock;

                if (status == PackageDeprecationStatus.NotDeprecated)
                {
                    dataReaderMock = MockDataReader(status);
                }
                else
                {
                    customMessage = "custom message";

                    dataReaderMock = MockDataReader(
                        status,
                        customMessage,
                        alternatePackageId,
                        alternatePackageVersionRange);
                }

                // Act
                var projection = _db2catalogProjection.ReadDeprecationInfoFromDataReader(dataReaderMock.Object);

                // Assert
                if (status == PackageDeprecationStatus.NotDeprecated)
                {
                    Assert.Null(projection);
                }
                else
                {
                    Assert.NotNull(projection);

                    foreach (var deprecationStatusFlag in Enum.GetValues(typeof(PackageDeprecationStatus))
                             .Cast <PackageDeprecationStatus>()
                             .Except(new[] { PackageDeprecationStatus.NotDeprecated }))
                    {
                        if (status.HasFlag(deprecationStatusFlag))
                        {
                            Assert.Contains(deprecationStatusFlag.ToString(), projection.Reasons);
                        }
                        else
                        {
                            Assert.DoesNotContain(deprecationStatusFlag.ToString(), projection.Reasons);
                        }
                    }

                    Assert.Equal(customMessage, projection.Message);
                    Assert.Equal(alternatePackageId, projection.AlternatePackageId);

                    if (alternatePackageId != null && alternatePackageVersionRange == null)
                    {
                        Assert.Equal(Db2CatalogProjection.AlternatePackageVersionWildCard, projection.AlternatePackageRange);
                    }
                    else if (alternatePackageId == null)
                    {
                        Assert.Null(projection.AlternatePackageRange);
                    }
                    else
                    {
                        Assert.Equal(
                            $"[{alternatePackageVersionRange}, )",
                            projection.AlternatePackageRange);
                    }
                }
            }