101 lines
3.4 KiB
C#
101 lines
3.4 KiB
C#
using AutoMapper;
|
|
using LANCommander.Server.Data;
|
|
using LANCommander.Server.Data.Models;
|
|
using LANCommander.Server.Services.Factories;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.Extensions.Logging;
|
|
using System.Data;
|
|
using LANCommander.Server.Services.Exceptions;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using ZiggyCreatures.Caching.Fusion;
|
|
|
|
namespace LANCommander.Server.Services
|
|
{
|
|
public sealed class RoleService(
|
|
ILogger<RoleService> logger,
|
|
SettingsProvider<Settings.Settings> settingsProvider,
|
|
IFusionCache cache,
|
|
IMapper mapper,
|
|
IHttpContextAccessor httpContextAccessor,
|
|
IDbContextFactory<DatabaseContext> contextFactory,
|
|
CollectionService collectionService,
|
|
IdentityContextFactory identityContextFactory) : BaseDatabaseService<Role>(logger, settingsProvider, cache, mapper, httpContextAccessor, contextFactory)
|
|
{
|
|
public const string AdministratorRoleName = "Administrator";
|
|
|
|
public override async Task<Role> AddAsync(Role role)
|
|
{
|
|
using var identityContext = await identityContextFactory.CreateAsync();
|
|
var result = await identityContext.RoleManager.CreateAsync(role);
|
|
|
|
if (result.Succeeded)
|
|
return await GetAsync(role.Name);
|
|
|
|
throw new AddRoleException(result, "Could not create role");
|
|
}
|
|
|
|
public override async Task<Role> UpdateAsync(Role entity)
|
|
{
|
|
var role = await base.UpdateAsync(entity, async context =>
|
|
{
|
|
await context.UpdateRelationshipAsync(r => r.Collections);
|
|
});
|
|
|
|
// Role limit columns are cached as part of users' role snapshots, so invalidate them.
|
|
await cache.RemoveByTagAsync(["User/Roles", "User/Security"]);
|
|
|
|
return role;
|
|
}
|
|
|
|
public async Task<Role> GetAsync(string roleName)
|
|
{
|
|
return await FirstOrDefaultAsync(r => r.Name == roleName);
|
|
}
|
|
|
|
public async Task<T> GetAsync<T>(string roleName)
|
|
{
|
|
var role = await FirstOrDefaultAsync(r => r.Name == roleName);
|
|
|
|
return mapper.Map<T>(role);
|
|
}
|
|
|
|
public async Task<Role> AssignCollections(Guid roleId, IEnumerable<Guid> collectionIds)
|
|
{
|
|
var role = await Include(r => r.Collections).GetAsync(roleId);
|
|
|
|
if (role.Collections == null)
|
|
role.Collections = new List<Collection>();
|
|
|
|
foreach (var collectionId in collectionIds.Where(id => !role.Collections.Any(c => c.Id == id)))
|
|
{
|
|
var collection = await collectionService.GetAsync(collectionId);
|
|
|
|
role.Collections.Add(collection);
|
|
}
|
|
|
|
foreach (var collection in role.Collections.Where(c => !collectionIds.Contains(c.Id)))
|
|
{
|
|
role.Collections.Remove(collection);
|
|
}
|
|
|
|
role = await UpdateAsync(role);
|
|
|
|
return role;
|
|
}
|
|
|
|
public async Task<IEnumerable<User>> GetUsersAsync(string roleName)
|
|
{
|
|
var role = await Query(q =>
|
|
{
|
|
return q
|
|
.Include(r => r.UserRoles)
|
|
.ThenInclude(ur => ur.User);
|
|
}).AsNoTracking().FirstOrDefaultAsync(r => r.Name.ToLower() == roleName.ToLower());
|
|
|
|
if (role != null && role.Users != null)
|
|
return role.Users;
|
|
return new List<User>();
|
|
}
|
|
}
|
|
}
|