95 lines
3.8 KiB
C#
95 lines
3.8 KiB
C#
using e_suite.API.Common;
|
|
using e_suite.API.Common.models;
|
|
using e_suite.API.Common.repository;
|
|
using e_suite.Database.Audit;
|
|
using e_suite.Modules.BlockedIPsManager.Extensions;
|
|
using e_suite.Utilities.Pagination;
|
|
using eSuite.Core.Clock;
|
|
using Microsoft.Extensions.Configuration;
|
|
using System.Linq.Expressions;
|
|
using MockQueryable;
|
|
|
|
namespace e_suite.Modules.BlockedIPsManager;
|
|
|
|
public class BlockedIPsManager : IBlockedIPsManager
|
|
{
|
|
private readonly IClock _clock;
|
|
private readonly IConfiguration _configuration;
|
|
private readonly IBlockedIPsManagerRepository _blockedIPsManagerRepository;
|
|
|
|
public BlockedIPsManager(IBlockedIPsManagerRepository blockedIPsManagerRepository, IClock clock, IConfiguration configuration)
|
|
{
|
|
_blockedIPsManagerRepository = blockedIPsManagerRepository;
|
|
_clock = clock;
|
|
_configuration = configuration;
|
|
}
|
|
|
|
public async Task<IPaginatedData<BlockedIPs>> GetBlockedIPs(Paging paging, CancellationToken cancellationToken)
|
|
{
|
|
//Can I make this move, its a copied code from the sentinal
|
|
var loginAttemptTimeoutMinutes = _configuration.GetValue<int>("Sentinel:LoginAttemptTimeoutMinutes");
|
|
var maxLoginAttempts = _configuration.GetValue<int>("Sentinel:MaxLoginAttempts");
|
|
|
|
var earliestAttemptTime = _clock.GetNow.AddMinutes(-loginAttemptTimeoutMinutes);
|
|
|
|
var blockedIPs = _blockedIPsManagerRepository.GetBlockedIPs(earliestAttemptTime);
|
|
|
|
var dateTimeNow = _clock.GetNow;
|
|
|
|
var data = blockedIPs.GroupBy(g => g.IPAddress)
|
|
.Select(x => new BlockedIPs {
|
|
IPAddress = x.First().IPAddress,
|
|
NumberOfAttempts = x.Count(),
|
|
BlockedAt = x.Max(t => t.AttemptedTime),
|
|
UnblockedIn = GetUnlockedMinutes(x.Min(t => t.AttemptedTime), loginAttemptTimeoutMinutes, dateTimeNow).ToInteger()
|
|
})
|
|
.ToList()
|
|
.BuildMock();
|
|
|
|
var paginatedData = await PaginatedData.Paginate(data, paging,
|
|
KeySelector, FilterSelector, cancellationToken);
|
|
|
|
return new PaginatedData<BlockedIPs>
|
|
{
|
|
Count = paginatedData.Count,
|
|
Page = paginatedData.Page,
|
|
PageSize = paginatedData.PageSize,
|
|
Data = paginatedData.Data
|
|
};
|
|
}
|
|
|
|
public static double GetUnlockedMinutes(DateTimeOffset attemptedTime, int loginAttemptTimeoutMinutes, DateTimeOffset dateTimeNow)
|
|
{
|
|
return Math.Floor(attemptedTime.AddMinutes(loginAttemptTimeoutMinutes).Subtract(dateTimeNow).TotalMinutes);
|
|
}
|
|
|
|
private Expression<Func<BlockedIPs, bool>> FilterSelector(string? key, string value)
|
|
{
|
|
return key?.ToLowerInvariant() switch
|
|
{
|
|
"ipaddress" => x => x.IPAddress.ToString().Contains(value),
|
|
"numberOfAttempts" => x => x.NumberOfAttempts.ToString().Contains(value),
|
|
"blockedAt" => x => x.BlockedAt.ToString().Contains(value),
|
|
"unblockedin" => x => x.UnblockedIn.ToString().Contains(value),
|
|
_ => x => x.IPAddress.ToString().Contains(value)
|
|
};
|
|
}
|
|
|
|
private Expression<Func<BlockedIPs, object>> KeySelector(string? sortKey)
|
|
{
|
|
return sortKey?.ToLowerInvariant() switch
|
|
{
|
|
"ipaddress" => x => x.IPAddress,
|
|
"numberofattempts" => x => x.NumberOfAttempts,
|
|
"blockedat" => x => x.BlockedAt,
|
|
"unblockedin" => x => x.UnblockedIn,
|
|
_ => x => x.IPAddress
|
|
};
|
|
}
|
|
|
|
public async Task UnblockIPAddress(AuditUserDetails auditUserDetails, string ipaddress, CancellationToken cancellationToken)
|
|
{
|
|
await _blockedIPsManagerRepository.UnBlockIP(auditUserDetails, ipaddress, cancellationToken);
|
|
}
|
|
}
|