Prevent orphaned user permissions and preferences (#17643)

Prevent orphaned user permissions and preferences
This commit is contained in:
m0g3r
2026-08-18 18:16:48 +02:00
committed by GitHub
parent 3fe35fcbc1
commit 46be43ad24
3 changed files with 26 additions and 0 deletions
+1
View File
@@ -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
@@ -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)
{
@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Database.Implementations;
@@ -91,6 +92,28 @@ namespace Jellyfin.Server.Implementations.Tests.Users
new NoLockBehavior(NullLogger<NoLockBehavior>.Instance));
}
[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()
{