parent
82d27e6461
commit
c5d900b164
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Jellyfin.Api.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies that the marked controller or method is only accessible via the management interface.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class ManagementAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Attributes;
|
||||
using Jellyfin.Api.Constants;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Net;
|
||||
using MediaBrowser.Model.System;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Jellyfin.Api.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// The management controller.
|
||||
/// </summary>
|
||||
[Management]
|
||||
public class ManagementController : BaseJellyfinApiController
|
||||
{
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly INetworkManager _network;
|
||||
private readonly ILogger<ManagementController> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManagementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="serverConfigurationManager">Instance of <see cref="IServerConfigurationManager"/> interface.</param>
|
||||
/// <param name="appHost">Instance of <see cref="IServerApplicationHost"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="network">Instance of <see cref="INetworkManager"/> interface.</param>
|
||||
/// <param name="logger">Instance of <see cref="ILogger{SystemController}"/> interface.</param>
|
||||
public ManagementController(
|
||||
IServerConfigurationManager serverConfigurationManager,
|
||||
IServerApplicationHost appHost,
|
||||
IFileSystem fileSystem,
|
||||
INetworkManager network,
|
||||
ILogger<ManagementController> logger)
|
||||
{
|
||||
_appPaths = serverConfigurationManager.ApplicationPaths;
|
||||
_appHost = appHost;
|
||||
_fileSystem = fileSystem;
|
||||
_network = network;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about the server.
|
||||
/// </summary>
|
||||
/// <response code="200">Information retrieved.</response>
|
||||
/// <returns>A <see cref="SystemInfo"/> with info about the system.</returns>
|
||||
[HttpGet("Test")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<int> GetTest()
|
||||
{
|
||||
return 123456; // secret
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Attributes;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Jellyfin.Server.Filters
|
||||
{
|
||||
internal class ManagementInterfaceFilter : IActionFilter
|
||||
{
|
||||
private readonly List<(IPAddress Host, int Port)> managementEndpoints;
|
||||
|
||||
public ManagementInterfaceFilter(IConfiguration appConfig)
|
||||
{
|
||||
managementEndpoints = new List<(IPAddress Host, int Port)>();
|
||||
|
||||
if (appConfig.UseManagementInterface())
|
||||
{
|
||||
var socketPath = appConfig.GetManagementInterfaceSocketPath();
|
||||
var localhostPort = appConfig.GetManagementInterfaceLocalhostPort();
|
||||
bool useDefault = true;
|
||||
if (!string.IsNullOrEmpty(socketPath))
|
||||
{
|
||||
// TODO make this work, no idea where to get the SocketAddress or something similar
|
||||
managementEndpoints.Add((IPAddress.Any, 0));
|
||||
}
|
||||
|
||||
if (localhostPort > 0)
|
||||
{
|
||||
managementEndpoints.Add((IPAddress.Loopback, localhostPort));
|
||||
managementEndpoints.Add((IPAddress.IPv6Loopback, localhostPort));
|
||||
}
|
||||
|
||||
if (useDefault)
|
||||
{
|
||||
managementEndpoints.Add((IPAddress.Loopback, ServerConfiguration.DefaultManagementPort));
|
||||
managementEndpoints.Add((IPAddress.IPv6Loopback, ServerConfiguration.DefaultManagementPort));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnActionExecuted(ActionExecutedContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
var isManagementRoute = IsManagementRoute(context);
|
||||
var isManagementListenEntrypoint = IsManagementListenEntrypoint(context);
|
||||
|
||||
if ((isManagementRoute && !isManagementListenEntrypoint) || (!isManagementRoute && isManagementListenEntrypoint))
|
||||
{
|
||||
context.Result = new NotFoundResult();
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsManagementRoute(ActionExecutingContext context)
|
||||
{
|
||||
return HasAttribute<ManagementAttribute>(context);
|
||||
}
|
||||
|
||||
private bool HasAttribute<T>(ActionExecutingContext context)
|
||||
{
|
||||
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
|
||||
if (controllerActionDescriptor != null)
|
||||
{
|
||||
// Check if the attribute exists on the action method
|
||||
if (controllerActionDescriptor.MethodInfo?.GetCustomAttributes(inherit: true)?.Any(a => a.GetType().Equals(typeof(T))) ?? false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the attribute exists on the controller
|
||||
if (controllerActionDescriptor.ControllerTypeInfo?.GetCustomAttributes(typeof(T), true)?.Any() ?? false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsManagementListenEntrypoint(ActionExecutingContext context)
|
||||
{
|
||||
return managementEndpoints.Contains((context.HttpContext.Connection.LocalIpAddress, context.HttpContext.Connection.LocalPort));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue