DefaultAuthorizationHandler.cs 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using System.Threading.Tasks;
  2. using Jellyfin.Api.Constants;
  3. using Jellyfin.Api.Extensions;
  4. using Jellyfin.Data.Enums;
  5. using Jellyfin.Extensions;
  6. using MediaBrowser.Common.Extensions;
  7. using MediaBrowser.Common.Net;
  8. using MediaBrowser.Controller.Library;
  9. using Microsoft.AspNetCore.Authorization;
  10. using Microsoft.AspNetCore.Http;
  11. namespace Jellyfin.Api.Auth.DefaultAuthorizationPolicy
  12. {
  13. /// <summary>
  14. /// Default authorization handler.
  15. /// </summary>
  16. public class DefaultAuthorizationHandler : AuthorizationHandler<DefaultAuthorizationRequirement>
  17. {
  18. private readonly IUserManager _userManager;
  19. private readonly INetworkManager _networkManager;
  20. private readonly IHttpContextAccessor _httpContextAccessor;
  21. /// <summary>
  22. /// Initializes a new instance of the <see cref="DefaultAuthorizationHandler"/> class.
  23. /// </summary>
  24. /// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
  25. /// <param name="networkManager">Instance of the <see cref="INetworkManager"/> interface.</param>
  26. /// <param name="httpContextAccessor">Instance of the <see cref="IHttpContextAccessor"/> interface.</param>
  27. public DefaultAuthorizationHandler(
  28. IUserManager userManager,
  29. INetworkManager networkManager,
  30. IHttpContextAccessor httpContextAccessor)
  31. {
  32. _userManager = userManager;
  33. _networkManager = networkManager;
  34. _httpContextAccessor = httpContextAccessor;
  35. }
  36. /// <inheritdoc />
  37. protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DefaultAuthorizationRequirement requirement)
  38. {
  39. var isApiKey = context.User.GetIsApiKey();
  40. var userId = context.User.GetUserId();
  41. // This likely only happens during the wizard, so skip the default checks and let any other handlers do it
  42. if (!isApiKey && userId.IsEmpty())
  43. {
  44. return Task.CompletedTask;
  45. }
  46. if (isApiKey)
  47. {
  48. // Api keys are unrestricted.
  49. context.Succeed(requirement);
  50. return Task.CompletedTask;
  51. }
  52. var isInLocalNetwork = _httpContextAccessor.HttpContext is not null
  53. && _networkManager.IsInLocalNetwork(_httpContextAccessor.HttpContext.GetNormalizedRemoteIP());
  54. var user = _userManager.GetUserById(userId);
  55. if (user is null)
  56. {
  57. throw new ResourceNotFoundException();
  58. }
  59. // User cannot access remotely and user is remote
  60. if (!isInLocalNetwork && !user.HasPermission(PermissionKind.EnableRemoteAccess))
  61. {
  62. context.Fail();
  63. return Task.CompletedTask;
  64. }
  65. // Admins can do everything
  66. if (context.User.IsInRole(UserRoles.Administrator))
  67. {
  68. context.Succeed(requirement);
  69. return Task.CompletedTask;
  70. }
  71. // It's not great to have this check, but parental schedule must usually be honored except in a few rare cases
  72. if (requirement.ValidateParentalSchedule && !user.IsParentalScheduleAllowed())
  73. {
  74. context.Fail();
  75. return Task.CompletedTask;
  76. }
  77. // Only succeed if the requirement isn't a subclass as any subclassed requirement will handle success in its own handler
  78. if (requirement.GetType() == typeof(DefaultAuthorizationRequirement))
  79. {
  80. context.Succeed(requirement);
  81. }
  82. return Task.CompletedTask;
  83. }
  84. }
  85. }