feat(api): аутентификация и авторизация. Кастомные ParrAuthenticationHandler и BaseSimpleRoleProvider.
This commit is contained in:
8
PARR.API/Authentication/Models/UserCache.cs
Normal file
8
PARR.API/Authentication/Models/UserCache.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace PARR.API.Authentication.Models
|
||||||
|
{
|
||||||
|
public class UserCache
|
||||||
|
{
|
||||||
|
public required string UserIp { get; set; }
|
||||||
|
public List<UserRoleInCache> Roles { get; set; } = new List<UserRoleInCache>();
|
||||||
|
}
|
||||||
|
}
|
||||||
8
PARR.API/Authentication/Models/UserRoleInCache.cs
Normal file
8
PARR.API/Authentication/Models/UserRoleInCache.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace PARR.API.Authentication.Models
|
||||||
|
{
|
||||||
|
public class UserRoleInCache
|
||||||
|
{
|
||||||
|
public required string Name { get; set; }
|
||||||
|
public required string Description { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
58
PARR.API/Authentication/ParrAuthenticationHandler.cs
Normal file
58
PARR.API/Authentication/ParrAuthenticationHandler.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using PARR.API.Services.Interfaces;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
|
||||||
|
namespace PARR.API.Authentication
|
||||||
|
{
|
||||||
|
public class ParrAuthenticationHandler : AuthenticationHandler<ParrAuthenticationOptions>
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
|
||||||
|
public ParrAuthenticationHandler(
|
||||||
|
IOptionsMonitor<ParrAuthenticationOptions> options,
|
||||||
|
ILoggerFactory logger,
|
||||||
|
UrlEncoder encoder,
|
||||||
|
ISystemClock clock,
|
||||||
|
IServiceProvider serviceProvider) : base(options, logger, encoder, clock)
|
||||||
|
{
|
||||||
|
this.serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||||
|
{
|
||||||
|
var ipClient = Request.HttpContext.Connection.RemoteIpAddress?.MapToIPv4().ToString();
|
||||||
|
|
||||||
|
if (ipClient == null)
|
||||||
|
return AuthenticateResult.Fail($"IP address not defined.");
|
||||||
|
|
||||||
|
// Аутентификация - просто проверка, есть ли у нас такой пользователь
|
||||||
|
using (var scope = serviceProvider.CreateScope())
|
||||||
|
{
|
||||||
|
var authService = scope.ServiceProvider.GetRequiredService<IAuthService>();
|
||||||
|
|
||||||
|
var userIsBlocked = await authService.UserIsBlockedAsync(ipClient);
|
||||||
|
if (userIsBlocked)
|
||||||
|
return AuthenticateResult.Fail($"IP address is on the blocking list.");
|
||||||
|
|
||||||
|
var user = await authService.GetUserAsync(ipClient);
|
||||||
|
if (user == null)
|
||||||
|
return AuthenticateResult.Fail($"IP address not defined.");
|
||||||
|
|
||||||
|
|
||||||
|
// пользователь найден, аутентификация пройдена
|
||||||
|
|
||||||
|
var claims = new List<Claim> {
|
||||||
|
new Claim(ClaimTypes.Name, user.UserIp)
|
||||||
|
};
|
||||||
|
|
||||||
|
var claimsIdentity = new ClaimsIdentity(claims, Scheme.Name);
|
||||||
|
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
|
||||||
|
|
||||||
|
|
||||||
|
return AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, Scheme.Name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
PARR.API/Authentication/ParrAuthenticationOptions.cs
Normal file
10
PARR.API/Authentication/ParrAuthenticationOptions.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
|
||||||
|
namespace PARR.API.Authentication
|
||||||
|
{
|
||||||
|
public class ParrAuthenticationOptions : AuthenticationSchemeOptions
|
||||||
|
{
|
||||||
|
public const string DefaultScheme = "ParrAuthenticationScheme";
|
||||||
|
//public string TokenHeaderName { get; set; } = "MyToken";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using PARR.API.Contracts.V1;
|
using PARR.API.Contracts.V1;
|
||||||
using PARR.API.Contracts.V1.Responses.Base;
|
using PARR.API.Contracts.V1.Responses.Base;
|
||||||
using PARR.API.Controllers.V1.Base;
|
using PARR.API.Controllers.V1.Base;
|
||||||
using PARR.API.Services.Interfaces;
|
using PARR.API.Services.Interfaces;
|
||||||
|
using PARR.Constants;
|
||||||
using PARR.DAL.CacheServices;
|
using PARR.DAL.CacheServices;
|
||||||
using PARR.DAL.TransformServices;
|
using PARR.DAL.TransformServices;
|
||||||
|
|
||||||
@@ -26,13 +28,13 @@ namespace PARR.API.Controllers.V1
|
|||||||
/// Получить мой ip
|
/// Получить мой ip
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
//[Authorize(Roles = ParrRoles.Administrator.Role)]
|
||||||
|
[Authorize]
|
||||||
[HttpGet(ApiRoutes.Test.GetMyIp)]
|
[HttpGet(ApiRoutes.Test.GetMyIp)]
|
||||||
public IActionResult GetMyIp()
|
public IActionResult GetMyIp()
|
||||||
{
|
{
|
||||||
var ipAddress = clientService.GetClientIp();
|
var ipAddress = clientService.GetClientIp();
|
||||||
|
|
||||||
//var ipV4 = ipAddress?.MapToIPv4();
|
|
||||||
|
|
||||||
var ip = ipAddress?.ToString();
|
var ip = ipAddress?.ToString();
|
||||||
|
|
||||||
return Ok(new Response<object>(new { ip }, true));
|
return Ok(new Response<object>(new { ip }, true));
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace PARR.API.Installers
|
|||||||
});
|
});
|
||||||
|
|
||||||
services.AddTransient<IClientService, ClientService>();
|
services.AddTransient<IClientService, ClientService>();
|
||||||
|
services.AddTransient<IAuthService, AuthService>();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ namespace PARR.API.Installers
|
|||||||
configuration.GetSection(nameof(MqSettings)).Bind(mqSettings);
|
configuration.GetSection(nameof(MqSettings)).Bind(mqSettings);
|
||||||
services.AddSingleton(mqSettings);
|
services.AddSingleton(mqSettings);
|
||||||
|
|
||||||
|
var userCacheSettings = new UserCacheSettings();
|
||||||
//var storageSettings = new StorageSettings();
|
configuration.GetSection(nameof(UserCacheSettings)).Bind(userCacheSettings);
|
||||||
//configuration.GetSection(nameof(StorageSettings)).Bind(storageSettings);
|
services.AddSingleton(userCacheSettings);
|
||||||
//services.AddSingleton(storageSettings);
|
|
||||||
|
|
||||||
//TODO: add other
|
//TODO: add other
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
using Elastic.CommonSchema.Serilog;
|
using Elastic.CommonSchema.Serilog;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
|
using Microsoft.AspNetCore.Server.HttpSys;
|
||||||
|
using PARR.API.Authentication;
|
||||||
using PARR.API.Installers;
|
using PARR.API.Installers;
|
||||||
|
using PARR.API.RoleProvider;
|
||||||
using PARR.BLL;
|
using PARR.BLL;
|
||||||
using PARR.DAL;
|
using PARR.DAL;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
@@ -29,6 +32,12 @@ builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
|
|||||||
builder.Configuration.AddDalConfigurations(builder.Services);
|
builder.Configuration.AddDalConfigurations(builder.Services);
|
||||||
builder.Services.AddDallSettings(builder.Configuration);
|
builder.Services.AddDallSettings(builder.Configuration);
|
||||||
|
|
||||||
|
// Auth
|
||||||
|
builder.Services.AddAuthentication(ParrAuthenticationOptions.DefaultScheme)
|
||||||
|
.AddScheme<ParrAuthenticationOptions, ParrAuthenticationHandler>(ParrAuthenticationOptions.DefaultScheme, opt => { });
|
||||||
|
builder.Services.AddSimpleRoleAuthorization<BaseSimpleRoleProvider>();
|
||||||
|
|
||||||
|
|
||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddHttpContextAccessor();
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
@@ -44,6 +53,7 @@ var app = builder.Build();
|
|||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
app.InstallSwagger();
|
app.InstallSwagger();
|
||||||
|
|
||||||
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|||||||
48
PARR.API/RoleProvider/BaseSimpleRoleProvider.cs
Normal file
48
PARR.API/RoleProvider/BaseSimpleRoleProvider.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using PARR.API.Services.Interfaces;
|
||||||
|
|
||||||
|
namespace PARR.API.RoleProvider
|
||||||
|
{
|
||||||
|
public class BaseSimpleRoleProvider : ISimpleRoleProvider
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
|
||||||
|
public BaseSimpleRoleProvider(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
this.serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<string>> GetUserRolesAsync(string ipClient)
|
||||||
|
{
|
||||||
|
// Авторизация - проверка на разрешения
|
||||||
|
// В данном случае, получаем все разрешения (роли)
|
||||||
|
|
||||||
|
ICollection<string> defaultResult = new string[0];
|
||||||
|
|
||||||
|
using (var scope = serviceProvider.CreateScope())
|
||||||
|
{
|
||||||
|
//var clientService = scope.ServiceProvider.GetRequiredService<IClientService>();
|
||||||
|
|
||||||
|
//var ipClient = clientService.GetClientIp()?.ToString();
|
||||||
|
//if (string.IsNullOrEmpty(ipClient))
|
||||||
|
// return await Task.FromResult(defaultResult);
|
||||||
|
|
||||||
|
var authService = scope.ServiceProvider.GetRequiredService<IAuthService>();
|
||||||
|
|
||||||
|
// проверяем блокировку пользователя
|
||||||
|
var userIsBlocked = await authService.UserIsBlockedAsync(ipClient);
|
||||||
|
if (userIsBlocked)
|
||||||
|
return await Task.FromResult(defaultResult);
|
||||||
|
|
||||||
|
// получаем пользователя из кэша или бд
|
||||||
|
var user = await authService.GetUserAsync(ipClient);
|
||||||
|
if (user == null)
|
||||||
|
return await Task.FromResult(defaultResult);
|
||||||
|
|
||||||
|
|
||||||
|
return user.Roles.Select(t => t.Name).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// return await Task.FromResult(defaultResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
PARR.API/RoleProvider/ISimpleRoleProvider.cs
Normal file
7
PARR.API/RoleProvider/ISimpleRoleProvider.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace PARR.API.RoleProvider
|
||||||
|
{
|
||||||
|
public interface ISimpleRoleProvider
|
||||||
|
{
|
||||||
|
Task<ICollection<string>> GetUserRolesAsync(string ipClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
|
||||||
|
namespace PARR.API.RoleProvider
|
||||||
|
{
|
||||||
|
public static class SimpleRoleAuthorizationServiceCollectionExtensions
|
||||||
|
{
|
||||||
|
public static void AddSimpleRoleAuthorization<TRoleProvider>(this IServiceCollection services)
|
||||||
|
where TRoleProvider : class, ISimpleRoleProvider
|
||||||
|
{
|
||||||
|
services.AddSingleton<ISimpleRoleProvider, TRoleProvider>();
|
||||||
|
services.AddSingleton<IClaimsTransformation, SimpleRoleAuthorizationTransform>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
PARR.API/RoleProvider/SimpleRoleAuthorizationTransform.cs
Normal file
39
PARR.API/RoleProvider/SimpleRoleAuthorizationTransform.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace PARR.API.RoleProvider
|
||||||
|
{
|
||||||
|
public class SimpleRoleAuthorizationTransform : IClaimsTransformation
|
||||||
|
{
|
||||||
|
//private static readonly string RoleClaimType = $"http://{typeof(SimpleRoleAuthorizationTransform).FullName.Replace('.', '/')}/role";
|
||||||
|
private static readonly string RoleClaimType = ClaimTypes.Role;
|
||||||
|
|
||||||
|
private readonly ISimpleRoleProvider roleProvider;
|
||||||
|
|
||||||
|
public SimpleRoleAuthorizationTransform(ISimpleRoleProvider roleProvider)
|
||||||
|
{
|
||||||
|
this.roleProvider = roleProvider ?? throw new ArgumentNullException(nameof(roleProvider));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
|
||||||
|
{
|
||||||
|
// Cast the principal identity to a Claims identity to access claims etc...
|
||||||
|
var oldIdentity = (ClaimsIdentity)principal.Identity!;
|
||||||
|
|
||||||
|
// "Clone" the old identity to avoid nasty side effects.
|
||||||
|
// NB: We take a chance to replace the claim type used to define the roles with our own.
|
||||||
|
var newIdentity = new ClaimsIdentity(
|
||||||
|
oldIdentity.Claims,
|
||||||
|
oldIdentity.AuthenticationType,
|
||||||
|
oldIdentity.NameClaimType,
|
||||||
|
RoleClaimType);
|
||||||
|
|
||||||
|
// Fetch the roles for the user and add the claims of the correct type so that roles can be recognized.
|
||||||
|
var roles = await roleProvider.GetUserRolesAsync(newIdentity.Name!);
|
||||||
|
newIdentity.AddClaims(roles.Select(r => new Claim(RoleClaimType, r)));
|
||||||
|
|
||||||
|
// Create and return a new claims principal
|
||||||
|
return new ClaimsPrincipal(newIdentity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
87
PARR.API/Services/Implementations/AuthService.cs
Normal file
87
PARR.API/Services/Implementations/AuthService.cs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
using PARR.API.Authentication.Models;
|
||||||
|
using PARR.API.Services.Interfaces;
|
||||||
|
using PARR.API.Settings;
|
||||||
|
using PARR.Constants;
|
||||||
|
using PARR.DAL.CacheServices;
|
||||||
|
using PARR.DAL.Services.Interfaces;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public AuthService(IRedisCacheService cacheService, IUserService userService, IHostService hostService, UserCacheSettings userCacheSettings)
|
||||||
|
{
|
||||||
|
this.cacheService = cacheService;
|
||||||
|
this.userService = userService;
|
||||||
|
this.hostService = hostService;
|
||||||
|
this.userCacheSettings = userCacheSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<bool> UserIsBlockedAsync(string ipAddress)
|
||||||
|
{
|
||||||
|
//пользователь есть в списке блокировки?
|
||||||
|
var existUserInBlockList = await cacheService.GetCachedDataAsync<DateTimeOffset?>(GetBlockKey(ipAddress));
|
||||||
|
|
||||||
|
return existUserInBlockList != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<UserCache?> GetUserAsync(string ipAddress)
|
||||||
|
{
|
||||||
|
// смотрим, есть ли в кэше
|
||||||
|
var userInCache = await cacheService.GetCachedDataAsync<UserCache>(GetAllowKey(ipAddress));
|
||||||
|
if (userInCache != null)
|
||||||
|
return userInCache;
|
||||||
|
|
||||||
|
// нет в кэше
|
||||||
|
var roles = new List<UserRoleInCache>();
|
||||||
|
|
||||||
|
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 });
|
||||||
|
});
|
||||||
|
|
||||||
|
var host = await hostService.GetByIpAsync(ipAddress);
|
||||||
|
if (host != null)
|
||||||
|
roles.Add(new UserRoleInCache { Name = ParrRoles.Agent.Role, Description = ParrRoles.Agent.Description });
|
||||||
|
|
||||||
|
if (user == null && host == null)
|
||||||
|
{
|
||||||
|
// если это не пользователь и не хост, добавляем в кэш на блокировку
|
||||||
|
await cacheService.SetCachedDataAsync(GetBlockKey(ipAddress), DateTimeOffset.UtcNow, userCacheSettings.UserBlockTtl);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// пользователь есть, добавляем в КЭШ и возвращаем роли
|
||||||
|
var cacheData = new UserCache { UserIp = ipAddress, Roles = roles };
|
||||||
|
await cacheService.SetCachedDataAsync(GetAllowKey(ipAddress), cacheData, userCacheSettings.UserCacheTtl);
|
||||||
|
|
||||||
|
return cacheData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private string GetBlockKey(string ipAddress)
|
||||||
|
{
|
||||||
|
// d - deny
|
||||||
|
return $"d_{ipAddress}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetAllowKey(string ipAddress)
|
||||||
|
{
|
||||||
|
// a - allow
|
||||||
|
return $"a_{ipAddress}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
22
PARR.API/Services/Interfaces/IAuthService.cs
Normal file
22
PARR.API/Services/Interfaces/IAuthService.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using PARR.API.Authentication.Models;
|
||||||
|
|
||||||
|
namespace PARR.API.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface IAuthService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Получить пользователя с ролями по ip адресу.
|
||||||
|
/// Смотрим в кэше, затем в БД. При необходимости блокирует или добавлет в кэш.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<UserCache?> GetUserAsync(string ipAddress);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверяет, блокировку пользователя
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<bool> UserIsBlockedAsync(string ipAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
PARR.API/Settings/UserCacheSettings.cs
Normal file
18
PARR.API/Settings/UserCacheSettings.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
namespace PARR.API.Settings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Настройки кэша пользователй
|
||||||
|
/// </summary>
|
||||||
|
public class UserCacheSettings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Сколько хранить в кэше авторизованных пользователей
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan UserCacheTtl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Сколько хранить в кэше заблокированных пользователей (как долго блокировать пользователя)
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan UserBlockTtl { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"RedisConnection": "10.99.253.216:6379"
|
"RedisConnection": "10.99.253.216:6379,password=ParrP@ssPtk202MMdevDvs"
|
||||||
},
|
},
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
|
|||||||
@@ -45,5 +45,9 @@
|
|||||||
"User": "generate_templates_api",
|
"User": "generate_templates_api",
|
||||||
"Password": "DHhjgdsf*&%95"
|
"Password": "DHhjgdsf*&%95"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"UserCacheSettings": {
|
||||||
|
"UserCacheTtl": "00:05:00",
|
||||||
|
"UserBlockTtl": "00:03:00"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ namespace PARR.DAL
|
|||||||
services.AddTransient<IAgentHistoryService, AgentHistoryService>();
|
services.AddTransient<IAgentHistoryService, AgentHistoryService>();
|
||||||
services.AddTransient<IOrderService, OrderService>();
|
services.AddTransient<IOrderService, OrderService>();
|
||||||
services.AddTransient<IOrderStatusService, OrderStatusService>();
|
services.AddTransient<IOrderStatusService, OrderStatusService>();
|
||||||
|
services.AddTransient<IUserService, UserService>();
|
||||||
|
|
||||||
|
|
||||||
// TransformServices
|
// TransformServices
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ namespace PARR.DAL.Services.Implementations
|
|||||||
.FirstOrDefaultAsync(h => h.IP == IP);
|
.FirstOrDefaultAsync(h => h.IP == IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Host?> GetByIpAsync(string ip)
|
||||||
|
{
|
||||||
|
return await EntitySet.FirstOrDefaultAsync(t => t.IP == ip);
|
||||||
|
}
|
||||||
|
|
||||||
//public async Task<Host?> GetHostByRegionalEKAsync(string RegionalEK)И
|
//public async Task<Host?> GetHostByRegionalEKAsync(string RegionalEK)И
|
||||||
//{
|
//{
|
||||||
// try
|
// try
|
||||||
|
|||||||
30
PARR.DAL/Services/Implementations/UserService.cs
Normal file
30
PARR.DAL/Services/Implementations/UserService.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using PARR.DAL.Context;
|
||||||
|
using PARR.DAL.Models;
|
||||||
|
using PARR.DAL.Services.Abstracts;
|
||||||
|
using PARR.DAL.Services.Interfaces;
|
||||||
|
|
||||||
|
namespace PARR.DAL.Services.Implementations
|
||||||
|
{
|
||||||
|
internal class UserService : BaseService<User>, IUserService
|
||||||
|
{
|
||||||
|
private readonly DataContext dataContext;
|
||||||
|
|
||||||
|
public UserService(DataContext dataContext, ILogger<UserService> logger) : base(logger)
|
||||||
|
{
|
||||||
|
this.dataContext = dataContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DbSet<User> EntitySet => dataContext.Users;
|
||||||
|
|
||||||
|
protected override DataContext EntitiContext => dataContext;
|
||||||
|
|
||||||
|
public async Task<User?> GetByIpWithRolesAsync(string ipAddress)
|
||||||
|
{
|
||||||
|
return await EntitySet
|
||||||
|
.Include(t => t.Roles).ThenInclude(t => t.Role)
|
||||||
|
.FirstOrDefaultAsync(t => t.Ip == ipAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,10 @@ namespace PARR.DAL.Services.Interfaces
|
|||||||
{
|
{
|
||||||
public interface IHostService : IBaseService<Host>
|
public interface IHostService : IBaseService<Host>
|
||||||
{
|
{
|
||||||
Task<Host?> GetHostWithAppsAsync(string IP);
|
Task<Host?> GetHostWithAppsAsync(string ip);
|
||||||
|
|
||||||
|
Task<Host?> GetByIpAsync(string ip);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
PARR.DAL/Services/Interfaces/IUserService.cs
Normal file
10
PARR.DAL/Services/Interfaces/IUserService.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using PARR.DAL.Models;
|
||||||
|
using PARR.DAL.Services.Interfaces.Base;
|
||||||
|
|
||||||
|
namespace PARR.DAL.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface IUserService: IBaseService<User>
|
||||||
|
{
|
||||||
|
Task<User?> GetByIpWithRolesAsync(string ipAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user