using CH.Dal; using CH.Dal.DbEntity; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Text; using System.Threading.Tasks; namespace CH.Authority.Services; public class UserIdentityService { private User? _user; private readonly IHttpContextAccessor _httpContextAccessor; private readonly IConfiguration _configuration; private readonly CHDbContext _dbContext; public string? SubjectId { get; } public string? Email { get; } public string? FirstName { get; } public string? LastName { get; } public bool? EmailVerified { get; } public string? AuthIssuer { get; } public UserIdentityService(CHDbContext dbContext, IHttpContextAccessor httpContextAccessor, IConfiguration configuration) { _dbContext = dbContext; _httpContextAccessor = httpContextAccessor; _configuration = configuration; // microsoft you twats! NameIdentifier = Sub SubjectId = ResolveClaim(ClaimTypes.NameIdentifier); Email = ResolveClaim(ClaimTypes.Email); FirstName = ResolveClaim(ClaimTypes.GivenName); LastName = ResolveClaim(ClaimTypes.Surname); var emailVerifiedString = ResolveClaim("email_verified"); if (null != emailVerifiedString && bool.TryParse(emailVerifiedString, out var emailVerified)) { EmailVerified = emailVerified; } AuthIssuer = ResolveClaim("iss"); } public bool IsAuthenticated() { var isAuthenticated = _httpContextAccessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false; if (!isAuthenticated || null == EmailVerified) return false; return EmailVerified ?? false; } private string? ResolveClaim(params string[] name) { var isAuthenticated = _httpContextAccessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false; if (false == isAuthenticated) return null; var claim = _httpContextAccessor.HttpContext.User.Claims.FirstOrDefault(claim => name.Contains(claim.Type)); return claim?.Value; } public async Task GetUserOrDefaultAsync(CancellationToken cancellationToken = default) { if (false == IsAuthenticated()) return null; if (null != _user) return _user; if (string.IsNullOrWhiteSpace(Email)) return null; // otherwise search for the user by email var email = Email?.ToLower() ?? ""; //_user = await _dbContext.Users // .Include(user => user.SubjectId) // .FirstOrDefaultAsync(user => user.Email.ToLower() == email, cancellationToken); // create user if it doesn't exist if (null == _user) { _user = await CreateUserAsync(cancellationToken); return _user; } return _user; } public async Task IsAuthorizedAsync(CancellationToken cancellationToken) { var user = await GetUserOrDefaultAsync(cancellationToken); return null != user; } private async Task CreateUserAsync(CancellationToken cancellationToken = default) { var user = new User { Email = Email, FirstName = FirstName, LastName = LastName, }; //await _dbContext.SaveChangesAsync(cancellationToken); return user; } }