Skip to content

Commit a151ef0

Browse files
authored
Added support to read mode from environment variables for aad subcommands (#423)
* Support reading mode from env variables * update comment * early return when envvars is empty * log env auth mode * string manipulation * fix indendation
1 parent 5520cb0 commit a151ef0

4 files changed

Lines changed: 123 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Added
9+
- Added support for reading auth mode from the environment variable `AZUREAUTH_MODE` for aad subcommands.
810

911
## [0.9.1] - 2024-12-09
1012
### Changed

src/AzureAuth.Test/CommandAadTest.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ public void TestEvaluateOptionsProvidedAliasWithEnvVarConfig()
236236

237237
// Specify config via env var
238238
this.envMock.Setup(e => e.Get("AZUREAUTH_CONFIG")).Returns(configFile);
239+
this.envMock.Setup(env => env.Get(It.Is<string>(key => key != "AZUREAUTH_CONFIG"))).Returns<string>(key => null);
239240

240241
// Specify a client override on the command line.
241242
subject.Client = clientOverride;
@@ -444,6 +445,72 @@ public void TestEvaluateOptionsWithoutAliasValidCommandLineOptions()
444445
subject.TokenFetcherOptions.Should().BeEquivalentTo(expected);
445446
}
446447

448+
[Test]
449+
public void TestEvaluateOptionsWithAuthModeFromCommandLineOptions()
450+
{
451+
CommandAad subject = this.serviceProvider.GetService<CommandAad>();
452+
subject.Resource = "f0e8d801-3a50-48fd-b2da-6476d6e832a2";
453+
subject.Client = "e19f71ed-3b14-448d-9346-9eff9753646b";
454+
subject.Tenant = "9f6227ee-3d14-473e-8bed-1281171ef8c9";
455+
subject.AuthModes = new List<AuthMode>() { AuthMode.DeviceCode };
456+
457+
this.envMock.Setup(env => env.Get(EnvVars.AuthMode)).Returns("Web,DeviceCode");
458+
subject.EvaluateOptions().Should().BeTrue();
459+
subject.AuthModes.Should().Contain(new[] { AuthMode.DeviceCode });
460+
}
461+
462+
[Test]
463+
public void TestEvaluateOptionsWithAuthModeFromEnvVar()
464+
{
465+
CommandAad subject = this.serviceProvider.GetService<CommandAad>();
466+
subject.Resource = "f0e8d801-3a50-48fd-b2da-6476d6e832a2";
467+
subject.Client = "e19f71ed-3b14-448d-9346-9eff9753646b";
468+
subject.Tenant = "9f6227ee-3d14-473e-8bed-1281171ef8c9";
469+
470+
this.envMock.Setup(env => env.Get("AZUREAUTH_MODE")).Returns("Web,DeviceCode");
471+
subject.EvaluateOptions().Should().BeTrue();
472+
subject.AuthModes.Should().Contain(new[] { AuthMode.Web, AuthMode.DeviceCode });
473+
}
474+
475+
[Test]
476+
public void TestEvaluateOptionsWithNoAuthModeInEnvVarOrOptions()
477+
{
478+
CommandAad subject = this.serviceProvider.GetService<CommandAad>();
479+
subject.Resource = "f0e8d801-3a50-48fd-b2da-6476d6e832a2";
480+
subject.Client = "e19f71ed-3b14-448d-9346-9eff9753646b";
481+
subject.Tenant = "9f6227ee-3d14-473e-8bed-1281171ef8c9";
482+
483+
this.envMock.Setup(env => env.Get(It.IsAny<string>())).Returns((string)null);
484+
subject.EvaluateOptions().Should().BeTrue();
485+
subject.AuthModes.Should().Contain(new[] { AuthMode.Default });
486+
}
487+
488+
[Test]
489+
public void TestEvaluateOptionsWithAuthModeFromInvalidEnvVars()
490+
{
491+
CommandAad subject = this.serviceProvider.GetService<CommandAad>();
492+
subject.Resource = "f0e8d801-3a50-48fd-b2da-6476d6e832a2";
493+
subject.Client = "e19f71ed-3b14-448d-9346-9eff9753646b";
494+
subject.Tenant = "9f6227ee-3d14-473e-8bed-1281171ef8c9";
495+
496+
this.envMock.Setup(env => env.Get(EnvVars.AuthMode)).Returns("Invalid");
497+
subject.EvaluateOptions().Should().BeFalse();
498+
this.logTarget.Logs.Should().ContainMatch($"Invalid value specified for environment variable {EnvVars.AuthMode}*");
499+
}
500+
501+
[Test]
502+
public void TestEvaluateOptionsWithAuthModeFromEmptyEnvVars()
503+
{
504+
CommandAad subject = this.serviceProvider.GetService<CommandAad>();
505+
subject.Resource = "f0e8d801-3a50-48fd-b2da-6476d6e832a2";
506+
subject.Client = "e19f71ed-3b14-448d-9346-9eff9753646b";
507+
subject.Tenant = "9f6227ee-3d14-473e-8bed-1281171ef8c9";
508+
509+
this.envMock.Setup(env => env.Get(EnvVars.AuthMode)).Returns("");
510+
subject.EvaluateOptions().Should().BeTrue();
511+
subject.AuthModes.Should().Contain(new[] { AuthMode.Default });
512+
}
513+
447514
/// <summary>
448515
/// The root path.
449516
/// </summary>

