diff options
| author | m0g3r <87276771+m0g3r@users.noreply.github.com> | 2026-08-18 18:16:48 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-18 18:16:48 +0200 |
| commit | 46be43ad245d8f01026bf08f7d3a57c8c726a826 (patch) | |
| tree | 97113344faba948e8638100b5615798ce37da4ad | |
| parent | 3fe35fcbc1f7d2677e9c8d7be324db0d6f2a1f63 (diff) | |
Prevent orphaned user permissions and preferences (#17643)
Prevent orphaned user permissions and preferences
| -rw-r--r-- | CONTRIBUTORS.md | 1 | ||||
| -rw-r--r-- | Jellyfin.Server.Implementations/Users/UserManager.cs | 2 | ||||
| -rw-r--r-- | tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerProfileImageTests.cs | 23 |
3 files changed, 26 insertions, 0 deletions
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index f6a725853d..b3bd573215 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -238,6 +238,7 @@ - [elio42](https://github.com/elio42) - [rwebster85](https://github.com/rwebster85) - [Florin-Popescu](https://github.com/Florin-Popescu) + - [m0g3r](https://github.com/m0g3r) - [martin-77](https://github.com/martin-77) # Emby Contributors diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 81408d9aa8..932ced547a 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -225,12 +225,14 @@ namespace Jellyfin.Server.Implementations.Users ?? throw new ResourceNotFoundException(nameof(user.Id)); dbContext.Entry(dbUser).CurrentValues.SetValues(user); + dbContext.Permissions.RemoveRange(dbUser.Permissions); dbUser.Permissions.Clear(); foreach (var permission in user.Permissions) { dbUser.Permissions.Add(new Permission(permission.Kind, permission.Value)); } + dbContext.Preferences.RemoveRange(dbUser.Preferences); dbUser.Preferences.Clear(); foreach (var preference in user.Preferences) { diff --git a/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerProfileImageTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerProfileImageTests.cs index cb714a4014..778b888735 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerProfileImageTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerProfileImageTests.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Jellyfin.Database.Implementations; @@ -92,6 +93,28 @@ namespace Jellyfin.Server.Implementations.Tests.Users } [Fact] + public async Task UpdateUserAsync_DoesNotLeaveOrphanedPermissionsOrPreferences() + { + var user = await _userManager.CreateUserAsync("updateduser"); + var permissionCount = user.Permissions.Count; + var preferenceCount = user.Preferences.Count; + + user.LastActivityDate = DateTime.UtcNow; + await _userManager.UpdateUserAsync(user); + await _userManager.UpdateUserAsync(user); + + await using var context = CreateDbContext(); + Assert.Empty(await context.Permissions + .Where(permission => !permission.UserId.HasValue) + .ToListAsync(TestContext.Current.CancellationToken)); + Assert.Empty(await context.Preferences + .Where(preference => !preference.UserId.HasValue) + .ToListAsync(TestContext.Current.CancellationToken)); + Assert.Equal(permissionCount, await context.Permissions.CountAsync(TestContext.Current.CancellationToken)); + Assert.Equal(preferenceCount, await context.Preferences.CountAsync(TestContext.Current.CancellationToken)); + } + + [Fact] public async Task ClearProfileImageAsync_WhenInMemoryImageHasTemporaryKey_RemovesPersistedImage() { var user = await _userManager.CreateUserAsync("profileimageuser"); |
