// Copyright Epic Games, Inc. All Rights Reserved. using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using EpicGames.Horde.Storage; using Jupiter.Common; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; namespace Jupiter.Controllers { [ApiController] [Route("api/v1/auth")] [Authorize] public class AuthController : ControllerBase { private readonly IRequestHelper _requestHelper; private readonly INamespacePolicyResolver _namespacePolicyResolver; private readonly IOptionsMonitor _authSettings; public AuthController(IRequestHelper requestHelper, INamespacePolicyResolver namespacePolicyResolver, IOptionsMonitor authSettings) { _requestHelper = requestHelper; _namespacePolicyResolver = namespacePolicyResolver; _authSettings = authSettings; } [HttpGet("{ns}")] public async Task VerifyAsync( [FromRoute][Required] NamespaceId ns ) { ActionResult? result = await _requestHelper.HasAccessToNamespaceAsync(User, Request, ns, new[] { JupiterAclAction.ReadObject }); if (result != null) { return result; } return Ok(); } [HttpGet("{ns}/actions")] public IActionResult Actions( [FromRoute][Required] NamespaceId ns ) { NamespacePolicy policy = _namespacePolicyResolver.GetPoliciesForNs(ns); List allowedActions = new List(); foreach (AclEntry acl in policy.Acls) { allowedActions.AddRange(acl.Resolve(User)); } // the root and namespace acls are combined, namespace acls can not override what we define in the root foreach (AclEntry acl in _authSettings.CurrentValue.Acls) { allowedActions.AddRange(acl.Resolve(User)); } return Ok(new JsonResult(new { Actions = allowedActions })); } } public class ActionsResult { [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Used by serialization")] public List Actions { get; set; } = new List(); } }