using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MTWorkHR.Core.Global; using MTWorkHR.Infrastructure.DBContext; namespace MTWorkHR.Infrastructure.Entities { public class ApplicationUserManager : UserManager<ApplicationUser> { private UserStore<ApplicationUser, ApplicationRole, HRDataContext, string, IdentityUserClaim<string> , IdentityUserRole<string>, IdentityUserLogin<string>, IdentityUserToken<string> , IdentityRoleClaim<string>> _store; private readonly GlobalInfo _globalInfo; public ApplicationUserManager(IUserStore<ApplicationUser> store, GlobalInfo globalInfo, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ApplicationUser> passwordHasher, IEnumerable<IUserValidator<ApplicationUser>> userValidators, IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ApplicationUser>> logger) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger) { _globalInfo = globalInfo; } private HRDataContext GetContext() { _store = (UserStore<ApplicationUser, ApplicationRole, HRDataContext, string, IdentityUserClaim<string>, IdentityUserRole<string>, IdentityUserLogin<string>, IdentityUserToken<string>, IdentityRoleClaim<string>>)this.Store; var context = _store.Context; return context; } public async Task<bool> UserHasAccess(string userId, string permmisions) { var context = GetContext(); //check if curr user has admin role bool isAdminUser = await IsAdminAsync(userId); if (isAdminUser) return true; var permissionsArr = permmisions.Split(",").ToArray(); var count = await context.UserRoles .Join(context.RolePermissions, userRole => userRole.RoleId, rolePermission => rolePermission.RoleId, (userRole, rolePermission) => new { userRole, rolePermission }) .Join(context.Permissions, rp => rp.rolePermission.PermissionId, permission => permission.Id, (rp, permission) => new { rp, permission }) .Where(x => permissionsArr.Any(a => a == x.permission.Name) && x.rp.userRole.UserId == userId) .CountAsync(); return count > 0; } public async Task<string[]> GetUserPermission(string userId) { var context = GetContext(); string[] permissions = Array.Empty<string>(); //check if curr user has admin role bool isAdminUser = await IsAdminAsync(userId); //if curr user has admin role, return all available permissions for curr tenant if (isAdminUser) { permissions = context.Permissions .Select(xx => xx.Name).ToArray(); } //if not admin then return only assigned permissions else { permissions = await context.UserRoles .Join(context.RolePermissions, userRole => userRole.RoleId, rolePermission => rolePermission.RoleId, (userRole, rolePermission) => new { userRole, rolePermission }) .Join(context.Permissions, rp => rp.rolePermission.PermissionId, permission => permission.Id, (rp, permission) => new { rp, permission }) .Where(x => x.rp.userRole.UserId == userId) .Select(x => x.permission.Name) .AsNoTracking().ToArrayAsync(); } return permissions; } private async Task<bool> IsAdminAsync(string userId) { var context = GetContext(); return await context.Roles .Join(context.UserRoles, role => role.Id, userRole => userRole.RoleId, (role, userRole) => new { role, userRole }) .Where(x => x.userRole.UserId == userId && x.role.IsAdmin == true) .CountAsync() > 0; } public async Task<ApplicationUser> FindByAnyAsync(string name) { var context = GetContext(); var res = await context.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == name.ToUpper() || x.NormalizedEmail == name.ToUpper() || x.PhoneNumber.ToUpper() == name.ToUpper()); return res; } public async Task<bool> IsStopped(string userId) { var context = GetContext(); var user = await context.Users .FirstOrDefaultAsync(x => x.Id == userId); return user.IsStopped; } } }