using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using zero.Core.Entities; using zero.Core.Identity; namespace zero.Core.Security { public class ZeroBackofficeClaimsPrincipalFactory : ZeroClaimsPrinicipalFactory where TUser : BackofficeUser where TRole : BackofficeUserRole { public ZeroBackofficeClaimsPrincipalFactory(UserManager userManager, RoleManager roleManager, IOptions optionsAccessor, IOptions> authOptions, IZeroContext zero) : base(userManager, roleManager, optionsAccessor, authOptions, zero) { } protected override async Task GenerateClaimsAsync(TUser user) { List claims = await CreateClaimList(user); // create the user identity ClaimsIdentity identity = new ClaimsIdentity(claims, AuthOptions.Scheme, Constants.Auth.Claims.UserName, Constants.Auth.Claims.Role); // "Identity.Application" if (BackofficeUserIdentity.TryCreate(identity, out BackofficeUserIdentity userIdentity)) { Claim isZeroClaim = userIdentity.FindFirst(Constants.Auth.Claims.IsZero); Claim appIdClaim = userIdentity.FindFirst(Constants.Auth.Claims.AppId); if (appIdClaim is null || isZeroClaim is null or not { Value: PermissionsValue.True }) { return null; } return userIdentity; } return null; } protected override async Task> CreateClaimList(TUser user) { List claims = await base.CreateClaimList(user); claims.RemoveAll(x => x.Type == Constants.Auth.Claims.IsZero); claims.Add(new Claim(Constants.Auth.Claims.IsZero, PermissionsValue.True)); if (user.IsSuper) { claims.Add(new Claim(Constants.Auth.Claims.IsSuper, PermissionsValue.True)); } // get all allowed app ids string[] appIds = claims .Where(x => x.Type == Constants.Auth.Claims.Permission && x.Value.StartsWith(Permissions.Applications)) .Select(x => Permission.FromClaim(x, Permissions.Applications)) .Where(x => x.IsTrue) .Select(x => x.NormalizedKey) .ToArray(); string currentAppId = user.CurrentAppId ?? user.AppId; if (!user.IsSuper && !appIds.Contains(currentAppId)) { currentAppId = user.AppId; } claims.RemoveAll(x => x.Type == Constants.Auth.Claims.AppId); claims.Add(new Claim(Constants.Auth.Claims.AppId, currentAppId)); claims.Add(new Claim(Constants.Auth.Claims.DefaultAppId, user.AppId)); return claims; } } }