using PARR.API.Authentication.Models; using PARR.API.Domain.InfluxDbModels; using PARR.API.Services.Interfaces; using PARR.API.Settings; using PARR.Constants; using PARR.DAL.CacheServices; using PARR.DAL.InfluxDbServices; using PARR.DAL.Services.Interfaces; using PARR.DAL.Settings; namespace PARR.API.Services.Implementations { public class AuthService : IAuthService { private readonly IRedisCacheService cacheService; private readonly IUserService userService; private readonly IHostService hostService; private readonly UserCacheSettings userCacheSettings; private readonly IClientService clientService; private readonly IInfluxDbService influxDbService; private readonly InfluxDbSettings influxDbSettings; public AuthService( IRedisCacheService cacheService, IUserService userService, IHostService hostService, UserCacheSettings userCacheSettings, IClientService clientService, IInfluxDbService influxDbService, InfluxDbSettings influxDbSettings ) { this.cacheService = cacheService; this.userService = userService; this.hostService = hostService; this.userCacheSettings = userCacheSettings; this.clientService = clientService; this.influxDbService = influxDbService; this.influxDbSettings = influxDbSettings; } public async Task UserIsBlockedAsync(string ipAddress) { //пользователь есть в списке блокировки? var existUserInBlockList = await cacheService.GetCachedDataAsync(GetBlockKey(ipAddress)); return existUserInBlockList != null; } public async Task GetCurrentUserAsync() { var userIp = clientService.GetClientIp()?.ToString(); if (userIp == null) return null; return await GetUserAsync(userIp); } public async Task GetUserAsync(string ipAddress) { // смотрим, есть ли в кэше var userInCache = await cacheService.GetCachedDataAsync(GetAllowKey(ipAddress)); if (userInCache != null) return userInCache; // нет в кэше var roles = new List(); var user = await userService.GetByIpWithRolesAsync(ipAddress); if (user != null) { user.Roles.ToList().ForEach(t => { if (t.Role != null) roles.Add(new UserRoleInCache { Name = t.Role.Name, Description = t.Role.Description }); }); // сохраняем время входа user.LastLogon = DateTimeOffset.UtcNow; await userService.CommitAsync(); } var host = await hostService.GetByIpAsync(ipAddress); if (host != null) { roles.Add(new UserRoleInCache { Name = ParrRoles.Agent.Role, Description = ParrRoles.Agent.Description }); // сохраняем время входа host.LastLogon = DateTimeOffset.UtcNow; await hostService.CommitAsync(); } if (user == null && host == null) { // если это не пользователь и не хост, добавляем в кэш на блокировку await cacheService.SetCachedDataAsync(GetBlockKey(ipAddress), DateTimeOffset.UtcNow, userCacheSettings.UserBlockTtl); return null; } // пользователь есть, добавляем в КЭШ и возвращаем роли var cacheData = new UserCache { UserIp = ipAddress, Roles = roles }; if (host != null) { cacheData.Name = host.Ek; cacheData.HostId = host.Id; cacheData.LastLogon = host.LastLogon; } if (user != null) { cacheData.Name = user.Name + (host != null ? $", {host.Ek}" : string.Empty); cacheData.Description = user.Description ?? string.Empty; cacheData.UserId = user.Id; cacheData.LastLogon = user.LastLogon; } await cacheService.SetCachedDataAsync(GetAllowKey(ipAddress), cacheData, userCacheSettings.UserCacheTtl); //тут записать в статистику входов в influxdb WriteLogonStatistic(cacheData); return cacheData; } private void WriteLogonStatistic(UserCache cacheData) { influxDbService.Write(write => { var data = new LogonDbModel { HostId = cacheData.HostId, Ip = cacheData.UserIp, UserId = cacheData.UserId }; write.WriteMeasurement(data, InfluxDB.Client.Api.Domain.WritePrecision.Ns, bucket: influxDbSettings.Logons!.Bucket, org: influxDbSettings.Organization); }, influxDbSettings.Logons!.Token); } public async Task UnlockUserAsync(string ipAddress) { await cacheService.DeleteCachedDataAsync(GetBlockKey(ipAddress)); } public async Task RemoveCacheUserAsync(string ipAddress) { await cacheService.DeleteCachedDataAsync(GetAllowKey(ipAddress)); await cacheService.DeleteCachedDataAsync(GetBlockKey(ipAddress)); } private string GetBlockKey(string ipAddress) { // d - deny return $"d_{ipAddress}"; } private string GetAllowKey(string ipAddress) { // a - allow return $"a_{ipAddress}"; } } }