56 lines
1.9 KiB
C#
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();
|
|
}
|
|
}
|