diff --git a/tests/Jellyfin.Api.Tests/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandlerTests.cs new file mode 100644 index 0000000000..991ea3262f --- /dev/null +++ b/tests/Jellyfin.Api.Tests/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandlerTests.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using AutoFixture; +using AutoFixture.AutoMoq; +using Jellyfin.Api.Auth.DefaultAuthorizationPolicy; +using Jellyfin.Api.Constants; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Library; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Moq; +using Xunit; + +namespace Jellyfin.Api.Tests.Auth.DefaultAuthorizationPolicy +{ + public class DefaultAuthorizationHandlerTests + { + private readonly Mock _configurationManagerMock; + private readonly List _requirements; + private readonly DefaultAuthorizationHandler _sut; + private readonly Mock _userManagerMock; + private readonly Mock _httpContextAccessor; + + public DefaultAuthorizationHandlerTests() + { + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + _configurationManagerMock = fixture.Freeze>(); + _requirements = new List { new DefaultAuthorizationRequirement() }; + _userManagerMock = fixture.Freeze>(); + _httpContextAccessor = fixture.Freeze>(); + + _sut = fixture.Create(); + } + + [Theory] + [InlineData(UserRoles.Administrator)] + [InlineData(UserRoles.Guest)] + [InlineData(UserRoles.User)] + public async Task ShouldSucceedOnUser(string userRole) + { + TestHelpers.SetupConfigurationManager(_configurationManagerMock, true); + var (_, claims) = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + userRole, + TestHelpers.InternalIp); + + var context = new AuthorizationHandlerContext(_requirements, claims, null); + + await _sut.HandleAsync(context); + Assert.True(context.HasSucceeded); + } + } +} diff --git a/tests/Jellyfin.Api.Tests/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandlerTests.cs index e455df6435..2b49419082 100644 --- a/tests/Jellyfin.Api.Tests/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandlerTests.cs +++ b/tests/Jellyfin.Api.Tests/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandlerTests.cs @@ -1,19 +1,11 @@ -using System; using System.Collections.Generic; -using System.Globalization; -using System.Net; -using System.Security.Claims; using System.Threading.Tasks; using AutoFixture; using AutoFixture.AutoMoq; using Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy; using Jellyfin.Api.Constants; -using Jellyfin.Data.Entities; -using Jellyfin.Data.Enums; -using Jellyfin.Server.Implementations.Users; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Configuration; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Moq; @@ -23,15 +15,6 @@ namespace Jellyfin.Api.Tests.Auth.FirstTimeSetupOrElevatedPolicy { public class FirstTimeSetupOrElevatedHandlerTests { - /// - /// 127.0.0.1. - /// - private const long InternalIp = 16777343; - - /// - /// 1.1.1.1. - /// - /// private const long ExternalIp = 16843009; private readonly Mock _configurationManagerMock; private readonly List _requirements; private readonly FirstTimeSetupOrElevatedHandler _sut; @@ -55,14 +38,12 @@ namespace Jellyfin.Api.Tests.Auth.FirstTimeSetupOrElevatedPolicy [InlineData(UserRoles.User)] public async Task ShouldSucceedIfStartupWizardIncomplete(string userRole) { - SetupConfigurationManager(false); - var (user, claims) = SetupUser(userRole); - - _userManagerMock.Setup(u => u.GetUserById(It.IsAny())) - .Returns(user); - - _httpContextAccessor.Setup(h => h.HttpContext.Connection.RemoteIpAddress) - .Returns(new IPAddress(InternalIp)); + TestHelpers.SetupConfigurationManager(_configurationManagerMock, false); + var (_, claims) = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + userRole, + TestHelpers.InternalIp); var context = new AuthorizationHandlerContext(_requirements, claims, null); @@ -76,54 +57,17 @@ namespace Jellyfin.Api.Tests.Auth.FirstTimeSetupOrElevatedPolicy [InlineData(UserRoles.User, false)] public async Task ShouldRequireAdministratorIfStartupWizardComplete(string userRole, bool shouldSucceed) { - SetupConfigurationManager(true); - var (user, claims) = SetupUser(userRole); - - _userManagerMock.Setup(u => u.GetUserById(It.IsAny())) - .Returns(user); - - _httpContextAccessor.Setup(h => h.HttpContext.Connection.RemoteIpAddress) - .Returns(new IPAddress(InternalIp)); + TestHelpers.SetupConfigurationManager(_configurationManagerMock, true); + var (_, claims) = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + userRole, + TestHelpers.InternalIp); var context = new AuthorizationHandlerContext(_requirements, claims, null); await _sut.HandleAsync(context); Assert.Equal(shouldSucceed, context.HasSucceeded); } - - private static (User, ClaimsPrincipal) SetupUser(string role) - { - var user = new User( - "jellyfin", - typeof(DefaultAuthenticationProvider).FullName, - typeof(DefaultPasswordResetProvider).FullName); - - user.SetPermission(PermissionKind.IsAdministrator, role.Equals(UserRoles.Administrator, StringComparison.OrdinalIgnoreCase)); - var claims = new[] - { - new Claim(ClaimTypes.Role, role), - new Claim(ClaimTypes.Name, "jellyfin"), - new Claim(InternalClaimTypes.UserId, Guid.Empty.ToString("N", CultureInfo.InvariantCulture)), - new Claim(InternalClaimTypes.DeviceId, Guid.Empty.ToString("N", CultureInfo.InvariantCulture)), - new Claim(InternalClaimTypes.Device, "test"), - new Claim(InternalClaimTypes.Client, "test"), - new Claim(InternalClaimTypes.Version, "test"), - new Claim(InternalClaimTypes.Token, "test"), - }; - - var identity = new ClaimsIdentity(claims); - return (user, new ClaimsPrincipal(identity)); - } - - private void SetupConfigurationManager(bool startupWizardCompleted) - { - var commonConfiguration = new BaseApplicationConfiguration - { - IsStartupWizardCompleted = startupWizardCompleted - }; - - _configurationManagerMock.Setup(c => c.CommonConfiguration) - .Returns(commonConfiguration); - } } } diff --git a/tests/Jellyfin.Api.Tests/Auth/IgnoreSchedulePolicy/IgnoreScheduleHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/IgnoreSchedulePolicy/IgnoreScheduleHandlerTests.cs new file mode 100644 index 0000000000..25acfb581f --- /dev/null +++ b/tests/Jellyfin.Api.Tests/Auth/IgnoreSchedulePolicy/IgnoreScheduleHandlerTests.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using AutoFixture; +using AutoFixture.AutoMoq; +using Jellyfin.Api.Auth.IgnoreSchedulePolicy; +using Jellyfin.Api.Constants; +using Jellyfin.Data.Entities; +using Jellyfin.Data.Enums; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Library; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Moq; +using Xunit; + +namespace Jellyfin.Api.Tests.Auth.IgnoreSchedulePolicy +{ + public class IgnoreScheduleHandlerTests + { + private readonly Mock _configurationManagerMock; + private readonly List _requirements; + private readonly IgnoreScheduleHandler _sut; + private readonly Mock _userManagerMock; + private readonly Mock _httpContextAccessor; + + private readonly AccessSchedule[] _accessSchedules = { new AccessSchedule(DynamicDayOfWeek.Everyday, 0, 0, Guid.Empty) }; + + public IgnoreScheduleHandlerTests() + { + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + _configurationManagerMock = fixture.Freeze>(); + _requirements = new List { new IgnoreScheduleRequirement() }; + _userManagerMock = fixture.Freeze>(); + _httpContextAccessor = fixture.Freeze>(); + + _sut = fixture.Create(); + } + + [Theory] + [InlineData(UserRoles.Administrator, true)] + [InlineData(UserRoles.User, true)] + [InlineData(UserRoles.Guest, true)] + public async Task ShouldAllowScheduleCorrectly(string role, bool shouldSucceed) + { + TestHelpers.SetupConfigurationManager(_configurationManagerMock, true); + var (_, claims) = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + role, + TestHelpers.InternalIp, + _accessSchedules); + + var context = new AuthorizationHandlerContext(_requirements, claims, null); + + await _sut.HandleAsync(context); + Assert.Equal(shouldSucceed, context.HasSucceeded); + } + } +} diff --git a/tests/Jellyfin.Api.Tests/Auth/RequiresElevationPolicy/RequiresElevationHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/RequiresElevationPolicy/RequiresElevationHandlerTests.cs index 58eae84789..f4617d0a42 100644 --- a/tests/Jellyfin.Api.Tests/Auth/RequiresElevationPolicy/RequiresElevationHandlerTests.cs +++ b/tests/Jellyfin.Api.Tests/Auth/RequiresElevationPolicy/RequiresElevationHandlerTests.cs @@ -1,19 +1,11 @@ -using System; using System.Collections.Generic; -using System.Globalization; -using System.Net; -using System.Security.Claims; using System.Threading.Tasks; using AutoFixture; using AutoFixture.AutoMoq; using Jellyfin.Api.Auth.RequiresElevationPolicy; using Jellyfin.Api.Constants; -using Jellyfin.Data.Entities; -using Jellyfin.Data.Enums; -using Jellyfin.Server.Implementations.Users; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Configuration; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Moq; @@ -23,11 +15,6 @@ namespace Jellyfin.Api.Tests.Auth.RequiresElevationPolicy { public class RequiresElevationHandlerTests { - /// - /// 127.0.0.1. - /// - private const long InternalIp = 16777343; - private readonly Mock _configurationManagerMock; private readonly List _requirements; private readonly RequiresElevationHandler _sut; @@ -51,54 +38,17 @@ namespace Jellyfin.Api.Tests.Auth.RequiresElevationPolicy [InlineData(UserRoles.Guest, false)] public async Task ShouldHandleRolesCorrectly(string role, bool shouldSucceed) { - SetupConfigurationManager(true); - var (user, claims) = SetupUser(role); - - _userManagerMock.Setup(u => u.GetUserById(It.IsAny())) - .Returns(user); - - _httpContextAccessor.Setup(h => h.HttpContext.Connection.RemoteIpAddress) - .Returns(new IPAddress(InternalIp)); + TestHelpers.SetupConfigurationManager(_configurationManagerMock, true); + var (_, claims) = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + role, + TestHelpers.InternalIp); var context = new AuthorizationHandlerContext(_requirements, claims, null); await _sut.HandleAsync(context); Assert.Equal(shouldSucceed, context.HasSucceeded); } - - private static (User, ClaimsPrincipal) SetupUser(string role) - { - var user = new User( - "jellyfin", - typeof(DefaultAuthenticationProvider).FullName, - typeof(DefaultPasswordResetProvider).FullName); - - user.SetPermission(PermissionKind.IsAdministrator, role.Equals(UserRoles.Administrator, StringComparison.OrdinalIgnoreCase)); - var claims = new[] - { - new Claim(ClaimTypes.Role, role), - new Claim(ClaimTypes.Name, "jellyfin"), - new Claim(InternalClaimTypes.UserId, Guid.Empty.ToString("N", CultureInfo.InvariantCulture)), - new Claim(InternalClaimTypes.DeviceId, Guid.Empty.ToString("N", CultureInfo.InvariantCulture)), - new Claim(InternalClaimTypes.Device, "test"), - new Claim(InternalClaimTypes.Client, "test"), - new Claim(InternalClaimTypes.Version, "test"), - new Claim(InternalClaimTypes.Token, "test"), - }; - - var identity = new ClaimsIdentity(claims); - return (user, new ClaimsPrincipal(identity)); - } - - private void SetupConfigurationManager(bool startupWizardCompleted) - { - var commonConfiguration = new BaseApplicationConfiguration - { - IsStartupWizardCompleted = startupWizardCompleted - }; - - _configurationManagerMock.Setup(c => c.CommonConfiguration) - .Returns(commonConfiguration); - } } } diff --git a/tests/Jellyfin.Api.Tests/TestHelpers.cs b/tests/Jellyfin.Api.Tests/TestHelpers.cs new file mode 100644 index 0000000000..4617486fd9 --- /dev/null +++ b/tests/Jellyfin.Api.Tests/TestHelpers.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Net; +using System.Security.Claims; +using Jellyfin.Api.Constants; +using Jellyfin.Data.Entities; +using Jellyfin.Data.Enums; +using Jellyfin.Server.Implementations.Users; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Configuration; +using Microsoft.AspNetCore.Http; +using Moq; +using AccessSchedule = Jellyfin.Data.Entities.AccessSchedule; + +namespace Jellyfin.Api.Tests +{ + public static class TestHelpers + { + /// + /// 127.0.0.1. + /// + public const long InternalIp = 16777343; + + /// + /// 1.1.1.1. + /// + public const long ExternalIp = 16843009; + + public static (User, ClaimsPrincipal) SetupUser( + Mock userManagerMock, + Mock httpContextAccessorMock, + string role, + long ip, + IEnumerable? accessSchedules = null) + { + var user = new User( + "jellyfin", + typeof(DefaultAuthenticationProvider).FullName, + typeof(DefaultPasswordResetProvider).FullName); + + // Set administrator flag. + user.SetPermission(PermissionKind.IsAdministrator, role.Equals(UserRoles.Administrator, StringComparison.OrdinalIgnoreCase)); + + // Add access schedules if set. + if (accessSchedules != null) + { + foreach (var accessSchedule in accessSchedules) + { + user.AccessSchedules.Add(accessSchedule); + } + } + + var claims = new[] + { + new Claim(ClaimTypes.Role, role), + new Claim(ClaimTypes.Name, "jellyfin"), + new Claim(InternalClaimTypes.UserId, Guid.Empty.ToString("N", CultureInfo.InvariantCulture)), + new Claim(InternalClaimTypes.DeviceId, Guid.Empty.ToString("N", CultureInfo.InvariantCulture)), + new Claim(InternalClaimTypes.Device, "test"), + new Claim(InternalClaimTypes.Client, "test"), + new Claim(InternalClaimTypes.Version, "test"), + new Claim(InternalClaimTypes.Token, "test"), + }; + + var identity = new ClaimsIdentity(claims); + + userManagerMock + .Setup(u => u.GetUserById(It.IsAny())) + .Returns(user); + + httpContextAccessorMock + .Setup(h => h.HttpContext.Connection.RemoteIpAddress) + .Returns(new IPAddress(ip)); + + return (user, new ClaimsPrincipal(identity)); + } + + public static void SetupConfigurationManager(in Mock configurationManagerMock, bool startupWizardCompleted) + { + var commonConfiguration = new BaseApplicationConfiguration + { + IsStartupWizardCompleted = startupWizardCompleted + }; + + configurationManagerMock + .Setup(c => c.CommonConfiguration) + .Returns(commonConfiguration); + } + } +}