Skip to content

Commit 8033d34

Browse files
authored
Properly no-op deprecations and allow unlisting at the same time in API (#9922)
* Allow a package to be unlisted at the same time as deprecated via API * Add proper package-level deprecation no-oping This will improve V3 performance for cases when a deprecation has not changed on a version Plumb through proper audit reason for deprecation via API * Only update deprecated-by if the deprecation changed * Use ListedVerb instead of nullable bool Fix #9921
1 parent 3b316f8 commit 8033d34

16 files changed

Lines changed: 312 additions & 62 deletions

src/GitHubVulnerabilities2Db/Gallery/GalleryDbVulnerabilityWriter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ public GalleryDbVulnerabilityWriter(
2525
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
2626
}
2727

28-
public async Task FlushAsync(string outputFileName = null)
28+
public Task FlushAsync(string outputFileName = null)
2929
{
3030
// This method is unused for this implementation.
31-
return;
31+
return Task.CompletedTask;
3232
}
3333

3434
public async Task<int> WriteVulnerabilitiesAsync(IEnumerable<Tuple<PackageVulnerability,bool>> vulnerabilities)

src/GitHubVulnerabilities2v3/Extensions/BlobStorageVulnerabilityWriter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public async Task<int> WriteVulnerabilitiesAsync(IEnumerable<Tuple<PackageVulner
122122
return vulnerabilities.Count();
123123
}
124124

125-
public async Task WriteVulnerabilityAsync(PackageVulnerability packageVulnerability, bool wasWithdrawn)
125+
public Task WriteVulnerabilityAsync(PackageVulnerability packageVulnerability, bool wasWithdrawn)
126126
{
127127
_firstVulnWrittenTimestamp = _firstVulnWrittenTimestamp == DateTime.MinValue ? DateTimeOffset.UtcNow : _firstVulnWrittenTimestamp;
128128
try
@@ -177,6 +177,8 @@ public async Task WriteVulnerabilityAsync(PackageVulnerability packageVulnerabil
177177
_logger.LogError(e, "WriteVulnerability Failed for Advisory Url {AdvisoryUrl}", packageVulnerability.AdvisoryUrl);
178178
throw;
179179
}
180+
181+
return Task.CompletedTask;
180182
}
181183

182184
public async Task<RunMode> DetermineRunMode(ReadWriteCursor<DateTimeOffset> cursor)

src/NuGetGallery.Core/Auditing/PackageAuditReasons.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ public static class PackageDeletedVia
3131

3232
public static class PackageDeprecatedVia
3333
{
34+
/// <summary>
35+
/// Package has been deprecated via NuGet API
36+
/// </summary>
37+
public const string Api = "Deprecated via API.";
38+
3439
/// <summary>
3540
/// Package has been deprecated via NuGet web interface (browser)
3641
/// </summary>
@@ -39,6 +44,11 @@ public static class PackageDeprecatedVia
3944

4045
public static class PackageUndeprecatedVia
4146
{
47+
/// <summary>
48+
/// Package has been undeprecated via NuGet API
49+
/// </summary>
50+
public const string Api = "Undeprecated via API.";
51+
4252
/// <summary>
4353
/// Package has been undeprecated via NuGet web interface (browser)
4454
/// </summary>

src/NuGetGallery.Core/Frameworks/PackageFrameworkCompatibilityFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class PackageFrameworkCompatibilityFactory : IPackageFrameworkCompatibili
1919
FrameworkProductNames.NetStandard,
2020
FrameworkProductNames.NetFramework
2121
};
22-
private readonly NuGetFrameworkSorter Sorter = new NuGetFrameworkSorter();
22+
private readonly NuGetFrameworkSorter Sorter = NuGetFrameworkSorter.Instance;
2323
private readonly int NetStartingMajorVersion = 5;
2424

2525
public PackageFrameworkCompatibility Create(ICollection<PackageFramework> packageFrameworks, string packageId, string packageVersion, bool includeComputedBadges = false)

src/NuGetGallery/Controllers/ApiController.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
using NuGetGallery.Infrastructure.Authentication;
2929
using NuGetGallery.Infrastructure.Mail.Messages;
3030
using NuGetGallery.Packaging;
31+
using NuGetGallery.RequestModels;
3132
using NuGetGallery.Security;
3233
using PackageIdValidator = NuGetGallery.Packaging.PackageIdValidator;
3334

@@ -1010,7 +1011,8 @@ public virtual async Task<ActionResult> DeprecatePackage(
10101011
bool isOther = false,
10111012
string alternatePackageId = null,
10121013
string alternatePackageVersion = null,
1013-
string message = null)
1014+
string message = null,
1015+
ListedVerb listedVerb = ListedVerb.Unchanged)
10141016
{
10151017
var registration = PackageService.FindPackageRegistrationById(id);
10161018
if (registration == null)
@@ -1035,12 +1037,14 @@ public virtual async Task<ActionResult> DeprecatePackage(
10351037
apiScopeEvaluationResult.Owner,
10361038
id,
10371039
versions.ToList(),
1040+
isLegacy || hasCriticalBugs || isOther ? PackageDeprecatedVia.Api : PackageUndeprecatedVia.Api,
10381041
isLegacy,
10391042
hasCriticalBugs,
10401043
isOther,
10411044
alternatePackageId,
10421045
alternatePackageVersion,
1043-
message);
1046+
message,
1047+
listedVerb);
10441048

10451049
if (error != null)
10461050
{

src/NuGetGallery/Controllers/ManageDeprecationJsonApiController.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Net;
77
using System.Threading.Tasks;
88
using System.Web.Mvc;
9+
using NuGetGallery.Auditing;
910
using NuGetGallery.Filters;
1011
using NuGetGallery.RequestModels;
1112

@@ -37,10 +38,13 @@ public virtual JsonResult GetAlternatePackageVersions(string id)
3738
public virtual async Task<JsonResult> Deprecate(
3839
DeprecatePackageRequest request)
3940
{
41+
var isDeprecated = request.IsLegacy || request.HasCriticalBugs || request.IsOther;
42+
4043
var error = await _deprecationManagementService.UpdateDeprecation(
4144
GetCurrentUser(),
4245
request.Id,
4346
request.Versions.ToList(),
47+
isDeprecated ? PackageDeprecatedVia.Web : PackageUndeprecatedVia.Web,
4448
request.IsLegacy,
4549
request.HasCriticalBugs,
4650
request.IsOther,
@@ -54,8 +58,7 @@ public virtual async Task<JsonResult> Deprecate(
5458
}
5559

5660
var packagePluralString = request.Versions.Count() > 1 ? "packages have" : "package has";
57-
var deprecatedString = request.IsLegacy || request.HasCriticalBugs || request.IsOther
58-
? "deprecated" : "undeprecated";
61+
var deprecatedString = isDeprecated ? "deprecated" : "undeprecated";
5962
TempData["Message"] =
6063
$"Your {packagePluralString} been {deprecatedString}. " +
6164
$"It may take several hours for this change to propagate through our system.";

src/NuGetGallery/NuGetGallery.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@
350350
<Compile Include="Modules\CookieComplianceHttpModule.cs" />
351351
<Compile Include="RequestModels\DeletePackagesApiRequest.cs" />
352352
<Compile Include="RequestModels\UpdateListedRequest.cs" />
353+
<Compile Include="Services\ListedVerb.cs" />
353354
<Compile Include="Services\MissingLicenseValidationMessageV2.cs" />
354355
<Compile Include="Services\NullTyposquattingService.cs" />
355356
<Compile Include="Services\UploadPackageMissingReadme.cs" />

src/NuGetGallery/Services/IPackageDeprecationManagementService.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ IReadOnlyCollection<string> GetPossibleAlternatePackageVersions(
2222
/// <param name="currentUser">The user that is performing the update.</param>
2323
/// <param name="id">The ID of the package to update.</param>
2424
/// <param name="versions">The versions of the package to update.</param>
25+
/// <param name="auditReason">A reason description used for auditing purposes.</param>
2526
/// <param name="isLegacy">Whether or not the packages are legacy.</param>
2627
/// <param name="hasCriticalBugs">Whether or not the packages have critical bugs.</param>
2728
/// <param name="isOther">Whether or not the packages have an unlisted reason for being deprecated.</param>
2829
/// <param name="alternatePackageId">An alternate package ID to use instead.</param>
2930
/// <param name="alternatePackageVersion">A version of <paramref name="alternatePackageId"/> to use instead.</param>
3031
/// <param name="message">A custom message to add to the deprecation.</param>
32+
/// <param name="listedVerb">The action to perform on the listed status of each package version.</param>
3133
/// <returns>
3234
/// <c>null</c> if there were no issues updating the deprecation.
3335
/// Otherwise, a <see cref="UpdateDeprecationError"/> that describes the problem that was encountered.
@@ -36,11 +38,13 @@ Task<UpdateDeprecationError> UpdateDeprecation(
3638
User currentUser,
3739
string id,
3840
IReadOnlyCollection<string> versions,
41+
string auditReason,
3942
bool isLegacy = false,
4043
bool hasCriticalBugs = false,
4144
bool isOther = false,
4245
string alternatePackageId = null,
4346
string alternatePackageVersion = null,
44-
string message = null);
47+
string message = null,
48+
ListedVerb listedVerb = ListedVerb.Unchanged);
4549
}
4650
}

src/NuGetGallery/Services/IPackageDeprecationService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ Task UpdateDeprecation(
2222
PackageRegistration alternatePackageRegistration,
2323
Package alternatePackage,
2424
string customMessage,
25-
User user);
25+
User user,
26+
ListedVerb listedVerb,
27+
string auditReason);
2628

2729
IReadOnlyList<PackageDeprecation> GetDeprecationsById(string id);
2830
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
namespace NuGetGallery
5+
{
6+
public enum ListedVerb
7+
{
8+
/// <summary>
9+
/// Leave the current listed status as is (either unlisted or listed).
10+
/// </summary>
11+
Unchanged,
12+
13+
/// <summary>
14+
/// Change the listed status to unlisted, allowing for no-op if the package is already unlisted.
15+
/// </summary>
16+
Unlist,
17+
18+
/// <summary>
19+
/// Change the listed status to listed, allowing for no-op if the package is already listed.
20+
/// </summary>
21+
Relist,
22+
}
23+
}

0 commit comments

Comments
 (0)