Authinator/Controllers/AuthenticateController.cs
2023-06-01 06:14:24 +02:00

56 lines
1.9 KiB
C#

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();
}
}