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 logger, IFusionCache cache, IMapper mapper, IHttpContextAccessor httpContextAccessor, IDbContextFactory contextFactory, CollectionService collectionService, IdentityContextFactory identityContextFactory, RoleManager roleManager) : BaseDatabaseService(logger, cache, mapper, httpContextAccessor, contextFactory) { public const string AdministratorRoleName = "Administrator"; private IdentityContext _identityContext; public override void Initialize() { _identityContext = identityContextFactory.Create(); } public override async Task UpdateAsync(Role entity) { return await base.UpdateAsync(entity, async context => { await context.UpdateRelationshipAsync(r => r.Collections); await context.UpdateRelationshipAsync(r => r.Users); }); } public async Task AddAsync(Role role) { var result = await roleManager.CreateAsync(role); if (result.Succeeded) return await roleManager.FindByNameAsync(role.Name); throw new AddRoleException(result, "Could not create role"); } public async Task GetAsync(string roleName) { return await FirstOrDefaultAsync(r => r.Name == roleName); } public async Task GetAsync(string roleName) { var role = await FirstOrDefaultAsync(r => r.Name == roleName); return mapper.Map(role); } public async Task AssignCollections(Guid roleId, IEnumerable collectionIds) { var role = await Include(r => r.Collections).GetAsync(roleId); if (role.Collections == null) role.Collections = new List(); 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> GetUsersAsync(string roleName) { return await _identityContext.UserManager.GetUsersInRoleAsync(roleName); } } }