Skip to content

Commit 88bed84

Browse files
authored
feat(WebClientServer): add UserName property (#7601)
* feat(WebClientServer): add UserName property * test: 增加单元测试 * chore: bump version 10.3.0 * feat: 更新取值逻辑
1 parent beee938 commit 88bed84

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

src/BootstrapBlazor/BootstrapBlazor.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>10.2.4-beta01</Version>
4+
<Version>10.3.0</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

src/BootstrapBlazor/Components/ConnectionHub/ConnectionHub.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// See the LICENSE file in the project root for more information.
44
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
55

6+
using Microsoft.AspNetCore.Components.Authorization;
7+
using Microsoft.Extensions.DependencyInjection;
8+
69
namespace BootstrapBlazor.Components;
710

811
/// <summary>
@@ -32,6 +35,11 @@ public class ConnectionHub : BootstrapModuleComponentBase
3235
[NotNull]
3336
private IOptions<BootstrapBlazorOptions>? BootstrapBlazorOptions { get; set; }
3437

38+
[Inject]
39+
[NotNull]
40+
private IServiceProvider? Provider { get; set; }
41+
42+
3543
private IIpLocatorProvider? _ipLocatorProvider;
3644

3745
private ThrottleOptions? _throttleOptions;
@@ -77,6 +85,17 @@ await dispatch.ThrottleAsync(async () =>
7785
_ipLocatorProvider ??= IpLocatorFactory.Create(BootstrapBlazorOptions.Value.IpLocatorOptions.ProviderName);
7886
client.City = await _ipLocatorProvider.Locate(client.Ip);
7987
}
88+
89+
var authenticationStateProvider = Provider.GetService<AuthenticationStateProvider>();
90+
if (authenticationStateProvider != null)
91+
{
92+
var state = await authenticationStateProvider.GetAuthenticationStateAsync();
93+
var identity = state.User.Identity;
94+
if (identity is { IsAuthenticated: true })
95+
{
96+
client.UserName = identity.Name;
97+
}
98+
}
8099
ConnectionService.AddOrUpdate(client);
81100
});
82101
}

src/BootstrapBlazor/Services/WebClientService.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,10 @@ public class ClientInfo
180180
/// <para lang="en">Gets or sets Browser Engine Info</para>
181181
/// </summary>
182182
public string? Engine { get; set; }
183+
184+
/// <summary>
185+
/// <para lang="zh">获得/设置 当前已登录用户账号</para>
186+
/// <para lang="en">Gets or sets currently logged-in user account</para>
187+
/// </summary>
188+
public string? UserName { get; set; }
183189
}

test/UnitTest/Services/ConnectionHubTest.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
// See the LICENSE file in the project root for more information.
44
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
55

6+
using Microsoft.AspNetCore.Components.Authorization;
67
using Microsoft.Extensions.Options;
78
using Microsoft.JSInterop;
9+
using System.Security.Claims;
810

911
namespace UnitTest.Services;
1012

@@ -17,6 +19,9 @@ public async Task Callback_Ok()
1719
context.JSInterop.Mode = JSRuntimeMode.Loose;
1820
context.Services.AddBootstrapBlazor();
1921

22+
var authorizationContext = new MockAuthenticationStateProvider();
23+
context.Services.AddScoped<AuthenticationStateProvider>(p => authorizationContext);
24+
2025
var options = context.Services.GetRequiredService<IOptions<BootstrapBlazorOptions>>();
2126
options.Value.ConnectionHubOptions = new()
2227
{
@@ -36,6 +41,7 @@ await cut.InvokeAsync(async () =>
3641
await Task.Delay(100);
3742
client.SetData(new ClientInfo() { Id = "test_id", Ip = "::1" });
3843
});
44+
3945
await cut.Instance.Callback(new ClientInfo { Id = "test_id", Ip = "::1" });
4046
});
4147
Assert.Equal(1, service.Count);
@@ -49,12 +55,15 @@ await cut.InvokeAsync(async () =>
4955

5056
// 触发 Beat 时间
5157
await Task.Delay(200);
58+
authorizationContext.SetAuthorized("mock_user");
5259
await cut.InvokeAsync(async () =>
5360
{
5461
await cut.Instance.Callback(new ClientInfo { Id = "test_id", Ip = "::1" });
5562
});
5663
Assert.True(service.TryGetValue("test_id", out var item));
5764
Assert.NotNull(item?.ClientInfo);
65+
Assert.Equal("mock_user", item.ClientInfo.UserName);
66+
5867
Assert.True(item?.ConnectionTime < DateTimeOffset.Now);
5968
cut.Dispose();
6069

@@ -155,4 +164,24 @@ public void ConnectionService_Ok()
155164
var d = service as IDisposable;
156165
d?.Dispose();
157166
}
167+
168+
class MockAuthenticationStateProvider : AuthenticationStateProvider
169+
{
170+
ClaimsPrincipal _claim = new();
171+
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
172+
{
173+
await Task.Yield();
174+
175+
var state = new AuthenticationState(_claim);
176+
return state;
177+
}
178+
179+
public void SetAuthorized(string userName)
180+
{
181+
_claim = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
182+
{
183+
new(ClaimTypes.Name, userName),
184+
}, "mock"));
185+
}
186+
}
158187
}

0 commit comments

Comments
 (0)