From 75df6965a046967dca94912c9490fd4b4af9f0a6 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 13 Apr 2021 20:01:21 -0400 Subject: [PATCH] Don't use database for QuickConnect --- .../QuickConnect/QuickConnectManager.cs | 71 ++++++++----------- .../Session/SessionManager.cs | 18 ----- .../QuickConnect/IQuickConnect.cs | 8 +++ 3 files changed, 38 insertions(+), 59 deletions(-) diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs index 7bed06de36..9f639138a9 100644 --- a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs +++ b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs @@ -1,16 +1,15 @@ using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Security.Cryptography; -using MediaBrowser.Common; using MediaBrowser.Common.Extensions; -using MediaBrowser.Controller; using MediaBrowser.Controller.Authentication; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.QuickConnect; -using MediaBrowser.Controller.Security; +using MediaBrowser.Controller.Session; using MediaBrowser.Model.QuickConnect; using Microsoft.Extensions.Logging; @@ -21,36 +20,26 @@ namespace Emby.Server.Implementations.QuickConnect /// public class QuickConnectManager : IQuickConnect, IDisposable { - private readonly RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider(); - private readonly ConcurrentDictionary _currentRequests = new ConcurrentDictionary(); + private readonly RNGCryptoServiceProvider _rng = new (); + private readonly ConcurrentDictionary _currentRequests = new (); + private readonly ConcurrentDictionary _quickConnectTokens = new (); private readonly IServerConfigurationManager _config; private readonly ILogger _logger; - private readonly IAuthenticationRepository _authenticationRepository; - private readonly IAuthorizationContext _authContext; - private readonly IServerApplicationHost _appHost; + private readonly ISessionManager _sessionManager; /// /// Initializes a new instance of the class. /// Should only be called at server startup when a singleton is created. /// - /// Configuration. - /// Logger. - /// Application host. - /// Authentication context. - /// Authentication repository. - public QuickConnectManager( - IServerConfigurationManager config, - ILogger logger, - IServerApplicationHost appHost, - IAuthorizationContext authContext, - IAuthenticationRepository authenticationRepository) + /// The server configuration manager. + /// The logger. + /// The session manager. + public QuickConnectManager(IServerConfigurationManager config, ILogger logger, ISessionManager sessionManager) { _config = config; _logger = logger; - _appHost = appHost; - _authContext = authContext; - _authenticationRepository = authenticationRepository; + _sessionManager = sessionManager; ReloadConfiguration(); } @@ -138,6 +127,19 @@ namespace Emby.Server.Implementations.QuickConnect return result; } + public void AuthenticateRequest(AuthenticationRequest request, string token) + { + if (!_quickConnectTokens.TryGetValue(token, out var entry)) + { + throw new SecurityException("Unknown quick connect token"); + } + + request.UserId = entry.Item2; + _quickConnectTokens.Remove(token, out _); + + _sessionManager.AuthenticateQuickConnect(request, token); + } + /// public string GenerateCode() { @@ -179,16 +181,7 @@ namespace Emby.Server.Implementations.QuickConnect var added = result.DateAdded ?? DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(Timeout)); result.DateAdded = added.Subtract(TimeSpan.FromMinutes(Timeout - 1)); - _authenticationRepository.Create(new AuthenticationInfo - { - AppName = TokenName, - AccessToken = result.Authentication, - DateCreated = DateTime.UtcNow, - DeviceId = _appHost.SystemId, - DeviceName = _appHost.FriendlyName, - AppVersion = _appHost.ApplicationVersionString, - UserId = userId - }); + _quickConnectTokens[result.Authentication] = (TokenName, userId); _logger.LogDebug("Authorizing device with code {Code} to login as user {userId}", code, userId); @@ -198,19 +191,15 @@ namespace Emby.Server.Implementations.QuickConnect /// public int DeleteAllDevices(Guid user) { - var raw = _authenticationRepository.Get(new AuthenticationInfoQuery() - { - DeviceId = _appHost.SystemId, - UserId = user - }); - - var tokens = raw.Items.Where(x => x.AppName.StartsWith(TokenName, StringComparison.Ordinal)); + var tokens = _quickConnectTokens + .Where(entry => entry.Value.Item1.StartsWith(TokenName, StringComparison.Ordinal) && entry.Value.Item2 == user) + .ToList(); var removed = 0; foreach (var token in tokens) { - _authenticationRepository.Delete(token); - _logger.LogDebug("Deleted token {AccessToken}", token.AccessToken); + _quickConnectTokens.Remove(token.Key, out _); + _logger.LogDebug("Deleted token {AccessToken}", token.Key); removed++; } diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 50156d2b6f..99d2947f0e 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1441,24 +1441,6 @@ namespace Emby.Server.Implementations.Session public Task AuthenticateQuickConnect(AuthenticationRequest request, string token) { - var result = _authRepo.Get(new AuthenticationInfoQuery() - { - AccessToken = token, - DeviceId = _appHost.SystemId, - Limit = 1 - }); - - if (result.TotalRecordCount == 0) - { - throw new SecurityException("Unknown quick connect token"); - } - - var info = result.Items[0]; - request.UserId = info.UserId; - - // There's no need to keep the quick connect token in the database, as AuthenticateNewSessionInternal() issues a long lived token. - _authRepo.Delete(info); - return AuthenticateNewSessionInternal(request, false); } diff --git a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs index 959a2d7712..ce8999e490 100644 --- a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs +++ b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs @@ -1,4 +1,5 @@ using System; +using MediaBrowser.Controller.Session; using MediaBrowser.Model.QuickConnect; namespace MediaBrowser.Controller.QuickConnect @@ -57,6 +58,13 @@ namespace MediaBrowser.Controller.QuickConnect /// Quick connect result. QuickConnectResult CheckRequestStatus(string secret); + /// + /// Authenticates a QuickConnect request. + /// + /// The request. + /// The token. + void AuthenticateRequest(AuthenticationRequest request, string token); + /// /// Authorizes a quick connect request to connect as the calling user. ///