fix(devices): read devices and device options through to the database
The device cache was filled once at construction, so a token minted by one replica was unknown to every other replica already running and a token revoked on one replica stayed valid on the others until they restarted. - drop the eager device and device options dictionaries - read devices and device options from the database on every query - push the device query filters and ordering into SQL - open the request's database context only for the api key fallback - cover both directions against real PostgreSQL with two manager instances
This commit is contained in:
@@ -256,7 +256,7 @@ namespace Emby.Server.Implementations.Session
|
||||
ArgumentException.ThrowIfNullOrEmpty(deviceId);
|
||||
|
||||
var activityDate = DateTime.UtcNow;
|
||||
var session = GetSessionInfo(appName, appVersion, deviceId, deviceName, remoteEndPoint, user);
|
||||
var session = await GetSessionInfo(appName, appVersion, deviceId, deviceName, remoteEndPoint, user).ConfigureAwait(false);
|
||||
var lastActivityDate = session.LastActivityDate;
|
||||
session.LastActivityDate = activityDate;
|
||||
|
||||
@@ -491,7 +491,7 @@ namespace Emby.Server.Implementations.Session
|
||||
/// <param name="remoteEndPoint">The remote end point.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>SessionInfo.</returns>
|
||||
private SessionInfo GetSessionInfo(
|
||||
private async Task<SessionInfo> GetSessionInfo(
|
||||
string appName,
|
||||
string appVersion,
|
||||
string deviceId,
|
||||
@@ -504,7 +504,7 @@ namespace Emby.Server.Implementations.Session
|
||||
ArgumentException.ThrowIfNullOrEmpty(deviceId);
|
||||
|
||||
var key = GetSessionKey(appName, deviceId, user?.Id ?? Guid.Empty);
|
||||
SessionInfo newSession = CreateSessionInfo(key, appName, appVersion, deviceId, deviceName, remoteEndPoint, user);
|
||||
SessionInfo newSession = await CreateSessionInfo(key, appName, appVersion, deviceId, deviceName, remoteEndPoint, user).ConfigureAwait(false);
|
||||
SessionInfo sessionInfo = _activeConnections.GetOrAdd(key, newSession);
|
||||
if (ReferenceEquals(newSession, sessionInfo))
|
||||
{
|
||||
@@ -532,7 +532,7 @@ namespace Emby.Server.Implementations.Session
|
||||
return sessionInfo;
|
||||
}
|
||||
|
||||
private SessionInfo CreateSessionInfo(
|
||||
private async Task<SessionInfo> CreateSessionInfo(
|
||||
string key,
|
||||
string appName,
|
||||
string appVersion,
|
||||
@@ -562,7 +562,7 @@ namespace Emby.Server.Implementations.Session
|
||||
deviceName = "Network Device";
|
||||
}
|
||||
|
||||
var deviceOptions = _deviceManager.GetDeviceOptions(deviceId) ?? new()
|
||||
var deviceOptions = await _deviceManager.GetDeviceOptions(deviceId).ConfigureAwait(false) ?? new()
|
||||
{
|
||||
DeviceId = deviceId
|
||||
};
|
||||
@@ -1768,12 +1768,12 @@ namespace Emby.Server.Implementations.Session
|
||||
// This should be validated above, but if it isn't don't delete all tokens.
|
||||
ArgumentException.ThrowIfNullOrEmpty(deviceId);
|
||||
|
||||
var existing = _deviceManager.GetDevices(
|
||||
var existing = (await _deviceManager.GetDevices(
|
||||
new DeviceQuery
|
||||
{
|
||||
DeviceId = deviceId,
|
||||
UserId = user.Id
|
||||
}).Items;
|
||||
}).ConfigureAwait(false)).Items;
|
||||
|
||||
foreach (var auth in existing)
|
||||
{
|
||||
@@ -1801,12 +1801,12 @@ namespace Emby.Server.Implementations.Session
|
||||
|
||||
ArgumentException.ThrowIfNullOrEmpty(accessToken);
|
||||
|
||||
var existing = _deviceManager.GetDevices(
|
||||
var existing = (await _deviceManager.GetDevices(
|
||||
new DeviceQuery
|
||||
{
|
||||
Limit = 1,
|
||||
AccessToken = accessToken
|
||||
}).Items;
|
||||
}).ConfigureAwait(false)).Items;
|
||||
|
||||
if (existing.Count > 0)
|
||||
{
|
||||
@@ -1845,10 +1845,10 @@ namespace Emby.Server.Implementations.Session
|
||||
{
|
||||
CheckDisposed();
|
||||
|
||||
var existing = _deviceManager.GetDevices(new DeviceQuery
|
||||
var existing = await _deviceManager.GetDevices(new DeviceQuery
|
||||
{
|
||||
UserId = userId
|
||||
});
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
foreach (var info in existing.Items)
|
||||
{
|
||||
@@ -2045,11 +2045,11 @@ namespace Emby.Server.Implementations.Session
|
||||
/// <inheritdoc />
|
||||
public async Task<SessionInfo> GetSessionByAuthenticationToken(string token, string deviceId, string remoteEndpoint)
|
||||
{
|
||||
var items = _deviceManager.GetDevices(new DeviceQuery
|
||||
var items = (await _deviceManager.GetDevices(new DeviceQuery
|
||||
{
|
||||
AccessToken = token,
|
||||
Limit = 1
|
||||
}).Items;
|
||||
}).ConfigureAwait(false)).Items;
|
||||
|
||||
if (items.Count == 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user