fix(scale): page mail and batch roles
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using JobTrackerApi.Models;
|
||||
using JobTrackerApi.Services;
|
||||
using JobTrackerApi.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -20,7 +21,8 @@ public sealed class UsersController : ControllerBase
|
||||
private readonly ExternalOrigin _externalOrigin;
|
||||
private readonly ILogger<UsersController> _logger;
|
||||
private readonly AccountDeletionService? _deletions;
|
||||
public UsersController(UserManager<ApplicationUser> users, RoleManager<IdentityRole> roles, IAppEmailSender email, IConfiguration cfg, ILogger<UsersController> logger, ExternalOrigin? externalOrigin = null, AccountDeletionService? deletions = null)
|
||||
private readonly JobTrackerContext? _db;
|
||||
public UsersController(UserManager<ApplicationUser> users, RoleManager<IdentityRole> roles, IAppEmailSender email, IConfiguration cfg, ILogger<UsersController> logger, ExternalOrigin? externalOrigin = null, AccountDeletionService? deletions = null, JobTrackerContext? db = null)
|
||||
{
|
||||
_users = users;
|
||||
_roles = roles;
|
||||
@@ -28,6 +30,7 @@ public sealed class UsersController : ControllerBase
|
||||
_externalOrigin = externalOrigin ?? ExternalOrigin.FromConfiguration(cfg);
|
||||
_logger = logger;
|
||||
_deletions = deletions;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public sealed record UserDto(
|
||||
@@ -47,6 +50,36 @@ public sealed class UsersController : ControllerBase
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<List<UserDto>>> List(CancellationToken cancellationToken)
|
||||
{
|
||||
if (_db is not null)
|
||||
{
|
||||
var users = await _db.Users.AsNoTracking()
|
||||
.OrderBy(user => user.Email)
|
||||
.ToListAsync(cancellationToken);
|
||||
var roleRows = await (
|
||||
from userRole in _db.UserRoles.AsNoTracking()
|
||||
join role in _db.Roles.AsNoTracking() on userRole.RoleId equals role.Id
|
||||
select new { userRole.UserId, role.Name })
|
||||
.ToListAsync(cancellationToken);
|
||||
var rolesByUser = roleRows
|
||||
.Where(row => !string.IsNullOrWhiteSpace(row.Name))
|
||||
.GroupBy(row => row.UserId)
|
||||
.ToDictionary(group => group.Key, group => group.Select(row => row.Name!).ToList());
|
||||
var relationalAdminCount = roleRows
|
||||
.Where(row => string.Equals(row.Name, "Admin", StringComparison.OrdinalIgnoreCase))
|
||||
.Select(row => row.UserId)
|
||||
.Distinct(StringComparer.Ordinal)
|
||||
.Count();
|
||||
var relationalCurrentUserId = User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub");
|
||||
|
||||
return Ok(users.Select(user =>
|
||||
{
|
||||
var roles = rolesByUser.GetValueOrDefault(user.Id) ?? [];
|
||||
return ToDto(user, roles, relationalCurrentUserId, !roles.Contains("Admin", StringComparer.OrdinalIgnoreCase) || relationalAdminCount > 1);
|
||||
}).ToList());
|
||||
}
|
||||
|
||||
// Retained only for isolated controller tests/manual construction. The application DI path
|
||||
// always supplies JobTrackerContext and uses the fixed two-query projection above.
|
||||
var items = await _users.Users
|
||||
.OrderBy(u => u.Email)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
Reference in New Issue
Block a user