Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

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

## [0.9.1] - 2024-12-09
### Changed
Expand Down
53 changes: 53 additions & 0 deletions src/AzureAuth.Test/CommandAadTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,59 @@ public void TestEvaluateOptionsWithoutAliasValidCommandLineOptions()
subject.TokenFetcherOptions.Should().BeEquivalentTo(expected);
}

[Test]
public void TestEvaluateOptionsWithAuthModeFromCommandLineOptions()
{
CommandAad subject = this.serviceProvider.GetService<CommandAad>();
subject.Resource = "f0e8d801-3a50-48fd-b2da-6476d6e832a2";
subject.Client = "e19f71ed-3b14-448d-9346-9eff9753646b";
subject.Tenant = "9f6227ee-3d14-473e-8bed-1281171ef8c9";
subject.AuthModes = new List<AuthMode>() { AuthMode.DeviceCode };

this.envMock.Setup(env => env.Get(EnvVars.AuthMode)).Returns("Web,DeviceCode");
Comment thread
mvanchaa marked this conversation as resolved.
subject.EvaluateOptions().Should().BeTrue();
subject.AuthModes.Should().Contain(new[] { AuthMode.DeviceCode });
}

[Test]
public void TestEvaluateOptionsWithAuthModeFromEnvVar()
{
CommandAad subject = this.serviceProvider.GetService<CommandAad>();
subject.Resource = "f0e8d801-3a50-48fd-b2da-6476d6e832a2";
subject.Client = "e19f71ed-3b14-448d-9346-9eff9753646b";
subject.Tenant = "9f6227ee-3d14-473e-8bed-1281171ef8c9";

this.envMock.Setup(env => env.Get("AZUREAUTH_MODE")).Returns("Web,DeviceCode");
subject.EvaluateOptions().Should().BeTrue();
subject.AuthModes.Should().Contain(new[] { AuthMode.Web, AuthMode.DeviceCode });
}

[Test]
public void TestEvaluateOptionsWithNoAuthModeInEnvVarOrOptions()
{
CommandAad subject = this.serviceProvider.GetService<CommandAad>();
subject.Resource = "f0e8d801-3a50-48fd-b2da-6476d6e832a2";
subject.Client = "e19f71ed-3b14-448d-9346-9eff9753646b";
subject.Tenant = "9f6227ee-3d14-473e-8bed-1281171ef8c9";

this.envMock.Setup(env => env.Get(It.IsAny<string>())).Returns((string)null);
subject.EvaluateOptions().Should().BeTrue();
subject.AuthModes.Should().Contain(new[] { AuthMode.Default });
}

[Test]
public void TestEvaluateOptionsWithAuthModeFromInvalidEnvVars()
{
CommandAad subject = this.serviceProvider.GetService<CommandAad>();
subject.Resource = "f0e8d801-3a50-48fd-b2da-6476d6e832a2";
subject.Client = "e19f71ed-3b14-448d-9346-9eff9753646b";
subject.Tenant = "9f6227ee-3d14-473e-8bed-1281171ef8c9";

this.envMock.Setup(env => env.Get(EnvVars.AuthMode)).Returns("Invalid");
subject.EvaluateOptions().Should().BeFalse();
this.logTarget.Logs.Should().ContainMatch($"Invalid value specified for environment variable {EnvVars.AuthMode}*");
}

/// <summary>
/// The root path.
/// </summary>
Expand Down
54 changes: 48 additions & 6 deletions src/AzureAuth/Commands/CommandAad.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,13 @@ public class CommandAad
/// The help text for the <see cref="ModeOption"/> option.
/// </summary>
#if PlatformWindows
public const string AuthModeHelperText = @"Authentication mode. Repeated invocations allowed.
[default: broker, then web]
[possible values: all, iwa, broker, web, devicecode]";
public const string AuthModeHelperText = $"Authentication mode. Repeated invocations allowed.\n" +
Comment thread
mvanchaa marked this conversation as resolved.
Outdated
$"[default: broker, then web]\n" +
$"[possible values: {AuthModeAllowedValues}]";
#else
public const string AuthModeHelperText = @"Authentication mode. Repeated invocations allowed. [default: web]
[possible values: all, web, devicecode]";
public const string AuthModeHelperText = $"Authentication mode. Repeated invocations allowed.\n" +
$"[default: web]\n" +
$"[possible values: {AuthModeAllowedValues}]";
#endif

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

#if PlatformWindows
private const string AuthModeAllowedValues = "all, iwa, broker, web, devicecode";
#else
private const string AuthModeAllowedValues = "all, web, devicecode";
#endif

private const string ResourceOption = "--resource";
private const string ClientOption = "--client";

Expand Down Expand Up @@ -179,7 +186,7 @@ public CommandAad(CommandExecuteEventData eventData, ITelemetryService telemetry
/// Gets or sets the auth modes.
/// </summary>
[Option(ModeOption, AuthModeHelperText, CommandOptionType.MultipleValue)]
public IEnumerable<AuthMode> AuthModes { get; set; } = new[] { AuthMode.Default };
public IEnumerable<AuthMode> AuthModes { get; set; }
Comment thread
mvanchaa marked this conversation as resolved.

/// <summary>
/// Gets or sets the output.
Expand Down Expand Up @@ -272,6 +279,12 @@ public bool EvaluateOptions()
}
}

if (this.AuthModes is null && !this.TrySetAuthModeFromEnvOrDefault())
{
this.logger.LogError($"Invalid value specified for environment variable {EnvVars.AuthMode}. Allowed values are: {AuthModeAllowedValues}");
return false;
}

// Handle Resource Shorthand for Default Scope
if (evaluatedOptions.Scopes.IsNullOrEmpty() && !string.IsNullOrEmpty(evaluatedOptions.Resource))
{
Expand Down Expand Up @@ -405,5 +418,34 @@ private int GetToken(IPublicClientAuth publicClientAuth)

return 0;
}

/// <summary>
/// Sets the <see cref="AuthMode"/> from the environment variable and sets a default if not set.
/// </summary>
/// <returns>True if authmode is set.</returns>
public bool TrySetAuthModeFromEnvOrDefault()
{
var authModesFromEnv = this.env.Get(EnvVars.AuthMode);
if (string.IsNullOrEmpty(authModesFromEnv))
{
this.AuthModes = new[] { AuthMode.Default };
}

var result = new List<AuthMode>();
foreach(var val in authModesFromEnv.Split(','))
Comment thread
mvanchaa marked this conversation as resolved.
{
if (Enum.TryParse<AuthMode>(val, ignoreCase: true, out var mode))
{
result.Add(mode);
}
else
{
return false;
}
}

this.AuthModes = result;
return true;
}
}
}
5 changes: 5 additions & 0 deletions src/AzureAuth/EnvVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ public static class EnvVars
/// </summary>
public static readonly string AdoPat = $"{EnvVarPrefix}_ADO_PAT";

/// <summary>
/// Name of the env var to get the Auth Mode.
/// </summary>
public static readonly string AuthMode = $"{EnvVarPrefix}_MODE";

/// <summary>
/// Name of the env var used to disable user based authentication modes.
/// NOTE: This is a private variable and it is recommended to not rely on this variable.
Expand Down
Loading