-
Notifications
You must be signed in to change notification settings - Fork 10.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
9f2b534
commit 2ff6a5c
Showing
43 changed files
with
1,516 additions
and
590 deletions.
There are no files selected for viewing
9 changes: 7 additions & 2 deletions
9
src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/App.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
<Router AppAssembly="typeof(Program).Assembly"> | ||
<Router AppAssembly="@typeof(Program).Assembly"> | ||
<Found Context="routeData"> | ||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> | ||
</Found> | ||
<NotFound> | ||
<p>Sorry, there's nothing at this address.</p> | ||
<LayoutView Layout="@typeof(MainLayout)"> | ||
<p>Sorry, there's nothing at this address.</p> | ||
</LayoutView> | ||
</NotFound> | ||
</Router> |
1 change: 0 additions & 1 deletion
1
src/Components/Blazor/Templates/src/content/BlazorWasm-CSharp/Client/Pages/_Imports.razor
This file was deleted.
Oops, something went wrong.
9 changes: 8 additions & 1 deletion
9
src/Components/Blazor/testassets/Microsoft.AspNetCore.Blazor.E2EPerformance/App.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,8 @@ | ||
<Router AppAssembly=typeof(Program).Assembly /> | ||
<Router AppAssembly=typeof(Program).Assembly> | ||
<Found Context="routeData"> | ||
<RouteView RouteData="@routeData" /> | ||
</Found> | ||
<NotFound> | ||
Sorry, there's nothing here. | ||
</NotFound> | ||
</Router> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,11 @@ | ||
<!-- | ||
Configuring this stuff here is temporary. Later we'll move the app config | ||
into Program.cs, and it won't be necessary to specify AppAssembly. | ||
--> | ||
<Router AppAssembly=typeof(StandaloneApp.Program).Assembly /> | ||
<Router AppAssembly=typeof(StandaloneApp.Program).Assembly> | ||
<Found Context="routeData"> | ||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> | ||
</Found> | ||
<NotFound> | ||
<LayoutView Layout="@typeof(MainLayout)"> | ||
<h2>Not found</h2> | ||
Sorry, there's nothing at this address. | ||
</LayoutView> | ||
</NotFound> | ||
</Router> |
1 change: 0 additions & 1 deletion
1
src/Components/Blazor/testassets/StandaloneApp/Pages/_Imports.razor
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 118 additions & 0 deletions
118
src/Components/Components/src/Auth/AuthorizeRouteView.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Components.Auth; | ||
using Microsoft.AspNetCore.Components.RenderTree; | ||
|
||
namespace Microsoft.AspNetCore.Components | ||
{ | ||
/// <summary> | ||
/// Combines the behaviors of <see cref="AuthorizeView"/> and <see cref="RouteView"/>, | ||
/// so that it displays the page matching the specified route but only if the user | ||
/// is authorized to see it. | ||
/// | ||
/// Additionally, this component supplies a cascading parameter of type <see cref="Task{AuthenticationState}"/>, | ||
/// which makes the user's current authentication state available to descendants. | ||
/// </summary> | ||
public sealed class AuthorizeRouteView : RouteView | ||
{ | ||
// We expect applications to supply their own authorizing/not-authorized content, but | ||
// it's better to have defaults than to make the parameters mandatory because in some | ||
// cases they will never be used (e.g., "authorizing" in out-of-box server-side Blazor) | ||
private static readonly RenderFragment<AuthenticationState> _defaultNotAuthorizedContent | ||
= state => builder => builder.AddContent(0, "Not authorized"); | ||
private static readonly RenderFragment _defaultAuthorizingContent | ||
= builder => builder.AddContent(0, "Authorizing..."); | ||
|
||
private readonly RenderFragment _renderAuthorizeRouteViewCoreDelegate; | ||
private readonly RenderFragment<AuthenticationState> _renderAuthorizedDelegate; | ||
private readonly RenderFragment<AuthenticationState> _renderNotAuthorizedDelegate; | ||
private readonly RenderFragment _renderAuthorizingDelegate; | ||
|
||
public AuthorizeRouteView() | ||
{ | ||
// Cache the rendering delegates so that we only construct new closure instances | ||
// when they are actually used (e.g., we never prepare a RenderFragment bound to | ||
// the NotAuthorized content except when you are displaying that particular state) | ||
RenderFragment renderBaseRouteViewDelegate = builder => base.Render(builder); | ||
_renderAuthorizedDelegate = authenticateState => renderBaseRouteViewDelegate; | ||
_renderNotAuthorizedDelegate = authenticationState => builder => RenderNotAuthorizedInDefaultLayout(builder, authenticationState); | ||
_renderAuthorizingDelegate = RenderAuthorizingInDefaultLayout; | ||
_renderAuthorizeRouteViewCoreDelegate = RenderAuthorizeRouteViewCore; | ||
} | ||
|
||
/// <summary> | ||
/// The content that will be displayed if the user is not authorized. | ||
/// </summary> | ||
[Parameter] | ||
public RenderFragment<AuthenticationState> NotAuthorized { get; set; } | ||
|
||
/// <summary> | ||
/// The content that will be displayed while asynchronous authorization is in progress. | ||
/// </summary> | ||
[Parameter] | ||
public RenderFragment Authorizing { get; set; } | ||
|
||
[CascadingParameter] | ||
private Task<AuthenticationState> ExistingCascadedAuthenticationState { get; set; } | ||
|
||
/// <inheritdoc /> | ||
protected override void Render(RenderTreeBuilder builder) | ||
{ | ||
if (ExistingCascadedAuthenticationState != null) | ||
{ | ||
// If this component is already wrapped in a <CascadingAuthenticationState> (or another | ||
// compatible provider), then don't interfere with the cascaded authentication state. | ||
_renderAuthorizeRouteViewCoreDelegate(builder); | ||
} | ||
else | ||
{ | ||
// Otherwise, implicitly wrap the output in a <CascadingAuthenticationState> | ||
builder.OpenComponent<CascadingAuthenticationState>(0); | ||
builder.AddAttribute(1, nameof(CascadingAuthenticationState.ChildContent), _renderAuthorizeRouteViewCoreDelegate); | ||
builder.CloseComponent(); | ||
} | ||
} | ||
|
||
private void RenderAuthorizeRouteViewCore(RenderTreeBuilder builder) | ||
{ | ||
builder.OpenComponent<AuthorizeRouteViewCore>(0); | ||
builder.AddAttribute(1, nameof(AuthorizeRouteViewCore.RouteData), RouteData); | ||
builder.AddAttribute(2, nameof(AuthorizeRouteViewCore.Authorized), _renderAuthorizedDelegate); | ||
builder.AddAttribute(3, nameof(AuthorizeRouteViewCore.Authorizing), _renderAuthorizingDelegate); | ||
builder.AddAttribute(4, nameof(AuthorizeRouteViewCore.NotAuthorized), _renderNotAuthorizedDelegate); | ||
builder.CloseComponent(); | ||
} | ||
|
||
private void RenderContentInDefaultLayout(RenderTreeBuilder builder, RenderFragment content) | ||
{ | ||
builder.OpenComponent<LayoutView>(0); | ||
builder.AddAttribute(1, nameof(LayoutView.Layout), DefaultLayout); | ||
builder.AddAttribute(2, nameof(LayoutView.ChildContent), content); | ||
builder.CloseComponent(); | ||
} | ||
|
||
private void RenderNotAuthorizedInDefaultLayout(RenderTreeBuilder builder, AuthenticationState authenticationState) | ||
{ | ||
var content = NotAuthorized ?? _defaultNotAuthorizedContent; | ||
RenderContentInDefaultLayout(builder, content(authenticationState)); | ||
} | ||
|
||
private void RenderAuthorizingInDefaultLayout(RenderTreeBuilder builder) | ||
{ | ||
var content = Authorizing ?? _defaultAuthorizingContent; | ||
RenderContentInDefaultLayout(builder, content); | ||
} | ||
|
||
private class AuthorizeRouteViewCore : AuthorizeViewCore | ||
{ | ||
[Parameter] | ||
public RouteData RouteData { get; set; } | ||
|
||
protected override IAuthorizeData[] GetAuthorizeData() | ||
=> AttributeAuthorizeDataCache.GetAuthorizeDataForType(RouteData.PageType); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Reflection; | ||
using System.Threading.Tasks; | ||
|
||
namespace Microsoft.AspNetCore.Components | ||
{ | ||
/// <summary> | ||
/// Displays the specified content inside the specified layout and any further | ||
/// nested layouts. | ||
/// </summary> | ||
public class LayoutView : IComponent | ||
{ | ||
private static readonly RenderFragment EmptyRenderFragment = builder => { }; | ||
|
||
private RenderHandle _renderHandle; | ||
|
||
/// <summary> | ||
/// Gets or sets the content to display. | ||
/// </summary> | ||
[Parameter] | ||
public RenderFragment ChildContent { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the type of the layout in which to display the content. | ||
/// The type must implement <see cref="IComponent"/> and accept a parameter named <see cref="LayoutComponentBase.Body"/>. | ||
/// </summary> | ||
[Parameter] | ||
public Type Layout { get; set; } | ||
|
||
/// <inheritdoc /> | ||
public void Attach(RenderHandle renderHandle) | ||
{ | ||
_renderHandle = renderHandle; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public Task SetParametersAsync(ParameterView parameters) | ||
{ | ||
parameters.SetParameterProperties(this); | ||
Render(); | ||
return Task.CompletedTask; | ||
} | ||
|
||
private void Render() | ||
{ | ||
// In the middle goes the supplied content | ||
var fragment = ChildContent ?? EmptyRenderFragment; | ||
|
||
// Then repeatedly wrap that in each layer of nested layout until we get | ||
// to a layout that has no parent | ||
var layoutType = Layout; | ||
while (layoutType != null) | ||
{ | ||
fragment = WrapInLayout(layoutType, fragment); | ||
layoutType = GetParentLayoutType(layoutType); | ||
} | ||
|
||
_renderHandle.Render(fragment); | ||
} | ||
|
||
private static RenderFragment WrapInLayout(Type layoutType, RenderFragment bodyParam) | ||
{ | ||
return builder => | ||
{ | ||
builder.OpenComponent(0, layoutType); | ||
builder.AddAttribute(1, LayoutComponentBase.BodyPropertyName, bodyParam); | ||
builder.CloseComponent(); | ||
}; | ||
} | ||
|
||
private static Type GetParentLayoutType(Type type) | ||
=> type.GetCustomAttribute<LayoutAttribute>()?.LayoutType; | ||
} | ||
} |
Oops, something went wrong.