Skip to content

Commit e0ef3d2

Browse files
authored
Merge pull request #24387 from dotnet-maestro-bot/merge/release/5.0-preview8-to-master
[automated] Merge branch 'release/5.0-preview8' => 'master'
2 parents cf72817 + d6ed980 commit e0ef3d2

File tree

50 files changed

+1324
-466
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1324
-466
lines changed

eng/Version.Details.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,9 @@
305305
<Uri>https://github.com/dotnet/runtime</Uri>
306306
<Sha>0e0e648770e54b12c2fa81a77538ce1a72fca8af</Sha>
307307
</Dependency>
308-
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="5.0.0-beta.20364.3">
308+
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="5.0.0-beta.20377.2">
309309
<Uri>https://github.com/dotnet/arcade</Uri>
310-
<Sha>ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915</Sha>
310+
<Sha>22d6355c4f3c9ac00b0e3abf9d85f2fb07e4787b</Sha>
311311
</Dependency>
312312
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="5.0.0-beta.20364.3">
313313
<Uri>https://github.com/dotnet/arcade</Uri>

eng/Versions.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,8 @@
256256
<IdentityServer4StoragePackageVersion>3.0.0</IdentityServer4StoragePackageVersion>
257257
<IdentityServer4EntityFrameworkStoragePackageVersion>3.0.0</IdentityServer4EntityFrameworkStoragePackageVersion>
258258
<MessagePackPackageVersion>2.1.90</MessagePackPackageVersion>
259-
<MicrosoftIdentityWebPackageVersion>0.2.0-preview</MicrosoftIdentityWebPackageVersion>
260-
<MicrosoftIdentityWebUIPackageVersion>0.2.0-preview</MicrosoftIdentityWebUIPackageVersion>
259+
<MicrosoftIdentityWebPackageVersion>0.2.1-preview</MicrosoftIdentityWebPackageVersion>
260+
<MicrosoftIdentityWebUIPackageVersion>0.2.1-preview</MicrosoftIdentityWebUIPackageVersion>
261261
<MicrosoftGraphPackageVersion>3.8.0</MicrosoftGraphPackageVersion>
262262
<MessagePackAnalyzerPackageVersion>$(MessagePackPackageVersion)</MessagePackAnalyzerPackageVersion>
263263
<MoqPackageVersion>4.10.0</MoqPackageVersion>

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
},
3131
"msbuild-sdks": {
3232
"Yarn.MSBuild": "1.15.2",
33-
"Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20364.3",
33+
"Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20377.2",
3434
"Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20364.3"
3535
}
3636
}

