From 169ebc15fdd6d48e60ee9ba3767391ac54bfdf6c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 19:17:10 +0000 Subject: [PATCH 1/6] [release/10.0.1xx] Use backward-compatible GUID generation in Wix 5 (#2926) Co-authored-by: Nikola Milosavljevic --- src/arcade/Directory.Packages.props | 2 +- .../tools/DefaultVersions.props | 2 +- .../build/wix5/wix.targets | 4 ++++ .../src/CreateWixBuildWixpack.cs | 8 ++++++++ src/aspnetcore/global.json | 2 +- src/aspnetcore/src/Installers/Windows/Wix.targets | 9 +++++++++ src/runtime/eng/Versions.props | 12 ++++++------ src/sdk/global.json | 2 +- .../src/Layout/pkg/windows/Directory.Build.targets | 9 +++++++++ 9 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/arcade/Directory.Packages.props b/src/arcade/Directory.Packages.props index 3b6b934b425..9e2d6effc94 100644 --- a/src/arcade/Directory.Packages.props +++ b/src/arcade/Directory.Packages.props @@ -11,7 +11,7 @@ 5.8.4 3.14.1-9323.2545153 - 5.0.2-dotnet.2737382 + 5.0.2-dotnet.2811440 2.9.3 diff --git a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/DefaultVersions.props b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/DefaultVersions.props index c1ccc8727a3..1f3433c1f8e 100644 --- a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/DefaultVersions.props +++ b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/DefaultVersions.props @@ -99,7 +99,7 @@ 2.1.3 1.1.286 3.14.1-9323.2545153 - 5.0.2-dotnet.2737382 + 5.0.2-dotnet.2811440 diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/wix.targets b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/wix.targets index 742bf80955f..f1e21028a38 100644 --- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/wix.targets +++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/wix.targets @@ -325,6 +325,8 @@ RunHeatHarvester"> $(InstallerName.Replace('-', '_')) + + -bcgg @@ -363,6 +365,7 @@ <_wixArgs>$(_wixArgs) $(AdditionalCandleArgs) <_wixArgs>$(_wixArgs) $(AdditionalLightArgs) + <_wixArgs>$(_wixArgs) $(WixAdditionalOptions) <_wixCommand>wix.exe build $(_wixArgs) @@ -381,6 +384,7 @@ RetryDelayBase="2" /> + + + + + $(CompilerAdditionalOptions) -bcgg + + + $(IntermediateOutputPath)wixpack @@ -117,6 +125,7 @@ 3.1.56 - 5.0.2-dotnet.2737382 - 5.0.2-dotnet.2737382 - 5.0.2-dotnet.2737382 - 5.0.2-dotnet.2737382 - 5.0.2-dotnet.2737382 - 5.0.2-dotnet.2737382 + 5.0.2-dotnet.2811440 + 5.0.2-dotnet.2811440 + 5.0.2-dotnet.2811440 + 5.0.2-dotnet.2811440 + 5.0.2-dotnet.2811440 + 5.0.2-dotnet.2811440 diff --git a/src/sdk/global.json b/src/sdk/global.json index eaf51045dc4..36c38f0ed3c 100644 --- a/src/sdk/global.json +++ b/src/sdk/global.json @@ -25,6 +25,6 @@ "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25514.103", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", - "Microsoft.WixToolset.Sdk": "5.0.2-dotnet.2737382" + "Microsoft.WixToolset.Sdk": "5.0.2-dotnet.2811440" } } diff --git a/src/sdk/src/Layout/pkg/windows/Directory.Build.targets b/src/sdk/src/Layout/pkg/windows/Directory.Build.targets index 6af25135bb8..f3abf2a9572 100644 --- a/src/sdk/src/Layout/pkg/windows/Directory.Build.targets +++ b/src/sdk/src/Layout/pkg/windows/Directory.Build.targets @@ -44,6 +44,14 @@ Text="Bundles must target x86. InstallerPlatform=$(InstallerPlatform)" /> + + + + + $(CompilerAdditionalOptions) -bcgg + + + $(IntermediateOutputPath)wixpack @@ -51,6 +59,7 @@ Date: Wed, 15 Oct 2025 22:03:59 +0000 Subject: [PATCH 2/6] [release/10.0.1xx] Clean existing .dotnet dir (#2934) Co-authored-by: Matt Thalman --- eng/pipelines/templates/jobs/vmr-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/pipelines/templates/jobs/vmr-build.yml b/eng/pipelines/templates/jobs/vmr-build.yml index 9e596f065e9..083d0212805 100644 --- a/eng/pipelines/templates/jobs/vmr-build.yml +++ b/eng/pipelines/templates/jobs/vmr-build.yml @@ -526,6 +526,7 @@ jobs: if [[ "$prepSdk" == "false" ]]; then customPrepArgs="${customPrepArgs} --no-sdk" + rm -rf $(sourcesPath)/.dotnet mkdir $(sourcesPath)/.dotnet previousSdkPath="$(sourcesPath)/prereqs/packages/archive/dotnet-sdk-*.tar.gz" eval tar -ozxf "$previousSdkPath" -C "$(sourcesPath)/.dotnet" From 329a75be2596496ada68882f850505945195853b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 15:53:13 -0700 Subject: [PATCH 3/6] [release/10.0.1xx] Source code updates from dotnet/sdk (#2932) Co-authored-by: dotnet-maestro[bot] --- src/sdk/eng/Version.Details.props | 4 ++-- src/sdk/eng/Version.Details.xml | 8 ++++---- .../WorkloadManifest.targets.in | 11 ++++++----- .../WorkloadManifest.targets.in | 4 ---- src/source-manifest.json | 4 ++-- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/sdk/eng/Version.Details.props b/src/sdk/eng/Version.Details.props index 40d846eb3dc..983fc777e61 100644 --- a/src/sdk/eng/Version.Details.props +++ b/src/sdk/eng/Version.Details.props @@ -140,8 +140,8 @@ This file should be imported by eng/Versions.props 2.1.0 - 2.1.0-preview.25511.2 - 4.1.0-preview.25511.2 + 2.1.0-preview.25514.10 + 4.1.0-preview.25514.10 diff --git a/src/sdk/eng/Version.Details.xml b/src/sdk/eng/Version.Details.xml index 20a7e6d4a1f..3bd6355dcd6 100644 --- a/src/sdk/eng/Version.Details.xml +++ b/src/sdk/eng/Version.Details.xml @@ -553,13 +553,13 @@ https://github.com/dotnet/dotnet 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/microsoft/testfx - f820ad104e64123673d850e8f892d84c8cae113c + 0cac6e8732572e1543aa4a1226afbd0c4d4ceda8 - + https://github.com/microsoft/testfx - f820ad104e64123673d850e8f892d84c8cae113c + 0cac6e8732572e1543aa4a1226afbd0c4d4ceda8 https://github.com/dotnet/dotnet diff --git a/src/sdk/src/Workloads/Manifests/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in b/src/sdk/src/Workloads/Manifests/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in index 90c46744a87..1e6eba7c63d 100644 --- a/src/sdk/src/Workloads/Manifests/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in +++ b/src/sdk/src/Workloads/Manifests/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in @@ -91,6 +91,12 @@ true + + + $(_RuntimePackInWorkloadVersionCurrent) + + + true @@ -220,7 +226,6 @@ <_MonoWorkloadRuntimePackPackageVersion>$(_RuntimePackInWorkloadVersionCurrent) - <_KnownWebAssemblySdkPackVersion>$(_RuntimePackInWorkloadVersionCurrent) @@ -235,10 +240,6 @@ $(_MonoWorkloadRuntimePackPackageVersion) - - $(_KnownWebAssemblySdkPackVersion) - - diff --git a/src/sdk/src/Workloads/Manifests/Microsoft.NET.Workload.Mono.Toolchain.net9.Manifest/WorkloadManifest.targets.in b/src/sdk/src/Workloads/Manifests/Microsoft.NET.Workload.Mono.Toolchain.net9.Manifest/WorkloadManifest.targets.in index 11b58a3db42..f787e69abb3 100644 --- a/src/sdk/src/Workloads/Manifests/Microsoft.NET.Workload.Mono.Toolchain.net9.Manifest/WorkloadManifest.targets.in +++ b/src/sdk/src/Workloads/Manifests/Microsoft.NET.Workload.Mono.Toolchain.net9.Manifest/WorkloadManifest.targets.in @@ -72,7 +72,6 @@ <_MonoWorkloadRuntimePackPackageVersion>$(_RuntimePackInWorkloadVersion9) - <_KnownWebAssemblySdkPackVersion>$(_RuntimePackInWorkloadVersion9) @@ -87,9 +86,6 @@ $(_MonoWorkloadRuntimePackPackageVersion) - - $(_KnownWebAssemblySdkPackVersion) - diff --git a/src/source-manifest.json b/src/source-manifest.json index 2a41719aee4..216a641c089 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -91,10 +91,10 @@ "commitSha": "082359066ee0064039b9b1f1f025bdd0507d06de" }, { - "barId": 287157, + "barId": 287252, "path": "sdk", "remoteUri": "https://github.com/dotnet/sdk", - "commitSha": "c92a32ff53dd25396b4603ca481dd078d97fcab8" + "commitSha": "2ee5539e482d6e38d4aa9c36ec33b9a232ad475d" }, { "barId": 282656, From a5b04da49b1b539b9ca491103a0525b6ad71e065 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 15:53:52 -0700 Subject: [PATCH 4/6] [release/10.0.1xx] Source code updates from dotnet/aspnetcore (#2936) Co-authored-by: dotnet-maestro[bot] --- src/aspnetcore/NuGet.config | 5 + src/aspnetcore/eng/Version.Details.props | 184 ++++----- src/aspnetcore/eng/Version.Details.xml | 370 +++++++++--------- .../eng/common/SetupNugetSources.sh | 6 +- src/aspnetcore/global.json | 6 +- .../src/IdentityUserPasskeyExtensions.cs | 35 ++ .../EntityFrameworkCore/src/UserOnlyStore.cs | 40 +- .../EntityFrameworkCore/src/UserStore.cs | 39 +- .../test/EF.InMemory.Test/InMemoryContext.cs | 52 ++- .../InMemoryStoreWithGenericsTest.cs | 4 + .../test/EF.Test/DbUtil.cs | 5 + .../test/EF.Test/SqlStoreTestBase.cs | 1 + .../UserStoreEncryptPersonalDataTest.cs | 1 + .../test/EF.Test/UserStoreTest.cs | 67 ++-- .../Utilities/ScratchDatabaseFixture.cs | 10 +- .../src/IdentitySpecificationTestBase.cs | 222 ++++++++++- .../src/UserManagerSpecificationTests.cs | 1 + .../test/InMemory.Test/InMemoryStore.cs | 77 ++++ src/source-manifest.json | 4 +- 19 files changed, 726 insertions(+), 403 deletions(-) create mode 100644 src/aspnetcore/src/Identity/EntityFrameworkCore/src/IdentityUserPasskeyExtensions.cs diff --git a/src/aspnetcore/NuGet.config b/src/aspnetcore/NuGet.config index c1a0e3ace90..bd0ec98d8c2 100644 --- a/src/aspnetcore/NuGet.config +++ b/src/aspnetcore/NuGet.config @@ -2,6 +2,11 @@ + + + + + diff --git a/src/aspnetcore/eng/Version.Details.props b/src/aspnetcore/eng/Version.Details.props index 81c977cfdd0..ad8179ee5d8 100644 --- a/src/aspnetcore/eng/Version.Details.props +++ b/src/aspnetcore/eng/Version.Details.props @@ -6,98 +6,98 @@ This file should be imported by eng/Versions.props - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-beta.25513.102 - 10.0.0-beta.25513.102 - 10.0.0-beta.25513.102 - 10.0.0-beta.25513.102 - 10.0.0-beta.25513.102 - 10.0.0-beta.25513.102 - 10.0.0-beta.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 3.2.0-preview.25513.102 - 7.0.0-rc.1402 - 7.0.0-rc.1402 - 7.0.0-rc.1402 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 - 10.0.0-rtm.25513.102 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0-beta.25514.103 + 10.0.0-beta.25514.103 + 10.0.0-beta.25514.103 + 10.0.0-beta.25514.103 + 10.0.0-beta.25514.103 + 10.0.0-beta.25514.103 + 10.0.0-beta.25514.103 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0-rtm.25514.103 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0-rtm.25514.103 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0-rtm.25514.103 + 10.0.0-rtm.25514.103 + 3.2.0-preview.25514.103 + 7.0.0-rc.1503 + 7.0.0-rc.1503 + 7.0.0-rc.1503 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 + 10.0.0 4.13.0-3.24613.7 4.13.0-3.24613.7 diff --git a/src/aspnetcore/eng/Version.Details.xml b/src/aspnetcore/eng/Version.Details.xml index 4135a2542e2..40941a2bb50 100644 --- a/src/aspnetcore/eng/Version.Details.xml +++ b/src/aspnetcore/eng/Version.Details.xml @@ -8,333 +8,333 @@ See https://github.com/dotnet/arcade/blob/master/Documentation/Darc.md for instructions on using darc. --> - + - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 @@ -358,37 +358,37 @@ - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 https://github.com/dotnet/extensions @@ -440,17 +440,17 @@ https://github.com/dotnet/msbuild d1cce8d7cc03c23a4f1bad8e9240714fd9d199a3 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 - + https://github.com/dotnet/dotnet - b502b6eeec0db06720ead7fd9570befa39a6b2f7 + 862de94f7792651640741a4651183e8bd5f64029 diff --git a/src/aspnetcore/eng/common/SetupNugetSources.sh b/src/aspnetcore/eng/common/SetupNugetSources.sh index dd2564aef01..b97cc536379 100755 --- a/src/aspnetcore/eng/common/SetupNugetSources.sh +++ b/src/aspnetcore/eng/common/SetupNugetSources.sh @@ -66,10 +66,8 @@ EnableInternalPackageSource() { grep -i " /dev/null if [ "$?" == "0" ]; then echo "Enabling internal source '$PackageSourceName'." - # Remove the disabled entry - local OldDisableValue="" - local NewDisableValue="" - sed -i.bak "s|$OldDisableValue|$NewDisableValue|" "$ConfigFile" + # Remove the disabled entry (including any surrounding comments or whitespace on the same line) + sed -i.bak "//d" "$ConfigFile" # Add the source name to PackageSources for credential handling PackageSources+=("$PackageSourceName") diff --git a/src/aspnetcore/global.json b/src/aspnetcore/global.json index f27324ab4e7..3e8390cb595 100644 --- a/src/aspnetcore/global.json +++ b/src/aspnetcore/global.json @@ -27,9 +27,9 @@ "jdk": "latest" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25513.102", - "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25513.102", - "Microsoft.DotNet.SharedFramework.Sdk": "10.0.0-beta.25513.102", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25514.103", + "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25514.103", + "Microsoft.DotNet.SharedFramework.Sdk": "10.0.0-beta.25514.103", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.WixToolset.Sdk": "5.0.2-dotnet.2811440" diff --git a/src/aspnetcore/src/Identity/EntityFrameworkCore/src/IdentityUserPasskeyExtensions.cs b/src/aspnetcore/src/Identity/EntityFrameworkCore/src/IdentityUserPasskeyExtensions.cs new file mode 100644 index 00000000000..4e2f4a040a5 --- /dev/null +++ b/src/aspnetcore/src/Identity/EntityFrameworkCore/src/IdentityUserPasskeyExtensions.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore; + +internal static class IdentityUserPasskeyExtensions +{ + extension(IdentityUserPasskey passkey) + where TKey : IEquatable + { + public void UpdateFromUserPasskeyInfo(UserPasskeyInfo passkeyInfo) + { + passkey.Data.Name = passkeyInfo.Name; + passkey.Data.SignCount = passkeyInfo.SignCount; + passkey.Data.IsBackedUp = passkeyInfo.IsBackedUp; + passkey.Data.IsUserVerified = passkeyInfo.IsUserVerified; + } + + public UserPasskeyInfo ToUserPasskeyInfo() + => new( + passkey.CredentialId, + passkey.Data.PublicKey, + passkey.Data.CreatedAt, + passkey.Data.SignCount, + passkey.Data.Transports, + passkey.Data.IsUserVerified, + passkey.Data.IsBackupEligible, + passkey.Data.IsBackedUp, + passkey.Data.AttestationObject, + passkey.Data.ClientDataJson) + { + Name = passkey.Data.Name + }; + } +} diff --git a/src/aspnetcore/src/Identity/EntityFrameworkCore/src/UserOnlyStore.cs b/src/aspnetcore/src/Identity/EntityFrameworkCore/src/UserOnlyStore.cs index 732e7ccee9f..2e711f498ee 100644 --- a/src/aspnetcore/src/Identity/EntityFrameworkCore/src/UserOnlyStore.cs +++ b/src/aspnetcore/src/Identity/EntityFrameworkCore/src/UserOnlyStore.cs @@ -625,10 +625,7 @@ public virtual async Task AddOrUpdatePasskeyAsync(TUser user, UserPasskeyInfo pa var userPasskey = await FindUserPasskeyByIdAsync(passkey.CredentialId, cancellationToken).ConfigureAwait(false); if (userPasskey != null) { - userPasskey.Data.Name = passkey.Name; - userPasskey.Data.SignCount = passkey.SignCount; - userPasskey.Data.IsBackedUp = passkey.IsBackedUp; - userPasskey.Data.IsUserVerified = passkey.IsUserVerified; + userPasskey.UpdateFromUserPasskeyInfo(passkey); UserPasskeys.Update(userPasskey); } else @@ -655,20 +652,7 @@ public virtual async Task> GetPasskeysAsync(TUser user, C var userId = user.Id; var passkeys = await UserPasskeys .Where(p => p.UserId.Equals(userId)) - .Select(p => new UserPasskeyInfo( - p.CredentialId, - p.Data.PublicKey, - p.Data.CreatedAt, - p.Data.SignCount, - p.Data.Transports, - p.Data.IsUserVerified, - p.Data.IsBackupEligible, - p.Data.IsBackedUp, - p.Data.AttestationObject, - p.Data.ClientDataJson) - { - Name = p.Data.Name, - }) + .Select(p => p.ToUserPasskeyInfo()) .ToListAsync(cancellationToken) .ConfigureAwait(false); @@ -708,26 +692,10 @@ public virtual async Task> GetPasskeysAsync(TUser user, C cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); ArgumentNullException.ThrowIfNull(user); + ArgumentNullException.ThrowIfNull(credentialId); var passkey = await FindUserPasskeyAsync(user.Id, credentialId, cancellationToken).ConfigureAwait(false); - if (passkey != null) - { - return new UserPasskeyInfo( - passkey.CredentialId, - passkey.Data.PublicKey, - passkey.Data.CreatedAt, - passkey.Data.SignCount, - passkey.Data.Transports, - passkey.Data.IsUserVerified, - passkey.Data.IsBackupEligible, - passkey.Data.IsBackedUp, - passkey.Data.AttestationObject, - passkey.Data.ClientDataJson) - { - Name = passkey.Data.Name, - }; - } - return null; + return passkey?.ToUserPasskeyInfo(); } /// diff --git a/src/aspnetcore/src/Identity/EntityFrameworkCore/src/UserStore.cs b/src/aspnetcore/src/Identity/EntityFrameworkCore/src/UserStore.cs index f3347a97259..50bf2f71b01 100644 --- a/src/aspnetcore/src/Identity/EntityFrameworkCore/src/UserStore.cs +++ b/src/aspnetcore/src/Identity/EntityFrameworkCore/src/UserStore.cs @@ -770,9 +770,7 @@ public virtual async Task AddOrUpdatePasskeyAsync(TUser user, UserPasskeyInfo pa var userPasskey = await FindUserPasskeyByIdAsync(passkey.CredentialId, cancellationToken).ConfigureAwait(false); if (userPasskey != null) { - userPasskey.Data.SignCount = passkey.SignCount; - userPasskey.Data.IsBackedUp = passkey.IsBackedUp; - userPasskey.Data.IsUserVerified = passkey.IsUserVerified; + userPasskey.UpdateFromUserPasskeyInfo(passkey); UserPasskeys.Update(userPasskey); } else @@ -799,20 +797,7 @@ public virtual async Task> GetPasskeysAsync(TUser user, C var userId = user.Id; var passkeys = await UserPasskeys .Where(p => p.UserId.Equals(userId)) - .Select(p => new UserPasskeyInfo( - p.CredentialId, - p.Data.PublicKey, - p.Data.CreatedAt, - p.Data.SignCount, - p.Data.Transports, - p.Data.IsUserVerified, - p.Data.IsBackupEligible, - p.Data.IsBackedUp, - p.Data.AttestationObject, - p.Data.ClientDataJson) - { - Name = p.Data.Name - }) + .Select(p => p.ToUserPasskeyInfo()) .ToListAsync(cancellationToken) .ConfigureAwait(false); @@ -851,27 +836,11 @@ public virtual async Task> GetPasskeysAsync(TUser user, C { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); + ArgumentNullException.ThrowIfNull(user); ArgumentNullException.ThrowIfNull(credentialId); var passkey = await FindUserPasskeyAsync(user.Id, credentialId, cancellationToken).ConfigureAwait(false); - if (passkey != null) - { - return new UserPasskeyInfo( - passkey.CredentialId, - passkey.Data.PublicKey, - passkey.Data.CreatedAt, - passkey.Data.SignCount, - passkey.Data.Transports, - passkey.Data.IsUserVerified, - passkey.Data.IsBackupEligible, - passkey.Data.IsBackedUp, - passkey.Data.AttestationObject, - passkey.Data.ClientDataJson) - { - Name = passkey.Data.Name - }; - } - return null; + return passkey?.ToUserPasskeyInfo(); } /// diff --git a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryContext.cs b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryContext.cs index d5e292d7404..37cb9ba7785 100644 --- a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryContext.cs +++ b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryContext.cs @@ -3,17 +3,31 @@ using System.Data.Common; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test; public class InMemoryContext : InMemoryContext { - private InMemoryContext(DbConnection connection) : base(connection) + private InMemoryContext(DbConnection connection, IServiceProvider serviceProvider) : base(connection, serviceProvider) { } - public static new InMemoryContext Create(DbConnection connection) - => Initialize(new InMemoryContext(connection)); + public static new InMemoryContext Create(DbConnection connection, IServiceCollection services = null) + { + services = ConfigureDbServices(services); + return Initialize(new InMemoryContext(connection, services.BuildServiceProvider())); + } + + public static IServiceCollection ConfigureDbServices(IServiceCollection services = null) + { + services ??= new ServiceCollection(); + services.Configure(options => + { + options.Stores.SchemaVersion = IdentitySchemaVersions.Version3; + }); + return services; + } public static TContext Initialize(TContext context) where TContext : DbContext { @@ -28,17 +42,25 @@ public class InMemoryContext : where TUser : IdentityUser { private readonly DbConnection _connection; + private readonly IServiceProvider _serviceProvider; - private InMemoryContext(DbConnection connection) + private InMemoryContext(DbConnection connection, IServiceProvider serviceProvider) { _connection = connection; + _serviceProvider = serviceProvider; } - public static InMemoryContext Create(DbConnection connection) - => InMemoryContext.Initialize(new InMemoryContext(connection)); + public static InMemoryContext Create(DbConnection connection, IServiceCollection services = null) + { + services = InMemoryContext.ConfigureDbServices(services); + return InMemoryContext.Initialize(new InMemoryContext(connection, services.BuildServiceProvider())); + } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - => optionsBuilder.UseSqlite(_connection); + { + optionsBuilder.UseSqlite(_connection); + optionsBuilder.UseApplicationServiceProvider(_serviceProvider); + } } public class InMemoryContext : IdentityDbContext @@ -47,17 +69,25 @@ public class InMemoryContext : IdentityDbContext { private readonly DbConnection _connection; + private readonly IServiceProvider _serviceProvider; - protected InMemoryContext(DbConnection connection) + protected InMemoryContext(DbConnection connection, IServiceProvider serviceProvider) { _connection = connection; + _serviceProvider = serviceProvider; } - public static InMemoryContext Create(DbConnection connection) - => InMemoryContext.Initialize(new InMemoryContext(connection)); + public static InMemoryContext Create(DbConnection connection, IServiceCollection services = null) + { + services = InMemoryContext.ConfigureDbServices(services); + return InMemoryContext.Initialize(new InMemoryContext(connection, services.BuildServiceProvider())); + } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - => optionsBuilder.UseSqlite(_connection); + { + optionsBuilder.UseSqlite(_connection); + optionsBuilder.UseApplicationServiceProvider(_serviceProvider); + } } public abstract class InMemoryContext : diff --git a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryStoreWithGenericsTest.cs b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryStoreWithGenericsTest.cs index f85e2ea66e3..d4516b0b45b 100644 --- a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryStoreWithGenericsTest.cs +++ b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.InMemory.Test/InMemoryStoreWithGenericsTest.cs @@ -24,6 +24,10 @@ public InMemoryEFUserStoreTestWithGenerics(InMemoryDatabaseFixture fixture) var services = new ServiceCollection(); services.AddHttpContextAccessor(); + services.Configure(options => + { + options.Stores.SchemaVersion = IdentitySchemaVersions.Version3; + }); services.AddDbContext( options => options .UseSqlite(_fixture.Connection) diff --git a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/DbUtil.cs b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/DbUtil.cs index 4bfb6bb171e..a17c48bff2a 100644 --- a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/DbUtil.cs +++ b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/DbUtil.cs @@ -30,6 +30,11 @@ public static IServiceCollection ConfigureDbServices( .UseSqlite(connection); }); + services.Configure(options => + { + options.Stores.SchemaVersion = IdentitySchemaVersions.Version3; + }); + return services; } diff --git a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreTestBase.cs b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreTestBase.cs index 3d30b28e6f9..6d1718c79ae 100644 --- a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreTestBase.cs +++ b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/SqlStoreTestBase.cs @@ -37,6 +37,7 @@ protected virtual void SetupAddIdentity(IServiceCollection services) options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.User.AllowedUserNameCharacters = null; + options.Stores.SchemaVersion = IdentitySchemaVersions.Version3; }) .AddRoles() .AddDefaultTokenProviders() diff --git a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreEncryptPersonalDataTest.cs b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreEncryptPersonalDataTest.cs index 9aedbeaf192..5d143464c23 100644 --- a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreEncryptPersonalDataTest.cs +++ b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreEncryptPersonalDataTest.cs @@ -25,6 +25,7 @@ protected override void SetupAddIdentity(IServiceCollection services) options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.User.AllowedUserNameCharacters = null; + options.Stores.SchemaVersion = IdentitySchemaVersions.Version3; }) .AddDefaultTokenProviders() .AddEntityFrameworkStores() diff --git a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreTest.cs b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreTest.cs index fe7eb5ee900..4cc3e43918c 100644 --- a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreTest.cs +++ b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/UserStoreTest.cs @@ -19,6 +19,12 @@ public UserStoreTest(ScratchDatabaseFixture fixture) _fixture = fixture; } + public class UserStoreTestDbContext : IdentityDbContext + { + public UserStoreTestDbContext(DbContextOptions options) : base(options) + { } + } + public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions options) : base(options) @@ -38,9 +44,9 @@ public void CanCreateUserUsingEF() } } - private IdentityDbContext CreateContext() + private UserStoreTestDbContext CreateContext() { - var db = DbUtil.Create(_fixture.Connection); + var db = DbUtil.Create(_fixture.Connection); db.Database.EnsureCreated(); return db; } @@ -52,18 +58,18 @@ protected override object CreateTestContext() protected override void AddUserStore(IServiceCollection services, object context = null) { - services.AddSingleton>(new UserStore((IdentityDbContext)context)); + services.AddSingleton>(new UserStore((UserStoreTestDbContext)context)); } protected override void AddRoleStore(IServiceCollection services, object context = null) { - services.AddSingleton>(new RoleStore((IdentityDbContext)context)); + services.AddSingleton>(new RoleStore((UserStoreTestDbContext)context)); } [Fact] public async Task SqlUserStoreMethodsThrowWhenDisposedTest() { - var store = new UserStore(new IdentityDbContext(new DbContextOptionsBuilder().Options)); + var store = new UserStore(new UserStoreTestDbContext(new DbContextOptionsBuilder().Options)); store.Dispose(); await Assert.ThrowsAsync(async () => await store.AddClaimsAsync(null, null)); await Assert.ThrowsAsync(async () => await store.AddLoginAsync(null, null)); @@ -97,7 +103,7 @@ await Assert.ThrowsAsync( public async Task UserStorePublicNullCheckTest() { Assert.Throws("context", () => new UserStore(null)); - var store = new UserStore(new IdentityDbContext(new DbContextOptionsBuilder().Options)); + var store = new UserStore(new UserStoreTestDbContext(new DbContextOptionsBuilder().Options)); await Assert.ThrowsAsync("user", async () => await store.GetUserIdAsync(null)); await Assert.ThrowsAsync("user", async () => await store.GetUserNameAsync(null)); await Assert.ThrowsAsync("user", async () => await store.SetUserNameAsync(null, null)); @@ -195,7 +201,6 @@ public async Task FindByEmailThrowsWithTwoUsersWithSameEmail() userB.Email = "dupe@dupe.com"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(userB, "password")); await Assert.ThrowsAsync(async () => await manager.FindByEmailAsync("dupe@dupe.com")); - } [ConditionalFact] @@ -211,17 +216,17 @@ await Assert.ThrowsAsync( [ConditionalFact] public async Task ConcurrentUpdatesWillFail() { - var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; + var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; var user = CreateTestUser(); - using (var db = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) { db.Database.EnsureCreated(); var manager = CreateManager(db); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); } - using (var db = new IdentityDbContext(options)) - using (var db2 = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) + using (var db2 = new UserStoreTestDbContext(options)) { var manager1 = CreateManager(db); var manager2 = CreateManager(db2); @@ -242,17 +247,17 @@ public async Task ConcurrentUpdatesWillFail() [ConditionalFact] public async Task ConcurrentUpdatesWillFailWithDetachedUser() { - var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; + var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; var user = CreateTestUser(); - using (var db = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) { db.Database.EnsureCreated(); var manager = CreateManager(db); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); } - using (var db = new IdentityDbContext(options)) - using (var db2 = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) + using (var db2 = new UserStoreTestDbContext(options)) { var manager1 = CreateManager(db); var manager2 = CreateManager(db2); @@ -271,17 +276,17 @@ public async Task ConcurrentUpdatesWillFailWithDetachedUser() [ConditionalFact] public async Task DeleteAModifiedUserWillFail() { - var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; + var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; var user = CreateTestUser(); - using (var db = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) { db.Database.EnsureCreated(); var manager = CreateManager(db); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); } - using (var db = new IdentityDbContext(options)) - using (var db2 = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) + using (var db2 = new UserStoreTestDbContext(options)) { var manager1 = CreateManager(db); var manager2 = CreateManager(db2); @@ -301,17 +306,17 @@ public async Task DeleteAModifiedUserWillFail() [ConditionalFact] public async Task ConcurrentRoleUpdatesWillFail() { - var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; + var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; var role = new IdentityRole(Guid.NewGuid().ToString()); - using (var db = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) { db.Database.EnsureCreated(); var manager = CreateRoleManager(db); IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); } - using (var db = new IdentityDbContext(options)) - using (var db2 = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) + using (var db2 = new UserStoreTestDbContext(options)) { var manager1 = CreateRoleManager(db); var manager2 = CreateRoleManager(db2); @@ -332,17 +337,17 @@ public async Task ConcurrentRoleUpdatesWillFail() [ConditionalFact] public async Task ConcurrentRoleUpdatesWillFailWithDetachedRole() { - var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; + var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; var role = new IdentityRole(Guid.NewGuid().ToString()); - using (var db = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) { db.Database.EnsureCreated(); var manager = CreateRoleManager(db); IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); } - using (var db = new IdentityDbContext(options)) - using (var db2 = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) + using (var db2 = new UserStoreTestDbContext(options)) { var manager1 = CreateRoleManager(db); var manager2 = CreateRoleManager(db2); @@ -362,17 +367,17 @@ public async Task ConcurrentRoleUpdatesWillFailWithDetachedRole() [ConditionalFact] public async Task DeleteAModifiedRoleWillFail() { - var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; + var options = new DbContextOptionsBuilder().UseSqlite($"Data Source=D{Guid.NewGuid()}.db").Options; var role = new IdentityRole(Guid.NewGuid().ToString()); - using (var db = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) { db.Database.EnsureCreated(); var manager = CreateRoleManager(db); IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); } - using (var db = new IdentityDbContext(options)) - using (var db2 = new IdentityDbContext(options)) + using (var db = new UserStoreTestDbContext(options)) + using (var db2 = new UserStoreTestDbContext(options)) { var manager1 = CreateRoleManager(db); var manager2 = CreateRoleManager(db2); diff --git a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/Utilities/ScratchDatabaseFixture.cs b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/Utilities/ScratchDatabaseFixture.cs index b29a046cff3..80b88e97387 100644 --- a/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/Utilities/ScratchDatabaseFixture.cs +++ b/src/aspnetcore/src/Identity/EntityFrameworkCore/test/EF.Test/Utilities/ScratchDatabaseFixture.cs @@ -4,6 +4,7 @@ using System.Data.Common; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test; @@ -23,7 +24,14 @@ public ScratchDatabaseFixture() } private DbContext CreateEmptyContext() - => new DbContext(new DbContextOptionsBuilder().UseSqlite(_connection).Options); + { + var services = new ServiceCollection(); + services.Configure(options => options.Stores.SchemaVersion = IdentitySchemaVersions.Version3); + return new DbContext(new DbContextOptionsBuilder() + .UseSqlite(_connection) + .UseApplicationServiceProvider(services.BuildServiceProvider()) + .Options); + } public DbConnection Connection => _connection; diff --git a/src/aspnetcore/src/Identity/Specification.Tests/src/IdentitySpecificationTestBase.cs b/src/aspnetcore/src/Identity/Specification.Tests/src/IdentitySpecificationTestBase.cs index 2d0b0ccec43..7f587d5f87e 100644 --- a/src/aspnetcore/src/Identity/Specification.Tests/src/IdentitySpecificationTestBase.cs +++ b/src/aspnetcore/src/Identity/Specification.Tests/src/IdentitySpecificationTestBase.cs @@ -48,6 +48,7 @@ protected override void SetupIdentityServices(IServiceCollection services, objec options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.User.AllowedUserNameCharacters = null; + options.Stores.SchemaVersion = IdentitySchemaVersions.Version3; }).AddDefaultTokenProviders(); AddUserStore(services, context); AddRoleStore(services, context); @@ -236,7 +237,7 @@ public async Task CanAddRemoveRoleClaim() var roleSafe = CreateTestRole("ClaimsAdd"); IdentityResultAssert.IsSuccess(await manager.CreateAsync(role)); IdentityResultAssert.IsSuccess(await manager.CreateAsync(roleSafe)); - Claim[] claims = { new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3") }; + Claim[] claims = [new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3")]; foreach (Claim c in claims) { IdentityResultAssert.IsSuccess(await manager.AddClaimAsync(role, c)); @@ -366,9 +367,9 @@ public async Task CanAddUsersToRole() var role = CreateTestRole(roleName, useRoleNamePrefixAsRoleName: true); IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(role)); TUser[] users = - { + [ CreateTestUser("1"),CreateTestUser("2"),CreateTestUser("3"),CreateTestUser("4"), - }; + ]; foreach (var u in users) { IdentityResultAssert.IsSuccess(await manager.CreateAsync(u)); @@ -604,4 +605,219 @@ private List GenerateRoles(string namePrefix, int count) } return roles; } + + /// + /// Test. + /// + /// Task + [Fact] + public async Task CanAddAndRetrievePasskey() + { + var context = CreateTestContext(); + var manager = CreateManager(context); + Assert.True(manager.SupportsUserPasskey); + var user = CreateTestUser(); + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + + var credentialId = Guid.NewGuid().ToByteArray(); + var passkey = new UserPasskeyInfo( + credentialId, + publicKey: [1, 2, 3, 4], + DateTimeOffset.UtcNow, + signCount: 0, + transports: ["usb"], + isUserVerified: false, + isBackupEligible: true, + isBackedUp: false, + attestationObject: [5, 6, 7], + clientDataJson: [8, 9]) + { + Name = "InitialName" + }; + + IdentityResultAssert.IsSuccess(await manager.AddOrUpdatePasskeyAsync(user, passkey)); + + var fetchedPasskey = await manager.GetPasskeyAsync(user, credentialId); + AssertPasskeysEqual(passkey, fetchedPasskey); + + var fetchedPasskeys = await manager.GetPasskeysAsync(user); + Assert.Single(fetchedPasskeys); + AssertPasskeysEqual(passkey, fetchedPasskeys[0]); + } + + /// + /// Test. + /// + /// Task + [Fact] + public async Task CanRemovePasskey() + { + var context = CreateTestContext(); + var manager = CreateManager(context); + Assert.True(manager.SupportsUserPasskey); + var user = CreateTestUser(); + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + + var passkey = new UserPasskeyInfo( + credentialId: Guid.NewGuid().ToByteArray(), + publicKey: [1], + DateTimeOffset.UtcNow, + signCount: 0, + transports: null, + isUserVerified: false, + isBackupEligible: false, + isBackedUp: false, + attestationObject: [2], + clientDataJson: [3]) + { + Name = "ToRemove" + }; + + IdentityResultAssert.IsSuccess(await manager.AddOrUpdatePasskeyAsync(user, passkey)); + Assert.Single(await manager.GetPasskeysAsync(user)); + IdentityResultAssert.IsSuccess(await manager.RemovePasskeyAsync(user, passkey.CredentialId)); + Assert.Empty(await manager.GetPasskeysAsync(user)); + + // Second removal should not throw or change anything + IdentityResultAssert.IsSuccess(await manager.RemovePasskeyAsync(user, passkey.CredentialId)); + Assert.Empty(await manager.GetPasskeysAsync(user)); + } + + /// + /// Test. + /// + /// Task + [Fact] + public async Task CanAddMultiplePasskeys() + { + var context = CreateTestContext(); + var manager = CreateManager(context); + Assert.True(manager.SupportsUserPasskey); + var user = CreateTestUser(); + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + + var passkey1 = new UserPasskeyInfo( + credentialId: Guid.NewGuid().ToByteArray(), + publicKey: [1], + DateTimeOffset.UtcNow, + signCount: 0, + transports: ["usb"], + isUserVerified: false, + isBackupEligible: false, + isBackedUp: false, + attestationObject: [10], + clientDataJson: [11]) + { + Name = "One" + }; + var passkey2 = new UserPasskeyInfo( + credentialId: Guid.NewGuid().ToByteArray(), + publicKey: [2], + DateTimeOffset.UtcNow, + signCount: 5, + transports: ["nfc"], + isUserVerified: true, + isBackupEligible: false, + isBackedUp: false, + attestationObject: [12], + clientDataJson: [13]) + { + Name = "Two" + }; + + IdentityResultAssert.IsSuccess(await manager.AddOrUpdatePasskeyAsync(user, passkey1)); + IdentityResultAssert.IsSuccess(await manager.AddOrUpdatePasskeyAsync(user, passkey2)); + + var all = await manager.GetPasskeysAsync(user); + Assert.Equal(2, all.Count); + Assert.Contains(all, p => p.Name == "One"); + Assert.Contains(all, p => p.Name == "Two"); + + var fetchedPasskey1 = await manager.GetPasskeyAsync(user, passkey1.CredentialId); + var fetchedPasskey2 = await manager.GetPasskeyAsync(user, passkey2.CredentialId); + AssertPasskeysEqual(passkey1, fetchedPasskey1); + AssertPasskeysEqual(passkey2, fetchedPasskey2); + } + + /// + /// Test. + /// + /// Task + [Fact] + public async Task UpdatingPasskeyChangesOnlyMutableFields() + { + var context = CreateTestContext(); + var manager = CreateManager(context); + var user = CreateTestUser(); + IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); + + var original = new UserPasskeyInfo( + credentialId: Guid.NewGuid().ToByteArray(), + publicKey: [9, 9], + createdAt: DateTimeOffset.UtcNow, + signCount: 1, + transports: ["usb", "nfc"], + isUserVerified: false, + isBackupEligible: true, + isBackedUp: false, + attestationObject: [5], + clientDataJson: [6]) + { + Name = "ImmutableTest" + }; + IdentityResultAssert.IsSuccess(await manager.AddOrUpdatePasskeyAsync(user, original)); + + // Attempt to modify both mutable and immutable fields + var updated = new UserPasskeyInfo( + credentialId: original.CredentialId, + publicKey: [0xFF, 0xFF], + createdAt: original.CreatedAt.AddMinutes(5), + signCount: 3, + transports: ["ble"], + isUserVerified: true, + isBackupEligible: false, + isBackedUp: true, + attestationObject: [7], + clientDataJson: [8]) + { + Name = "Changed" + }; + + var expected = new UserPasskeyInfo( + credentialId: original.CredentialId, + publicKey: original.PublicKey, + createdAt: original.CreatedAt, + signCount: updated.SignCount, + transports: original.Transports, + isUserVerified: updated.IsUserVerified, + isBackupEligible: original.IsBackupEligible, + isBackedUp: updated.IsBackedUp, + attestationObject: original.AttestationObject, + clientDataJson: original.ClientDataJson) + { + Name = updated.Name, + }; + + IdentityResultAssert.IsSuccess(await manager.AddOrUpdatePasskeyAsync(user, updated)); + + var stored = await manager.GetPasskeyAsync(user, original.CredentialId); + AssertPasskeysEqual(expected, stored); + } + + private static void AssertPasskeysEqual(UserPasskeyInfo expected, UserPasskeyInfo actual) + { + Assert.NotNull(expected); + Assert.NotNull(actual); + + Assert.Equal(expected.Name, actual.Name); + Assert.Equal(expected.SignCount, actual.SignCount); + Assert.Equal(expected.IsBackedUp, actual.IsBackedUp); + Assert.Equal(expected.IsUserVerified, actual.IsUserVerified); + Assert.Equal(expected.PublicKey, actual.PublicKey); + Assert.Equal(expected.CreatedAt, actual.CreatedAt); + Assert.Equal(expected.IsBackupEligible, actual.IsBackupEligible); + Assert.Equal(expected.AttestationObject, actual.AttestationObject); + Assert.Equal(expected.ClientDataJson, actual.ClientDataJson); + Assert.Equal(expected.Transports, actual.Transports); + } } diff --git a/src/aspnetcore/src/Identity/Specification.Tests/src/UserManagerSpecificationTests.cs b/src/aspnetcore/src/Identity/Specification.Tests/src/UserManagerSpecificationTests.cs index 933dad56f92..5d58387bdfa 100644 --- a/src/aspnetcore/src/Identity/Specification.Tests/src/UserManagerSpecificationTests.cs +++ b/src/aspnetcore/src/Identity/Specification.Tests/src/UserManagerSpecificationTests.cs @@ -61,6 +61,7 @@ protected virtual IdentityBuilder SetupBuilder(IServiceCollection services, obje options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.User.AllowedUserNameCharacters = null; + options.Stores.SchemaVersion = IdentitySchemaVersions.Version3; }).AddDefaultTokenProviders(); AddUserStore(services, context); services.AddLogging(); diff --git a/src/aspnetcore/src/Identity/test/InMemory.Test/InMemoryStore.cs b/src/aspnetcore/src/Identity/test/InMemory.Test/InMemoryStore.cs index 23598c8b8ce..c5860db8458 100644 --- a/src/aspnetcore/src/Identity/test/InMemory.Test/InMemoryStore.cs +++ b/src/aspnetcore/src/Identity/test/InMemory.Test/InMemoryStore.cs @@ -9,6 +9,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory; public class InMemoryStore : InMemoryUserStore, IUserRoleStore, + IUserPasskeyStore, IQueryableRoleStore, IRoleClaimStore where TRole : PocoRole @@ -158,6 +159,82 @@ Task IRoleStore.FindByNameAsync(string roleName, CancellationToken return Task.FromResult(0); } + public Task AddOrUpdatePasskeyAsync(TUser user, UserPasskeyInfo passkey, CancellationToken cancellationToken) + { + var passkeyEntity = user.Passkeys.FirstOrDefault(p => p.CredentialId.SequenceEqual(passkey.CredentialId)); + if (passkeyEntity is null) + { + user.Passkeys.Add(ToPocoUserPasskey(user, passkey)); + } + else + { + passkeyEntity.Name = passkey.Name; + passkeyEntity.SignCount = passkey.SignCount; + passkeyEntity.IsBackedUp = passkey.IsBackedUp; + passkeyEntity.IsUserVerified = passkey.IsUserVerified; + } + return Task.CompletedTask; + } + + public Task> GetPasskeysAsync(TUser user, CancellationToken cancellationToken) + { + return Task.FromResult>(user.Passkeys.Select(ToUserPasskeyInfo).ToList()!); + } + + public Task FindByPasskeyIdAsync(byte[] credentialId, CancellationToken cancellationToken) + { + return Task.FromResult(Users.FirstOrDefault(u => u.Passkeys.Any(p => p.CredentialId.SequenceEqual(credentialId)))); + } + + public Task FindPasskeyAsync(TUser user, byte[] credentialId, CancellationToken cancellationToken) + { + return Task.FromResult(ToUserPasskeyInfo(user.Passkeys.FirstOrDefault(p => p.CredentialId.SequenceEqual(credentialId)))); + } + + public Task RemovePasskeyAsync(TUser user, byte[] credentialId, CancellationToken cancellationToken) + { + var passkey = user.Passkeys.SingleOrDefault(p => p.CredentialId.SequenceEqual(credentialId)); + if (passkey is not null) + { + user.Passkeys.Remove(passkey); + } + + return Task.CompletedTask; + } + + private static UserPasskeyInfo ToUserPasskeyInfo(PocoUserPasskey p) + => p is null ? null : new( + p.CredentialId, + p.PublicKey, + p.CreatedAt, + p.SignCount, + p.Transports, + p.IsUserVerified, + p.IsBackupEligible, + p.IsBackedUp, + p.AttestationObject, + p.ClientDataJson) + { + Name = p.Name + }; + + private static PocoUserPasskey ToPocoUserPasskey(TUser user, UserPasskeyInfo p) + => new() + { + UserId = user.Id, + CredentialId = p.CredentialId, + PublicKey = p.PublicKey, + Name = p.Name, + CreatedAt = p.CreatedAt, + Transports = p.Transports, + SignCount = p.SignCount, + IsUserVerified = p.IsUserVerified, + IsBackupEligible = p.IsBackupEligible, + IsBackedUp = p.IsBackedUp, + AttestationObject = p.AttestationObject, + ClientDataJson = p.ClientDataJson, + }; + public IQueryable Roles { get { return _roles.Values.AsQueryable(); } diff --git a/src/source-manifest.json b/src/source-manifest.json index 216a641c089..66a13e9db3c 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -7,10 +7,10 @@ "commitSha": "e8ca69398033dd1eea35e9667bf857234465de2b" }, { - "barId": 287136, + "barId": 287272, "path": "aspnetcore", "remoteUri": "https://github.com/dotnet/aspnetcore", - "commitSha": "9fc1da3057ef21c3771ecd55ad8f6e1ec72c62bc" + "commitSha": "c697d89744c309f4085856630213054242a13010" }, { "barId": 279211, From 702ebdcd205ac3453ed55d68ad07a48692130de3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 15:54:18 -0700 Subject: [PATCH 5/6] [release/10.0.1xx] Source code updates from dotnet/runtime (#2929) Co-authored-by: dotnet-maestro[bot] --- src/runtime/src/installer/pkg/sfx/bundle/bundle.thm | 4 ++-- src/source-manifest.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/runtime/src/installer/pkg/sfx/bundle/bundle.thm b/src/runtime/src/installer/pkg/sfx/bundle/bundle.thm index 7cb2e2ef027..9dd8f98e35b 100644 --- a/src/runtime/src/installer/pkg/sfx/bundle/bundle.thm +++ b/src/runtime/src/installer/pkg/sfx/bundle/bundle.thm @@ -44,8 +44,8 @@ - <A HREF="https://aka.ms/dev-privacy">Privacy Statement</A> - <A HREF="https://aka.ms/dotnet-license-windows">Licensing Information for .NET</A> + #(loc.PrivacyStatementLink) + #(loc.EulaLink)