Browse Source

Fix auth endpoints using api key (#9408)

Cody Robibero 2 years ago
parent
commit
4873d2a54d

+ 8 - 1
Jellyfin.Api/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandler.cs

@@ -46,6 +46,13 @@ namespace Jellyfin.Api.Auth.DefaultAuthorizationPolicy
                 return Task.CompletedTask;
             }
 
+            if (isApiKey)
+            {
+                // Api keys are unrestricted.
+                context.Succeed(requirement);
+                return Task.CompletedTask;
+            }
+
             var isInLocalNetwork = _httpContextAccessor.HttpContext is not null
                                    && _networkManager.IsInLocalNetwork(_httpContextAccessor.HttpContext.GetNormalizedRemoteIp());
             var user = _userManager.GetUserById(userId);
@@ -62,7 +69,7 @@ namespace Jellyfin.Api.Auth.DefaultAuthorizationPolicy
             }
 
             // Admins can do everything
-            if (isApiKey || context.User.IsInRole(UserRoles.Administrator))
+            if (context.User.IsInRole(UserRoles.Administrator))
             {
                 context.Succeed(requirement);
                 return Task.CompletedTask;

+ 31 - 1
tests/Jellyfin.Api.Tests/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandlerTests.cs

@@ -1,9 +1,13 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Security.Claims;
 using System.Threading.Tasks;
 using AutoFixture;
 using AutoFixture.AutoMoq;
 using Jellyfin.Api.Auth.DefaultAuthorizationPolicy;
 using Jellyfin.Api.Constants;
+using Jellyfin.Data.Entities;
 using Jellyfin.Server.Implementations.Security;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Controller.Library;
@@ -51,6 +55,32 @@ namespace Jellyfin.Api.Tests.Auth.DefaultAuthorizationPolicy
             Assert.True(context.HasSucceeded);
         }
 
+        [Fact]
+        public async Task ShouldSucceedOnApiKey()
+        {
+            TestHelpers.SetupConfigurationManager(_configurationManagerMock, true);
+
+            _httpContextAccessor
+                .Setup(h => h.HttpContext!.Connection.RemoteIpAddress)
+                .Returns(new IPAddress(0));
+
+            _userManagerMock
+                .Setup(u => u.GetUserById(It.IsAny<Guid>()))
+                .Returns<User>(null);
+
+            var claims = new[]
+            {
+                new Claim(InternalClaimTypes.IsApiKey, bool.TrueString)
+            };
+
+            var identity = new ClaimsIdentity(claims, string.Empty);
+            var principal = new ClaimsPrincipal(identity);
+            var context = new AuthorizationHandlerContext(_requirements, principal, null);
+
+            await _sut.HandleAsync(context);
+            Assert.True(context.HasSucceeded);
+        }
+
         [Theory]
         [MemberData(nameof(GetParts_ValidAuthHeader_Success_Data))]
         public void GetParts_ValidAuthHeader_Success(string input, Dictionary<string, string> parts)