using Kafka.Lib.Auth; using MassTransit; using OpenWarehouse.auth.api.Common.CustomIdentifyManager; using OpenWarehouse.auth.api.Common.Exemptions; using OpenWarehouse.auth.lib.Model.Role; using OpenWarehouse.auth.lib.Model.Service; namespace OpenWarehouse.auth.api.Common.ServiceManager; public class ServiceManager( UserManager userManager, RoleManager roleManager, PrivilageManager.PrivilegeManager privilegeManager, ILogger logger, ITopicProducer userTopic) : IServiceManager { public async Task CheckIfServiceUserExist(string serviceName) { return await userManager.FindByNameAsync($"Service-{serviceName}") != null; } public async Task CreateServiceUserResult(string serviceName, bool serviceIsAdmin = false) { var serviceUser = new ApplicationUser() { UserName = $"Service-{serviceName}", Email = $"service-{serviceName}@service.local", LockoutEnabled = true, }; var result = await userManager.CreateAsync(serviceUser); if (!result.Succeeded) throw new Exception(result.ToString()); if (serviceIsAdmin) await AddAdminToServiceUser(serviceName); var addClaim = await userManager.AddClaimAsync(serviceUser, AccountType.Service.Claim()); var topic = new UserChangeMessageType() { UserId = serviceUser.Id, Changes = new Dictionary() { {"Username", $"Service-{serviceName}"}, {"AccountType", AccountType.Service.GetValue()}, {"IsGlobalAdmin", serviceIsAdmin.ToString()} } }; _ = userTopic.Produce(topic); return result.Succeeded && addClaim.Succeeded; } public async Task AddAdminToServiceUser(string serviceName) { var roleName = $"Service-{serviceName}"; var user = await userManager.FindByNameAsync(roleName) ?? throw new AccountExemptions(false, "Account not found"); var isAllready = await privilegeManager.UserHasGlobalPrivilage(user, GlobalPrivilage.Privilege.GlobalAdmin); if (isAllready) return true; isAllready = await roleManager.FindByNameAsync(roleName) != null; if (!isAllready) { var serviceRole = new ApplicationRole() { IsGlobalAdmin = true, Name = roleName }; var serviceRoleResult = await roleManager.CreateAsync(serviceRole); if (!serviceRoleResult.Succeeded) { throw new RoleExemptions(false, serviceRoleResult.ToString(), serviceRoleResult .Errors.Select(error => new KeyValuePair(error.Code, error.Description)) .ToDictionary()); } } var addRes = await userManager.AddToRoleAsync(user, roleName); var topic = new UserChangeMessageType() { UserId = user.Id, Changes = new Dictionary() { {"Role", isAllready ? "Allready exist" : "Created"}, {"Operation", "Added admin to user"}, {"Sucess", addRes.Succeeded.ToString()} } }; _ = userTopic.Produce(topic); return addRes.Succeeded; } public async Task> CreateServiceRoles(List serviceRoles, bool forcePrivilages = false) { logger.LogDebug($"Create roles: {serviceRoles.Select(q => q.RoleName).ToList()}"); var result = new List(); foreach (var role in serviceRoles) { Dictionary errors = new(); var roleApp = new ApplicationRole() { IsGlobalAdmin = role.IsGlobalAdmin, Name = role.RoleName }; foreach (var privilage in role.Privilage ?? throw new Exception("Role is null")) { RolePrivilage? privilageObj; if (forcePrivilages) { privilageObj = await privilegeManager.GetPrivilageByName(privilage); } else { privilageObj = await privilegeManager.GetPrivilageByNameIfDontExistCreateAsync(privilage); } if (privilageObj != null) { roleApp.Privilege.Add(privilageObj); } else { errors[privilage] = "Not found"; logger.LogWarning($"Privilage {privilage} not found"); } } var resultRole = await roleManager.CreateAsync(roleApp); if (!resultRole.Succeeded) { _ = resultRole.Errors.Select(errorL => errors[errorL.Code] = errorL.Description); } result.Add(new CreateServiceRoleResult(resultRole.Succeeded, errors)); } return result; } public async Task> CreateServicesPrivilage(List servicePrivilages) { List results = new(); foreach (var privilage in servicePrivilages) { var resultsLocal = await privilegeManager.CreatePrivageAsync(privilage); logger.LogDebug($"Create new role {privilage} is sucess {resultsLocal.IsSuccessed} with errors {resultsLocal.Errors}"); results.Add(new CreateServicePrivilageResult(privilage, resultsLocal.IsSuccessed)); } return results; } }