using System.Security.Claims; using Jellyfin.Api.Extensions; using Jellyfin.Api.Helpers; using Jellyfin.Data.Enums; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Library; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; namespace Jellyfin.Api.Auth { /// /// Base authorization handler. /// /// Type of Authorization Requirement. public abstract class BaseAuthorizationHandler : AuthorizationHandler where T : IAuthorizationRequirement { private readonly IUserManager _userManager; private readonly INetworkManager _networkManager; private readonly IHttpContextAccessor _httpContextAccessor; /// /// Initializes a new instance of the class. /// /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. protected BaseAuthorizationHandler( IUserManager userManager, INetworkManager networkManager, IHttpContextAccessor httpContextAccessor) { _userManager = userManager; _networkManager = networkManager; _httpContextAccessor = httpContextAccessor; } /// /// Validate authenticated claims. /// /// Request claims. /// Whether to ignore parental control. /// Whether access is to be allowed locally only. /// Whether validation requires download permission. /// Validated claim status. protected bool ValidateClaims( ClaimsPrincipal claimsPrincipal, bool ignoreSchedule = false, bool localAccessOnly = false, bool requiredDownloadPermission = false) { // ApiKey is currently global admin, always allow. var isApiKey = claimsPrincipal.GetIsApiKey(); if (isApiKey) { return true; } // Ensure claim has userId. var userId = claimsPrincipal.GetUserId(); if (userId.Equals(default)) { return false; } // Ensure userId links to a valid user. var user = _userManager.GetUserById(userId); if (user is null) { return false; } // Ensure user is not disabled. if (user.HasPermission(PermissionKind.IsDisabled)) { return false; } var isInLocalNetwork = _httpContextAccessor.HttpContext != null && _networkManager.IsInLocalNetwork(_httpContextAccessor.HttpContext.GetNormalizedRemoteIp()); // User cannot access remotely and user is remote if (!user.HasPermission(PermissionKind.EnableRemoteAccess) && !isInLocalNetwork) { return false; } if (localAccessOnly && !isInLocalNetwork) { return false; } // User attempting to access out of parental control hours. if (!ignoreSchedule && !user.HasPermission(PermissionKind.IsAdministrator) && !user.IsParentalScheduleAllowed()) { return false; } // User attempting to download without permission. if (requiredDownloadPermission && !user.HasPermission(PermissionKind.EnableContentDownloading)) { return false; } return true; } } }