dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.49k stars 10.04k forks source link

User Secrets broke on different first word capitalization #8602

Open Keroosha opened 5 years ago

Keroosha commented 5 years ago

Describe the bug

On adding secret key with different first word capitalization, CLI tool fall with unhandled exception until manually fixing secret.json, or changing key Id at csproj

To Reproduce

Steps to reproduce the behavior:

  1. Execute at project DIR commands:
    dotnet user-secrets set "ConnectionStrings:DefaultConnection" "test"
    dotnet user-secrets set "connectionStrings:DefaultConnection1" "test"
  2. Try to run anything else from user-secrets commands, for example:
    dotnet user-secrets list
  3. See error
    System.ArgumentException: An item with the same key has already been added. Key: ConnectionStrings:DefaultConnection1
    at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
    at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityCompa
    rer`1 comparer)
    at Microsoft.Extensions.SecretManager.Tools.Internal.SecretsStore.Load(String userSecretsId) in /_/src/dotnet-user-secrets/Internal/SecretsSto
    re.cs:line 79
    at Microsoft.Extensions.SecretManager.Tools.Internal.SecretsStore..ctor(String userSecretsId, IReporter reporter) in /_/src/dotnet-user-secret
    s/Internal/SecretsStore.cs:line 32
    at Microsoft.Extensions.SecretManager.Tools.Program.RunInternal(String[] args) in /_/src/dotnet-user-secrets/Program.cs:line 86
    at Microsoft.Extensions.SecretManager.Tools.Program.TryRun(String[] args, Int32& returnCode) in /_/src/dotnet-user-secrets/Program.cs:line 36
    Command failed : An item with the same key has already been added. Key: ConnectionStrings:DefaultConnection1

Expected behavior

Show error on adding, or fixing that issue silently for user

Additional context

.NET Core SDK (reflecting any global.json):
 Version:   2.2.105
 Commit:    7cecb35b92

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.14393
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.2.105\

Host (useful for support):
  Version: 2.2.3
  Commit:  6b8ad509b6

.NET Core SDKs installed:
  2.1.403 [C:\Program Files\dotnet\sdk]
  2.1.500 [C:\Program Files\dotnet\sdk]
  2.2.105 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
mkArtakMSFT commented 4 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

collinstevens commented 3 years ago

I was unable to reproduce this issue. It seems it may have been fixed and this hasn't been closed. See below for the output.

PS C:\projects\scratch> dotnet user-secrets --version
User Secrets Manager
5.0.6-servicing.21223.5+dc5e11abdb05b322f4b74b3afbcfb352fe984b2e

PS C:\projects\scratch> dotnet user-secrets init
Set UserSecretsId to '462f422a-24fe-40f1-aeeb-4746283e5d1a' for MSBuild project 'C:\projects\scratch\scratch.csproj'.

PS C:\projects\scratch> dotnet user-secrets list
No secrets configured for this application.

PS C:\projects\scratch> dotnet user-secrets set "ConnectionStrings:DefaultConnection" "test"
Successfully saved ConnectionStrings:DefaultConnection = test to the secret store.

PS C:\projects\scratch> dotnet user-secrets set "connectionStrings:DefaultConnection1" "test"
Successfully saved connectionStrings:DefaultConnection1 = test to the secret store.

PS C:\projects\scratch> dotnet user-secrets list
ConnectionStrings:DefaultConnection1 = test
ConnectionStrings:DefaultConnection = test
.NET SDK (reflecting any global.json):
 Version:   5.0.203
 Commit:    383637d63f

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19042
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\5.0.203\

Host (useful for support):
  Version: 5.0.6
  Commit:  478b2f8c0e

.NET SDKs installed:
  5.0.203 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download
jikuja commented 3 years ago

I think OP did a minor typo in the example and it should be the following:

dotnet user-secrets set "ConnectionStrings:DefaultConnection" "test"
dotnet user-secrets set "connectionStrings:DefaultConnection" "test2"

and now results are:

dotnet user-secrets list
ConnectionStrings:DefaultConnection = test2

Therefore looks like now key-value pair can be added with a different capitalization but only the value on of newest entry is kept and original key capitalization is maintained.

Some changes have happened in the other parts of the framework and behavior of the original bug report has been changed.

But the problem with key capitalization differences is still present:


Also if you pipe the following JSON as input for dotnet user-secrets set

{
  "ConnectionStrings:DefaultConnection": "test",
  "connectionStrings:DefaultConnection": "test2"
}

the command will fail

$ cat x.json | dotnet user-secrets set
System.FormatException: A duplicate key 'connectionStrings:DefaultConnection' was found.
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationFileParser.VisitValue(JsonElement value)
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationFileParser.VisitElement(JsonElement element)
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationFileParser.ParseStream(Stream input)
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationFileParser.Parse(Stream input)
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider.Load(Stream stream)
   at Microsoft.Extensions.SecretManager.Tools.Internal.SetCommand.FromStdInStrategy.Execute(CommandContext context)
   at Microsoft.Extensions.SecretManager.Tools.Program.RunInternal(String[] args)
   at Microsoft.Extensions.SecretManager.Tools.Program.TryRun(String[] args, Int32& returnCode)
Command failed : A duplicate key 'connectionStrings:DefaultConnection' was found.

Similar crash happens if you manually edit credential storage to have the same content as in the previous example

dotnet user-secrets list
System.FormatException: A duplicate key 'ConnectionStrings:DefaultConnection' was found.
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationFileParser.VisitValue(JsonElement value)
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationFileParser.VisitElement(JsonElement element)
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationFileParser.ParseStream(Stream input)
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationFileParser.Parse(Stream input)
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider.Load(Stream stream)
   at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
--- End of stack trace from previous location ---
   at Microsoft.Extensions.Configuration.FileConfigurationProvider.HandleException(ExceptionDispatchInfo info)
   at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
   at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load()
   at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
   at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
   at Microsoft.Extensions.SecretManager.Tools.Internal.SecretsStore.Load(String userSecretsId)
   at Microsoft.Extensions.SecretManager.Tools.Internal.SecretsStore..ctor(String userSecretsId, IReporter reporter)
   at Microsoft.Extensions.SecretManager.Tools.Program.RunInternal(String[] args)
   at Microsoft.Extensions.SecretManager.Tools.Program.TryRun(String[] args, Int32& returnCode)
Command failed : A duplicate key 'ConnectionStrings:DefaultConnection' was found.

Here you can see that different parts of the framework are used to parse string from the disk and the stdin. To make things even messier JSON is saved into a disk by using JObject.ToString.

⚠️⚠️ For a proper fix, the first step is to define if this tool and configuration extensions are case-sensitive or not. ⚠️⚠️


$ dotnet --info
.NET SDK (reflecting any global.json):
 Version:   5.0.203
 Commit:    383637d63f

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  10.15
 OS Platform: Darwin
 RID:         osx.10.15-x64
 Base Path:   /usr/local/share/dotnet/sdk/5.0.203/

Host (useful for support):
  Version: 5.0.6
  Commit:  478b2f8c0e

.NET SDKs installed:
  3.1.409 [/usr/local/share/dotnet/sdk]
  5.0.203 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.15 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.6 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.15 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.6 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download