DeviceManager.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #nullable disable
  2. #pragma warning disable CS1591
  3. using System;
  4. using System.Collections.Concurrent;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using Jellyfin.Data.Entities;
  8. using Jellyfin.Data.Enums;
  9. using Jellyfin.Data.Events;
  10. using MediaBrowser.Controller.Devices;
  11. using MediaBrowser.Controller.Library;
  12. using MediaBrowser.Controller.Security;
  13. using MediaBrowser.Model.Devices;
  14. using MediaBrowser.Model.Querying;
  15. using MediaBrowser.Model.Session;
  16. namespace Emby.Server.Implementations.Devices
  17. {
  18. public class DeviceManager : IDeviceManager
  19. {
  20. private readonly IUserManager _userManager;
  21. private readonly IAuthenticationRepository _authRepo;
  22. private readonly ConcurrentDictionary<string, ClientCapabilities> _capabilitiesMap = new ();
  23. public DeviceManager(IAuthenticationRepository authRepo, IUserManager userManager)
  24. {
  25. _userManager = userManager;
  26. _authRepo = authRepo;
  27. }
  28. public event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
  29. public void SaveCapabilities(string deviceId, ClientCapabilities capabilities)
  30. {
  31. _capabilitiesMap[deviceId] = capabilities;
  32. }
  33. public void UpdateDeviceOptions(string deviceId, DeviceOptions options)
  34. {
  35. _authRepo.UpdateDeviceOptions(deviceId, options);
  36. DeviceOptionsUpdated?.Invoke(this, new GenericEventArgs<Tuple<string, DeviceOptions>>(new Tuple<string, DeviceOptions>(deviceId, options)));
  37. }
  38. public DeviceOptions GetDeviceOptions(string deviceId)
  39. {
  40. return _authRepo.GetDeviceOptions(deviceId);
  41. }
  42. public ClientCapabilities GetCapabilities(string id)
  43. {
  44. return _capabilitiesMap.TryGetValue(id, out ClientCapabilities result)
  45. ? result
  46. : new ClientCapabilities();
  47. }
  48. public DeviceInfo GetDevice(string id)
  49. {
  50. var session = _authRepo.Get(new AuthenticationInfoQuery
  51. {
  52. DeviceId = id
  53. }).Items.FirstOrDefault();
  54. var device = session == null ? null : ToDeviceInfo(session);
  55. return device;
  56. }
  57. public QueryResult<DeviceInfo> GetDevices(DeviceQuery query)
  58. {
  59. IEnumerable<AuthenticationInfo> sessions = _authRepo.Get(new AuthenticationInfoQuery
  60. {
  61. // UserId = query.UserId
  62. HasUser = true
  63. }).Items;
  64. // TODO: DeviceQuery doesn't seem to be used from client. Not even Swagger.
  65. if (query.SupportsSync.HasValue)
  66. {
  67. var val = query.SupportsSync.Value;
  68. sessions = sessions.Where(i => GetCapabilities(i.DeviceId).SupportsSync == val);
  69. }
  70. if (!query.UserId.Equals(Guid.Empty))
  71. {
  72. var user = _userManager.GetUserById(query.UserId);
  73. sessions = sessions.Where(i => CanAccessDevice(user, i.DeviceId));
  74. }
  75. var array = sessions.Select(ToDeviceInfo).ToArray();
  76. return new QueryResult<DeviceInfo>(array);
  77. }
  78. private DeviceInfo ToDeviceInfo(AuthenticationInfo authInfo)
  79. {
  80. var caps = GetCapabilities(authInfo.DeviceId);
  81. return new DeviceInfo
  82. {
  83. AppName = authInfo.AppName,
  84. AppVersion = authInfo.AppVersion,
  85. Id = authInfo.DeviceId,
  86. LastUserId = authInfo.UserId,
  87. LastUserName = authInfo.UserName,
  88. Name = authInfo.DeviceName,
  89. DateLastActivity = authInfo.DateLastActivity,
  90. IconUrl = caps?.IconUrl
  91. };
  92. }
  93. public bool CanAccessDevice(User user, string deviceId)
  94. {
  95. if (user == null)
  96. {
  97. throw new ArgumentException("user not found");
  98. }
  99. if (string.IsNullOrEmpty(deviceId))
  100. {
  101. throw new ArgumentNullException(nameof(deviceId));
  102. }
  103. if (user.HasPermission(PermissionKind.EnableAllDevices) || user.HasPermission(PermissionKind.IsAdministrator))
  104. {
  105. return true;
  106. }
  107. if (!user.GetPreference(PreferenceKind.EnabledDevices).Contains(deviceId, StringComparer.OrdinalIgnoreCase))
  108. {
  109. var capabilities = GetCapabilities(deviceId);
  110. if (capabilities != null && capabilities.SupportsPersistentIdentifier)
  111. {
  112. return false;
  113. }
  114. }
  115. return true;
  116. }
  117. }
  118. }