proposal-system/api/src/ProposalSystem.Api/Services/CurrentUserService.cs

74 lines
2.4 KiB
C#
Raw Normal View History

using System.Security.Claims;
using Microsoft.EntityFrameworkCore;
using ProposalSystem.Application.Interfaces;
using ProposalSystem.Domain.Entities;
using ProposalSystem.Infrastructure.Data;
namespace ProposalSystem.Api.Services;
public class CurrentUserService : ICurrentUserService
{
private readonly IHttpContextAccessor _httpContext;
private readonly ProposalDbContext _db;
private User? _cachedUser;
public CurrentUserService(IHttpContextAccessor httpContext, ProposalDbContext db)
{
_httpContext = httpContext;
_db = db;
}
public Guid UserId => GetUser().Id;
public string Email => GetUser().Email;
public UserRole Role => GetUser().Role;
public string? IpAddress =>
_httpContext.HttpContext?.Connection.RemoteIpAddress?.ToString();
private User GetUser()
{
if (_cachedUser != null) return _cachedUser;
var cognitoSub = _httpContext.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier)
?? _httpContext.HttpContext?.User.FindFirstValue("sub")
?? throw new UnauthorizedAccessException("No authenticated user");
_cachedUser = _db.Users
.FirstOrDefault(u => u.CognitoSub == cognitoSub);
if (_cachedUser == null)
{
var email = _httpContext.HttpContext?.User.FindFirstValue(ClaimTypes.Email)
?? _httpContext.HttpContext?.User.FindFirstValue("email")
?? "unknown@seahaven.com";
var name = _httpContext.HttpContext?.User.FindFirstValue("name")
?? email.Split('@')[0];
var groups = _httpContext.HttpContext?.User.FindAll("cognito:groups")
.Select(c => c.Value).ToList() ?? new List<string>();
var role = groups.Contains("sysadmins") ? UserRole.SysAdmin
: groups.Contains("admins") ? UserRole.Admin
: UserRole.Dispatcher;
_cachedUser = new User
{
Id = Guid.NewGuid(),
CognitoSub = cognitoSub,
Email = email,
DisplayName = name,
Role = role,
IsActive = true,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow,
};
_db.Users.Add(_cachedUser);
_db.SaveChanges();
}
return _cachedUser;
}
}