Skip to content

Commit 0ba6c4e

Browse files
authored
Add Program Context to UserAgent Header (#517)
Add Program context comment to user agent header to enable tracking of usage across our credprovider wrappers (ex conda, artifacts-keyring) example header with changes: `(NuGet) CredentialProvider.Microsoft/1.2.1 (Windows; X64; Microsoft Windows 10.0.22631) CLR/6.0.33 (.NETCoreApp,Version=v6.0; win10-x64; .NET 6.0.33)` before: `CredentialProvider.Microsoft/1.2.1 (Windows; X64; Microsoft Windows 10.0.22631) CLR/6.0.33 (.NETCoreApp,Version=v6.0; win10-x64; .NET 6.0.33)`
1 parent d6adc53 commit 0ba6c4e

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

.vscode/launch.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"version": "0.2.0",
33
"configurations": [
44
{
5-
"name": ".NET Core Launch (console)",
5+
"name": "net 6 launch",
66
"type": "coreclr",
77
"request": "launch",
88
"preLaunchTask": "build",
@@ -13,7 +13,10 @@
1313
],
1414
"cwd": "${workspaceFolder}/CredentialProvider.Microsoft",
1515
"console": "integratedTerminal",
16-
"stopAtEntry": false
16+
"stopAtEntry": false,
17+
"env": {
18+
"ARTIFACTS_CREDENTIALPROVIDER_PROGRAM_CONTEXT":"nuGET"
19+
}
1720
},
1821
{
1922
"name": ".NET Core Attach",

CredentialProvider.Microsoft/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public static async Task<int> Main(string[] args)
113113
multiLogger.Add(new PluginConnectionLogger(plugin.Connection));
114114
multiLogger.Verbose(Resources.RunningInPlugin);
115115
multiLogger.Verbose(string.Format(Resources.CommandLineArgs, PlatformInformation.GetProgramVersion(), Environment.CommandLine));
116+
EnvUtil.SetProgramContextInEnvironment(Context.NuGet);
116117

117118
await WaitForPluginExitAsync(plugin, multiLogger, TimeSpan.FromMinutes(2)).ConfigureAwait(continueOnCapturedContext: false);
118119
}

CredentialProvider.Microsoft/Util/EnvUtil.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public static class EnvUtil
3939
public const string EndpointCredentials = "ARTIFACTS_CREDENTIALPROVIDER_FEED_ENDPOINTS";
4040
public const string BuildTaskExternalEndpoints = "VSS_NUGET_EXTERNAL_FEED_ENDPOINTS";
4141

42+
public const string ProgramContext = "ARTIFACTS_CREDENTIALPROVIDER_PROGRAM_CONTEXT";
43+
4244
public static bool GetLogPIIEnabled()
4345
{
4446
return GetEnabledFromEnvironment(LogPIIEnvVar, defaultValue: false);
@@ -182,6 +184,24 @@ public static int GetDeviceFlowTimeoutFromEnvironmentInSeconds(ILogger logger)
182184
return null;
183185
}
184186

187+
public static Context? GetProgramContextFromEnvironment()
188+
{
189+
var context = Environment.GetEnvironmentVariable(ProgramContext);
190+
191+
if (!string.IsNullOrWhiteSpace(context) && Enum.TryParse<Context>(context, ignoreCase: true, out Context result))
192+
{
193+
return result;
194+
}
195+
196+
return null;
197+
}
198+
199+
public static void SetProgramContextInEnvironment(Context context)
200+
{
201+
Environment.SetEnvironmentVariable(ProgramContext, context.ToString());
202+
return;
203+
}
204+
185205
private static bool GetEnabledFromEnvironment(string envVar, bool defaultValue = true)
186206
{
187207
if (bool.TryParse(Environment.GetEnvironmentVariable(envVar), out bool result))

CredentialProvider.Microsoft/Util/HttpClientFactory.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Licensed under the MIT license.
44

55
using System.Net.Http;
6+
using System.Net.Http.Headers;
67
using Microsoft.Artifacts.Authentication;
78

89
namespace NuGetCredentialProvider.Util
@@ -26,7 +27,32 @@ static HttpClientFactory()
2627
UseDefaultCredentials = true
2728
});
2829

30+
// Add program context to headers if available
31+
if (ProgramContext != null)
32+
{
33+
httpClient.DefaultRequestHeaders.UserAgent.Add(ProgramContext);
34+
}
35+
2936
httpClientFactory = new(httpClient);
3037
}
38+
39+
private static ProductInfoHeaderValue ProgramContext
40+
{
41+
get
42+
{
43+
var context = EnvUtil.GetProgramContextFromEnvironment();
44+
return context != null
45+
? new ProductInfoHeaderValue($"({context})")
46+
: null;
47+
}
48+
}
49+
}
50+
51+
public enum Context
52+
{
53+
Maven,
54+
NuGet,
55+
Pip,
56+
Conda,
3157
}
3258
}

0 commit comments

Comments
 (0)