From 1b46fb62c48c86e5f9aed9426a90702e2d392bb6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 9 Mar 2015 15:40:03 -0400 Subject: [PATCH] fix session not found errors --- MediaBrowser.Api/BaseApiService.cs | 7 +- MediaBrowser.Api/LiveTv/LiveTvService.cs | 2 +- MediaBrowser.Api/Session/SessionsService.cs | 18 ++-- .../UserLibrary/PlaystateService.cs | 10 +-- .../Net/ISessionContext.cs | 11 +-- .../Session/ISessionManager.cs | 13 ++- .../HttpServer/Security/SessionContext.cs | 30 +++++-- .../Session/SessionManager.cs | 89 +++++++++++-------- .../Session/SessionWebSocketListener.cs | 13 ++- 9 files changed, 118 insertions(+), 75 deletions(-) diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index dff433c9dc..91e1c7d9a1 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Dto; +using System.Threading.Tasks; +using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; @@ -88,9 +89,9 @@ namespace MediaBrowser.Api /// Gets the session. /// /// SessionInfo. - protected SessionInfo GetSession() + protected async Task GetSession() { - var session = SessionContext.GetSession(Request); + var session = await SessionContext.GetSession(Request).ConfigureAwait(false); if (session == null) { diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index fe21b9ada1..f3fd8f42a6 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -315,7 +315,7 @@ namespace MediaBrowser.Api.LiveTv private void AssertUserCanManageLiveTv() { - var user = SessionContext.GetUser(Request); + var user = SessionContext.GetUser(Request).Result; if (user == null) { diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs index 319b3d28c6..52ecb95ec6 100644 --- a/MediaBrowser.Api/Session/SessionsService.cs +++ b/MediaBrowser.Api/Session/SessionsService.cs @@ -418,7 +418,7 @@ namespace MediaBrowser.Api.Session SeekPositionTicks = request.SeekPositionTicks }; - var task = _sessionManager.SendPlaystateCommand(GetSession().Id, request.Id, command, CancellationToken.None); + var task = _sessionManager.SendPlaystateCommand(GetSession().Result.Id, request.Id, command, CancellationToken.None); Task.WaitAll(task); } @@ -436,7 +436,7 @@ namespace MediaBrowser.Api.Session ItemType = request.ItemType }; - var task = _sessionManager.SendBrowseCommand(GetSession().Id, request.Id, command, CancellationToken.None); + var task = _sessionManager.SendBrowseCommand(GetSession().Result.Id, request.Id, command, CancellationToken.None); Task.WaitAll(task); } @@ -455,7 +455,7 @@ namespace MediaBrowser.Api.Session name = commandType.ToString(); } - var currentSession = GetSession(); + var currentSession = GetSession().Result; var command = new GeneralCommand { @@ -481,7 +481,7 @@ namespace MediaBrowser.Api.Session Text = request.Text }; - var task = _sessionManager.SendMessageCommand(GetSession().Id, request.Id, command, CancellationToken.None); + var task = _sessionManager.SendMessageCommand(GetSession().Result.Id, request.Id, command, CancellationToken.None); Task.WaitAll(task); } @@ -500,14 +500,14 @@ namespace MediaBrowser.Api.Session StartPositionTicks = request.StartPositionTicks }; - var task = _sessionManager.SendPlayCommand(GetSession().Id, request.Id, command, CancellationToken.None); + var task = _sessionManager.SendPlayCommand(GetSession().Result.Id, request.Id, command, CancellationToken.None); Task.WaitAll(task); } public void Post(SendGeneralCommand request) { - var currentSession = GetSession(); + var currentSession = GetSession().Result; var command = new GeneralCommand { @@ -522,7 +522,7 @@ namespace MediaBrowser.Api.Session public void Post(SendFullGeneralCommand request) { - var currentSession = GetSession(); + var currentSession = GetSession().Result; request.ControllingUserId = currentSession.UserId.HasValue ? currentSession.UserId.Value.ToString("N") : null; @@ -545,7 +545,7 @@ namespace MediaBrowser.Api.Session { if (string.IsNullOrWhiteSpace(request.Id)) { - request.Id = GetSession().Id; + request.Id = GetSession().Result.Id; } _sessionManager.ReportCapabilities(request.Id, new ClientCapabilities { @@ -569,7 +569,7 @@ namespace MediaBrowser.Api.Session { if (string.IsNullOrWhiteSpace(request.Id)) { - request.Id = GetSession().Id; + request.Id = GetSession().Result.Id; } _sessionManager.ReportCapabilities(request.Id, request); } diff --git a/MediaBrowser.Api/UserLibrary/PlaystateService.cs b/MediaBrowser.Api/UserLibrary/PlaystateService.cs index fae83e3692..55e1681e0d 100644 --- a/MediaBrowser.Api/UserLibrary/PlaystateService.cs +++ b/MediaBrowser.Api/UserLibrary/PlaystateService.cs @@ -231,7 +231,7 @@ namespace MediaBrowser.Api.UserLibrary datePlayed = DateTime.ParseExact(request.DatePlayed, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); } - var session = GetSession(); + var session = await GetSession().ConfigureAwait(false); var dto = await UpdatePlayedStatus(user, request.Id, true, datePlayed).ConfigureAwait(false); @@ -266,7 +266,7 @@ namespace MediaBrowser.Api.UserLibrary public void Post(ReportPlaybackStart request) { - request.SessionId = GetSession().Id; + request.SessionId = GetSession().Result.Id; var task = _sessionManager.OnPlaybackStart(request); @@ -294,7 +294,7 @@ namespace MediaBrowser.Api.UserLibrary public void Post(ReportPlaybackProgress request) { - request.SessionId = GetSession().Id; + request.SessionId = GetSession().Result.Id; var task = _sessionManager.OnPlaybackProgress(request); @@ -317,7 +317,7 @@ namespace MediaBrowser.Api.UserLibrary public void Post(ReportPlaybackStopped request) { - request.SessionId = GetSession().Id; + request.SessionId = GetSession().Result.Id; var task = _sessionManager.OnPlaybackStopped(request); @@ -339,7 +339,7 @@ namespace MediaBrowser.Api.UserLibrary { var user = _userManager.GetUserById(request.UserId); - var session = GetSession(); + var session = await GetSession().ConfigureAwait(false); var dto = await UpdatePlayedStatus(user, request.Id, false, null).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/Net/ISessionContext.cs b/MediaBrowser.Controller/Net/ISessionContext.cs index be8d28acc6..167e178671 100644 --- a/MediaBrowser.Controller/Net/ISessionContext.cs +++ b/MediaBrowser.Controller/Net/ISessionContext.cs @@ -1,14 +1,15 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Session; +using System.Threading.Tasks; namespace MediaBrowser.Controller.Net { public interface ISessionContext { - SessionInfo GetSession(object requestContext); - User GetUser(object requestContext); - - SessionInfo GetSession(IServiceRequest requestContext); - User GetUser(IServiceRequest requestContext); + Task GetSession(object requestContext); + Task GetUser(object requestContext); + + Task GetSession(IServiceRequest requestContext); + Task GetUser(IServiceRequest requestContext); } } diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index b51b590cf7..234a823460 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Security; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; using MediaBrowser.Model.Session; @@ -282,8 +283,18 @@ namespace MediaBrowser.Controller.Session /// Gets the session by authentication token. /// /// The token. + /// The remote endpoint. /// SessionInfo. - SessionInfo GetSessionByAuthenticationToken(string token); + Task GetSessionByAuthenticationToken(string token, string remoteEndpoint); + + /// + /// Gets the session by authentication token. + /// + /// The information. + /// The remote endpoint. + /// The application version. + /// Task<SessionInfo>. + Task GetSessionByAuthenticationToken(AuthenticationInfo info, string remoteEndpoint, string appVersion); /// /// Logouts the specified access token. diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs index 954db3a9d8..0557f7528d 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs @@ -1,8 +1,10 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Session; using ServiceStack.Web; +using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.HttpServer.Security { @@ -19,31 +21,41 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security _sessionManager = sessionManager; } - public SessionInfo GetSession(IServiceRequest requestContext) + public Task GetSession(IServiceRequest requestContext) { var authorization = _authContext.GetAuthorizationInfo(requestContext); if (!string.IsNullOrWhiteSpace(authorization.Token)) { - return _sessionManager.GetSessionByAuthenticationToken(authorization.Token); + var auth = GetTokenInfo(requestContext); + return _sessionManager.GetSessionByAuthenticationToken(auth, requestContext.RemoteIp, authorization.Version); } - return _sessionManager.GetSession(authorization.DeviceId, authorization.Client, authorization.Version); + + var session = _sessionManager.GetSession(authorization.DeviceId, authorization.Client, authorization.Version); + return Task.FromResult(session); } - public User GetUser(IServiceRequest requestContext) + private AuthenticationInfo GetTokenInfo(IServiceRequest request) { - var session = GetSession(requestContext); - - return session == null || !session.UserId.HasValue ? null : _userManager.GetUserById(session.UserId.Value); + object info; + request.Items.TryGetValue("OriginalAuthenticationInfo", out info); + return info as AuthenticationInfo; } - public SessionInfo GetSession(object requestContext) + public Task GetSession(object requestContext) { var req = new ServiceStackServiceRequest((IRequest)requestContext); return GetSession(req); } - public User GetUser(object requestContext) + public async Task GetUser(IServiceRequest requestContext) + { + var session = await GetSession(requestContext).ConfigureAwait(false); + + return session == null || !session.UserId.HasValue ? null : _userManager.GetUserById(session.UserId.Value); + } + + public Task GetUser(object requestContext) { var req = new ServiceStackServiceRequest((IRequest)requestContext); return GetUser(req); diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index a09f585fd4..2e28862e9e 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -237,10 +237,7 @@ namespace MediaBrowser.Server.Implementations.Session var activityDate = DateTime.UtcNow; - var userId = user == null ? (Guid?)null : user.Id; - var username = user == null ? null : user.Name; - - var session = await GetSessionInfo(clientType, appVersion, deviceId, deviceName, remoteEndPoint, userId, username).ConfigureAwait(false); + var session = await GetSessionInfo(clientType, appVersion, deviceId, deviceName, remoteEndPoint, user).ConfigureAwait(false); session.LastActivityDate = activityDate; @@ -281,7 +278,7 @@ namespace MediaBrowser.Server.Implementations.Session if (session != null) { - var key = GetSessionKey(session.Client, session.ApplicationVersion, session.DeviceId); + var key = GetSessionKey(session.Client, session.DeviceId); SessionInfo removed; @@ -365,7 +362,7 @@ namespace MediaBrowser.Server.Implementations.Session } } - private string GetSessionKey(string clientType, string appVersion, string deviceId) + private string GetSessionKey(string clientType, string deviceId) { return clientType + deviceId; } @@ -378,29 +375,31 @@ namespace MediaBrowser.Server.Implementations.Session /// The device id. /// Name of the device. /// The remote end point. - /// The user identifier. - /// The username. + /// The user. /// SessionInfo. - private async Task GetSessionInfo(string clientType, string appVersion, string deviceId, string deviceName, string remoteEndPoint, Guid? userId, string username) + private async Task GetSessionInfo(string clientType, string appVersion, string deviceId, string deviceName, string remoteEndPoint, User user) { - var key = GetSessionKey(clientType, appVersion, deviceId); + var key = GetSessionKey(clientType, deviceId); await _sessionLock.WaitAsync(CancellationToken.None).ConfigureAwait(false); + var userId = user == null ? (Guid?)null : user.Id; + var username = user == null ? null : user.Name; + try { - SessionInfo connection; + SessionInfo sessionInfo; DeviceInfo device = null; - if (!_activeConnections.TryGetValue(key, out connection)) + if (!_activeConnections.TryGetValue(key, out sessionInfo)) { - var sessionInfo = new SessionInfo - { - Client = clientType, - DeviceId = deviceId, - ApplicationVersion = appVersion, - Id = key.GetMD5().ToString("N") - }; + sessionInfo = new SessionInfo + { + Client = clientType, + DeviceId = deviceId, + ApplicationVersion = appVersion, + Id = key.GetMD5().ToString("N") + }; sessionInfo.DeviceName = deviceName; sessionInfo.UserId = userId; @@ -410,7 +409,6 @@ namespace MediaBrowser.Server.Implementations.Session OnSessionStarted(sessionInfo); _activeConnections.TryAdd(key, sessionInfo); - connection = sessionInfo; if (!string.IsNullOrEmpty(deviceId)) { @@ -426,24 +424,25 @@ namespace MediaBrowser.Server.Implementations.Session deviceName = device.CustomName; } - connection.DeviceName = deviceName; - connection.UserId = userId; - connection.UserName = username; - connection.RemoteEndPoint = remoteEndPoint; + sessionInfo.DeviceName = deviceName; + sessionInfo.UserId = userId; + sessionInfo.UserName = username; + sessionInfo.RemoteEndPoint = remoteEndPoint; + sessionInfo.ApplicationVersion = appVersion; if (!userId.HasValue) { - connection.AdditionalUsers.Clear(); + sessionInfo.AdditionalUsers.Clear(); } - if (connection.SessionController == null) + if (sessionInfo.SessionController == null) { - connection.SessionController = _sessionFactories - .Select(i => i.GetSessionController(connection)) + sessionInfo.SessionController = _sessionFactories + .Select(i => i.GetSessionController(sessionInfo)) .FirstOrDefault(i => i != null); } - return connection; + return sessionInfo; } finally { @@ -920,7 +919,7 @@ namespace MediaBrowser.Server.Implementations.Session return FilterToSingleMediaType(items) .OrderBy(i => i.SortName); } - + if (item.IsFolder) { var folder = (Folder)item; @@ -1640,7 +1639,25 @@ namespace MediaBrowser.Server.Implementations.Session string.Equals(i.Client, client)); } - public SessionInfo GetSessionByAuthenticationToken(string token) + public Task GetSessionByAuthenticationToken(AuthenticationInfo info, string remoteEndpoint, string appVersion) + { + if (info == null) + { + throw new ArgumentNullException("info"); + } + + var user = string.IsNullOrWhiteSpace(info.UserId) + ? null + : _userManager.GetUserById(info.UserId); + + appVersion = string.IsNullOrWhiteSpace(appVersion) + ? "1" + : appVersion; + + return GetSessionInfo(info.AppName, appVersion, info.DeviceId, info.DeviceName, remoteEndpoint, user); + } + + public Task GetSessionByAuthenticationToken(string token, string remoteEndpoint) { var result = _authRepo.Get(new AuthenticationInfoQuery { @@ -1654,10 +1671,12 @@ namespace MediaBrowser.Server.Implementations.Session var info = result.Items[0]; - // TODO: Make Token part of SessionInfo and get result that way - // This can't be done until all apps are updated to new authentication. - return Sessions.FirstOrDefault(i => string.Equals(i.DeviceId, info.DeviceId) && - string.Equals(i.Client, info.AppName)); + if (info == null) + { + return null; + } + + return GetSessionByAuthenticationToken(info, remoteEndpoint, null); } public Task SendMessageToUserSessions(string userId, string name, T data, diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs index b581f9144e..72ec16f85d 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; @@ -61,9 +60,9 @@ namespace MediaBrowser.Server.Implementations.Session serverManager.WebSocketConnected += _serverManager_WebSocketConnected; } - void _serverManager_WebSocketConnected(object sender, GenericEventArgs e) + async void _serverManager_WebSocketConnected(object sender, GenericEventArgs e) { - var session = GetSession(e.Argument.QueryString); + var session = await GetSession(e.Argument.QueryString, e.Argument.RemoteEndPoint).ConfigureAwait(false); if (session != null) { @@ -84,11 +83,11 @@ namespace MediaBrowser.Server.Implementations.Session } } - void _httpServer_WebSocketConnecting(object sender, WebSocketConnectingEventArgs e) + async void _httpServer_WebSocketConnecting(object sender, WebSocketConnectingEventArgs e) { if (e.QueryString.AllKeys.Contains("api_key", StringComparer.OrdinalIgnoreCase)) { - var session = GetSession(e.QueryString); + var session = await GetSession(e.QueryString, e.Endpoint).ConfigureAwait(false); if (session == null) { @@ -97,10 +96,10 @@ namespace MediaBrowser.Server.Implementations.Session } } - private SessionInfo GetSession(NameValueCollection queryString) + private Task GetSession(NameValueCollection queryString, string remoteEndpoint) { var token = queryString["api_key"]; - return _sessionManager.GetSessionByAuthenticationToken(token); + return _sessionManager.GetSessionByAuthenticationToken(token, remoteEndpoint); } public void Dispose()