re-enable login to webfront with password

update cookie to last 3 months
add configuration option to limit # of rss feed items
prevent database tracking of bots if ignore bots requested
add last map and last server played to profile
This commit is contained in:
RaidMax 2019-02-22 19:06:51 -06:00
parent 74cdf8e885
commit 4b1f44cc2a
15 changed files with 864 additions and 27 deletions

View File

@ -6,7 +6,7 @@
<RuntimeFrameworkVersion>2.2.2</RuntimeFrameworkVersion>
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
<Version>2.2.5.4</Version>
<Version>2.2.5.5</Version>
<Authors>RaidMax</Authors>
<Company>Forever None</Company>
<Product>IW4MAdmin</Product>
@ -31,8 +31,8 @@
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>true</TieredCompilation>
<AssemblyVersion>2.2.5.4</AssemblyVersion>
<FileVersion>2.2.5.4</FileVersion>
<AssemblyVersion>2.2.5.5</AssemblyVersion>
<FileVersion>2.2.5.5</FileVersion>
</PropertyGroup>
<ItemGroup>

View File

@ -7,6 +7,7 @@ using SharedLibraryCore.Commands;
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Dtos;
using SharedLibraryCore.Events;
using SharedLibraryCore.Exceptions;
using SharedLibraryCore.Helpers;
@ -58,6 +59,7 @@ namespace IW4MAdmin.Application
readonly SemaphoreSlim ProcessingEvent = new SemaphoreSlim(1, 1);
readonly Dictionary<long, ILogger> Loggers = new Dictionary<long, ILogger>();
readonly ITokenAuthentication _authenticator;
private readonly MetaService _metaService;
private ApplicationManager()
{
@ -77,6 +79,7 @@ namespace IW4MAdmin.Application
OnServerEvent += OnGameEvent;
OnServerEvent += EventApi.OnGameEvent;
_authenticator = new TokenAuthentication();
_metaService = new MetaService();
}
private async void OnGameEvent(object sender, GameEventArgs args)
@ -384,6 +387,45 @@ namespace IW4MAdmin.Application
}
#endregion
#region META
async Task<List<ProfileMeta>> getLastMap(int clientId)
{
var meta = await _metaService.GetPersistentMeta("LastMapPlayed", new EFClient() { ClientId = clientId });
return meta == null ? new List<ProfileMeta>() : new List<ProfileMeta>()
{
new ProfileMeta()
{
Id = meta.MetaId,
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_MAP"],
Value = meta.Value,
Show = true
}
};
}
async Task<List<ProfileMeta>> getLastServer(int clientId)
{
var meta = await _metaService.GetPersistentMeta("LastServerPlayed", new EFClient() { ClientId = clientId });
return meta == null ? new List<ProfileMeta>() : new List<ProfileMeta>()
{
new ProfileMeta()
{
Id = meta.MetaId,
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_SERVER"],
Value = meta.Value,
Show = true
}
};
}
MetaService.AddRuntimeMeta(getLastMap);
MetaService.AddRuntimeMeta(getLastServer);
#endregion
#region INIT
async Task Init(ServerConfiguration Conf)
{

View File

@ -9,6 +9,7 @@ using SharedLibraryCore.Exceptions;
using SharedLibraryCore.Interfaces;
using SharedLibraryCore.Localization;
using SharedLibraryCore.Objects;
using SharedLibraryCore.Services;
using System;
using System.Collections.Generic;
using System.IO;
@ -199,6 +200,12 @@ namespace IW4MAdmin
else if (E.Type == GameEvent.EventType.PreConnect)
{
// we don't want to track bots in the database at all if ignore bots is requested
if (E.Origin.IsBot && Manager.GetApplicationSettings().Configuration().IgnoreBots)
{
return false;
}
if (Clients[E.Origin.ClientNumber] == null)
{
#if DEBUG == true
@ -306,6 +313,12 @@ namespace IW4MAdmin
}
}
else if (E.Type == GameEvent.EventType.Disconnect)
{
await new MetaService().AddPersistentMeta("LastMapPlayed", CurrentMap.Alias, E.Origin);
await new MetaService().AddPersistentMeta("LastServerPlayed", E.Owner.Hostname, E.Origin);
}
else if (E.Type == GameEvent.EventType.PreDisconnect)
{
if ((DateTime.UtcNow - SessionStart).TotalSeconds < 30)

View File

@ -1,8 +1,5 @@
using SharedLibraryCore;
using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace AutomessageFeed
{
@ -10,6 +7,7 @@ namespace AutomessageFeed
{
public bool EnableFeed { get; set; }
public string FeedUrl { get; set; }
public int MaxFeedItems { get; set; }
public IBaseConfiguration Generate()
{
@ -18,6 +16,9 @@ namespace AutomessageFeed
if (EnableFeed)
{
FeedUrl = Utilities.PromptString(Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_AUTOMESSAGEFEED_URL"]);
MaxFeedItems = Utilities.PromptInt(Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_AUTOMESSAGEFEED_PROMPT_MAXITEMS"],
Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_AUTOMESSAGEFEED_PROMPT_MAXITEMS_DESC"],
0, int.MaxValue, 0);
}
return this;

View File

@ -43,7 +43,7 @@ namespace AutomessageFeed
}
}
if (_currentFeedItem < items.Count)
if (_currentFeedItem < items.Count && (_configuration.MaxFeedItems == 0 || _currentFeedItem < _configuration.MaxFeedItems))
{
_currentFeedItem++;
return items[_currentFeedItem - 1];

View File

@ -282,14 +282,14 @@ namespace IW4MAdmin.Plugins.Stats
return messageMeta;
}
MetaService.AddMeta(getStats);
MetaService.AddRuntimeMeta(getStats);
if (Config.Configuration().EnableAntiCheat)
{
MetaService.AddMeta(getAnticheatInfo);
MetaService.AddRuntimeMeta(getAnticheatInfo);
}
MetaService.AddMeta(getMessages);
MetaService.AddRuntimeMeta(getMessages);
async Task<string> totalKills(Server server)
{

View File

@ -13,8 +13,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>

View File

@ -4,6 +4,7 @@ using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
@ -22,7 +23,7 @@ namespace SharedLibraryCore.Database
static string _ConnectionString;
static string _provider;
private static readonly string _migrationPluginDirectory = @"X:\IW4MAdmin\BUILD\Plugins\";
private static readonly string _migrationPluginDirectory = @"X:\IW4MAdmin\BUILD\Plugins";
public DatabaseContext(DbContextOptions<DatabaseContext> opt) : base(opt) { }
@ -123,6 +124,11 @@ namespace SharedLibraryCore.Database
ent.HasIndex(a => a.Name);
});
modelBuilder.Entity<EFMeta>(ent =>
{
ent.HasIndex(_meta => _meta.Key);
});
// force full name for database conversion
modelBuilder.Entity<EFClient>().ToTable("EFClients");
modelBuilder.Entity<EFAlias>().ToTable("EFAlias");
@ -138,7 +144,6 @@ namespace SharedLibraryCore.Database
#endif
IEnumerable<string> directoryFiles = Directory.GetFiles(pluginDir).Where(f => f.EndsWith(".dll"));
foreach (string dllPath in directoryFiles)
{
Assembly library;

View File

@ -0,0 +1,696 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SharedLibraryCore.Database;
namespace SharedLibraryCore.Migrations
{
[DbContext(typeof(DatabaseContext))]
[Migration("20190222234742_AddIndexToEFMeta-KeyAndClientId")]
partial class AddIndexToEFMetaKeyAndClientId
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.2.2-servicing-10034");
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
{
b.Property<int>("SnapshotId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<int>("ClientId");
b.Property<int>("CurrentSessionLength");
b.Property<double>("CurrentStrain");
b.Property<int>("CurrentViewAngleId");
b.Property<int>("Deaths");
b.Property<double>("Distance");
b.Property<double>("EloRating");
b.Property<int>("HitDestinationId");
b.Property<int>("HitLocation");
b.Property<int>("HitOriginId");
b.Property<int>("HitType");
b.Property<int>("Hits");
b.Property<int>("Kills");
b.Property<int>("LastStrainAngleId");
b.Property<double>("SessionAngleOffset");
b.Property<double>("SessionSPM");
b.Property<int>("SessionScore");
b.Property<double>("StrainAngleBetween");
b.Property<int>("TimeSinceLastEvent");
b.Property<int>("WeaponId");
b.Property<DateTime>("When");
b.HasKey("SnapshotId");
b.HasIndex("ClientId");
b.HasIndex("CurrentViewAngleId");
b.HasIndex("HitDestinationId");
b.HasIndex("HitOriginId");
b.HasIndex("LastStrainAngleId");
b.ToTable("EFACSnapshot");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
{
b.Property<long>("KillId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<int>("AttackerId");
b.Property<int>("Damage");
b.Property<int?>("DeathOriginVector3Id");
b.Property<int>("DeathType");
b.Property<double>("Fraction");
b.Property<int>("HitLoc");
b.Property<bool>("IsKill");
b.Property<int?>("KillOriginVector3Id");
b.Property<int>("Map");
b.Property<long>("ServerId");
b.Property<int>("VictimId");
b.Property<int?>("ViewAnglesVector3Id");
b.Property<double>("VisibilityPercentage");
b.Property<int>("Weapon");
b.Property<DateTime>("When");
b.HasKey("KillId");
b.HasIndex("AttackerId");
b.HasIndex("DeathOriginVector3Id");
b.HasIndex("KillOriginVector3Id");
b.HasIndex("ServerId");
b.HasIndex("VictimId");
b.HasIndex("ViewAnglesVector3Id");
b.ToTable("EFClientKills");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b =>
{
b.Property<long>("MessageId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<int>("ClientId");
b.Property<string>("Message");
b.Property<long>("ServerId");
b.Property<DateTime>("TimeSent");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.HasIndex("ServerId");
b.HasIndex("TimeSent");
b.ToTable("EFClientMessages");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
{
b.Property<int>("RatingHistoryId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<int>("ClientId");
b.HasKey("RatingHistoryId");
b.HasIndex("ClientId");
b.ToTable("EFClientRatingHistory");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
{
b.Property<int>("ClientId");
b.Property<long>("ServerId");
b.Property<bool>("Active");
b.Property<int>("Deaths");
b.Property<double>("EloRating");
b.Property<int>("Kills");
b.Property<double>("MaxStrain");
b.Property<double>("RollingWeightedKDR");
b.Property<double>("SPM");
b.Property<double>("Skill");
b.Property<int>("TimePlayed");
b.Property<double>("VisionAverage");
b.HasKey("ClientId", "ServerId");
b.HasIndex("ServerId");
b.ToTable("EFClientStatistics");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
{
b.Property<int>("HitLocationCountId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<int>("ClientId")
.HasColumnName("EFClientStatistics_ClientId");
b.Property<int>("HitCount");
b.Property<float>("HitOffsetAverage");
b.Property<int>("Location");
b.Property<float>("MaxAngleDistance");
b.Property<long>("ServerId")
.HasColumnName("EFClientStatistics_ServerId");
b.HasKey("HitLocationCountId");
b.HasIndex("ServerId");
b.HasIndex("ClientId", "ServerId");
b.ToTable("EFHitLocationCounts");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
{
b.Property<int>("RatingId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<int>("ActivityAmount");
b.Property<bool>("Newest");
b.Property<double>("Performance");
b.Property<int>("Ranking");
b.Property<int>("RatingHistoryId");
b.Property<long?>("ServerId");
b.Property<DateTime>("When");
b.HasKey("RatingId");
b.HasIndex("Performance");
b.HasIndex("Ranking");
b.HasIndex("RatingHistoryId");
b.HasIndex("ServerId");
b.HasIndex("When");
b.ToTable("EFRating");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServer", b =>
{
b.Property<long>("ServerId");
b.Property<bool>("Active");
b.Property<string>("EndPoint");
b.Property<int>("Port");
b.HasKey("ServerId");
b.ToTable("EFServers");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
{
b.Property<int>("StatisticId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<long>("ServerId");
b.Property<long>("TotalKills");
b.Property<long>("TotalPlayTime");
b.HasKey("StatisticId");
b.HasIndex("ServerId");
b.ToTable("EFServerStatistics");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
{
b.Property<int>("AliasId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<DateTime>("DateAdded");
b.Property<int?>("IPAddress");
b.Property<int>("LinkId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(24);
b.HasKey("AliasId");
b.HasIndex("IPAddress");
b.HasIndex("LinkId");
b.HasIndex("Name");
b.ToTable("EFAlias");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAliasLink", b =>
{
b.Property<int>("AliasLinkId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.HasKey("AliasLinkId");
b.ToTable("EFAliasLinks");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
{
b.Property<int>("ChangeHistoryId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<string>("Comment")
.HasMaxLength(128);
b.Property<string>("CurrentValue");
b.Property<int>("OriginEntityId");
b.Property<string>("PreviousValue");
b.Property<int>("TargetEntityId");
b.Property<DateTime>("TimeChanged");
b.Property<int>("TypeOfChange");
b.HasKey("ChangeHistoryId");
b.ToTable("EFChangeHistory");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
{
b.Property<int>("ClientId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<int>("AliasLinkId");
b.Property<int>("Connections");
b.Property<int>("CurrentAliasId");
b.Property<DateTime>("FirstConnection");
b.Property<DateTime>("LastConnection");
b.Property<int>("Level");
b.Property<bool>("Masked");
b.Property<long>("NetworkId");
b.Property<string>("Password");
b.Property<string>("PasswordSalt");
b.Property<int>("TotalConnectionTime");
b.HasKey("ClientId");
b.HasIndex("AliasLinkId");
b.HasIndex("CurrentAliasId");
b.HasIndex("NetworkId")
.IsUnique();
b.ToTable("EFClients");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
{
b.Property<int>("MetaId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<int>("ClientId");
b.Property<DateTime>("Created");
b.Property<string>("Extra");
b.Property<string>("Key")
.IsRequired();
b.Property<DateTime>("Updated");
b.Property<string>("Value")
.IsRequired();
b.HasKey("MetaId");
b.HasIndex("ClientId");
b.HasIndex("Key");
b.ToTable("EFMeta");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.Property<int>("PenaltyId")
.ValueGeneratedOnAdd();
b.Property<bool>("Active");
b.Property<string>("AutomatedOffense");
b.Property<DateTime?>("Expires");
b.Property<bool>("IsEvadedOffense");
b.Property<int>("LinkId");
b.Property<int>("OffenderId");
b.Property<string>("Offense")
.IsRequired();
b.Property<int>("PunisherId");
b.Property<int>("Type");
b.Property<DateTime>("When");
b.HasKey("PenaltyId");
b.HasIndex("LinkId");
b.HasIndex("OffenderId");
b.HasIndex("PunisherId");
b.ToTable("EFPenalties");
});
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
{
b.Property<int>("Vector3Id")
.ValueGeneratedOnAdd();
b.Property<int?>("EFACSnapshotSnapshotId");
b.Property<float>("X");
b.Property<float>("Y");
b.Property<float>("Z");
b.HasKey("Vector3Id");
b.HasIndex("EFACSnapshotSnapshotId");
b.ToTable("Vector3");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany()
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("SharedLibraryCore.Helpers.Vector3", "CurrentViewAngle")
.WithMany()
.HasForeignKey("CurrentViewAngleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitDestination")
.WithMany()
.HasForeignKey("HitDestinationId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitOrigin")
.WithMany()
.HasForeignKey("HitOriginId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("SharedLibraryCore.Helpers.Vector3", "LastStrainAngle")
.WithMany()
.HasForeignKey("LastStrainAngleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker")
.WithMany()
.HasForeignKey("AttackerId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("SharedLibraryCore.Helpers.Vector3", "DeathOrigin")
.WithMany()
.HasForeignKey("DeathOriginVector3Id");
b.HasOne("SharedLibraryCore.Helpers.Vector3", "KillOrigin")
.WithMany()
.HasForeignKey("KillOriginVector3Id");
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
.WithMany()
.HasForeignKey("ServerId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Victim")
.WithMany()
.HasForeignKey("VictimId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("SharedLibraryCore.Helpers.Vector3", "ViewAngles")
.WithMany()
.HasForeignKey("ViewAnglesVector3Id");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany()
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
.WithMany()
.HasForeignKey("ServerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany()
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany()
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
.WithMany()
.HasForeignKey("ServerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany()
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
.WithMany()
.HasForeignKey("ServerId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics")
.WithMany("HitLocations")
.HasForeignKey("ClientId", "ServerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
{
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", "RatingHistory")
.WithMany("Ratings")
.HasForeignKey("RatingHistoryId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
.WithMany()
.HasForeignKey("ServerId");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
{
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
.WithMany()
.HasForeignKey("ServerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
.WithMany("Children")
.HasForeignKey("LinkId")
.OnDelete(DeleteBehavior.Restrict);
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "AliasLink")
.WithMany()
.HasForeignKey("AliasLinkId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias")
.WithMany()
.HasForeignKey("CurrentAliasId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany("Meta")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
.WithMany("ReceivedPenalties")
.HasForeignKey("LinkId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender")
.WithMany("ReceivedPenalties")
.HasForeignKey("OffenderId")
.OnDelete(DeleteBehavior.Restrict);
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher")
.WithMany("AdministeredPenalties")
.HasForeignKey("PunisherId")
.OnDelete(DeleteBehavior.Restrict);
});
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
{
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot")
.WithMany("PredictedViewAngles")
.HasForeignKey("EFACSnapshotSnapshotId");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,22 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace SharedLibraryCore.Migrations
{
public partial class AddIndexToEFMetaKeyAndClientId : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateIndex(
name: "IX_EFMeta_Key",
table: "EFMeta",
column: "Key");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_EFMeta_Key",
table: "EFMeta");
}
}
}

View File

@ -14,7 +14,7 @@ namespace SharedLibraryCore.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.4-rtm-31024");
.HasAnnotation("ProductVersion", "2.2.2-servicing-10034");
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
{
@ -443,6 +443,8 @@ namespace SharedLibraryCore.Migrations
b.HasIndex("ClientId");
b.HasIndex("Key");
b.ToTable("EFMeta");
});

View File

@ -1,24 +1,71 @@
using SharedLibraryCore.Dtos;
using Microsoft.EntityFrameworkCore;
using SharedLibraryCore.Database;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Dtos;
using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SharedLibraryCore.Services
{
public class MetaService
{
private static List<Func<int, Task<List<ProfileMeta>>>> MetaActions = new List<Func<int, Task<List<ProfileMeta>>>>();
private static List<Func<int, Task<List<ProfileMeta>>>> _metaActions = new List<Func<int, Task<List<ProfileMeta>>>>();
public static void AddMeta(Func<int, Task<List<ProfileMeta>>> metaAction)
public async Task AddPersistentMeta(string metaKey, string metaValue, EFClient client)
{
MetaActions.Add(metaAction);
using (var ctx = new DatabaseContext())
{
var existingMeta = await ctx.EFMeta.FirstOrDefaultAsync(_meta => _meta.ClientId == client.ClientId && _meta.Key == metaKey);
if (existingMeta != null)
{
existingMeta.Value = metaValue;
existingMeta.Updated = DateTime.UtcNow;
}
else
{
ctx.EFMeta.Add(new EFMeta()
{
ClientId = client.ClientId,
Created = DateTime.UtcNow,
Key = metaKey,
Value = metaValue
});
}
await ctx.SaveChangesAsync();
}
}
public static async Task<List<ProfileMeta>> GetMeta(int clientId)
public Task<EFMeta> GetPersistentMeta(string metaKey, EFClient client)
{
using (var ctx = new DatabaseContext(disableTracking:true))
{
return ctx.EFMeta
.Where(_meta => _meta.Key == metaKey)
.Where(_meta => _meta.ClientId == client.ClientId)
.FirstOrDefaultAsync();
}
}
public static void AddRuntimeMeta(Func<int, Task<List<ProfileMeta>>> metaAction)
{
_metaActions.Add(metaAction);
}
public static async Task<List<ProfileMeta>> GetRuntimeMeta(int clientId)
{
var meta = new List<ProfileMeta>();
foreach (var action in MetaActions)
foreach (var action in _metaActions)
{
meta.AddRange(await action(clientId));
}
return meta;
}
}

View File

@ -17,6 +17,7 @@
<Compile Remove="Migrations\20181126232438_AddEndpointToEFServer.cs" />
<Compile Remove="Migrations\20181126233300_AddEndpointToEFServer.cs" />
<Compile Remove="Migrations\20181127143920_AddEndpointToEFServerUpdateServerIdType.cs" />
<Compile Remove="Migrations\20190222234606_AddIndexToEFMeta-KeyAndClientId.cs" />
</ItemGroup>
<ItemGroup>

View File

@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Security.Claims;
@ -10,6 +9,11 @@ namespace WebfrontCore.Controllers
{
public class AccountController : BaseController
{
/// <summary>
/// life span in months
/// </summary>
private const int COOKIE_LIFESPAN = 3;
[HttpGet]
public async Task<IActionResult> LoginAsync(int clientId, string password)
{
@ -22,10 +26,10 @@ namespace WebfrontCore.Controllers
{
var client = Manager.GetPrivilegedClients()[clientId];
// string[] hashedPassword = await Task.FromResult(SharedLibraryCore.Helpers.Hashing.Hash(password, client.PasswordSalt));
//if (hashedPassword[0] == client.Password)
bool loginSuccess = Manager.TokenAuthenticator.AuthorizeToken(client.NetworkId, password) ||
(await Task.FromResult(SharedLibraryCore.Helpers.Hashing.Hash(password, client.PasswordSalt)))[0] == client.Password;
if (Manager.TokenAuthenticator.AuthorizeToken(client.NetworkId, password))
if (loginSuccess)
{
var claims = new[]
{
@ -40,7 +44,7 @@ namespace WebfrontCore.Controllers
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrinciple, new AuthenticationProperties()
{
AllowRefresh = true,
ExpiresUtc = DateTime.UtcNow.AddDays(30),
ExpiresUtc = DateTime.UtcNow.AddMonths(COOKIE_LIFESPAN),
IsPersistent = true,
IssuedUtc = DateTime.UtcNow
});

View File

@ -59,7 +59,7 @@ namespace WebfrontCore.Controllers
LinkedAccounts = client.LinkedAccounts
};
var meta = await MetaService.GetMeta(client.ClientId);
var meta = await MetaService.GetRuntimeMeta(client.ClientId);
var penaltyMeta = await Manager.GetPenaltyService()
.ReadGetClientPenaltiesAsync(client.ClientId);
var administeredPenaltiesMeta = await Manager.GetPenaltyService()