update request classes

This commit is contained in:
Luke Pulverenti 2017-09-03 14:38:26 -04:00
parent 2084678266
commit 504f56d841
12 changed files with 47 additions and 97 deletions

View File

@ -8,6 +8,7 @@ using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Session;
using System; using System;
using System.Linq; using System.Linq;
using MediaBrowser.Model.Services;
namespace Emby.Server.Implementations.HttpServer.Security namespace Emby.Server.Implementations.HttpServer.Security
{ {
@ -37,19 +38,19 @@ namespace Emby.Server.Implementations.HttpServer.Security
/// </summary> /// </summary>
public string HtmlRedirect { get; set; } public string HtmlRedirect { get; set; }
public void Authenticate(IServiceRequest request, public void Authenticate(IRequest request,
IAuthenticationAttributes authAttribtues) IAuthenticationAttributes authAttribtues)
{ {
ValidateUser(request, authAttribtues); ValidateUser(request, authAttribtues);
} }
private void ValidateUser(IServiceRequest request, private void ValidateUser(IRequest request,
IAuthenticationAttributes authAttribtues) IAuthenticationAttributes authAttribtues)
{ {
// This code is executed before the service // This code is executed before the service
var auth = AuthorizationContext.GetAuthorizationInfo(request); var auth = AuthorizationContext.GetAuthorizationInfo(request);
if (!IsExemptFromAuthenticationToken(auth, authAttribtues)) if (!IsExemptFromAuthenticationToken(auth, authAttribtues, request))
{ {
var valid = IsValidConnectKey(auth.Token); var valid = IsValidConnectKey(auth.Token);
@ -75,7 +76,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
var info = GetTokenInfo(request); var info = GetTokenInfo(request);
if (!IsExemptFromRoles(auth, authAttribtues, info)) if (!IsExemptFromRoles(auth, authAttribtues, request, info))
{ {
var roles = authAttribtues.GetRoles(); var roles = authAttribtues.GetRoles();
@ -95,7 +96,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
} }
} }
private void ValidateUserAccess(User user, IServiceRequest request, private void ValidateUserAccess(User user, IRequest request,
IAuthenticationAttributes authAttribtues, IAuthenticationAttributes authAttribtues,
AuthorizationInfo auth) AuthorizationInfo auth)
{ {
@ -111,7 +112,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
!authAttribtues.EscapeParentalControl && !authAttribtues.EscapeParentalControl &&
!user.IsParentalScheduleAllowed()) !user.IsParentalScheduleAllowed())
{ {
request.AddResponseHeader("X-Application-Error-Code", "ParentalControl"); request.Response.AddHeader("X-Application-Error-Code", "ParentalControl");
throw new SecurityException("This user account is not allowed access at this time.") throw new SecurityException("This user account is not allowed access at this time.")
{ {
@ -131,23 +132,33 @@ namespace Emby.Server.Implementations.HttpServer.Security
} }
} }
private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues) private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, IRequest request)
{ {
if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard) if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard)
{ {
return true; return true;
} }
if (authAttribtues.AllowLocal && request.IsLocal)
{
return true;
}
return false; return false;
} }
private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, AuthenticationInfo tokenInfo) private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, IRequest request, AuthenticationInfo tokenInfo)
{ {
if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard) if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard)
{ {
return true; return true;
} }
if (authAttribtues.AllowLocal && request.IsLocal)
{
return true;
}
if (string.IsNullOrWhiteSpace(auth.Token)) if (string.IsNullOrWhiteSpace(auth.Token))
{ {
return true; return true;
@ -195,7 +206,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
} }
} }
private AuthenticationInfo GetTokenInfo(IServiceRequest request) private AuthenticationInfo GetTokenInfo(IRequest request)
{ {
object info; object info;
request.Items.TryGetValue("OriginalAuthenticationInfo", out info); request.Items.TryGetValue("OriginalAuthenticationInfo", out info);
@ -212,7 +223,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
return ConnectManager.IsAuthorizationTokenValid(token); return ConnectManager.IsAuthorizationTokenValid(token);
} }
private void ValidateSecurityToken(IServiceRequest request, string token) private void ValidateSecurityToken(IRequest request, string token)
{ {
if (string.IsNullOrWhiteSpace(token)) if (string.IsNullOrWhiteSpace(token))
{ {

View File

@ -21,11 +21,10 @@ namespace Emby.Server.Implementations.HttpServer.Security
public AuthorizationInfo GetAuthorizationInfo(object requestContext) public AuthorizationInfo GetAuthorizationInfo(object requestContext)
{ {
var req = new ServiceRequest((IRequest)requestContext); return GetAuthorizationInfo((IRequest)requestContext);
return GetAuthorizationInfo(req);
} }
public AuthorizationInfo GetAuthorizationInfo(IServiceRequest requestContext) public AuthorizationInfo GetAuthorizationInfo(IRequest requestContext)
{ {
object cached; object cached;
if (requestContext.Items.TryGetValue("AuthorizationInfo", out cached)) if (requestContext.Items.TryGetValue("AuthorizationInfo", out cached))
@ -41,7 +40,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
/// </summary> /// </summary>
/// <param name="httpReq">The HTTP req.</param> /// <param name="httpReq">The HTTP req.</param>
/// <returns>Dictionary{System.StringSystem.String}.</returns> /// <returns>Dictionary{System.StringSystem.String}.</returns>
private AuthorizationInfo GetAuthorization(IServiceRequest httpReq) private AuthorizationInfo GetAuthorization(IRequest httpReq)
{ {
var auth = GetAuthorizationDictionary(httpReq); var auth = GetAuthorizationDictionary(httpReq);
@ -135,7 +134,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
/// </summary> /// </summary>
/// <param name="httpReq">The HTTP req.</param> /// <param name="httpReq">The HTTP req.</param>
/// <returns>Dictionary{System.StringSystem.String}.</returns> /// <returns>Dictionary{System.StringSystem.String}.</returns>
private Dictionary<string, string> GetAuthorizationDictionary(IServiceRequest httpReq) private Dictionary<string, string> GetAuthorizationDictionary(IRequest httpReq)
{ {
var auth = httpReq.Headers["X-Emby-Authorization"]; var auth = httpReq.Headers["X-Emby-Authorization"];

View File

@ -21,7 +21,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
_sessionManager = sessionManager; _sessionManager = sessionManager;
} }
public Task<SessionInfo> GetSession(IServiceRequest requestContext) public Task<SessionInfo> GetSession(IRequest requestContext)
{ {
var authorization = _authContext.GetAuthorizationInfo(requestContext); var authorization = _authContext.GetAuthorizationInfo(requestContext);
@ -38,7 +38,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
return _sessionManager.LogSessionActivity(authorization.Client, authorization.Version, authorization.DeviceId, authorization.Device, requestContext.RemoteIp, user); return _sessionManager.LogSessionActivity(authorization.Client, authorization.Version, authorization.DeviceId, authorization.Device, requestContext.RemoteIp, user);
} }
private AuthenticationInfo GetTokenInfo(IServiceRequest request) private AuthenticationInfo GetTokenInfo(IRequest request)
{ {
object info; object info;
request.Items.TryGetValue("OriginalAuthenticationInfo", out info); request.Items.TryGetValue("OriginalAuthenticationInfo", out info);
@ -47,11 +47,10 @@ namespace Emby.Server.Implementations.HttpServer.Security
public Task<SessionInfo> GetSession(object requestContext) public Task<SessionInfo> GetSession(object requestContext)
{ {
var req = new ServiceRequest((IRequest)requestContext); return GetSession((IRequest)requestContext);
return GetSession(req);
} }
public async Task<User> GetUser(IServiceRequest requestContext) public async Task<User> GetUser(IRequest requestContext)
{ {
var session = await GetSession(requestContext).ConfigureAwait(false); var session = await GetSession(requestContext).ConfigureAwait(false);
@ -60,8 +59,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
public Task<User> GetUser(object requestContext) public Task<User> GetUser(object requestContext)
{ {
var req = new ServiceRequest((IRequest)requestContext); return GetUser((IRequest)requestContext);
return GetUser(req);
} }
} }
} }

View File

@ -43,7 +43,7 @@ namespace MediaBrowser.Api.System
/// Class RestartApplication /// Class RestartApplication
/// </summary> /// </summary>
[Route("/System/Restart", "POST", Summary = "Restarts the application, if needed")] [Route("/System/Restart", "POST", Summary = "Restarts the application, if needed")]
[Authenticated(Roles = "Admin")] [Authenticated(Roles = "Admin", AllowLocal = true)]
public class RestartApplication public class RestartApplication
{ {
} }
@ -52,10 +52,9 @@ namespace MediaBrowser.Api.System
/// This is currently not authenticated because the uninstaller needs to be able to shutdown the server. /// This is currently not authenticated because the uninstaller needs to be able to shutdown the server.
/// </summary> /// </summary>
[Route("/System/Shutdown", "POST", Summary = "Shuts down the application")] [Route("/System/Shutdown", "POST", Summary = "Shuts down the application")]
[Authenticated(Roles = "Admin", AllowLocal = true)]
public class ShutdownApplication public class ShutdownApplication
{ {
// TODO: This is not currently authenticated due to uninstaller
// Improve later
} }
[Route("/System/Logs", "GET", Summary = "Gets a list of available server log files")] [Route("/System/Logs", "GET", Summary = "Gets a list of available server log files")]

View File

@ -183,14 +183,12 @@
<Compile Include="Net\IHttpResultFactory.cs" /> <Compile Include="Net\IHttpResultFactory.cs" />
<Compile Include="Net\IHttpServer.cs" /> <Compile Include="Net\IHttpServer.cs" />
<Compile Include="Net\IServerManager.cs" /> <Compile Include="Net\IServerManager.cs" />
<Compile Include="Net\IServiceRequest.cs" />
<Compile Include="Net\ISessionContext.cs" /> <Compile Include="Net\ISessionContext.cs" />
<Compile Include="Net\IWebSocket.cs" /> <Compile Include="Net\IWebSocket.cs" />
<Compile Include="Net\IWebSocketConnection.cs" /> <Compile Include="Net\IWebSocketConnection.cs" />
<Compile Include="Net\IWebSocketListener.cs" /> <Compile Include="Net\IWebSocketListener.cs" />
<Compile Include="Net\LoggedAttribute.cs" /> <Compile Include="Net\LoggedAttribute.cs" />
<Compile Include="Net\SecurityException.cs" /> <Compile Include="Net\SecurityException.cs" />
<Compile Include="Net\ServiceRequest.cs" />
<Compile Include="Net\StaticResultOptions.cs" /> <Compile Include="Net\StaticResultOptions.cs" />
<Compile Include="Net\WebSocketConnectEventArgs.cs" /> <Compile Include="Net\WebSocketConnectEventArgs.cs" />
<Compile Include="Net\WebSocketMessageInfo.cs" /> <Compile Include="Net\WebSocketMessageInfo.cs" />

View File

@ -25,6 +25,8 @@ namespace MediaBrowser.Controller.Net
/// <value><c>true</c> if [allow before startup wizard]; otherwise, <c>false</c>.</value> /// <value><c>true</c> if [allow before startup wizard]; otherwise, <c>false</c>.</value>
public bool AllowBeforeStartupWizard { get; set; } public bool AllowBeforeStartupWizard { get; set; }
public bool AllowLocal { get; set; }
/// <summary> /// <summary>
/// The request filter is executed before the service. /// The request filter is executed before the service.
/// </summary> /// </summary>
@ -33,9 +35,7 @@ namespace MediaBrowser.Controller.Net
/// <param name="requestDto">The request DTO</param> /// <param name="requestDto">The request DTO</param>
public void RequestFilter(IRequest request, IResponse response, object requestDto) public void RequestFilter(IRequest request, IResponse response, object requestDto)
{ {
var serviceRequest = new ServiceRequest(request); AuthService.Authenticate(request, this);
AuthService.Authenticate(serviceRequest, this);
} }
/// <summary> /// <summary>
@ -59,6 +59,7 @@ namespace MediaBrowser.Controller.Net
{ {
bool EscapeParentalControl { get; } bool EscapeParentalControl { get; }
bool AllowBeforeStartupWizard { get; } bool AllowBeforeStartupWizard { get; }
bool AllowLocal { get; }
string[] GetRoles(); string[] GetRoles();
} }

View File

@ -1,9 +1,9 @@
 using MediaBrowser.Model.Services;
namespace MediaBrowser.Controller.Net namespace MediaBrowser.Controller.Net
{ {
public interface IAuthService public interface IAuthService
{ {
void Authenticate(IServiceRequest request, void Authenticate(IRequest request, IAuthenticationAttributes authAttribtues);
IAuthenticationAttributes authAttribtues);
} }
} }

View File

@ -1,4 +1,5 @@
 using MediaBrowser.Model.Services;
namespace MediaBrowser.Controller.Net namespace MediaBrowser.Controller.Net
{ {
public interface IAuthorizationContext public interface IAuthorizationContext
@ -15,6 +16,6 @@ namespace MediaBrowser.Controller.Net
/// </summary> /// </summary>
/// <param name="requestContext">The request context.</param> /// <param name="requestContext">The request context.</param>
/// <returns>AuthorizationInfo.</returns> /// <returns>AuthorizationInfo.</returns>
AuthorizationInfo GetAuthorizationInfo(IServiceRequest requestContext); AuthorizationInfo GetAuthorizationInfo(IRequest requestContext);
} }
} }

View File

@ -1,14 +0,0 @@
using System.Collections.Generic;
using MediaBrowser.Model.Services;
namespace MediaBrowser.Controller.Net
{
public interface IServiceRequest
{
string RemoteIp { get; }
QueryParamCollection Headers { get; }
QueryParamCollection QueryString { get; }
IDictionary<string,object> Items { get; }
void AddResponseHeader(string name, string value);
}
}

View File

@ -1,6 +1,7 @@
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Session;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Model.Services;
namespace MediaBrowser.Controller.Net namespace MediaBrowser.Controller.Net
{ {
@ -9,7 +10,7 @@ namespace MediaBrowser.Controller.Net
Task<SessionInfo> GetSession(object requestContext); Task<SessionInfo> GetSession(object requestContext);
Task<User> GetUser(object requestContext); Task<User> GetUser(object requestContext);
Task<SessionInfo> GetSession(IServiceRequest requestContext); Task<SessionInfo> GetSession(IRequest requestContext);
Task<User> GetUser(IServiceRequest requestContext); Task<User> GetUser(IRequest requestContext);
} }
} }

View File

@ -30,10 +30,8 @@ namespace MediaBrowser.Controller.Net
/// <param name="requestDto">The request DTO</param> /// <param name="requestDto">The request DTO</param>
public void Filter(IRequest request, IResponse response, object requestDto) public void Filter(IRequest request, IResponse response, object requestDto)
{ {
var serviceRequest = new ServiceRequest(request);
//This code is executed before the service //This code is executed before the service
var auth = AuthorizationContext.GetAuthorizationInfo(serviceRequest); var auth = AuthorizationContext.GetAuthorizationInfo(request);
if (auth != null) if (auth != null)
{ {

View File

@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using MediaBrowser.Model.Services;
namespace MediaBrowser.Controller.Net
{
public class ServiceRequest : IServiceRequest
{
private readonly IRequest _request;
public ServiceRequest(IRequest request)
{
_request = request;
}
public string RemoteIp
{
get { return _request.RemoteIp; }
}
public QueryParamCollection Headers
{
get { return _request.Headers; }
}
public QueryParamCollection QueryString
{
get { return _request.QueryString; }
}
public IDictionary<string, object> Items
{
get { return _request.Items; }
}
public void AddResponseHeader(string name, string value)
{
_request.Response.AddHeader(name, value);
}
}
}