src/AzureAuth/Commands/CommandAad.cs

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@ public class CommandAad
6060
/// The help text for the <see cref="ModeOption"/> option.
6161
/// </summary>
6262
#if PlatformWindows
63-
public const string AuthModeHelperText = @"Authentication mode. Repeated invocations allowed.
63+
public const string AuthModeHelperText = $@"Authentication mode. Repeated invocations allowed.
6464
[default: broker, then web]
65-
[possible values: all, iwa, broker, web, devicecode]";
65+
[possible values: {AuthModeAllowedValues}]";
6666
#else
67-
public const string AuthModeHelperText = @"Authentication mode. Repeated invocations allowed. [default: web]
68-
[possible values: all, web, devicecode]";
67+
public const string AuthModeHelperText = $@"Authentication mode. Repeated invocations allowed
68+
[default: web]
69+
[possible values: {AuthModeAllowedValues}]";
6970
#endif
7071

7172
/// <summary>
@@ -83,6 +84,12 @@ public class CommandAad
8384
/// </summary>
8485
public static readonly TimeSpan GlobalTimeout = TimeSpan.FromMinutes(15);
8586

87+
#if PlatformWindows
88+
private const string AuthModeAllowedValues = "all, iwa, broker, web, devicecode";
89+
#else
90+
private const string AuthModeAllowedValues = "all, web, devicecode";
91+
#endif
92+
8693
private const string ResourceOption = "--resource";
8794
private const string ClientOption = "--client";
8895

@@ -179,7 +186,7 @@ public CommandAad(CommandExecuteEventData eventData, ITelemetryService telemetry
179186
/// Gets or sets the auth modes.
180187
/// </summary>
181188
[Option(ModeOption, AuthModeHelperText, CommandOptionType.MultipleValue)]
182-
public IEnumerable<AuthMode> AuthModes { get; set; } = new[] { AuthMode.Default };
189+
public IEnumerable<AuthMode> AuthModes { get; set; }
183190

184191
/// <summary>
185192
/// Gets or sets the output.
@@ -272,6 +279,12 @@ public bool EvaluateOptions()
272279
}
273280
}
274281

282+
if (this.AuthModes is null && !this.TrySetAuthModeFromEnvOrDefault())
283+
{
284+
this.logger.LogError($"Invalid value specified for environment variable {EnvVars.AuthMode}. Allowed values are: {AuthModeAllowedValues}");
285+
return false;
286+
}
287+
275288
// Handle Resource Shorthand for Default Scope
276289
if (evaluatedOptions.Scopes.IsNullOrEmpty() && !string.IsNullOrEmpty(evaluatedOptions.Resource))
277290
{
@@ -405,5 +418,36 @@ private int GetToken(IPublicClientAuth publicClientAuth)
405418

406419
return 0;
407420
}
421+
422+
/// <summary>
423+
/// Sets the <see cref="AuthMode"/> from the environment variable and sets a default if not set.
424+
/// </summary>
425+
/// <returns>True if authmode is set.</returns>
426+
public bool TrySetAuthModeFromEnvOrDefault()
427+
{
428+
var authModesFromEnv = this.env.Get(EnvVars.AuthMode);
429+
if (string.IsNullOrEmpty(authModesFromEnv))
430+
{
431+
this.AuthModes = new[] { AuthMode.Default };
432+
return true;
433+
}
434+
435+
var result = new List<AuthMode>();
436+
foreach(var val in authModesFromEnv.Split(','))
437+
{
438+
if (Enum.TryParse<AuthMode>(val, ignoreCase: true, out var mode))
439+
{
440+
result.Add(mode);
441+
}
442+
else
443+
{
444+
return false;
445+
}
446+
}
447+
448+
this.AuthModes = result;
449+
this.eventData.Add($"env_{EnvVars.AuthMode}", authModesFromEnv);
450+
return true;
451+
}
408452
}
409453
}

src/AzureAuth/EnvVars.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ public static class EnvVars
4646
/// </summary>
4747
public static readonly string AdoPat = $"{EnvVarPrefix}_ADO_PAT";
4848

49+
/// <summary>
50+
/// Name of the env var to get the Auth Mode.
51+
/// </summary>
52+
public static readonly string AuthMode = $"{EnvVarPrefix}_MODE";
53+
4954
/// <summary>
5055
/// Name of the env var used to disable user based authentication modes.
5156
/// NOTE: This is a private variable and it is recommended to not rely on this variable.

0 commit comments

Comments
 (0)