using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using Data.Models; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using SharedLibraryCore.Configuration; using SharedLibraryCore.Database.Models; using SharedLibraryCore.Dtos; using SharedLibraryCore.Interfaces; using SharedLibraryCore.Localization; namespace SharedLibraryCore { public class BaseController : Controller { protected readonly IInteractionRegistration InteractionRegistration; protected readonly IAlertManager AlertManager; /// /// life span in months /// private const int CookieLifespan = 3; private static readonly byte[] LocalHost = { 127, 0, 0, 1 }; private static string _socialLink; private static string _socialTitle; protected List Pages; protected List PermissionsSet; protected bool Authorized { get; set; } protected TranslationLookup Localization { get; } protected EFClient Client { get; } protected ApplicationConfiguration AppConfig { get; } public IManager Manager { get; } public BaseController(IManager manager) { InteractionRegistration = manager.InteractionRegistration; AlertManager = manager.AlertManager; Manager = manager; Localization = Utilities.CurrentLocalization.LocalizationIndex; AppConfig = Manager.GetApplicationSettings().Configuration(); if (AppConfig.EnableSocialLink && _socialLink == null) { _socialLink = AppConfig.SocialLinkAddress; _socialTitle = AppConfig.SocialLinkTitle; } Pages = Manager.GetPageList().Pages .Select(page => new Page { Name = page.Key, Location = page.Value }).ToList(); ViewBag.Version = Manager.Version; ViewBag.IsFluid = false; ViewBag.EnableColorCodes = AppConfig.EnableColorCodes; ViewBag.Language = Utilities.CurrentLocalization.Culture.TwoLetterISOLanguageName; Client = new EFClient { ClientId = -1, Level = Data.Models.Client.EFClient.Permission.User, CurrentAlias = new EFAlias { Name = "Webfront Guest" } }; } protected async Task SignInAsync(ClaimsPrincipal claimsPrinciple) { await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrinciple, new AuthenticationProperties { AllowRefresh = true, ExpiresUtc = DateTime.UtcNow.AddMonths(CookieLifespan), IsPersistent = true, IssuedUtc = DateTime.UtcNow }); } public override async void OnActionExecuting(ActionExecutingContext context) { if (!HttpContext.Connection.RemoteIpAddress.GetAddressBytes().SequenceEqual(LocalHost)) { try { var clientId = Convert.ToInt32(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid)?.Value ?? "-1"); if (clientId > 0) { Client.ClientId = clientId; Client.NetworkId = clientId == 1 ? 0 : User.Claims.First(claim => claim.Type == ClaimTypes.PrimarySid).Value .ConvertGuidToLong(NumberStyles.HexNumber); Client.Level = (Data.Models.Client.EFClient.Permission)Enum.Parse( typeof(Data.Models.Client.EFClient.Permission), User.Claims.First(c => c.Type == ClaimTypes.Role).Value); Client.CurrentAlias = new EFAlias { Name = User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value }; Authorized = Client.ClientId >= 0; Client.GameName = Enum.Parse(User.Claims .First(claim => claim.Type == ClaimTypes.PrimaryGroupSid).Value); } } catch (InvalidOperationException) { } catch (KeyNotFoundException) { // force the "banned" client to be signed out HttpContext.SignOutAsync().Wait(5000); } } // give the local host full access else if (!HttpContext.Request.Headers.ContainsKey("X-Forwarded-For")) { Client.ClientId = 1; Client.Level = Data.Models.Client.EFClient.Permission.Console; Client.CurrentAlias = new EFAlias { Name = "IW4MAdmin" }; Authorized = true; var claims = new[] { new Claim(ClaimTypes.NameIdentifier, Client.CurrentAlias.Name), new Claim(ClaimTypes.Role, Client.Level.ToString()), new Claim(ClaimTypes.Sid, Client.ClientId.ToString()), new Claim(ClaimTypes.PrimarySid, Client.NetworkId.ToString("X")), new Claim(ClaimTypes.PrimaryGroupSid, Client.GameName.ToString()) }; var claimsIdentity = new ClaimsIdentity(claims, "login"); SignInAsync(new ClaimsPrincipal(claimsIdentity)).Wait(); } if (AppConfig.PermissionSets.ContainsKey(Client.Level.ToString())) { PermissionsSet = AppConfig.PermissionSets[Client.Level.ToString()]; } var communityName = AppConfig.CommunityInformation?.Name; var shouldUseCommunityName = !string.IsNullOrWhiteSpace(communityName) && !communityName.Contains("IW4MAdmin") && AppConfig.CommunityInformation.IsEnabled; ViewBag.Interactions = await InteractionRegistration.GetInteractions("Webfront::Nav"); ViewBag.Authorized = Authorized; ViewBag.Url = AppConfig.WebfrontUrl; ViewBag.User = Client; ViewBag.Version = Manager.Version; ViewBag.SocialLink = _socialLink ?? ""; ViewBag.SocialTitle = _socialTitle; ViewBag.Pages = Pages; ViewBag.Localization = Utilities.CurrentLocalization.LocalizationIndex; ViewBag.CustomBranding = shouldUseCommunityName ? communityName : AppConfig.WebfrontCustomBranding ?? "IW4MAdmin"; ViewBag.EnableColorCodes = AppConfig.EnableColorCodes; ViewBag.EnablePrivilegedUserPrivacy = AppConfig.EnablePrivilegedUserPrivacy; ViewBag.Configuration = AppConfig; ViewBag.ScriptInjection = AppConfig.Webfront?.ScriptInjection; ViewBag.CommunityInformation = AppConfig.CommunityInformation; ViewBag.ClientCount = Manager.GetServers().Sum(server => server.ClientNum); ViewBag.AdminCount = Manager.GetServers().Sum(server => server.GetClientsAsList() .Count(client => client.Level >= Data.Models.Client.EFClient.Permission.Trusted)); ViewBag.ReportCount = Manager.GetServers().Sum(server => server.Reports.Count(report => DateTime.UtcNow - report.ReportedOn <= TimeSpan.FromHours(24))); ViewBag.PermissionsSet = PermissionsSet; ViewBag.Alerts = AlertManager.RetrieveAlerts(Client).ToList(); base.OnActionExecuting(context); } } }