Skip to content

Commit 5cc7aba

Browse files
committed
C#: Make a complete replacement of the default nuget.org feed in case private registries with replaces-base: true is set.
1 parent f3987d2 commit 5cc7aba

2 files changed

Lines changed: 93 additions & 4 deletions

File tree

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FeedManager.cs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
1010
{
1111
internal sealed partial class FeedManager : IDisposable
1212
{
13-
internal const string PublicNugetOrgFeed = "https://api.nuget.org/v3/index.json";
13+
private const string PublicNugetOrg = "nuget.org";
14+
private const string PublicDotNugetOrg = $".{PublicNugetOrg}";
15+
internal const string PublicApiNugetOrgFeed = $"https://api{PublicDotNugetOrg}/v3/index.json";
1416

1517
private readonly ILogger logger;
1618
private readonly IDotNet dotnet;
1719
private readonly IFileProvider fileProvider;
1820
private readonly DependencyDirectory emptyPackageDirectory;
1921
private readonly ImmutableHashSet<string> privateRegistryFeeds;
22+
private readonly bool hasPrivateRegistryBaseFeeds;
23+
private readonly ImmutableHashSet<string> privateRegistryBaseFeeds;
2024
private readonly IFeedManagerIO feedManagerIo;
2125

2226
/// <summary>
@@ -93,9 +97,12 @@ public FeedManager(ILogger logger, IDotNet dotnet, IDependabotProxy? dependabotP
9397
this.feedManagerIo = feedManagerIo;
9498
privateRegistryFeeds = dependabotProxy?.RegistryURLs ?? [];
9599
HasPrivateRegistryFeeds = privateRegistryFeeds.Count > 0;
96-
DefaultFeeds = dependabotProxy?.RegistryBaseURLs.Any() == true
97-
? dependabotProxy.RegistryBaseURLs
98-
: [PublicNugetOrgFeed];
100+
privateRegistryBaseFeeds = dependabotProxy?.RegistryBaseURLs ?? [];
101+
hasPrivateRegistryBaseFeeds = privateRegistryBaseFeeds.Count > 0;
102+
103+
DefaultFeeds = hasPrivateRegistryBaseFeeds
104+
? privateRegistryBaseFeeds
105+
: [PublicApiNugetOrgFeed];
99106
emptyPackageDirectory = new DependencyDirectory("empty", "empty package", logger);
100107

101108
lazyExplicitFeeds = new Lazy<ImmutableHashSet<string>>(GetExplicitFeeds);
@@ -120,6 +127,20 @@ public FeedManager(ILogger logger, IDotNet dotnet, IDependabotProxy? dependabotP
120127
{
121128
}
122129

130+
private bool IsNugetOrgFeed(string url)
131+
{
132+
try
133+
{
134+
var uri = new Uri(url);
135+
return uri.Host.EndsWith(PublicDotNugetOrg, StringComparison.InvariantCultureIgnoreCase) ||
136+
string.Equals(uri.Host, PublicNugetOrg, StringComparison.InvariantCultureIgnoreCase);
137+
}
138+
catch (UriFormatException)
139+
{
140+
return false;
141+
}
142+
}
143+
123144
private IEnumerable<string> GetFeeds(Func<IList<string>> getNugetFeeds)
124145
{
125146
var results = getNugetFeeds();
@@ -141,6 +162,17 @@ private IEnumerable<string> GetFeeds(Func<IList<string>> getNugetFeeds)
141162
continue;
142163
}
143164

165+
if (hasPrivateRegistryBaseFeeds && IsNugetOrgFeed(url))
166+
{
167+
// Use private registry base feeds.
168+
foreach (var feed in privateRegistryBaseFeeds)
169+
{
170+
logger.LogDebug($"Using private registry base feed '{feed}'.");
171+
yield return feed;
172+
}
173+
continue;
174+
}
175+
144176
yield return url;
145177
}
146178
}

csharp/extractor/Semmle.Extraction.Tests/FeedManager.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,5 +246,62 @@ public void TestDefaultFeeds2()
246246
"https://example.com/base2"
247247
], reachableFallback);
248248
}
249+
250+
[Fact]
251+
public void TestNugetOrg()
252+
{
253+
// Setup
254+
var logger = new LoggerStub();
255+
var dotnet = new DotNetStub([], [], [], ["E https://api.nuget.org/v3/index.json"]);
256+
var dependabotProxy = new DependabotProxyStub();
257+
var fileProvider = new FileProviderStub();
258+
var feedManagerIo = new FeedManagerIOStub(["https://example.com/registry2", "https://example.com/base1"]);
259+
var feedManager = new FeedManager(logger, dotnet, dependabotProxy, fileProvider, feedManagerIo);
260+
261+
// Execute
262+
var explicitFeeds = feedManager.ExplicitFeeds;
263+
var allFeeds = feedManager.AllFeeds;
264+
265+
// Verify
266+
Assert.Equal([
267+
"https://example.com/registry1",
268+
"https://example.com/registry2",
269+
], explicitFeeds);
270+
Assert.Equal([
271+
"https://example.com/registry1",
272+
"https://example.com/registry2",
273+
"https://api.nuget.org/v3/index.json"
274+
], allFeeds);
275+
276+
}
277+
[Fact]
278+
public void TestNugetOrgReplacement()
279+
{
280+
// Setup
281+
var logger = new LoggerStub();
282+
var dotnet = new DotNetStub([], [], ["E https://api.nuget.org/v3/index.json"], ["E https://api.nuget.org/v3/index.json"]);
283+
var dependabotProxy = new DependabotProxyStubWithBaseUrls();
284+
var fileProvider = new FileProviderStub();
285+
var feedManagerIo = new FeedManagerIOStub(["https://example.com/registry2", "https://example.com/base1"]);
286+
var feedManager = new FeedManager(logger, dotnet, dependabotProxy, fileProvider, feedManagerIo);
287+
288+
// Execute
289+
var explicitFeeds = feedManager.ExplicitFeeds;
290+
var allFeeds = feedManager.AllFeeds;
291+
292+
// Verify
293+
Assert.Equal([
294+
"https://example.com/base1",
295+
"https://example.com/base2",
296+
"https://example.com/registry1",
297+
"https://example.com/registry2"
298+
], explicitFeeds);
299+
Assert.Equal([
300+
"https://example.com/base1",
301+
"https://example.com/base2",
302+
"https://example.com/registry1",
303+
"https://example.com/registry2",
304+
], allFeeds);
305+
}
249306
}
250307
}

0 commit comments

Comments
 (0)