From b670937c3d373173159a40f803e6e907ec0cd060 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 11 Dec 2020 15:00:43 -0700 Subject: Use typed UserManager GetPreference --- Jellyfin.Server.Implementations/Users/UserManager.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index e37fcc908..f576e662a 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -376,14 +376,14 @@ namespace Jellyfin.Server.Implementations.Users EnablePublicSharing = user.HasPermission(PermissionKind.EnablePublicSharing), AccessSchedules = user.AccessSchedules.ToArray(), BlockedTags = user.GetPreference(PreferenceKind.BlockedTags), - EnabledChannels = user.GetPreference(PreferenceKind.EnabledChannels)?.Select(Guid.Parse).ToArray(), + EnabledChannels = user.GetPreference(PreferenceKind.EnabledChannels), EnabledDevices = user.GetPreference(PreferenceKind.EnabledDevices), - EnabledFolders = user.GetPreference(PreferenceKind.EnabledFolders)?.Select(Guid.Parse).ToArray(), + EnabledFolders = user.GetPreference(PreferenceKind.EnabledFolders), EnableContentDeletionFromFolders = user.GetPreference(PreferenceKind.EnableContentDeletionFromFolders), SyncPlayAccess = user.SyncPlayAccess, - BlockedChannels = user.GetPreference(PreferenceKind.BlockedChannels)?.Select(Guid.Parse).ToArray(), - BlockedMediaFolders = user.GetPreference(PreferenceKind.BlockedMediaFolders)?.Select(Guid.Parse).ToArray(), - BlockUnratedItems = user.GetPreference(PreferenceKind.BlockUnratedItems).Select(Enum.Parse).ToArray() + BlockedChannels = user.GetPreference(PreferenceKind.BlockedChannels), + BlockedMediaFolders = user.GetPreference(PreferenceKind.BlockedMediaFolders), + BlockUnratedItems = user.GetPreference(PreferenceKind.BlockUnratedItems) } }; } @@ -704,13 +704,11 @@ namespace Jellyfin.Server.Implementations.Users } // TODO: fix this at some point - user.SetPreference( - PreferenceKind.BlockUnratedItems, - policy.BlockUnratedItems?.Select(i => i.ToString()).ToArray() ?? Array.Empty()); + user.SetPreference(PreferenceKind.BlockUnratedItems, policy.BlockUnratedItems ?? Array.Empty()); user.SetPreference(PreferenceKind.BlockedTags, policy.BlockedTags); - user.SetPreference(PreferenceKind.EnabledChannels, policy.EnabledChannels?.Select(i => i.ToString("N", CultureInfo.InvariantCulture)).ToArray()); + user.SetPreference(PreferenceKind.EnabledChannels, policy.EnabledChannels); user.SetPreference(PreferenceKind.EnabledDevices, policy.EnabledDevices); - user.SetPreference(PreferenceKind.EnabledFolders, policy.EnabledFolders?.Select(i => i.ToString("N", CultureInfo.InvariantCulture)).ToArray()); + user.SetPreference(PreferenceKind.EnabledFolders, policy.EnabledFolders); user.SetPreference(PreferenceKind.EnableContentDeletionFromFolders, policy.EnableContentDeletionFromFolders); dbContext.Update(user); -- cgit v1.2.3 From ee23d06154133ffc506dda3a8ef0e09d20c03c6c Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 13 Dec 2020 08:15:26 -0700 Subject: Use a more descriptive function name --- Emby.Server.Implementations/Library/UserViewManager.cs | 6 +++--- Emby.Server.Implementations/TV/TVSeriesManager.cs | 2 +- Jellyfin.Api/Controllers/ItemsController.cs | 8 ++++---- Jellyfin.Data/Entities/User.cs | 4 ++-- Jellyfin.Server.Implementations/Users/UserManager.cs | 10 +++++----- MediaBrowser.Controller/Channels/Channel.cs | 4 ++-- MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs | 2 +- MediaBrowser.Controller/Entities/Audio/MusicArtist.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 4 ++-- MediaBrowser.Controller/Entities/Folder.cs | 4 ++-- MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 2 +- MediaBrowser.Controller/Entities/TV/Series.cs | 2 +- 12 files changed, 25 insertions(+), 25 deletions(-) (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs index 6c74e6bd4..b6b7ea949 100644 --- a/Emby.Server.Implementations/Library/UserViewManager.cs +++ b/Emby.Server.Implementations/Library/UserViewManager.cs @@ -129,12 +129,12 @@ namespace Emby.Server.Implementations.Library if (!query.IncludeHidden) { - list = list.Where(i => !user.GetPreference(PreferenceKind.MyMediaExcludes).Contains(i.Id)).ToList(); + list = list.Where(i => !user.GetPreferenceValues(PreferenceKind.MyMediaExcludes).Contains(i.Id)).ToList(); } var sorted = _libraryManager.Sort(list, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).ToList(); - var orders = user.GetPreference(PreferenceKind.OrderedViews); + var orders = user.GetPreferenceValues(PreferenceKind.OrderedViews); return list .OrderBy(i => @@ -280,7 +280,7 @@ namespace Emby.Server.Implementations.Library { parents = _libraryManager.GetUserRootFolder().GetChildren(user, true) .Where(i => i is Folder) - .Where(i => !user.GetPreference(PreferenceKind.LatestItemExcludes) + .Where(i => !user.GetPreferenceValues(PreferenceKind.LatestItemExcludes) .Contains(i.Id)) .ToList(); } diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index a2a9b37a7..f0734340b 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -75,7 +75,7 @@ namespace Emby.Server.Implementations.TV { parents = _libraryManager.GetUserRootFolder().GetChildren(user, true) .Where(i => i is Folder) - .Where(i => !user.GetPreference(PreferenceKind.LatestItemExcludes).Contains(i.Id)) + .Where(i => !user.GetPreferenceValues(PreferenceKind.LatestItemExcludes).Contains(i.Id)) .ToArray(); } diff --git a/Jellyfin.Api/Controllers/ItemsController.cs b/Jellyfin.Api/Controllers/ItemsController.cs index 0816efb38..b84136ac6 100644 --- a/Jellyfin.Api/Controllers/ItemsController.cs +++ b/Jellyfin.Api/Controllers/ItemsController.cs @@ -254,9 +254,9 @@ namespace Jellyfin.Api.Controllers includeItemTypes = new[] { "Playlist" }; } - var enabledChannels = user!.GetPreference(PreferenceKind.EnabledChannels); + var enabledChannels = user!.GetPreferenceValues(PreferenceKind.EnabledChannels); - bool isInEnabledFolder = Array.IndexOf(user.GetPreference(PreferenceKind.EnabledFolders), item.Id) != -1 + bool isInEnabledFolder = Array.IndexOf(user.GetPreferenceValues(PreferenceKind.EnabledFolders), item.Id) != -1 // Assume all folders inside an EnabledChannel are enabled || Array.IndexOf(enabledChannels, item.Id) != -1 // Assume all items inside an EnabledChannel are enabled @@ -265,7 +265,7 @@ namespace Jellyfin.Api.Controllers var collectionFolders = _libraryManager.GetCollectionFolders(item); foreach (var collectionFolder in collectionFolders) { - if (user.GetPreference(PreferenceKind.EnabledFolders).Contains(collectionFolder.Id)) + if (user.GetPreferenceValues(PreferenceKind.EnabledFolders).Contains(collectionFolder.Id)) { isInEnabledFolder = true; } @@ -786,7 +786,7 @@ namespace Jellyfin.Api.Controllers var ancestorIds = Array.Empty(); - var excludeFolderIds = user.GetPreference(PreferenceKind.LatestItemExcludes); + var excludeFolderIds = user.GetPreferenceValues(PreferenceKind.LatestItemExcludes); if (parentIdGuid.Equals(Guid.Empty) && excludeFolderIds.Length > 0) { ancestorIds = _libraryManager.GetUserRootFolder().GetChildren(user, true) diff --git a/Jellyfin.Data/Entities/User.cs b/Jellyfin.Data/Entities/User.cs index d19cbac7f..cc85a0b85 100644 --- a/Jellyfin.Data/Entities/User.cs +++ b/Jellyfin.Data/Entities/User.cs @@ -419,7 +419,7 @@ namespace Jellyfin.Data.Entities /// The preference kind. /// Type of preference. /// A {T} array containing the user's preference. - public T[] GetPreference(PreferenceKind preference) + public T[] GetPreferenceValues(PreferenceKind preference) { var val = Preferences.First(p => p.Kind == preference).Value; if (string.IsNullOrEmpty(val)) @@ -499,7 +499,7 @@ namespace Jellyfin.Data.Entities /// True if the folder is in the user's grouped folders. public bool IsFolderGrouped(Guid id) { - return Array.IndexOf(GetPreference(PreferenceKind.GroupedFolders), id) != -1; + return Array.IndexOf(GetPreferenceValues(PreferenceKind.GroupedFolders), id) != -1; } private static bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index f576e662a..400f02ef2 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -376,14 +376,14 @@ namespace Jellyfin.Server.Implementations.Users EnablePublicSharing = user.HasPermission(PermissionKind.EnablePublicSharing), AccessSchedules = user.AccessSchedules.ToArray(), BlockedTags = user.GetPreference(PreferenceKind.BlockedTags), - EnabledChannels = user.GetPreference(PreferenceKind.EnabledChannels), + EnabledChannels = user.GetPreferenceValues(PreferenceKind.EnabledChannels), EnabledDevices = user.GetPreference(PreferenceKind.EnabledDevices), - EnabledFolders = user.GetPreference(PreferenceKind.EnabledFolders), + EnabledFolders = user.GetPreferenceValues(PreferenceKind.EnabledFolders), EnableContentDeletionFromFolders = user.GetPreference(PreferenceKind.EnableContentDeletionFromFolders), SyncPlayAccess = user.SyncPlayAccess, - BlockedChannels = user.GetPreference(PreferenceKind.BlockedChannels), - BlockedMediaFolders = user.GetPreference(PreferenceKind.BlockedMediaFolders), - BlockUnratedItems = user.GetPreference(PreferenceKind.BlockUnratedItems) + BlockedChannels = user.GetPreferenceValues(PreferenceKind.BlockedChannels), + BlockedMediaFolders = user.GetPreferenceValues(PreferenceKind.BlockedMediaFolders), + BlockUnratedItems = user.GetPreferenceValues(PreferenceKind.BlockUnratedItems) } }; } diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index c8a8db528..b2315bda4 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Channels { public override bool IsVisible(User user) { - var blockedChannelsPreference = user.GetPreference(PreferenceKind.BlockedChannels); + var blockedChannelsPreference = user.GetPreferenceValues(PreferenceKind.BlockedChannels); if (blockedChannelsPreference.Length != 0) { if (blockedChannelsPreference.Contains(Id)) @@ -28,7 +28,7 @@ namespace MediaBrowser.Controller.Channels else { if (!user.HasPermission(PermissionKind.EnableAllChannels) - && !user.GetPreference(PreferenceKind.EnabledChannels).Contains(Id)) + && !user.GetPreferenceValues(PreferenceKind.EnabledChannels).Contains(Id)) { return false; } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 260daa1c2..9a33ad9d7 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -120,7 +120,7 @@ namespace MediaBrowser.Controller.Entities.Audio protected override bool GetBlockUnratedValue(User user) { - return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Music); + return user.GetPreferenceValues(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Music); } public override UnratedItem GetBlockUnratedType() diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 5d586bfb5..8a9bb12c7 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -145,7 +145,7 @@ namespace MediaBrowser.Controller.Entities.Audio protected override bool GetBlockUnratedValue(User user) { - return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Music); + return user.GetPreferenceValues(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Music); } public override UnratedItem GetBlockUnratedType() diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 3aa93565b..cbb02aabd 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -480,7 +480,7 @@ namespace MediaBrowser.Controller.Entities return true; } - var allowed = user.GetPreference(PreferenceKind.EnableContentDeletionFromFolders); + var allowed = user.GetPreferenceValues(PreferenceKind.EnableContentDeletionFromFolders); if (SourceType == SourceType.Channel) { @@ -1909,7 +1909,7 @@ namespace MediaBrowser.Controller.Entities return false; } - return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(GetBlockUnratedType()); + return user.GetPreferenceValues(PreferenceKind.BlockUnratedItems).Contains(GetBlockUnratedType()); } /// diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 0f936538b..cac5026f7 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -186,7 +186,7 @@ namespace MediaBrowser.Controller.Entities { if (this is ICollectionFolder && !(this is BasePluginFolder)) { - var blockedMediaFolders = user.GetPreference(PreferenceKind.BlockedMediaFolders); + var blockedMediaFolders = user.GetPreferenceValues(PreferenceKind.BlockedMediaFolders); if (blockedMediaFolders.Length > 0) { if (blockedMediaFolders.Contains(Id)) @@ -197,7 +197,7 @@ namespace MediaBrowser.Controller.Entities else { if (!user.HasPermission(PermissionKind.EnableAllFolders) - && !user.GetPreference(PreferenceKind.EnabledFolders).Contains(Id)) + && !user.GetPreferenceValues(PreferenceKind.EnabledFolders).Contains(Id)) { return false; } diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 343da3825..05e4229ca 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -49,7 +49,7 @@ namespace MediaBrowser.Controller.Entities.Movies protected override bool GetBlockUnratedValue(User user) { - return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Movie); + return user.GetPreferenceValues(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Movie); } public override double GetDefaultPrimaryImageAspectRatio() diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index aaed879c3..1a379074d 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -452,7 +452,7 @@ namespace MediaBrowser.Controller.Entities.TV protected override bool GetBlockUnratedValue(User user) { - return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Series); + return user.GetPreferenceValues(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Series); } public override UnratedItem GetBlockUnratedType() -- cgit v1.2.3 From a5e55ba85956fe54539cb22dfd95c9499aa3de6c Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sat, 6 Feb 2021 15:59:27 -0500 Subject: Clean up UserManager.AuthenticateUser --- .../Users/UserManager.cs | 23 +++++++--------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index d1de5408c..38a074e98 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -402,27 +402,18 @@ namespace Jellyfin.Server.Implementations.Users } var user = Users.FirstOrDefault(i => string.Equals(username, i.Username, StringComparison.OrdinalIgnoreCase)); - bool success; - IAuthenticationProvider? authenticationProvider; + var authResult = await AuthenticateLocalUser(username, password, user, remoteEndPoint) + .ConfigureAwait(false); + var authenticationProvider = authResult.authenticationProvider; + var success = authResult.success; - if (user != null) + if (user is null) { - var authResult = await AuthenticateLocalUser(username, password, user, remoteEndPoint) - .ConfigureAwait(false); - authenticationProvider = authResult.authenticationProvider; - success = authResult.success; - } - else - { - var authResult = await AuthenticateLocalUser(username, password, null, remoteEndPoint) - .ConfigureAwait(false); - authenticationProvider = authResult.authenticationProvider; string updatedUsername = authResult.username; - success = authResult.success; if (success - && authenticationProvider != null - && !(authenticationProvider is DefaultAuthenticationProvider)) + && authenticationProvider is not null + && authenticationProvider is not DefaultAuthenticationProvider) { // Trust the username returned by the authentication provider username = updatedUsername; -- cgit v1.2.3 From 1171b5ab923e0a0ad6b412201ed7ba0d33f51229 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 16 Feb 2021 20:41:53 -0500 Subject: Fix user renaming logic --- Jellyfin.Server.Implementations/Users/UserManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index d1de5408c..95736c37f 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -147,7 +147,7 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentException("The new and old names must be different."); } - if (Users.Any(u => u.Id != user.Id && u.Username.Equals(newName, StringComparison.Ordinal))) + if (Users.Any(u => u.Id != user.Id && u.Username.Equals(newName, StringComparison.OrdinalIgnoreCase))) { throw new ArgumentException(string.Format( CultureInfo.InvariantCulture, -- cgit v1.2.3 From f127096660a0eed7da2ef6db68720eba4dfbd7a0 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 16 Feb 2021 20:48:41 -0500 Subject: Don't allow new users to be created with the same name as an existing user. --- Jellyfin.Server.Implementations/Users/UserManager.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 95736c37f..a3a9e90d4 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -206,6 +206,14 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentException("Usernames can contain unicode symbols, numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)"); } + if (Users.Any(u => u.Username.Equals(name, StringComparison.OrdinalIgnoreCase))) + { + throw new ArgumentException(string.Format( + CultureInfo.InvariantCulture, + "A user with the name '{0}' already exists.", + name)); + } + await using var dbContext = _dbProvider.CreateContext(); var newUser = await CreateUserInternalAsync(name, dbContext).ConfigureAwait(false); -- cgit v1.2.3 From 442e7706880bba9a95404b4d04972674ad65d085 Mon Sep 17 00:00:00 2001 From: cvium Date: Wed, 17 Feb 2021 11:30:14 +0100 Subject: Validate the new username when renaming --- .../Properties/AssemblyInfo.cs | 23 ++++++++++++++++++ .../Users/UserManager.cs | 22 ++++++++++------- .../Jellyfin.Server.Implementations.Tests.csproj | 1 + .../Users/UserManagerTests.cs | 28 ++++++++++++++++++++++ 4 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 Jellyfin.Server.Implementations/Properties/AssemblyInfo.cs create mode 100644 tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerTests.cs (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Jellyfin.Server.Implementations/Properties/AssemblyInfo.cs b/Jellyfin.Server.Implementations/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..6528d4fdc --- /dev/null +++ b/Jellyfin.Server.Implementations/Properties/AssemblyInfo.cs @@ -0,0 +1,23 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Jellyfin.Server.Implementations")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Jellyfin Project")] +[assembly: AssemblyProduct("Jellyfin Server")] +[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: NeutralResourcesLanguage("en")] +[assembly: InternalsVisibleTo("Jellyfin.Server.Implementations.Tests")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index a3a9e90d4..76d1389ca 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -137,10 +137,7 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentNullException(nameof(user)); } - if (string.IsNullOrWhiteSpace(newName)) - { - throw new ArgumentException("Invalid username", nameof(newName)); - } + ThrowIfInvalidUsername(newName); if (user.Username.Equals(newName, StringComparison.Ordinal)) { @@ -201,10 +198,7 @@ namespace Jellyfin.Server.Implementations.Users /// public async Task CreateUserAsync(string name) { - if (!IsValidUsername(name)) - { - throw new ArgumentException("Usernames can contain unicode symbols, numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)"); - } + ThrowIfInvalidUsername(name); if (Users.Any(u => u.Username.Equals(name, StringComparison.OrdinalIgnoreCase))) { @@ -733,12 +727,22 @@ namespace Jellyfin.Server.Implementations.Users _users[user.Id] = user; } + internal static void ThrowIfInvalidUsername(string name) + { + if (!string.IsNullOrWhiteSpace(name) && IsValidUsername(name)) + { + return; + } + + throw new ArgumentException("Usernames can contain unicode symbols, numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)", nameof(name)); + } + private static bool IsValidUsername(string name) { // This is some regex that matches only on unicode "word" characters, as well as -, _ and @ // In theory this will cut out most if not all 'control' characters which should help minimize any weirdness // Usernames can contain letters (a-z + whatever else unicode is cool with), numbers (0-9), at-signs (@), dashes (-), underscores (_), apostrophes ('), periods (.) and spaces ( ) - return Regex.IsMatch(name, @"^[\w\ \-'._@]*$"); + return Regex.IsMatch(name, @"^[\w\ \-'._@]+$"); } private IAuthenticationProvider GetAuthenticationProvider(User user) diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index 174f29b09..c3b3155fe 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -39,6 +39,7 @@ + diff --git a/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerTests.cs new file mode 100644 index 000000000..9bcd43bc0 --- /dev/null +++ b/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerTests.cs @@ -0,0 +1,28 @@ +using System; +using Jellyfin.Server.Implementations.Users; +using Xunit; + +namespace Jellyfin.Server.Implementations.Tests.Users +{ + public class UserManagerTests + { + [Theory] + [InlineData("this_is_valid", true)] + [InlineData("this is also valid", true)] + [InlineData(" ", false)] + [InlineData("", false)] + [InlineData("0@_-' .", true)] + public void ThrowIfInvalidUsername_WhenInvalidUsername_ThrowsArgumentException(string username, bool isValid) + { + var ex = Record.Exception(() => UserManager.ThrowIfInvalidUsername(username)); + + var argumentExceptionNotThrown = ex is not ArgumentException; + if (ex != null) + { + Assert.Equal(typeof(ArgumentException), ex.GetType()); + } + + Assert.Equal(isValid, argumentExceptionNotThrown); + } + } +} -- cgit v1.2.3 From 03cc6b1d782067e58975dbea4b61e42a3c04e1aa Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Thu, 25 Feb 2021 19:02:27 -0500 Subject: Make styling more consistent --- Jellyfin.Server.Implementations/Users/UserManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 38a074e98..25d7524c7 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -407,12 +407,12 @@ namespace Jellyfin.Server.Implementations.Users var authenticationProvider = authResult.authenticationProvider; var success = authResult.success; - if (user is null) + if (user == null) { string updatedUsername = authResult.username; if (success - && authenticationProvider is not null + && authenticationProvider != null && authenticationProvider is not DefaultAuthenticationProvider) { // Trust the username returned by the authentication provider -- cgit v1.2.3 From f638ee6b0918c2ef05ec11cfa43584d3efad68d1 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sat, 6 Mar 2021 17:43:01 -0500 Subject: Enable nullable for Jellyfin.Data and remove unnecessary attributes --- Emby.Drawing/ImageProcessor.cs | 7 ++++++- Jellyfin.Api/Controllers/ImageController.cs | 12 +++++++++++- Jellyfin.Api/Controllers/StartupController.cs | 5 ++++- Jellyfin.Data/Entities/AccessSchedule.cs | 7 ------- Jellyfin.Data/Entities/ActivityLog.cs | 8 +++----- Jellyfin.Data/Entities/CustomItemDisplayPreferences.cs | 3 --- Jellyfin.Data/Entities/DisplayPreferences.cs | 7 ++----- Jellyfin.Data/Entities/Group.cs | 1 - Jellyfin.Data/Entities/HomeSection.cs | 1 - Jellyfin.Data/Entities/ImageInfo.cs | 1 - Jellyfin.Data/Entities/ItemDisplayPreferences.cs | 2 -- Jellyfin.Data/Entities/Libraries/Artwork.cs | 1 - Jellyfin.Data/Entities/Libraries/BookMetadata.cs | 2 -- Jellyfin.Data/Entities/Libraries/Chapter.cs | 3 +-- Jellyfin.Data/Entities/Libraries/Collection.cs | 2 +- Jellyfin.Data/Entities/Libraries/CollectionItem.cs | 13 +++++++++++-- Jellyfin.Data/Entities/Libraries/Company.cs | 2 +- Jellyfin.Data/Entities/Libraries/CompanyMetadata.cs | 8 ++++---- Jellyfin.Data/Entities/Libraries/CustomItemMetadata.cs | 2 -- Jellyfin.Data/Entities/Libraries/EpisodeMetadata.cs | 6 +++--- Jellyfin.Data/Entities/Libraries/Genre.cs | 1 - Jellyfin.Data/Entities/Libraries/ItemMetadata.cs | 6 ++---- Jellyfin.Data/Entities/Libraries/Library.cs | 12 +++--------- Jellyfin.Data/Entities/Libraries/LibraryItem.cs | 1 - Jellyfin.Data/Entities/Libraries/MediaFile.cs | 1 - Jellyfin.Data/Entities/Libraries/MetadataProvider.cs | 1 - Jellyfin.Data/Entities/Libraries/MetadataProviderId.cs | 5 +++-- Jellyfin.Data/Entities/Libraries/MovieMetadata.cs | 10 ++++------ Jellyfin.Data/Entities/Libraries/MusicAlbumMetadata.cs | 6 +++--- Jellyfin.Data/Entities/Libraries/Person.cs | 3 +-- Jellyfin.Data/Entities/Libraries/PersonRole.cs | 8 +++++--- Jellyfin.Data/Entities/Libraries/Rating.cs | 2 +- Jellyfin.Data/Entities/Libraries/RatingSource.cs | 4 ++-- Jellyfin.Data/Entities/Libraries/Release.cs | 1 - Jellyfin.Data/Entities/Libraries/SeasonMetadata.cs | 2 +- Jellyfin.Data/Entities/Libraries/SeriesMetadata.cs | 9 ++++----- Jellyfin.Data/Entities/Preference.cs | 1 - Jellyfin.Data/Entities/User.cs | 17 +++++++---------- Jellyfin.Data/Jellyfin.Data.csproj | 1 + .../Events/Consumers/Session/PlaybackStartLogger.cs | 4 ++-- Jellyfin.Server.Implementations/Users/UserManager.cs | 6 +++--- Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs | 4 +--- MediaBrowser.Controller/Drawing/IImageProcessor.cs | 2 +- tests/Jellyfin.Api.Tests/TestHelpers.cs | 4 ++-- 44 files changed, 93 insertions(+), 111 deletions(-) (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 8a2301d2d..aa8a3d212 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -352,8 +352,13 @@ namespace Emby.Drawing } /// - public string GetImageCacheTag(User user) + public string? GetImageCacheTag(User user) { + if (user.ProfileImage == null) + { + return null; + } + return (user.ProfileImage.Path + user.ProfileImage.LastModified.Ticks).GetMD5() .ToString("N", CultureInfo.InvariantCulture); } diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs index a50d6e46b..b016f2450 100644 --- a/Jellyfin.Api/Controllers/ImageController.cs +++ b/Jellyfin.Api/Controllers/ImageController.cs @@ -196,6 +196,11 @@ namespace Jellyfin.Api.Controllers } var user = _userManager.GetUserById(userId); + if (user?.ProfileImage == null) + { + return NoContent(); + } + try { System.IO.File.Delete(user.ProfileImage.Path); @@ -235,6 +240,11 @@ namespace Jellyfin.Api.Controllers } var user = _userManager.GetUserById(userId); + if (user?.ProfileImage == null) + { + return NoContent(); + } + try { System.IO.File.Delete(user.ProfileImage.Path); @@ -1469,7 +1479,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? imageIndex) { var user = _userManager.GetUserById(userId); - if (user == null) + if (user?.ProfileImage == null) { return NotFound(); } diff --git a/Jellyfin.Api/Controllers/StartupController.cs b/Jellyfin.Api/Controllers/StartupController.cs index d9cb34557..a01a617fc 100644 --- a/Jellyfin.Api/Controllers/StartupController.cs +++ b/Jellyfin.Api/Controllers/StartupController.cs @@ -132,7 +132,10 @@ namespace Jellyfin.Api.Controllers { var user = _userManager.Users.First(); - user.Username = startupUserDto.Name; + if (startupUserDto.Name != null) + { + user.Username = startupUserDto.Name; + } await _userManager.UpdateUserAsync(user).ConfigureAwait(false); diff --git a/Jellyfin.Data/Entities/AccessSchedule.cs b/Jellyfin.Data/Entities/AccessSchedule.cs index 72bca061d..9ac0666ac 100644 --- a/Jellyfin.Data/Entities/AccessSchedule.cs +++ b/Jellyfin.Data/Entities/AccessSchedule.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; using Jellyfin.Data.Enums; @@ -33,8 +32,6 @@ namespace Jellyfin.Data.Entities /// Identity, Indexed, Required. /// [XmlIgnore] - [Key] - [Required] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; protected set; } @@ -42,28 +39,24 @@ namespace Jellyfin.Data.Entities /// Gets or sets the id of the associated user. /// [XmlIgnore] - [Required] public Guid UserId { get; protected set; } /// /// Gets or sets the day of week. /// /// The day of week. - [Required] public DynamicDayOfWeek DayOfWeek { get; set; } /// /// Gets or sets the start hour. /// /// The start hour. - [Required] public double StartHour { get; set; } /// /// Gets or sets the end hour. /// /// The end hour. - [Required] public double EndHour { get; set; } /// diff --git a/Jellyfin.Data/Entities/ActivityLog.cs b/Jellyfin.Data/Entities/ActivityLog.cs index 80e32db30..e4534e8b5 100644 --- a/Jellyfin.Data/Entities/ActivityLog.cs +++ b/Jellyfin.Data/Entities/ActivityLog.cs @@ -50,7 +50,6 @@ namespace Jellyfin.Data.Entities /// /// Required, Max length = 512. /// - [Required] [MaxLength(512)] [StringLength(512)] public string Name { get; set; } @@ -63,7 +62,7 @@ namespace Jellyfin.Data.Entities /// [MaxLength(512)] [StringLength(512)] - public string Overview { get; set; } + public string? Overview { get; set; } /// /// Gets or sets the short overview. @@ -73,7 +72,7 @@ namespace Jellyfin.Data.Entities /// [MaxLength(512)] [StringLength(512)] - public string ShortOverview { get; set; } + public string? ShortOverview { get; set; } /// /// Gets or sets the type. @@ -81,7 +80,6 @@ namespace Jellyfin.Data.Entities /// /// Required, Max length = 256. /// - [Required] [MaxLength(256)] [StringLength(256)] public string Type { get; set; } @@ -102,7 +100,7 @@ namespace Jellyfin.Data.Entities /// [MaxLength(256)] [StringLength(256)] - public string ItemId { get; set; } + public string? ItemId { get; set; } /// /// Gets or sets the date created. This should be in UTC. diff --git a/Jellyfin.Data/Entities/CustomItemDisplayPreferences.cs b/Jellyfin.Data/Entities/CustomItemDisplayPreferences.cs index d407180d4..cc46248c7 100644 --- a/Jellyfin.Data/Entities/CustomItemDisplayPreferences.cs +++ b/Jellyfin.Data/Entities/CustomItemDisplayPreferences.cs @@ -57,7 +57,6 @@ namespace Jellyfin.Data.Entities /// /// Required. Max Length = 32. /// - [Required] [MaxLength(32)] [StringLength(32)] public string Client { get; set; } @@ -68,7 +67,6 @@ namespace Jellyfin.Data.Entities /// /// Required. /// - [Required] public string Key { get; set; } /// @@ -77,7 +75,6 @@ namespace Jellyfin.Data.Entities /// /// Required. /// - [Required] public string Value { get; set; } } } diff --git a/Jellyfin.Data/Entities/DisplayPreferences.cs b/Jellyfin.Data/Entities/DisplayPreferences.cs index d186deb29..64cd6812a 100644 --- a/Jellyfin.Data/Entities/DisplayPreferences.cs +++ b/Jellyfin.Data/Entities/DisplayPreferences.cs @@ -30,8 +30,6 @@ namespace Jellyfin.Data.Entities SkipBackwardLength = 10000; ScrollDirection = ScrollDirection.Horizontal; ChromecastVersion = ChromecastVersion.Stable; - DashboardTheme = string.Empty; - TvHome = string.Empty; HomeSections = new HashSet(); } @@ -67,7 +65,6 @@ namespace Jellyfin.Data.Entities /// /// Required. Max Length = 32. /// - [Required] [MaxLength(32)] [StringLength(32)] public string Client { get; set; } @@ -138,14 +135,14 @@ namespace Jellyfin.Data.Entities /// [MaxLength(32)] [StringLength(32)] - public string DashboardTheme { get; set; } + public string? DashboardTheme { get; set; } /// /// Gets or sets the tv home screen. /// [MaxLength(32)] [StringLength(32)] - public string TvHome { get; set; } + public string? TvHome { get; set; } /// /// Gets or sets the home sections. diff --git a/Jellyfin.Data/Entities/Group.cs b/Jellyfin.Data/Entities/Group.cs index 8c45dde92..b14e22b7b 100644 --- a/Jellyfin.Data/Entities/Group.cs +++ b/Jellyfin.Data/Entities/Group.cs @@ -46,7 +46,6 @@ namespace Jellyfin.Data.Entities /// /// Required, Max length = 255. /// - [Required] [MaxLength(255)] [StringLength(255)] public string Name { get; set; } diff --git a/Jellyfin.Data/Entities/HomeSection.cs b/Jellyfin.Data/Entities/HomeSection.cs index 062046260..5adc52491 100644 --- a/Jellyfin.Data/Entities/HomeSection.cs +++ b/Jellyfin.Data/Entities/HomeSection.cs @@ -15,7 +15,6 @@ namespace Jellyfin.Data.Entities /// /// Identity. Required. /// - [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; protected set; } diff --git a/Jellyfin.Data/Entities/ImageInfo.cs b/Jellyfin.Data/Entities/ImageInfo.cs index f9ae1a955..e0c37047d 100644 --- a/Jellyfin.Data/Entities/ImageInfo.cs +++ b/Jellyfin.Data/Entities/ImageInfo.cs @@ -39,7 +39,6 @@ namespace Jellyfin.Data.Entities /// /// Required. /// - [Required] [MaxLength(512)] [StringLength(512)] public string Path { get; set; } diff --git a/Jellyfin.Data/Entities/ItemDisplayPreferences.cs b/Jellyfin.Data/Entities/ItemDisplayPreferences.cs index f0a04f8ea..4bfeb2fa3 100644 --- a/Jellyfin.Data/Entities/ItemDisplayPreferences.cs +++ b/Jellyfin.Data/Entities/ItemDisplayPreferences.cs @@ -59,7 +59,6 @@ namespace Jellyfin.Data.Entities /// /// Required. Max Length = 32. /// - [Required] [MaxLength(32)] [StringLength(32)] public string Client { get; set; } @@ -99,7 +98,6 @@ namespace Jellyfin.Data.Entities /// /// Required. /// - [Required] [MaxLength(64)] [StringLength(64)] public string SortBy { get; set; } diff --git a/Jellyfin.Data/Entities/Libraries/Artwork.cs b/Jellyfin.Data/Entities/Libraries/Artwork.cs index df28ce737..84a524de2 100644 --- a/Jellyfin.Data/Entities/Libraries/Artwork.cs +++ b/Jellyfin.Data/Entities/Libraries/Artwork.cs @@ -44,7 +44,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required, Max length = 65535. /// - [Required] [MaxLength(65535)] [StringLength(65535)] public string Path { get; set; } diff --git a/Jellyfin.Data/Entities/Libraries/BookMetadata.cs b/Jellyfin.Data/Entities/Libraries/BookMetadata.cs index 8b0c96530..1ff4327b0 100644 --- a/Jellyfin.Data/Entities/Libraries/BookMetadata.cs +++ b/Jellyfin.Data/Entities/Libraries/BookMetadata.cs @@ -1,7 +1,6 @@ #pragma warning disable CA2227 using System.Collections.Generic; -using System.ComponentModel.DataAnnotations.Schema; using Jellyfin.Data.Interfaces; namespace Jellyfin.Data.Entities.Libraries @@ -32,7 +31,6 @@ namespace Jellyfin.Data.Entities.Libraries public virtual ICollection Publishers { get; protected set; } /// - [NotMapped] public ICollection Companies => Publishers; } } diff --git a/Jellyfin.Data/Entities/Libraries/Chapter.cs b/Jellyfin.Data/Entities/Libraries/Chapter.cs index f253143d7..11f53ae20 100644 --- a/Jellyfin.Data/Entities/Libraries/Chapter.cs +++ b/Jellyfin.Data/Entities/Libraries/Chapter.cs @@ -45,7 +45,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Name { get; set; } + public string? Name { get; set; } /// /// Gets or sets the language. @@ -54,7 +54,6 @@ namespace Jellyfin.Data.Entities.Libraries /// Required, Min length = 3, Max length = 3 /// ISO-639-3 3-character language codes. /// - [Required] [MinLength(3)] [MaxLength(3)] [StringLength(3)] diff --git a/Jellyfin.Data/Entities/Libraries/Collection.cs b/Jellyfin.Data/Entities/Libraries/Collection.cs index 39eded752..d230eeb2f 100644 --- a/Jellyfin.Data/Entities/Libraries/Collection.cs +++ b/Jellyfin.Data/Entities/Libraries/Collection.cs @@ -37,7 +37,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Name { get; set; } + public string? Name { get; set; } /// [ConcurrencyCheck] diff --git a/Jellyfin.Data/Entities/Libraries/CollectionItem.cs b/Jellyfin.Data/Entities/Libraries/CollectionItem.cs index 1157de442..e19362bdf 100644 --- a/Jellyfin.Data/Entities/Libraries/CollectionItem.cs +++ b/Jellyfin.Data/Entities/Libraries/CollectionItem.cs @@ -9,6 +9,15 @@ namespace Jellyfin.Data.Entities.Libraries /// public class CollectionItem : IHasConcurrencyToken { + /// + /// Initializes a new instance of the class. + /// + /// The library item. + public CollectionItem(LibraryItem libraryItem) + { + LibraryItem = libraryItem; + } + /// /// Gets or sets the id. /// @@ -36,7 +45,7 @@ namespace Jellyfin.Data.Entities.Libraries /// /// TODO check if this properly updated Dependant and has the proper principal relationship. /// - public virtual CollectionItem Next { get; set; } + public virtual CollectionItem? Next { get; set; } /// /// Gets or sets the previous item in the collection. @@ -44,7 +53,7 @@ namespace Jellyfin.Data.Entities.Libraries /// /// TODO check if this properly updated Dependant and has the proper principal relationship. /// - public virtual CollectionItem Previous { get; set; } + public virtual CollectionItem? Previous { get; set; } /// public void OnSavingChanges() diff --git a/Jellyfin.Data/Entities/Libraries/Company.cs b/Jellyfin.Data/Entities/Libraries/Company.cs index 499ba3800..09050bb52 100644 --- a/Jellyfin.Data/Entities/Libraries/Company.cs +++ b/Jellyfin.Data/Entities/Libraries/Company.cs @@ -18,6 +18,7 @@ namespace Jellyfin.Data.Entities.Libraries public Company() { CompanyMetadata = new HashSet(); + ChildCompanies = new HashSet(); } /// @@ -44,7 +45,6 @@ namespace Jellyfin.Data.Entities.Libraries public virtual ICollection ChildCompanies { get; protected set; } /// - [NotMapped] public ICollection Companies => ChildCompanies; /// diff --git a/Jellyfin.Data/Entities/Libraries/CompanyMetadata.cs b/Jellyfin.Data/Entities/Libraries/CompanyMetadata.cs index 86642b38a..a29f08c7f 100644 --- a/Jellyfin.Data/Entities/Libraries/CompanyMetadata.cs +++ b/Jellyfin.Data/Entities/Libraries/CompanyMetadata.cs @@ -24,7 +24,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(65535)] [StringLength(65535)] - public string Description { get; set; } + public string? Description { get; set; } /// /// Gets or sets the headquarters. @@ -34,7 +34,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(255)] [StringLength(255)] - public string Headquarters { get; set; } + public string? Headquarters { get; set; } /// /// Gets or sets the country code. @@ -44,7 +44,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(2)] [StringLength(2)] - public string Country { get; set; } + public string? Country { get; set; } /// /// Gets or sets the homepage. @@ -54,6 +54,6 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Homepage { get; set; } + public string? Homepage { get; set; } } } diff --git a/Jellyfin.Data/Entities/Libraries/CustomItemMetadata.cs b/Jellyfin.Data/Entities/Libraries/CustomItemMetadata.cs index a69a8eafa..af2393870 100644 --- a/Jellyfin.Data/Entities/Libraries/CustomItemMetadata.cs +++ b/Jellyfin.Data/Entities/Libraries/CustomItemMetadata.cs @@ -1,5 +1,3 @@ -using System; - namespace Jellyfin.Data.Entities.Libraries { /// diff --git a/Jellyfin.Data/Entities/Libraries/EpisodeMetadata.cs b/Jellyfin.Data/Entities/Libraries/EpisodeMetadata.cs index 5662decdb..b0ef11e0f 100644 --- a/Jellyfin.Data/Entities/Libraries/EpisodeMetadata.cs +++ b/Jellyfin.Data/Entities/Libraries/EpisodeMetadata.cs @@ -24,7 +24,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Outline { get; set; } + public string? Outline { get; set; } /// /// Gets or sets the plot. @@ -34,7 +34,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(65535)] [StringLength(65535)] - public string Plot { get; set; } + public string? Plot { get; set; } /// /// Gets or sets the tagline. @@ -44,6 +44,6 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Tagline { get; set; } + public string? Tagline { get; set; } } } diff --git a/Jellyfin.Data/Entities/Libraries/Genre.cs b/Jellyfin.Data/Entities/Libraries/Genre.cs index befa75550..9f3d65028 100644 --- a/Jellyfin.Data/Entities/Libraries/Genre.cs +++ b/Jellyfin.Data/Entities/Libraries/Genre.cs @@ -33,7 +33,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Indexed, Required, Max length = 255. /// - [Required] [MaxLength(255)] [StringLength(255)] public string Name { get; set; } diff --git a/Jellyfin.Data/Entities/Libraries/ItemMetadata.cs b/Jellyfin.Data/Entities/Libraries/ItemMetadata.cs index a0efa66e4..d12e011a8 100644 --- a/Jellyfin.Data/Entities/Libraries/ItemMetadata.cs +++ b/Jellyfin.Data/Entities/Libraries/ItemMetadata.cs @@ -57,7 +57,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required, Max length = 1024. /// - [Required] [MaxLength(1024)] [StringLength(1024)] public string Title { get; set; } @@ -70,7 +69,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string OriginalTitle { get; set; } + public string? OriginalTitle { get; set; } /// /// Gets or sets the sort title. @@ -80,7 +79,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string SortTitle { get; set; } + public string? SortTitle { get; set; } /// /// Gets or sets the language. @@ -89,7 +88,6 @@ namespace Jellyfin.Data.Entities.Libraries /// Required, Min length = 3, Max length = 3. /// ISO-639-3 3-character language codes. /// - [Required] [MinLength(3)] [MaxLength(3)] [StringLength(3)] diff --git a/Jellyfin.Data/Entities/Libraries/Library.cs b/Jellyfin.Data/Entities/Libraries/Library.cs index 3ec4341a4..e45384902 100644 --- a/Jellyfin.Data/Entities/Libraries/Library.cs +++ b/Jellyfin.Data/Entities/Libraries/Library.cs @@ -1,4 +1,3 @@ -using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Jellyfin.Data.Interfaces; @@ -14,14 +13,11 @@ namespace Jellyfin.Data.Entities.Libraries /// Initializes a new instance of the class. /// /// The name of the library. - public Library(string name) + /// The path of the library. + public Library(string name, string path) { - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentNullException(nameof(name)); - } - Name = name; + Path = path; } /// @@ -39,7 +35,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required, Max length = 128. /// - [Required] [MaxLength(128)] [StringLength(128)] public string Name { get; set; } @@ -50,7 +45,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required. /// - [Required] public string Path { get; set; } /// diff --git a/Jellyfin.Data/Entities/Libraries/LibraryItem.cs b/Jellyfin.Data/Entities/Libraries/LibraryItem.cs index 504b9c853..67ffad944 100644 --- a/Jellyfin.Data/Entities/Libraries/LibraryItem.cs +++ b/Jellyfin.Data/Entities/Libraries/LibraryItem.cs @@ -44,7 +44,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required. /// - [Required] public virtual Library Library { get; set; } /// diff --git a/Jellyfin.Data/Entities/Libraries/MediaFile.cs b/Jellyfin.Data/Entities/Libraries/MediaFile.cs index 7f64978e2..f3e2fe653 100644 --- a/Jellyfin.Data/Entities/Libraries/MediaFile.cs +++ b/Jellyfin.Data/Entities/Libraries/MediaFile.cs @@ -47,7 +47,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required, Max length = 65535. /// - [Required] [MaxLength(65535)] [StringLength(65535)] public string Path { get; set; } diff --git a/Jellyfin.Data/Entities/Libraries/MetadataProvider.cs b/Jellyfin.Data/Entities/Libraries/MetadataProvider.cs index 20de5bf4b..fb2587882 100644 --- a/Jellyfin.Data/Entities/Libraries/MetadataProvider.cs +++ b/Jellyfin.Data/Entities/Libraries/MetadataProvider.cs @@ -39,7 +39,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required, Max length = 1024. /// - [Required] [MaxLength(1024)] [StringLength(1024)] public string Name { get; set; } diff --git a/Jellyfin.Data/Entities/Libraries/MetadataProviderId.cs b/Jellyfin.Data/Entities/Libraries/MetadataProviderId.cs index 12672dd25..2a9c904c8 100644 --- a/Jellyfin.Data/Entities/Libraries/MetadataProviderId.cs +++ b/Jellyfin.Data/Entities/Libraries/MetadataProviderId.cs @@ -14,7 +14,8 @@ namespace Jellyfin.Data.Entities.Libraries /// Initializes a new instance of the class. /// /// The provider id. - public MetadataProviderId(string providerId) + /// The metadata provider. + public MetadataProviderId(string providerId, MetadataProvider metadataProvider) { if (string.IsNullOrEmpty(providerId)) { @@ -22,6 +23,7 @@ namespace Jellyfin.Data.Entities.Libraries } ProviderId = providerId; + MetadataProvider = metadataProvider; } /// @@ -39,7 +41,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required, Max length = 255. /// - [Required] [MaxLength(255)] [StringLength(255)] public string ProviderId { get; set; } diff --git a/Jellyfin.Data/Entities/Libraries/MovieMetadata.cs b/Jellyfin.Data/Entities/Libraries/MovieMetadata.cs index 8cf7ca6a7..fb181dea6 100644 --- a/Jellyfin.Data/Entities/Libraries/MovieMetadata.cs +++ b/Jellyfin.Data/Entities/Libraries/MovieMetadata.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; using Jellyfin.Data.Interfaces; namespace Jellyfin.Data.Entities.Libraries @@ -30,7 +29,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Outline { get; set; } + public string? Outline { get; set; } /// /// Gets or sets the tagline. @@ -40,7 +39,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Tagline { get; set; } + public string? Tagline { get; set; } /// /// Gets or sets the plot. @@ -50,7 +49,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(65535)] [StringLength(65535)] - public string Plot { get; set; } + public string? Plot { get; set; } /// /// Gets or sets the country code. @@ -60,7 +59,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(2)] [StringLength(2)] - public string Country { get; set; } + public string? Country { get; set; } /// /// Gets or sets the studios that produced this movie. @@ -68,7 +67,6 @@ namespace Jellyfin.Data.Entities.Libraries public virtual ICollection Studios { get; protected set; } /// - [NotMapped] public ICollection Companies => Studios; } } diff --git a/Jellyfin.Data/Entities/Libraries/MusicAlbumMetadata.cs b/Jellyfin.Data/Entities/Libraries/MusicAlbumMetadata.cs index 9e44e550a..3080bd692 100644 --- a/Jellyfin.Data/Entities/Libraries/MusicAlbumMetadata.cs +++ b/Jellyfin.Data/Entities/Libraries/MusicAlbumMetadata.cs @@ -28,7 +28,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(255)] [StringLength(255)] - public string Barcode { get; set; } + public string? Barcode { get; set; } /// /// Gets or sets the label number. @@ -38,7 +38,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(255)] [StringLength(255)] - public string LabelNumber { get; set; } + public string? LabelNumber { get; set; } /// /// Gets or sets the country code. @@ -48,7 +48,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(2)] [StringLength(2)] - public string Country { get; set; } + public string? Country { get; set; } /// /// Gets or sets a collection containing the labels. diff --git a/Jellyfin.Data/Entities/Libraries/Person.cs b/Jellyfin.Data/Entities/Libraries/Person.cs index cc4b9e0f9..159bd47be 100644 --- a/Jellyfin.Data/Entities/Libraries/Person.cs +++ b/Jellyfin.Data/Entities/Libraries/Person.cs @@ -46,7 +46,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required, Max length = 1024. /// - [Required] [MaxLength(1024)] [StringLength(1024)] public string Name { get; set; } @@ -59,7 +58,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(256)] [StringLength(256)] - public string SourceId { get; set; } + public string? SourceId { get; set; } /// /// Gets or sets the date added. diff --git a/Jellyfin.Data/Entities/Libraries/PersonRole.cs b/Jellyfin.Data/Entities/Libraries/PersonRole.cs index 3ae2e4a68..988aa84ba 100644 --- a/Jellyfin.Data/Entities/Libraries/PersonRole.cs +++ b/Jellyfin.Data/Entities/Libraries/PersonRole.cs @@ -17,9 +17,12 @@ namespace Jellyfin.Data.Entities.Libraries /// Initializes a new instance of the class. /// /// The role type. - public PersonRole(PersonRoleType type) + /// The person. + public PersonRole(PersonRoleType type, Person person) { Type = type; + Person = person; + Artwork = new HashSet(); Sources = new HashSet(); } @@ -40,7 +43,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Role { get; set; } + public string? Role { get; set; } /// /// Gets or sets the person's role type. @@ -60,7 +63,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required. /// - [Required] public virtual Person Person { get; set; } /// diff --git a/Jellyfin.Data/Entities/Libraries/Rating.cs b/Jellyfin.Data/Entities/Libraries/Rating.cs index 0ea933fd7..6862012a8 100644 --- a/Jellyfin.Data/Entities/Libraries/Rating.cs +++ b/Jellyfin.Data/Entities/Libraries/Rating.cs @@ -48,7 +48,7 @@ namespace Jellyfin.Data.Entities.Libraries /// Gets or sets the rating type. /// If this is null it's the internal user rating. /// - public virtual RatingSource RatingType { get; set; } + public virtual RatingSource? RatingType { get; set; } /// public void OnSavingChanges() diff --git a/Jellyfin.Data/Entities/Libraries/RatingSource.cs b/Jellyfin.Data/Entities/Libraries/RatingSource.cs index 7e1a5a8f4..ae0d806ff 100644 --- a/Jellyfin.Data/Entities/Libraries/RatingSource.cs +++ b/Jellyfin.Data/Entities/Libraries/RatingSource.cs @@ -37,7 +37,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Name { get; set; } + public string? Name { get; set; } /// /// Gets or sets the minimum value. @@ -62,7 +62,7 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Gets or sets the metadata source. /// - public virtual MetadataProviderId Source { get; set; } + public virtual MetadataProviderId? Source { get; set; } /// public void OnSavingChanges() diff --git a/Jellyfin.Data/Entities/Libraries/Release.cs b/Jellyfin.Data/Entities/Libraries/Release.cs index 1871e0f10..21d403979 100644 --- a/Jellyfin.Data/Entities/Libraries/Release.cs +++ b/Jellyfin.Data/Entities/Libraries/Release.cs @@ -45,7 +45,6 @@ namespace Jellyfin.Data.Entities.Libraries /// /// Required, Max length = 1024. /// - [Required] [MaxLength(1024)] [StringLength(1024)] public string Name { get; set; } diff --git a/Jellyfin.Data/Entities/Libraries/SeasonMetadata.cs b/Jellyfin.Data/Entities/Libraries/SeasonMetadata.cs index 61714f909..da40a075f 100644 --- a/Jellyfin.Data/Entities/Libraries/SeasonMetadata.cs +++ b/Jellyfin.Data/Entities/Libraries/SeasonMetadata.cs @@ -24,6 +24,6 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Outline { get; set; } + public string? Outline { get; set; } } } diff --git a/Jellyfin.Data/Entities/Libraries/SeriesMetadata.cs b/Jellyfin.Data/Entities/Libraries/SeriesMetadata.cs index e1acd2d45..730deccae 100644 --- a/Jellyfin.Data/Entities/Libraries/SeriesMetadata.cs +++ b/Jellyfin.Data/Entities/Libraries/SeriesMetadata.cs @@ -30,7 +30,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Outline { get; set; } + public string? Outline { get; set; } /// /// Gets or sets the plot. @@ -40,7 +40,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(65535)] [StringLength(65535)] - public string Plot { get; set; } + public string? Plot { get; set; } /// /// Gets or sets the tagline. @@ -50,7 +50,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(1024)] [StringLength(1024)] - public string Tagline { get; set; } + public string? Tagline { get; set; } /// /// Gets or sets the country code. @@ -60,7 +60,7 @@ namespace Jellyfin.Data.Entities.Libraries /// [MaxLength(2)] [StringLength(2)] - public string Country { get; set; } + public string? Country { get; set; } /// /// Gets or sets a collection containing the networks. @@ -68,7 +68,6 @@ namespace Jellyfin.Data.Entities.Libraries public virtual ICollection Networks { get; protected set; } /// - [NotMapped] public ICollection Companies => Networks; } } diff --git a/Jellyfin.Data/Entities/Preference.cs b/Jellyfin.Data/Entities/Preference.cs index 40f2f8ede..a8813ab88 100644 --- a/Jellyfin.Data/Entities/Preference.cs +++ b/Jellyfin.Data/Entities/Preference.cs @@ -46,7 +46,6 @@ namespace Jellyfin.Data.Entities /// /// Required, Max length = 65535. /// - [Required] [MaxLength(65535)] [StringLength(65535)] public string Value { get; set; } diff --git a/Jellyfin.Data/Entities/User.cs b/Jellyfin.Data/Entities/User.cs index 28e12adde..9aa809164 100644 --- a/Jellyfin.Data/Entities/User.cs +++ b/Jellyfin.Data/Entities/User.cs @@ -51,6 +51,7 @@ namespace Jellyfin.Data.Entities PasswordResetProviderId = passwordResetProviderId; AccessSchedules = new HashSet(); + DisplayPreferences = new HashSet(); ItemDisplayPreferences = new HashSet(); // Groups = new HashSet(); Permissions = new HashSet(); @@ -92,7 +93,6 @@ namespace Jellyfin.Data.Entities /// /// Required, Max length = 255. /// - [Required] [MaxLength(255)] [StringLength(255)] public string Username { get; set; } @@ -105,7 +105,7 @@ namespace Jellyfin.Data.Entities /// [MaxLength(65535)] [StringLength(65535)] - public string Password { get; set; } + public string? Password { get; set; } /// /// Gets or sets the user's easy password, or null if none is set. @@ -115,7 +115,7 @@ namespace Jellyfin.Data.Entities /// [MaxLength(65535)] [StringLength(65535)] - public string EasyPassword { get; set; } + public string? EasyPassword { get; set; } /// /// Gets or sets a value indicating whether the user must update their password. @@ -133,7 +133,7 @@ namespace Jellyfin.Data.Entities /// [MaxLength(255)] [StringLength(255)] - public string AudioLanguagePreference { get; set; } + public string? AudioLanguagePreference { get; set; } /// /// Gets or sets the authentication provider id. @@ -141,7 +141,6 @@ namespace Jellyfin.Data.Entities /// /// Required, Max length = 255. /// - [Required] [MaxLength(255)] [StringLength(255)] public string AuthenticationProviderId { get; set; } @@ -152,7 +151,6 @@ namespace Jellyfin.Data.Entities /// /// Required, Max length = 255. /// - [Required] [MaxLength(255)] [StringLength(255)] public string PasswordResetProviderId { get; set; } @@ -209,7 +207,7 @@ namespace Jellyfin.Data.Entities /// [MaxLength(255)] [StringLength(255)] - public string SubtitleLanguagePreference { get; set; } + public string? SubtitleLanguagePreference { get; set; } /// /// Gets or sets a value indicating whether missing episodes should be displayed. @@ -304,7 +302,7 @@ namespace Jellyfin.Data.Entities /// Gets or sets the user's profile image. Can be null. /// // [ForeignKey("UserId")] - public virtual ImageInfo ProfileImage { get; set; } + public virtual ImageInfo? ProfileImage { get; set; } /// /// Gets or sets the user's display preferences. @@ -312,8 +310,7 @@ namespace Jellyfin.Data.Entities /// /// Required. /// - [Required] - public virtual DisplayPreferences DisplayPreferences { get; set; } + public virtual ICollection DisplayPreferences { get; set; } /// /// Gets or sets the level of sync play permissions this user has. diff --git a/Jellyfin.Data/Jellyfin.Data.csproj b/Jellyfin.Data/Jellyfin.Data.csproj index a8ac45645..a2b6f074e 100644 --- a/Jellyfin.Data/Jellyfin.Data.csproj +++ b/Jellyfin.Data/Jellyfin.Data.csproj @@ -5,6 +5,7 @@ false true true + enable true true true diff --git a/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs b/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs index 0340248bb..aa6015caa 100644 --- a/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs +++ b/Jellyfin.Server.Implementations/Events/Consumers/Session/PlaybackStartLogger.cs @@ -86,7 +86,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Session return name; } - private static string? GetPlaybackNotificationType(string mediaType) + private static string GetPlaybackNotificationType(string mediaType) { if (string.Equals(mediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)) { @@ -98,7 +98,7 @@ namespace Jellyfin.Server.Implementations.Events.Consumers.Session return NotificationType.VideoPlayback.ToString(); } - return null; + return "Playback"; } } } diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 76d1389ca..b400a0dd1 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -184,8 +184,8 @@ namespace Jellyfin.Server.Implementations.Users var user = new User( name, - _defaultAuthenticationProvider.GetType().FullName, - _defaultPasswordResetProvider.GetType().FullName) + _defaultAuthenticationProvider.GetType().FullName!, + _defaultPasswordResetProvider.GetType().FullName!) { InternalId = max + 1 }; @@ -444,7 +444,7 @@ namespace Jellyfin.Server.Implementations.Users { var providerId = authenticationProvider.GetType().FullName; - if (!string.Equals(providerId, user.AuthenticationProviderId, StringComparison.OrdinalIgnoreCase)) + if (providerId != null && !string.Equals(providerId, user.AuthenticationProviderId, StringComparison.OrdinalIgnoreCase)) { user.AuthenticationProviderId = providerId; await UpdateUserAsync(user).ConfigureAwait(false); diff --git a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs index 33f039c39..6d318d232 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs @@ -1,7 +1,5 @@ using System; -using System.Globalization; using System.IO; -using System.Linq; using Emby.Server.Implementations.Data; using Emby.Server.Implementations.Serialization; using Jellyfin.Data.Entities; @@ -104,7 +102,7 @@ namespace Jellyfin.Server.Migrations.Routines _ => policy.LoginAttemptsBeforeLockout }; - var user = new User(mockup.Name, policy.AuthenticationProviderId, policy.PasswordResetProviderId) + var user = new User(mockup.Name, policy.AuthenticationProviderId!, policy.PasswordResetProviderId!) { Id = entry[1].ReadGuidFromBlob(), InternalId = entry[0].ToInt64(), diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs index 935a79031..142cebd0c 100644 --- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -61,7 +61,7 @@ namespace MediaBrowser.Controller.Drawing string GetImageCacheTag(BaseItem item, ChapterInfo info); - string GetImageCacheTag(User user); + string? GetImageCacheTag(User user); /// /// Processes the image. diff --git a/tests/Jellyfin.Api.Tests/TestHelpers.cs b/tests/Jellyfin.Api.Tests/TestHelpers.cs index f27cdf7b6..c1549561d 100644 --- a/tests/Jellyfin.Api.Tests/TestHelpers.cs +++ b/tests/Jellyfin.Api.Tests/TestHelpers.cs @@ -26,8 +26,8 @@ namespace Jellyfin.Api.Tests { var user = new User( "jellyfin", - typeof(DefaultAuthenticationProvider).FullName, - typeof(DefaultPasswordResetProvider).FullName); + typeof(DefaultAuthenticationProvider).FullName!, + typeof(DefaultPasswordResetProvider).FullName!); // Set administrator flag. user.SetPermission(PermissionKind.IsAdministrator, role.Equals(UserRoles.Administrator, StringComparison.OrdinalIgnoreCase)); -- cgit v1.2.3 From 12b8e29aefad3ad202769cdab9c6afc17c5687d9 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Wed, 17 Mar 2021 17:42:45 -0400 Subject: Fix duplicate permissions --- Jellyfin.Data/Entities/User.cs | 33 ++++++++++++---------- .../Users/UserManager.cs | 3 ++ 2 files changed, 21 insertions(+), 15 deletions(-) (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Jellyfin.Data/Entities/User.cs b/Jellyfin.Data/Entities/User.cs index 9aa809164..74331726c 100644 --- a/Jellyfin.Data/Entities/User.cs +++ b/Jellyfin.Data/Entities/User.cs @@ -73,9 +73,6 @@ namespace Jellyfin.Data.Entities PlayDefaultAudioTrack = true; SubtitleMode = SubtitlePlaybackMode.Default; SyncPlayAccess = SyncPlayUserAccessType.CreateAndJoinGroups; - - AddDefaultPermissions(); - AddDefaultPreferences(); } /// @@ -483,18 +480,11 @@ namespace Jellyfin.Data.Entities return Array.IndexOf(GetPreferenceValues(PreferenceKind.GroupedFolders), id) != -1; } - private static bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date) - { - var localTime = date.ToLocalTime(); - var hour = localTime.TimeOfDay.TotalHours; - - return DayOfWeekHelper.GetDaysOfWeek(schedule.DayOfWeek).Contains(localTime.DayOfWeek) - && hour >= schedule.StartHour - && hour <= schedule.EndHour; - } - + /// + /// Initializes the default permissions for a user. Should only be called on user creation. + /// // TODO: make these user configurable? - private void AddDefaultPermissions() + public void AddDefaultPermissions() { Permissions.Add(new Permission(PermissionKind.IsAdministrator, false)); Permissions.Add(new Permission(PermissionKind.IsDisabled, false)); @@ -519,12 +509,25 @@ namespace Jellyfin.Data.Entities Permissions.Add(new Permission(PermissionKind.EnableRemoteControlOfOtherUsers, false)); } - private void AddDefaultPreferences() + /// + /// Initializes the default preferences. Should only be called on user creation. + /// + public void AddDefaultPreferences() { foreach (var val in Enum.GetValues(typeof(PreferenceKind)).Cast()) { Preferences.Add(new Preference(val, string.Empty)); } } + + private static bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date) + { + var localTime = date.ToLocalTime(); + var hour = localTime.TimeOfDay.TotalHours; + + return DayOfWeekHelper.GetDaysOfWeek(schedule.DayOfWeek).Contains(localTime.DayOfWeek) + && hour >= schedule.StartHour + && hour <= schedule.EndHour; + } } } diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index b400a0dd1..50d7612f2 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -190,6 +190,9 @@ namespace Jellyfin.Server.Implementations.Users InternalId = max + 1 }; + user.AddDefaultPermissions(); + user.AddDefaultPreferences(); + _users.Add(user.Id, user); return user; -- cgit v1.2.3 From a7b29e2fe0bb08f4b8f37fa5aac7af66c7cb00e8 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Thu, 25 Mar 2021 19:48:30 -0400 Subject: Clean up user renaming --- Jellyfin.Server.Implementations/Users/UserManager.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 50d7612f2..f9a1a8ee9 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -144,7 +144,13 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentException("The new and old names must be different."); } - if (Users.Any(u => u.Id != user.Id && u.Username.Equals(newName, StringComparison.OrdinalIgnoreCase))) + await using var dbContext = _dbProvider.CreateContext(); + + if (await dbContext.Users + .AsQueryable() + .Where(u => u.Username == newName && u.Id != user.Id) + .AnyAsync() + .ConfigureAwait(false)) { throw new ArgumentException(string.Format( CultureInfo.InvariantCulture, -- cgit v1.2.3 From 7364155579c52e5019cdcb71edc03546babe3fb3 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Thu, 25 Mar 2021 19:49:52 -0400 Subject: Clean up user deletion --- Jellyfin.Server.Implementations/Users/UserManager.cs | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'Jellyfin.Server.Implementations/Users/UserManager.cs') diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index f9a1a8ee9..b6b45e69b 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -257,16 +257,6 @@ namespace Jellyfin.Server.Implementations.Users } await using var dbContext = _dbProvider.CreateContext(); - - // Clear all entities related to the user from the database. - if (user.ProfileImage != null) - { - dbContext.Remove(user.ProfileImage); - } - - dbContext.RemoveRange(user.Permissions); - dbContext.RemoveRange(user.Preferences); - dbContext.RemoveRange(user.AccessSchedules); dbContext.Users.Remove(user); await dbContext.SaveChangesAsync().ConfigureAwait(false); _users.Remove(userId); -- cgit v1.2.3