diff options
| author | Chris H <70915190+Chris-Codes-It@users.noreply.github.com> | 2023-11-10 14:51:44 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-10 07:51:44 -0700 |
| commit | 3fd505a4543a4ee42ead01793a91e0410032321b (patch) | |
| tree | 91e0466e350003f7f6b615beea0fbc544b8767e4 | |
| parent | b1acde54fbde30729b54ad50c88b4ec59655dc3d (diff) | |
Validate AuthenticationProviderId and PasswordResetProviderId (#10553)
| -rw-r--r-- | CONTRIBUTORS.md | 3 | ||||
| -rw-r--r-- | MediaBrowser.Model/Users/UserPolicy.cs | 3 | ||||
| -rw-r--r-- | tests/Jellyfin.Api.Tests/Controllers/UserControllerTests.cs | 120 |
3 files changed, 125 insertions, 1 deletions
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 74f1a8965..fff7136b8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -171,6 +171,7 @@ - [tallbl0nde](https://github.com/tallbl0nde) - [sleepycatcoding](https://github.com/sleepycatcoding) - [scampower3](https://github.com/scampower3) + - [Chris-Codes-It] (https://github.com/Chris-Codes-It) # Emby Contributors @@ -241,4 +242,4 @@ - [Jakob Kukla](https://github.com/jakobkukla) - [Utku Ă–zdemir](https://github.com/utkuozdemir) - [JPUC1143](https://github.com/Jpuc1143/) - - [0x25CBFC4F](https://github.com/0x25CBFC4F) + - [0x25CBFC4F](https://github.com/0x25CBFC4F)
\ No newline at end of file diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index f5aff07db..219ed5d5f 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -3,6 +3,7 @@ using System; using System.ComponentModel; +using System.ComponentModel.DataAnnotations; using System.Xml.Serialization; using Jellyfin.Data.Enums; using AccessSchedule = Jellyfin.Data.Entities.AccessSchedule; @@ -174,8 +175,10 @@ namespace MediaBrowser.Model.Users public int RemoteClientBitrateLimit { get; set; } [XmlElement(ElementName = "AuthenticationProviderId")] + [Required(AllowEmptyStrings = false)] public string AuthenticationProviderId { get; set; } + [Required(AllowEmptyStrings= false)] public string PasswordResetProviderId { get; set; } /// <summary> diff --git a/tests/Jellyfin.Api.Tests/Controllers/UserControllerTests.cs b/tests/Jellyfin.Api.Tests/Controllers/UserControllerTests.cs new file mode 100644 index 000000000..3f965d0ff --- /dev/null +++ b/tests/Jellyfin.Api.Tests/Controllers/UserControllerTests.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; +using AutoFixture.Xunit2; +using Jellyfin.Api.Controllers; +using Jellyfin.Data.Entities; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Playlists; +using MediaBrowser.Controller.QuickConnect; +using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Users; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Moq; +using Nikse.SubtitleEdit.Core.Common; +using Xunit; + +namespace Jellyfin.Api.Tests.Controllers; + +public class UserControllerTests +{ + private readonly UserController _subject; + private readonly Mock<IUserManager> _mockUserManager; + private readonly Mock<ISessionManager> _mockSessionManager; + private readonly Mock<INetworkManager> _mockNetworkManager; + private readonly Mock<IDeviceManager> _mockDeviceManager; + private readonly Mock<IAuthorizationContext> _mockAuthorizationContext; + private readonly Mock<IServerConfigurationManager> _mockServerConfigurationManager; + private readonly Mock<ILogger<UserController>> _mockLogger; + private readonly Mock<IQuickConnect> _mockQuickConnect; + private readonly Mock<IPlaylistManager> _mockPlaylistManager; + + public UserControllerTests() + { + _mockUserManager = new Mock<IUserManager>(); + _mockSessionManager = new Mock<ISessionManager>(); + _mockNetworkManager = new Mock<INetworkManager>(); + _mockDeviceManager = new Mock<IDeviceManager>(); + _mockAuthorizationContext = new Mock<IAuthorizationContext>(); + _mockServerConfigurationManager = new Mock<IServerConfigurationManager>(); + _mockLogger = new Mock<ILogger<UserController>>(); + _mockQuickConnect = new Mock<IQuickConnect>(); + _mockPlaylistManager = new Mock<IPlaylistManager>(); + + _subject = new UserController( + _mockUserManager.Object, + _mockSessionManager.Object, + _mockNetworkManager.Object, + _mockDeviceManager.Object, + _mockAuthorizationContext.Object, + _mockServerConfigurationManager.Object, + _mockLogger.Object, + _mockQuickConnect.Object, + _mockPlaylistManager.Object); + } + + [Theory] + [AutoData] + public async Task UpdateUserPolicy_WhenUserNotFound_ReturnsNotFound(Guid userId, UserPolicy userPolicy) + { + User? nullUser = null; + _mockUserManager. + Setup(m => m.GetUserById(userId)) + .Returns(nullUser); + + Assert.IsType<NotFoundResult>(await _subject.UpdateUserPolicy(userId, userPolicy)); + } + + [Theory] + [InlineAutoData(null)] + [InlineAutoData("")] + [InlineAutoData(" ")] + public void UpdateUserPolicy_WhenPasswordResetProviderIdNotSupplied_ReturnsBadRequest(string? passwordResetProviderId) + { + var userPolicy = new UserPolicy + { + PasswordResetProviderId = passwordResetProviderId, + AuthenticationProviderId = "AuthenticationProviderId" + }; + + Assert.Contains( + Validate(userPolicy), v => + v.MemberNames.Contains("PasswordResetProviderId") && + v.ErrorMessage != null && + v.ErrorMessage.Contains("required", StringComparison.CurrentCultureIgnoreCase)); + } + + [Theory] + [InlineAutoData(null)] + [InlineAutoData("")] + [InlineAutoData(" ")] + public void UpdateUserPolicy_WhenAuthenticationProviderIdNotSupplied_ReturnsBadRequest(string? authenticationProviderId) + { + var userPolicy = new UserPolicy + { + AuthenticationProviderId = authenticationProviderId, + PasswordResetProviderId = "PasswordResetProviderId" + }; + + Assert.Contains(Validate(userPolicy), v => + v.MemberNames.Contains("AuthenticationProviderId") && + v.ErrorMessage != null && + v.ErrorMessage.Contains("required", StringComparison.CurrentCultureIgnoreCase)); + } + + private IList<ValidationResult> Validate(object model) + { + var result = new List<ValidationResult>(); + var context = new ValidationContext(model, null, null); + Validator.TryValidateObject(model, context, result, true); + + return result; + } +} |
