diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 55e4856692..6a8ad2bdc5 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1858,15 +1858,38 @@ namespace Emby.Server.Implementations.Session Guid userId, string deviceId, int? activeWithinSeconds, - Guid? controllableUserToCheck) + Guid? controllableUserToCheck, + bool isApiKey) { var result = Sessions; - var user = _userManager.GetUserById(userId); if (!string.IsNullOrEmpty(deviceId)) { result = result.Where(i => string.Equals(i.DeviceId, deviceId, StringComparison.OrdinalIgnoreCase)); } + var userCanControlOthers = false; + var userIsAdmin = false; + User user = null; + + if (isApiKey) + { + userCanControlOthers = true; + userIsAdmin = true; + } + else if (!userId.IsEmpty()) + { + user = _userManager.GetUserById(userId); + if (user is not null) + { + userCanControlOthers = user.HasPermission(PermissionKind.EnableRemoteControlOfOtherUsers); + userIsAdmin = user.HasPermission(PermissionKind.IsAdministrator); + } + else + { + return []; + } + } + if (!controllableUserToCheck.IsNullOrEmpty()) { result = result.Where(i => i.SupportsRemoteControl); @@ -1883,29 +1906,34 @@ namespace Emby.Server.Implementations.Session result = result.Where(i => !i.UserId.IsEmpty()); } - if (!user.HasPermission(PermissionKind.EnableRemoteControlOfOtherUsers)) + if (!userCanControlOthers) { // User cannot control other user's sessions, validate user id. - result = result.Where(i => i.UserId.IsEmpty() || i.ContainsUser(user.Id)); + result = result.Where(i => i.UserId.IsEmpty() || i.ContainsUser(userId)); } result = result.Where(i => { - if (!string.IsNullOrWhiteSpace(i.DeviceId) && !_deviceManager.CanAccessDevice(user, i.DeviceId)) + if (isApiKey) + { + return true; + } + + if (user is null) { return false; } - return true; + return string.IsNullOrWhiteSpace(i.DeviceId) || _deviceManager.CanAccessDevice(user, i.DeviceId); }); } - else if (!user.HasPermission(PermissionKind.IsAdministrator)) + else if (!userIsAdmin) { // Request isn't from administrator, limit to "own" sessions. result = result.Where(i => i.UserId.IsEmpty() || i.ContainsUser(userId)); } - if (!user.HasPermission(PermissionKind.IsAdministrator)) + if (!userIsAdmin) { // Don't report acceleration type for non-admin users. result = result.Select(r => diff --git a/Jellyfin.Api/Controllers/SessionController.cs b/Jellyfin.Api/Controllers/SessionController.cs index 72eb93eff2..2f9e9f091d 100644 --- a/Jellyfin.Api/Controllers/SessionController.cs +++ b/Jellyfin.Api/Controllers/SessionController.cs @@ -62,7 +62,8 @@ public class SessionController : BaseJellyfinApiController User.GetUserId(), deviceId, activeWithinSeconds, - controllableUserToCheck); + controllableUserToCheck, + User.GetIsApiKey()); return Ok(result); } diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index f2e98dd787..462a624553 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -300,8 +300,9 @@ namespace MediaBrowser.Controller.Session /// The device id. /// Active within session limit. /// Filter for sessions remote controllable for this user. + /// Is the request authenticated with API key. /// IReadOnlyList{SessionInfoDto}. - IReadOnlyList GetSessions(Guid userId, string deviceId, int? activeWithinSeconds, Guid? controllableUserToCheck); + IReadOnlyList GetSessions(Guid userId, string deviceId, int? activeWithinSeconds, Guid? controllableUserToCheck, bool isApiKey); /// /// Gets the session by authentication token.