63 lines
2.1 KiB
C#
63 lines
2.1 KiB
C#
using System.Security.Claims;
|
|
using SharepointToolbox.Web.Core.Models;
|
|
using SharepointToolbox.Web.Infrastructure.Persistence;
|
|
|
|
namespace SharepointToolbox.Web.Services.Auth;
|
|
|
|
public class UserService : IUserService
|
|
{
|
|
private readonly UserRepository _repo;
|
|
|
|
public UserService(UserRepository repo) { _repo = repo; }
|
|
|
|
public async Task<AppUser> ProvisionAsync(ClaimsPrincipal principal)
|
|
{
|
|
var email = principal.FindFirstValue(ClaimTypes.Email)
|
|
?? principal.FindFirstValue("preferred_username")
|
|
?? throw new InvalidOperationException("OIDC token has no email claim.");
|
|
|
|
var display = principal.FindFirstValue("name")
|
|
?? principal.FindFirstValue(ClaimTypes.Name)
|
|
?? email;
|
|
|
|
var existing = await _repo.FindByEmailAsync(email);
|
|
if (existing is not null)
|
|
{
|
|
existing.LastLogin = DateTimeOffset.UtcNow;
|
|
existing.DisplayName = display;
|
|
await _repo.UpsertAsync(existing);
|
|
return existing;
|
|
}
|
|
|
|
// First user ever → Admin; subsequent → TechN0
|
|
var all = await _repo.LoadAsync();
|
|
var role = all.Count == 0 ? UserRole.Admin : UserRole.TechN0;
|
|
|
|
var user = new AppUser
|
|
{
|
|
Email = email,
|
|
DisplayName = display,
|
|
Role = role,
|
|
CreatedAt = DateTimeOffset.UtcNow,
|
|
LastLogin = DateTimeOffset.UtcNow
|
|
};
|
|
await _repo.UpsertAsync(user);
|
|
return user;
|
|
}
|
|
|
|
public Task<AppUser?> GetByEmailAsync(string email) => _repo.FindByEmailAsync(email);
|
|
|
|
public Task<IReadOnlyList<AppUser>> GetAllAsync() => _repo.LoadAsync();
|
|
|
|
public async Task UpdateRoleAsync(string userId, UserRole role)
|
|
{
|
|
var users = (await _repo.LoadAsync()).ToList();
|
|
var user = users.FirstOrDefault(u => u.Id == userId)
|
|
?? throw new KeyNotFoundException($"User {userId} not found.");
|
|
user.Role = role;
|
|
await _repo.UpsertAsync(user);
|
|
}
|
|
|
|
public Task DeleteAsync(string userId) => _repo.DeleteAsync(userId);
|
|
}
|