ManagementInterfaceFilter.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Threading.Tasks;
  6. using Jellyfin.Api.Attributes;
  7. using MediaBrowser.Controller.Extensions;
  8. using MediaBrowser.Model.Configuration;
  9. using Microsoft.AspNetCore.Mvc;
  10. using Microsoft.AspNetCore.Mvc.Controllers;
  11. using Microsoft.AspNetCore.Mvc.Filters;
  12. using Microsoft.Extensions.Configuration;
  13. using Microsoft.Extensions.Hosting;
  14. namespace Jellyfin.Server.Filters
  15. {
  16. internal class ManagementInterfaceFilter : IActionFilter
  17. {
  18. private readonly List<(IPAddress Host, int Port)> managementEndpoints;
  19. public ManagementInterfaceFilter(IConfiguration appConfig)
  20. {
  21. managementEndpoints = new List<(IPAddress Host, int Port)>();
  22. if (appConfig.UseManagementInterface())
  23. {
  24. var socketPath = appConfig.GetManagementInterfaceSocketPath();
  25. var localhostPort = appConfig.GetManagementInterfaceLocalhostPort();
  26. bool useDefault = true;
  27. if (!string.IsNullOrEmpty(socketPath))
  28. {
  29. // TODO make this work, no idea where to get the SocketAddress or something similar
  30. managementEndpoints.Add((IPAddress.Any, 0));
  31. }
  32. if (localhostPort > 0)
  33. {
  34. managementEndpoints.Add((IPAddress.Loopback, localhostPort));
  35. managementEndpoints.Add((IPAddress.IPv6Loopback, localhostPort));
  36. }
  37. if (useDefault)
  38. {
  39. managementEndpoints.Add((IPAddress.Loopback, ServerConfiguration.DefaultManagementPort));
  40. managementEndpoints.Add((IPAddress.IPv6Loopback, ServerConfiguration.DefaultManagementPort));
  41. }
  42. }
  43. }
  44. public void OnActionExecuted(ActionExecutedContext context)
  45. {
  46. }
  47. public void OnActionExecuting(ActionExecutingContext context)
  48. {
  49. var isManagementRoute = IsManagementRoute(context);
  50. var isManagementListenEntrypoint = IsManagementListenEntrypoint(context);
  51. if ((isManagementRoute && !isManagementListenEntrypoint) || (!isManagementRoute && isManagementListenEntrypoint))
  52. {
  53. context.Result = new NotFoundResult();
  54. }
  55. }
  56. private bool IsManagementRoute(ActionExecutingContext context)
  57. {
  58. return HasAttribute<ManagementAttribute>(context);
  59. }
  60. private bool HasAttribute<T>(ActionExecutingContext context)
  61. {
  62. var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
  63. if (controllerActionDescriptor != null)
  64. {
  65. // Check if the attribute exists on the action method
  66. if (controllerActionDescriptor.MethodInfo?.GetCustomAttributes(inherit: true)?.Any(a => a.GetType().Equals(typeof(T))) ?? false)
  67. {
  68. return true;
  69. }
  70. // Check if the attribute exists on the controller
  71. if (controllerActionDescriptor.ControllerTypeInfo?.GetCustomAttributes(typeof(T), true)?.Any() ?? false)
  72. {
  73. return true;
  74. }
  75. }
  76. return false;
  77. }
  78. private bool IsManagementListenEntrypoint(ActionExecutingContext context)
  79. {
  80. if (context.HttpContext.Connection.LocalIpAddress == null)
  81. {
  82. return false;
  83. }
  84. return managementEndpoints.Contains((context.HttpContext.Connection.LocalIpAddress, context.HttpContext.Connection.LocalPort));
  85. }
  86. }
  87. }