Skip to content

Commit

Permalink
fix:DefaultUserContext
Browse files Browse the repository at this point in the history
  • Loading branch information
duiapro committed May 9, 2024
1 parent ad2e5d2 commit 4351566
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

using System.Collections;

namespace Masa.Contrib.Authentication.Identity;

internal class DefaultUserContext : UserContext
Expand Down Expand Up @@ -44,26 +46,54 @@ public DefaultUserContext(
if (claimType == null)
continue;

string? claimValue = null;
if (property.PropertyType != typeof(string) && typeof(System.Collections.IEnumerable).IsAssignableFrom(property.PropertyType))
string? claimValue = ClaimsPrincipal.FindClaimValue(claimType);
object? claimTypeValue = null;
try
{
var claimsValues = ClaimsPrincipal?.Claims.Where(claim => claim.Type == claimType)
.Select(claim => claim.Value);
if (claimsValues?.Any() == true)
claimValue = JsonSerializer.Serialize(claimsValues);
claimTypeValue = TypeConvertProvider.ConvertTo(claimValue, property.PropertyType);
}
else
catch
{
claimValue = ClaimsPrincipal?.FindClaimValue(claimType);
claimTypeValue = this.ParseNonJson(property);
}

if (claimValue != null)
{
modelRelation.Setters[property]
.Invoke(userModel, new[] { TypeConvertProvider.ConvertTo(claimValue, property.PropertyType) });
.Invoke(userModel, new[] { claimTypeValue });
}
}

return userModel;
}

private object? ParseNonJson(PropertyInfo property)
{
var claimValues = new List<string>();
var claimType = _optionsMonitor.CurrentValue.GetClaimType(property.Name);
if (claimType == null)
return null;

if (property.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
var claimsValues = ClaimsPrincipal?.Claims.Where(claim => claim.Type == claimType)
.Select(claim => claim.Value).ToList();

claimsValues?.ForEach(item =>
{
try
{
var claimsValue = JsonSerializer.Deserialize<List<string>>(item);
if (claimsValue?.Any() == true)
claimValues.AddRange(claimsValue);
}
catch
{
claimValues.Add(item);
}
});
}

return TypeConvertProvider.ConvertTo(JsonSerializer.Serialize(claimValues), property.PropertyType);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) MASA Stack All rights reserved.
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

using Newtonsoft.Json;

namespace Masa.Contrib.Authentication.Identity.BlazorServer.Tests;

[TestClass]
Expand Down Expand Up @@ -62,6 +64,93 @@ public void TestMasaIdentity2()
Assert.AreEqual(1, userRoles[0]);
}

[TestMethod]
public void TestMasaIdentity3()
{
var services = new ServiceCollection();
var claimsPrincipal = new ClaimsPrincipal(new List<ClaimsIdentity>()
{
new(new List<Claim>()
{
new("sub", "1"),
new(ClaimType.DEFAULT_USER_NAME, "Jim"),
new(ClaimType.DEFAULT_USER_ROLE, "1")//"[\"1\"]"
})
});
Mock<AuthenticationStateProvider> authenticationStateProvider = new();
authenticationStateProvider
.Setup(provider => provider.GetAuthenticationStateAsync())
.ReturnsAsync(new AuthenticationState(claimsPrincipal));

services.AddScoped(_ => authenticationStateProvider.Object);
services.AddMasaIdentity(option =>
{
option.UserId = "sub";
});

Assert.IsTrue(services.Any<ICurrentPrincipalAccessor, BlazorCurrentPrincipalAccessor>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IUserSetter>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IUserContext>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IMultiTenantUserContext>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IMultiEnvironmentUserContext>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IIsolatedUserContext>(ServiceLifetime.Scoped));

var serviceProvider = services.BuildServiceProvider();
var userContext = serviceProvider.GetService<IUserContext>();
Assert.IsNotNull(userContext);
Assert.AreEqual("1", userContext.UserId);
Assert.AreEqual("Jim", userContext.UserName);

var userRoles = userContext.GetUserRoles<int>().ToList();
Assert.AreEqual(1, userRoles.Count);
Assert.AreEqual(1, userRoles[0]);
}

[TestMethod]
public void TestMasaIdentity4()
{
var roles = new List<string>()
{
"admin", "admin2", "admin3","admin4"
};
var services = new ServiceCollection();
var claimsPrincipal = new ClaimsPrincipal(new List<ClaimsIdentity>()
{
new(new List<Claim>()
{
new("sub", "1"),
new(ClaimType.DEFAULT_USER_NAME, "Jim"),
new(ClaimType.DEFAULT_USER_ROLE, JsonConvert.SerializeObject(roles))//"[\"1\"]"
})
});
Mock<AuthenticationStateProvider> authenticationStateProvider = new();
authenticationStateProvider
.Setup(provider => provider.GetAuthenticationStateAsync())
.ReturnsAsync(new AuthenticationState(claimsPrincipal));

services.AddScoped(_ => authenticationStateProvider.Object);
services.AddMasaIdentity(option =>
{
option.UserId = "sub";
});

Assert.IsTrue(services.Any<ICurrentPrincipalAccessor, BlazorCurrentPrincipalAccessor>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IUserSetter>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IUserContext>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IMultiTenantUserContext>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IMultiEnvironmentUserContext>(ServiceLifetime.Scoped));
Assert.IsTrue(services.Any<IIsolatedUserContext>(ServiceLifetime.Scoped));

var serviceProvider = services.BuildServiceProvider();
var userContext = serviceProvider.GetService<IUserContext>();
Assert.IsNotNull(userContext);
Assert.AreEqual("1", userContext.UserId);
Assert.AreEqual("Jim", userContext.UserName);

var userRoles = userContext.GetUserRoles<string>().ToList();
Assert.AreEqual(4, userRoles.Count);
}

[TestMethod]
public void TestIdentityByYaml()
{
Expand Down

0 comments on commit 4351566

Please sign in to comment.