src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ public BlazorServerTemplateTest(ProjectFactoryFixture projectFactory, BrowserFix
3030
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/20172")]
3131
public async Task BlazorServerTemplateWorks_NoAuth()
3232
{
33+
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
34+
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
35+
3336
Project = await ProjectFactory.GetOrCreateProject("blazorservernoauth", Output);
3437

3538
var createResult = await Project.RunDotNetNewAsync("blazorserver");
@@ -88,6 +91,9 @@ public async Task BlazorServerTemplateWorks_NoAuth()
8891
[QuarantinedTest]
8992
public async Task BlazorServerTemplateWorks_IndividualAuth(bool useLocalDB)
9093
{
94+
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
95+
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
96+
9197
Project = await ProjectFactory.GetOrCreateProject("blazorserverindividual" + (useLocalDB ? "uld" : ""), Output);
9298

9399
var createResult = await Project.RunDotNetNewAsync("blazorserver", auth: "Individual", useLocalDB: useLocalDB);
@@ -182,5 +188,30 @@ private void TestBasicNavigation()
182188
Browser.Exists(By.CssSelector("table>tbody>tr"));
183189
Browser.Equal(5, () => Browser.FindElements(By.CssSelector("p+table>tbody>tr")).Count);
184190
}
191+
192+
[Theory]
193+
[QuarantinedTest]
194+
[InlineData("IndividualB2C", null)]
195+
[InlineData("IndividualB2C", new string[] { "--called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
196+
[InlineData("SingleOrg", null)]
197+
[InlineData("SingleOrg", new string[] { "--called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
198+
[InlineData("SingleOrg", new string[] { "--calls-graph" })]
199+
public async Task BlazorServerTemplat_IdentityWeb_BuildAndPublish(string auth, string[] args)
200+
{
201+
Project = await ProjectFactory.GetOrCreateProject("blazorserveridweb" + Guid.NewGuid().ToString().Substring(0, 10).ToLower(), Output);
202+
203+
var createResult = await Project.RunDotNetNewAsync("blazorserver", auth: auth, args: args);
204+
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult));
205+
206+
var publishResult = await Project.RunDotNetPublishAsync();
207+
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
208+
209+
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
210+
// The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
211+
// later, while the opposite is not true.
212+
213+
var buildResult = await Project.RunDotNetBuildAsync();
214+
Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult));
215+
}
185216
}
186217
}

src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ public override Task InitializeAsync()
4343
[Fact]
4444
public async Task BlazorWasmStandaloneTemplate_Works()
4545
{
46+
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
47+
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
48+
4649
var project = await ProjectFactory.GetOrCreateProject("blazorstandalone", Output);
4750
project.RuntimeIdentifier = "browser-wasm";
4851

@@ -81,6 +84,9 @@ public async Task BlazorWasmStandaloneTemplate_Works()
8184
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/20172")]
8285
public async Task BlazorWasmHostedTemplate_Works()
8386
{
87+
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
88+
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
89+
8490
var project = await ProjectFactory.GetOrCreateProject("blazorhosted", Output);
8591

8692
var createResult = await project.RunDotNetNewAsync("blazorwasm", args: new[] { "--hosted" });
@@ -135,6 +141,9 @@ private static async Task AssertCompressionFormat(AspNetProcess aspNetProcess, s
135141
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23992")]
136142
public async Task BlazorWasmStandalonePwaTemplate_Works()
137143
{
144+
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
145+
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
146+
138147
var project = await ProjectFactory.GetOrCreateProject("blazorstandalonepwa", Output);
139148
project.RuntimeIdentifier = "browser-wasm";
140149

@@ -174,6 +183,9 @@ public async Task BlazorWasmStandalonePwaTemplate_Works()
174183
[Fact]
175184
public async Task BlazorWasmHostedPwaTemplate_Works()
176185
{
186+
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
187+
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
188+
177189
var project = await ProjectFactory.GetOrCreateProject("blazorhostedpwa", Output);
178190

179191
var createResult = await project.RunDotNetNewAsync("blazorwasm", args: new[] { "--hosted", "--pwa" });
@@ -269,6 +281,9 @@ public Task BlazorWasmHostedTemplate_IndividualAuth_Works_WithOutLocalDB()
269281

270282
private async Task BlazorWasmHostedTemplate_IndividualAuth_Works(bool useLocalDb)
271283
{
284+
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
285+
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
286+
272287
var project = await ProjectFactory.GetOrCreateProject("blazorhostedindividual" + (useLocalDb ? "uld" : ""), Output);
273288

274289
var createResult = await project.RunDotNetNewAsync("blazorwasm", args: new[] { "--hosted", "-au", "Individual", useLocalDb ? "-uld" : "" });
@@ -336,6 +351,9 @@ private async Task BlazorWasmHostedTemplate_IndividualAuth_Works(bool useLocalDb
336351
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23639")]
337352
public async Task BlazorWasmStandaloneTemplate_IndividualAuth_Works()
338353
{
354+
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
355+
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
356+
339357
var project = await ProjectFactory.GetOrCreateProject("blazorstandaloneindividual", Output);
340358
project.RuntimeIdentifier = "browser-wasm";
341359

@@ -403,6 +421,27 @@ public async Task BlazorWasmStandaloneTemplate_IndividualAuth_Works()
403421
"--default-scope", "full",
404422
"--app-id-uri", "ApiUri",
405423
"--api-client-id", "1234123413241324"),
424+
new TemplateInstance(
425+
"blazorwasmhostedaadgraph", "-ho",
426+
"-au", "SingleOrg",
427+
"--calls-graph",
428+
"--domain", "my-domain",
429+
"--tenant-id", "tenantId",
430+
"--client-id", "clientId",
431+
"--default-scope", "full",
432+
"--app-id-uri", "ApiUri",
433+
"--api-client-id", "1234123413241324"),
434+
new TemplateInstance(
435+
"blazorwasmhostedaadapi", "-ho",
436+
"-au", "SingleOrg",
437+
"--called-api-url", "\"https://graph.microsoft.com\"",
438+
"--called-api-scopes", "user.readwrite",
439+
"--domain", "my-domain",
440+
"--tenant-id", "tenantId",
441+
"--client-id", "clientId",
442+
"--default-scope", "full",
443+
"--app-id-uri", "ApiUri",
444+
"--api-client-id", "1234123413241324"),
406445
new TemplateInstance(
407446
"blazorwasmstandaloneaadb2c",
408447
"-au", "IndividualB2C",

src/ProjectTemplates/Web.ProjectTemplates/BlazorServerWeb-CSharp.csproj.in

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@
1717
<!--#endif -->
1818
<!--#if (IndividualAuth || OrganizationalAuth) -->
1919
<ItemGroup>
20-
<PackageReference Include="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="${MicrosoftAspNetCoreAuthenticationAzureADUIPackageVersion}" Condition="'$(OrganizationalAuth)' == 'True'" />
21-
<PackageReference Include="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" Version="${MicrosoftAspNetCoreAuthenticationAzureADB2CUIPackageVersion}" Condition="'$(IndividualB2CAuth)' == 'True'" />
2220
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="${MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' " />
2321
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="${MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' " />
2422
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="${MicrosoftAspNetCoreIdentityUIPackageVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' " />
2523
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="${MicrosoftEntityFrameworkCoreSqlServerPackageVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' == 'True'" />
2624
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="${MicrosoftEntityFrameworkCoreSqlitePackageVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' != 'True'" />
2725
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="${MicrosoftEntityFrameworkCoreToolsPackageVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' " />
26+
<PackageReference Include="Microsoft.Identity.Web" Version="${MicrosoftIdentityWebPackageVersion}" Condition=" '$(IndividualB2CAuth)' == 'True' OR '$(OrganizationalAuth)' == 'True'" />
27+
<PackageReference Include="Microsoft.Identity.Web.UI" Version="${MicrosoftIdentityWebUIPackageVersion}" Condition=" '$(IndividualB2CAuth)' == 'True' OR '$(OrganizationalAuth)' == 'True'" />
28+
<PackageReference Include="Microsoft.Graph" Version="${MicrosoftGraphPackageVersion}" Condition=" '$(GenerateGraph)' == 'True' "/>
2829
</ItemGroup>
2930

3031
<!--#endif -->

src/ProjectTemplates/Web.ProjectTemplates/ComponentsWebAssembly-CSharp.Server.csproj.in

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@
3838
<!--#endif -->
3939
<!--#if (OrganizationalAuth || IndividualB2CAuth) -->
4040
<ItemGroup>
41-
<PackageReference Include="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="${MicrosoftAspNetCoreAuthenticationAzureADUIPackageVersion}" Condition="'$(OrganizationalAuth)' == 'True'" />
42-
<PackageReference Include="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" Version="${MicrosoftAspNetCoreAuthenticationAzureADB2CUIPackageVersion}" Condition="'$(IndividualB2CAuth)' == 'True'" />
41+
<PackageReference Include="Microsoft.Identity.Web" Version="${MicrosoftIdentityWebPackageVersion}" />
42+
<PackageReference Include="Microsoft.Identity.Web.UI" Version="${MicrosoftIdentityWebUIPackageVersion}" />
43+
<PackageReference Include="Microsoft.Graph" Version="${MicrosoftGraphPackageVersion}" Condition=" '$(GenerateGraph)' == 'True' "/>
4344
</ItemGroup>
4445
<!--#endif -->
4546

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/dotnetcli.host.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@
6767
"NoHttps": {
6868
"longName": "no-https",
6969
"shortName": ""
70+
},
71+
"CalledApiUrl": {
72+
"longName": "called-api-url",
73+
"shortName": ""
74+
},
75+
"CalledApiScopes": {
76+
"longName": "called-api-scopes",
77+
"shortName": ""
78+
},
79+
"CallsMicrosoftGraph": {
80+
"longName": "calls-graph",
81+
"shortName": ""
7082
}
7183
},
7284
"usageExamples": [

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,52 @@
127127
"Shared/LoginDisplay.IndividualB2CAuth.razor",
128128
"Shared/LoginDisplay.OrganizationalAuth.razor"
129129
]
130+
},
131+
{
132+
"condition": "(!GenerateApi)",
133+
"exclude": [
134+
"Services/DownstreamWebApi.cs",
135+
"Pages/CallWebApi.razor"
136+
]
137+
},
138+
{
139+
"condition": "(!GenerateGraph)",
140+
"exclude": [
141+
"Services/MicrosoftGraphServiceExtensions.cs",
142+
"Services/TokenAcquisitionCredentialProvider.cs",
143+
"Shared/NavMenu.CallsMicrosoftGraph.razor",
144+
"Pages/ShowProfile.razor"
145+
]
146+
},
147+
{
148+
"condition": "(!GenerateApiOrGraph)",
149+
"rename": {
150+
"Shared/NavMenu.NoGraphOrApi.razor": "Shared/NavMenu.razor"
151+
},
152+
"exclude": [
153+
"Shared/NavMenu.CallsMicrosoftGraph.razor",
154+
"Shared/NavMenu.CallsWebApi.razor"
155+
]
156+
},
157+
{
158+
"condition": "(GenerateGraph)",
159+
"rename": {
160+
"Shared/NavMenu.CallsMicrosoftGraph.razor": "Shared/NavMenu.razor"
161+
},
162+
"exclude": [
163+
"Shared/NavMenu.NoGraphOrApi.razor",
164+
"Shared/NavMenu.CallsWebApi.razor"
165+
]
166+
},
167+
{
168+
"condition": "(GenerateApi)",
169+
"rename": {
170+
"Shared/NavMenu.CallsWebApi.razor": "Shared/NavMenu.razor"
171+
},
172+
"exclude": [
173+
"Shared/NavMenu.NoGraphOrApi.razor",
174+
"Shared/NavMenu.CallsMicrosoftGraph.razor"
175+
]
130176
}
131177
]
132178
}
@@ -174,21 +220,28 @@
174220
"SignUpSignInPolicyId": {
175221
"type": "parameter",
176222
"datatype": "string",
177-
"defaultValue": "",
223+
"defaultValue": "b2c_1_susi",
178224
"replaces": "MySignUpSignInPolicyId",
179225
"description": "The sign-in and sign-up policy ID for this project (use with IndividualB2C auth)."
180226
},
227+
"SignedOutCallbackPath": {
228+
"type": "parameter",
229+
"datatype": "string",
230+
"defaultValue": "/signout/B2C_1_susi",
231+
"replaces": "/signout/MySignUpSignInPolicyId",
232+
"description": "The global signout callback (use with IndividualB2C auth)."
233+
},
181234
"ResetPasswordPolicyId": {
182235
"type": "parameter",
183236
"datatype": "string",
184-
"defaultValue": "",
237+
"defaultValue": "b2c_1_reset",
185238
"replaces": "MyResetPasswordPolicyId",
186239
"description": "The reset password policy ID for this project (use with IndividualB2C auth)."
187240
},
188241
"EditProfilePolicyId": {
189242
"type": "parameter",
190243
"datatype": "string",
191-
"defaultValue": "",
244+
"defaultValue": "b2c_1_edit_profile",
192245
"replaces": "MyEditProfilePolicyId",
193246
"description": "The edit profile policy ID for this project (use with IndividualB2C auth)."
194247
},
@@ -352,6 +405,37 @@
352405
"format": "yyyy"
353406
}
354407
},
408+
"CalledApiUrl": {
409+
"type": "parameter",
410+
"datatype": "string",
411+
"replaces": "[WebApiUrl]",
412+
"defaultValue" : "https://graph.microsoft.com/beta",
413+
"description": "URL of the API to call from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified."
414+
},
415+
"CallsMicrosoftGraph": {
416+
"type": "parameter",
417+
"datatype": "bool",
418+
"defaultValue": "false",
419+
"description": "Specifies if the web app calls Microsoft Graph. This option only applies if --auth SingleOrg or --auth MultiOrg is specified."
420+
},
421+
"CalledApiScopes": {
422+
"type": "parameter",
423+
"datatype": "string",
424+
"replaces" : "user.read",
425+
"description": "Scopes to request to call the API from the web app. This option only applies if --auth SingleOrg, --auth MultiOrg or --auth IndividualB2C is specified."
426+
},
427+
"GenerateApi": {
428+
"type": "computed",
429+
"value": "((IndividualB2CAuth || OrganizationalAuth) && (CalledApiUrl != \"https://graph.microsoft.com/beta\" || CalledApiScopes != \"user.read\"))"
430+
},
431+
"GenerateGraph": {
432+
"type": "computed",
433+
"value": "(OrganizationalAuth && CallsMicrosoftGraph)"
434+
},
435+
"GenerateApiOrGraph": {
436+
"type": "computed",
437+
"value": "(GenerateApi || GenerateGraph)"
438+
},
355439
"skipRestore": {
356440
"type": "parameter",
357441
"datatype": "bool",

src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Areas/Identity/Pages/Shared/_LoginPartial.cshtml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@
77
@if (SignInManager.IsSignedIn(User))
88
{
99
<li class="nav-item">
10-
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a>
10+
<a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a>
1111
</li>
1212
<li class="nav-item">
13-
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="/" method="post">
13+
<form class="form-inline" asp-area="MicrosoftIdentity" asp-page="/Account/Logout" asp-route-returnUrl="/" method="post">
1414
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
1515
</form>
1616
</li>
1717
}
1818
else
1919
{
2020
<li class="nav-item">
21-
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
21+
<a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-page="/Account/Register">Register</a>
2222
</li>
2323
<li class="nav-item">
24-
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
24+
<a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-page="/Account/Login">Login</a>
2525
</li>
2626
}
2727
</ul>

0 commit comments

Comments
 (0)