| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 | using System.Threading;using System.Threading.Tasks;using Jellyfin.Data.Entities;using Jellyfin.Data.Enums;using Jellyfin.Data.Events;using Jellyfin.Data.Queries;using MediaBrowser.Controller.Devices;using MediaBrowser.Controller.Library;using MediaBrowser.Controller.Session;using Microsoft.Extensions.Hosting;namespace Jellyfin.Server.Implementations.Users;/// <summary>/// <see cref="IHostedService"/> responsible for managing user device permissions./// </summary>public sealed class DeviceAccessHost : IHostedService{    private readonly IUserManager _userManager;    private readonly IDeviceManager _deviceManager;    private readonly ISessionManager _sessionManager;    /// <summary>    /// Initializes a new instance of the <see cref="DeviceAccessHost"/> class.    /// </summary>    /// <param name="userManager">The <see cref="IUserManager"/>.</param>    /// <param name="deviceManager">The <see cref="IDeviceManager"/>.</param>    /// <param name="sessionManager">The <see cref="ISessionManager"/>.</param>    public DeviceAccessHost(IUserManager userManager, IDeviceManager deviceManager, ISessionManager sessionManager)    {        _userManager = userManager;        _deviceManager = deviceManager;        _sessionManager = sessionManager;    }    /// <inheritdoc />    public Task StartAsync(CancellationToken cancellationToken)    {        _userManager.OnUserUpdated += OnUserUpdated;        return Task.CompletedTask;    }    /// <inheritdoc />    public Task StopAsync(CancellationToken cancellationToken)    {        _userManager.OnUserUpdated -= OnUserUpdated;        return Task.CompletedTask;    }    private async void OnUserUpdated(object? sender, GenericEventArgs<User> e)    {        var user = e.Argument;        if (!user.HasPermission(PermissionKind.EnableAllDevices))        {            await UpdateDeviceAccess(user).ConfigureAwait(false);        }    }    private async Task UpdateDeviceAccess(User user)    {        var existing = _deviceManager.GetDevices(new DeviceQuery        {            UserId = user.Id        }).Items;        foreach (var device in existing)        {            if (!string.IsNullOrEmpty(device.DeviceId) && !_deviceManager.CanAccessDevice(user, device.DeviceId))            {                await _sessionManager.Logout(device).ConfigureAwait(false);            }        }    }}
 |