using System.Net; using System.Text.RegularExpressions; using Authinator.Backend.Database; using Authinator.Backend.Database.Tables; using Authinator.Backend.Utils; using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace Authinator.Controllers; [Controller] [SkipStatusCodePages] [Route("/api/authenticate")] public class AuthenticateController : Controller { [HttpGet] public IActionResult Get() { var db = new DatabaseContext(); if (!HttpContext.IsAuthenticated(db)) return Unauthorized(); var user = HttpContext.GetRemoteUser(db); if (user == null) { return Ok(); } var srcAddress = Request.Headers["X-Forwarded-For"].FirstOrDefault()?.Split(',').FirstOrDefault(); var domain = Request.Host; var acls = db.ACLs.Include(p => p.Groups).Include(p => p.Users).AsEnumerable(); var aclsThatApplyRegex = acls.Where(p => p.TargetIsRegex).Where(p => new Regex(p.Target).IsMatch(domain.ToString())); var aclsThatApplyMatch = acls.Where(p => !p.TargetIsRegex) .Where(p => p.Target.StartsWith("*") ? domain.ToString().EndsWith(p.Target[1..]) : domain.ToString().Equals(p.Target)); var aclsThatApply = aclsThatApplyMatch.Union(aclsThatApplyRegex); if (IPAddress.TryParse(srcAddress, out var srcIp) && aclsThatApply.Any(acl => acl.Networks.Any(p => p.Subnet.Equals(srcIp)))) return AuthOk(user); return aclsThatApply.Any(acl => acl.Groups.Any(aclGroup => user.Groups.Any(userGroup => userGroup == aclGroup)) || acl.Users.Any(u => u == user)) ? AuthOk(user) : Unauthorized(); } private IActionResult AuthOk(User user) { Response.Headers.Add("Remote-User", user.Username); Response.Headers.Add("Remote-Groups", user.Groups.Select(p => p.Name).Aggregate((s, s1) => $"{s},{s1}")); Response.Headers.Add("Remote-Name", user.Username); Response.Headers.Add("Remote-Email", user.Email); return Ok(); } }