diff --git a/src/Accounts/Accounts/ChangeLog.md b/src/Accounts/Accounts/ChangeLog.md index 0d28b8547940..da5b9558adb3 100644 --- a/src/Accounts/Accounts/ChangeLog.md +++ b/src/Accounts/Accounts/ChangeLog.md @@ -19,6 +19,7 @@ --> ## Upcoming Release +* Fixed an issue that Az.Accounts failed to be imported if multiple environment variables, which only differ by case, are set. [#18304] ## Version 2.8.0 * Added a preview feature allowing user to control the following configurations by using `Get-AzConfig`, `Update-AzConfig` and `Clear-AzConfig`: diff --git a/src/Accounts/Authentication.Test/UnitTests/DefaultEnvironmentVariableProviderTests.cs b/src/Accounts/Authentication.Test/UnitTests/DefaultEnvironmentVariableProviderTests.cs new file mode 100644 index 000000000000..434717a26cdb --- /dev/null +++ b/src/Accounts/Authentication.Test/UnitTests/DefaultEnvironmentVariableProviderTests.cs @@ -0,0 +1,48 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Common.Authentication.Config; +using Microsoft.Rest.ClientRuntime.Azure.TestFramework; +using Xunit; +using System; + +namespace Microsoft.Azure.Authentication.Test.UnitTests +{ + public class DefaultEnvironmentVariableProviderTests + { + [Fact] + [Trait(TestTraits.AcceptanceType, TestTraits.CheckIn)] + public void ShouldNotThrowWhen2EnvVarDifferOnlyByCase() + { + const string varName = "NameOfAnEnvVar"; + Environment.SetEnvironmentVariable(varName, "a"); + string varNameInUpper = varName.ToUpperInvariant(); + Environment.SetEnvironmentVariable(varNameInUpper, "b"); + + try + { + DefaultEnvironmentVariableProvider provider = new DefaultEnvironmentVariableProvider(); + var dict = provider.List(); + Assert.True(dict.ContainsKey(varName)); + Assert.True(dict.ContainsKey(varNameInUpper)); + Assert.Equal(dict[varName], dict[varNameInUpper]); + } + finally + { + Environment.SetEnvironmentVariable(varName, null); + Environment.SetEnvironmentVariable(varNameInUpper, null); + } + } + } +} diff --git a/src/Accounts/Authentication/Config/Helper/DefaultEnvironmentVariableProvider.cs b/src/Accounts/Authentication/Config/Helper/DefaultEnvironmentVariableProvider.cs index cbc44f067bbc..7ea5cd8e8279 100644 --- a/src/Accounts/Authentication/Config/Helper/DefaultEnvironmentVariableProvider.cs +++ b/src/Accounts/Authentication/Config/Helper/DefaultEnvironmentVariableProvider.cs @@ -16,6 +16,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; namespace Microsoft.Azure.Commands.Common.Authentication.Config @@ -32,9 +33,15 @@ public string Get(string variableName, EnvironmentVariableTarget target = Enviro public IReadOnlyDictionary List(EnvironmentVariableTarget target = EnvironmentVariableTarget.Process) { - return Environment.GetEnvironmentVariables() - .Cast() - .ToDictionary(pair => pair.Key.ToString(), pair => pair.Value.ToString(), StringComparer.OrdinalIgnoreCase); + IDictionary source = Environment.GetEnvironmentVariables(); + IDictionary results = new Dictionary(StringComparer.OrdinalIgnoreCase); + // cannot use ToDictionary() because keys (names of env var) may duplicate on Linux, + // with case being the only difference + foreach (var item in source.Cast()) + { + results[item.Key.ToString()] = item.Value.ToString(); + } + return new ReadOnlyDictionary(results); } public void Set(string variableName, string value, EnvironmentVariableTarget target = EnvironmentVariableTarget.Process)