tweak linking behavior

This commit is contained in:
RaidMax 2021-08-21 10:40:03 -05:00
parent b83ea57579
commit 596272a3de
4 changed files with 65 additions and 37 deletions

View File

@ -462,7 +462,7 @@ namespace IW4MAdmin
Link = E.Target.AliasLink Link = E.Target.AliasLink
}; };
var addedPenalty = await Manager.GetPenaltyService().Create(newPenalty); await Manager.GetPenaltyService().Create(newPenalty);
E.Target.SetLevel(Permission.Flagged, E.Origin); E.Target.SetLevel(Permission.Flagged, E.Origin);
} }

View File

@ -1,10 +1,12 @@
using System.Linq; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Data.Abstractions; using Data.Abstractions;
using Data.Models; using Data.Models;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using SharedLibraryCore; using SharedLibraryCore;
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Dtos.Meta.Responses; using SharedLibraryCore.Dtos.Meta.Responses;
using SharedLibraryCore.Helpers; using SharedLibraryCore.Helpers;
using SharedLibraryCore.Interfaces; using SharedLibraryCore.Interfaces;
@ -21,11 +23,14 @@ namespace IW4MAdmin.Application.Meta
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IDatabaseContextFactory _contextFactory; private readonly IDatabaseContextFactory _contextFactory;
private readonly ApplicationConfiguration _appConfig;
public ReceivedPenaltyResourceQueryHelper(ILogger<ReceivedPenaltyResourceQueryHelper> logger, IDatabaseContextFactory contextFactory) public ReceivedPenaltyResourceQueryHelper(ILogger<ReceivedPenaltyResourceQueryHelper> logger,
IDatabaseContextFactory contextFactory, ApplicationConfiguration appConfig)
{ {
_contextFactory = contextFactory; _contextFactory = contextFactory;
_logger = logger; _logger = logger;
_appConfig = appConfig;
} }
public async Task<ResourceQueryHelperResult<ReceivedPenaltyResponse>> QueryResource(ClientPaginationRequest query) public async Task<ResourceQueryHelperResult<ReceivedPenaltyResponse>> QueryResource(ClientPaginationRequest query)
@ -39,11 +44,30 @@ namespace IW4MAdmin.Application.Meta
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
var iqPenalties = ctx.Penalties.AsNoTracking() var iqPenalties = ctx.Penalties.AsNoTracking()
.Where(_penalty => _penalty.OffenderId == query.ClientId || (linkedPenaltyType.Contains(_penalty.Type) && _penalty.LinkId == linkId)) .Where(_penalty => _penalty.OffenderId == query.ClientId ||
.Where(_penalty => _penalty.When < query.Before) linkedPenaltyType.Contains(_penalty.Type) && _penalty.LinkId == linkId);
.OrderByDescending(_penalty => _penalty.When);
var penalties = await iqPenalties var iqIpLinkedPenalties = new List<EFPenalty>().AsQueryable();
if (!_appConfig.EnableImplicitAccountLinking)
{
var usedIps = await ctx.Aliases.AsNoTracking()
.Where(alias => alias.LinkId == linkId && alias.IPAddress != null)
.Select(alias => alias.IPAddress).ToListAsync();
var aliasedIds = await ctx.Aliases.AsNoTracking().Where(alias => usedIps.Contains(alias.IPAddress))
.Select(alias => alias.LinkId)
.ToListAsync();
iqIpLinkedPenalties = ctx.Penalties.AsNoTracking()
.Where(penalty =>
linkedPenaltyType.Contains(penalty.Type) &&
/*usedIps.Contains(penalty.Offender.CurrentAlias.IPAddress)*/aliasedIds.Contains(penalty.LinkId));
}
var penalties = await iqPenalties.Union(iqIpLinkedPenalties)
.Where(_penalty => _penalty.When < query.Before)
.OrderByDescending(_penalty => _penalty.When)
.Take(query.Count) .Take(query.Count)
.Select(_penalty => new ReceivedPenaltyResponse() .Select(_penalty => new ReceivedPenaltyResponse()
{ {

View File

@ -593,24 +593,15 @@ namespace SharedLibraryCore.Database.Models
// we want to kick them if any account is banned // we want to kick them if any account is banned
if (banPenalty != null) if (banPenalty != null)
{
if (enableImplicitLinking)
{ {
if (Level != Permission.Banned) if (Level != Permission.Banned)
{ {
Utilities.DefaultLogger.LogInformation( Utilities.DefaultLogger.LogInformation(
"Client {client} is banned, but using a new GUID, we we're updating their level and kicking them", "Client {client} has a ban penalty, but they're using a new GUID, we we're updating their level and kicking them",
ToString()); ToString());
await SetLevel(Permission.Banned, autoKickClient).WaitAsync(Utilities.DefaultCommandTimeout, await SetLevel(Permission.Banned, autoKickClient).WaitAsync(Utilities.DefaultCommandTimeout,
CurrentServer.Manager.CancellationToken); CurrentServer.Manager.CancellationToken);
} }
}
if (Level != Permission.Banned)
{
Ban(banPenalty.Offense, autoKickClient, true);
return false;
}
Utilities.DefaultLogger.LogInformation("Kicking {client} because they are banned", ToString()); Utilities.DefaultLogger.LogInformation("Kicking {client} because they are banned", ToString());
Kick(loc["WEBFRONT_PENALTY_LIST_BANNED_REASON"], autoKickClient, banPenalty); Kick(loc["WEBFRONT_PENALTY_LIST_BANNED_REASON"], autoKickClient, banPenalty);

View File

@ -9,6 +9,7 @@ using System.Linq.Expressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Data.Abstractions; using Data.Abstractions;
using Data.Models; using Data.Models;
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Interfaces; using SharedLibraryCore.Interfaces;
namespace SharedLibraryCore.Services namespace SharedLibraryCore.Services
@ -16,10 +17,12 @@ namespace SharedLibraryCore.Services
public class PenaltyService : IEntityService<EFPenalty> public class PenaltyService : IEntityService<EFPenalty>
{ {
private readonly IDatabaseContextFactory _contextFactory; private readonly IDatabaseContextFactory _contextFactory;
private readonly ApplicationConfiguration _appConfig;
public PenaltyService(IDatabaseContextFactory contextFactory) public PenaltyService(IDatabaseContextFactory contextFactory, ApplicationConfiguration appConfig)
{ {
_contextFactory = contextFactory; _contextFactory = contextFactory;
_appConfig = appConfig;
} }
public virtual async Task<EFPenalty> Create(EFPenalty newEntity) public virtual async Task<EFPenalty> Create(EFPenalty newEntity)
@ -75,7 +78,7 @@ namespace SharedLibraryCore.Services
await using var context = _contextFactory.CreateContext(false); await using var context = _contextFactory.CreateContext(false);
var iqPenalties = context.Penalties var iqPenalties = context.Penalties
.Where(p => showOnly == EFPenalty.PenaltyType.Any ? p.Type != EFPenalty.PenaltyType.Any : p.Type == showOnly) .Where(p => showOnly == EFPenalty.PenaltyType.Any ? p.Type != EFPenalty.PenaltyType.Any : p.Type == showOnly)
.Where(_penalty => ignoreAutomated ? _penalty.PunisherId != 1 : true) .Where(_penalty => !ignoreAutomated || _penalty.PunisherId != 1)
.OrderByDescending(p => p.When) .OrderByDescending(p => p.When)
.Skip(offset) .Skip(offset)
.Take(count) .Take(count)
@ -145,7 +148,7 @@ namespace SharedLibraryCore.Services
{ {
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
Expression<Func<EFPenalty, bool>> filter = (p) => (new EFPenalty.PenaltyType[] Expression<Func<EFPenalty, bool>> filter = (p) => (new []
{ {
EFPenalty.PenaltyType.TempBan, EFPenalty.PenaltyType.TempBan,
EFPenalty.PenaltyType.Ban, EFPenalty.PenaltyType.Ban,
@ -159,28 +162,38 @@ namespace SharedLibraryCore.Services
.Where(p => p.LinkId == linkId) .Where(p => p.LinkId == linkId)
.Where(filter); .Where(filter);
var iqIPPenalties = context.Aliases var iqIpPenalties = _appConfig.EnableImplicitAccountLinking
? context.Aliases
.Where(a => a.IPAddress != null && a.IPAddress == ip) .Where(a => a.IPAddress != null && a.IPAddress == ip)
.SelectMany(a => a.Link.ReceivedPenalties) .SelectMany(a => a.Link.ReceivedPenalties)
.Where(filter)
: context.Penalties.Where(penalty =>
penalty.Offender.CurrentAlias.IPAddress != null &&
penalty.Offender.CurrentAlias.IPAddress == ip)
.Where(filter); .Where(filter);
var activePenalties = (await iqLinkPenalties.ToListAsync()) var activePenalties = (await iqLinkPenalties.ToListAsync())
.Union(await iqIPPenalties.ToListAsync()) .Union(await iqIpPenalties.ToListAsync())
.Distinct(); .Distinct();
// this is a bit more performant in memory (ordering) // this is a bit more performant in memory (ordering)
return activePenalties.OrderByDescending(p => p.When).ToList(); return activePenalties.OrderByDescending(p => p.When).ToList();
} }
public virtual async Task RemoveActivePenalties(int aliasLinkId) public virtual async Task RemoveActivePenalties(int aliasLinkId, int? ipAddress = null)
{ {
await using var context = _contextFactory.CreateContext(); await using var context = _contextFactory.CreateContext();
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
await context.Penalties var penaltiesByLink = context.Penalties
.Where(p => p.LinkId == aliasLinkId) .Where(p => p.LinkId == aliasLinkId)
.Where(p => p.Expires > now || p.Expires == null) .Where(p => p.Expires > now || p.Expires == null);
.ForEachAsync(p =>
var penaltiesByIp = context.Penalties
.Where(p => p.Offender.CurrentAlias.IPAddress != null && p.Offender.CurrentAlias.IPAddress == null)
.Where(p => p.Expires > now || p.Expires == null);
await penaltiesByLink.Union(penaltiesByIp).Distinct().ForEachAsync(p =>
{ {
p.Active = false; p.Active = false;
p.Expires = now; p.Expires = now;