diff --git a/MediaBrowser.Api/AppThemeService.cs b/MediaBrowser.Api/AppThemeService.cs
index 4d8eed7ddb..0c8a0aaa63 100644
--- a/MediaBrowser.Api/AppThemeService.cs
+++ b/MediaBrowser.Api/AppThemeService.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Themes;
using MediaBrowser.Model.Themes;
using ServiceStack;
@@ -47,6 +48,7 @@ namespace MediaBrowser.Api
{
}
+ [Authenticated]
public class AppThemeService : BaseApiService
{
private readonly IAppThemeManager _themeManager;
diff --git a/MediaBrowser.Api/AuthorizationRequestFilterAttribute.cs b/MediaBrowser.Api/AuthorizationRequestFilterAttribute.cs
deleted file mode 100644
index 6c56083cbf..0000000000
--- a/MediaBrowser.Api/AuthorizationRequestFilterAttribute.cs
+++ /dev/null
@@ -1,190 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Session;
-using MediaBrowser.Model.Logging;
-using ServiceStack.Web;
-using System;
-using System.Collections.Generic;
-
-namespace MediaBrowser.Api
-{
- public class AuthorizationRequestFilterAttribute : Attribute, IHasRequestFilter
- {
- //This property will be resolved by the IoC container
- ///
- /// Gets or sets the user manager.
- ///
- /// The user manager.
- public IUserManager UserManager { get; set; }
-
- public ISessionManager SessionManager { get; set; }
-
- ///
- /// Gets or sets the logger.
- ///
- /// The logger.
- public ILogger Logger { get; set; }
-
- ///
- /// The request filter is executed before the service.
- ///
- /// The http request wrapper
- /// The http response wrapper
- /// The request DTO
- public void RequestFilter(IRequest request, IResponse response, object requestDto)
- {
- //This code is executed before the service
- var auth = GetAuthorizationDictionary(request);
-
- if (auth != null)
- {
- User user = null;
-
- if (auth.ContainsKey("UserId"))
- {
- var userId = auth["UserId"];
-
- if (!string.IsNullOrEmpty(userId))
- {
- user = UserManager.GetUserById(new Guid(userId));
- }
- }
-
- string deviceId;
- string device;
- string client;
- string version;
-
- auth.TryGetValue("DeviceId", out deviceId);
- auth.TryGetValue("Device", out device);
- auth.TryGetValue("Client", out client);
- auth.TryGetValue("Version", out version);
-
- if (!string.IsNullOrEmpty(client) && !string.IsNullOrEmpty(deviceId) && !string.IsNullOrEmpty(device) && !string.IsNullOrEmpty(version))
- {
- var remoteEndPoint = request.RemoteIp;
-
- SessionManager.LogSessionActivity(client, version, deviceId, device, remoteEndPoint, user);
- }
- }
- }
-
- ///
- /// Gets the auth.
- ///
- /// The HTTP req.
- /// Dictionary{System.StringSystem.String}.
- private static Dictionary GetAuthorizationDictionary(IRequest httpReq)
- {
- var auth = httpReq.Headers["Authorization"];
-
- return GetAuthorization(auth);
- }
-
- public static User GetCurrentUser(IRequest httpReq, IUserManager userManager)
- {
- var info = GetAuthorization(httpReq);
-
- return string.IsNullOrEmpty(info.UserId) ? null :
- userManager.GetUserById(new Guid(info.UserId));
- }
-
- ///
- /// Gets the authorization.
- ///
- /// The HTTP req.
- /// Dictionary{System.StringSystem.String}.
- public static AuthorizationInfo GetAuthorization(IRequest httpReq)
- {
- var auth = GetAuthorizationDictionary(httpReq);
-
- string userId = null;
- string deviceId = null;
- string device = null;
- string client = null;
- string version = null;
-
- if (auth != null)
- {
- auth.TryGetValue("UserId", out userId);
- auth.TryGetValue("DeviceId", out deviceId);
- auth.TryGetValue("Device", out device);
- auth.TryGetValue("Client", out client);
- auth.TryGetValue("Version", out version);
- }
-
- return new AuthorizationInfo
- {
- Client = client,
- Device = device,
- DeviceId = deviceId,
- UserId = userId,
- Version = version
- };
- }
-
- ///
- /// Gets the authorization.
- ///
- /// The authorization header.
- /// Dictionary{System.StringSystem.String}.
- private static Dictionary GetAuthorization(string authorizationHeader)
- {
- if (authorizationHeader == null) return null;
-
- var parts = authorizationHeader.Split(' ');
-
- // There should be at least to parts
- if (parts.Length < 2) return null;
-
- // It has to be a digest request
- if (!string.Equals(parts[0], "MediaBrowser", StringComparison.OrdinalIgnoreCase))
- {
- return null;
- }
-
- // Remove uptil the first space
- authorizationHeader = authorizationHeader.Substring(authorizationHeader.IndexOf(' '));
- parts = authorizationHeader.Split(',');
-
- var result = new Dictionary(StringComparer.OrdinalIgnoreCase);
-
- foreach (var item in parts)
- {
- var param = item.Trim().Split(new[] { '=' }, 2);
- result.Add(param[0], param[1].Trim(new[] { '"' }));
- }
-
- return result;
- }
-
- ///
- /// A new shallow copy of this filter is used on every request.
- ///
- /// IHasRequestFilter.
- public IHasRequestFilter Copy()
- {
- return this;
- }
-
- ///
- /// Order in which Request Filters are executed.
- /// <0 Executed before global request filters
- /// >0 Executed after global request filters
- ///
- /// The priority.
- public int Priority
- {
- get { return 0; }
- }
- }
-
- public class AuthorizationInfo
- {
- public string UserId;
- public string DeviceId;
- public string Device;
- public string Client;
- public string Version;
- }
-}
diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
index f1d5962139..09eb1ea414 100644
--- a/MediaBrowser.Api/BaseApiService.cs
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -14,8 +14,7 @@ namespace MediaBrowser.Api
///
/// Class BaseApiService
///
- [AuthorizationRequestFilter]
- public class BaseApiService : IHasResultFactory, IRestfulService
+ public class BaseApiService : IHasResultFactory, IRestfulService, IHasSession
{
///
/// Gets or sets the logger.
@@ -35,6 +34,8 @@ namespace MediaBrowser.Api
/// The request context.
public IRequest Request { get; set; }
+ public ISessionContext SessionContext { get; set; }
+
public string GetHeader(string name)
{
return Request.Headers[name];
@@ -82,13 +83,11 @@ namespace MediaBrowser.Api
///
/// Gets the session.
///
- /// The session manager.
/// SessionInfo.
- protected SessionInfo GetSession(ISessionManager sessionManager)
+ /// Session not found.
+ protected SessionInfo GetSession()
{
- var auth = AuthorizationRequestFilterAttribute.GetAuthorization(Request);
-
- var session = sessionManager.GetSession(auth.DeviceId, auth.Client, auth.Version);
+ var session = SessionContext.GetSession(Request);
if (session == null)
{
diff --git a/MediaBrowser.Api/ChannelService.cs b/MediaBrowser.Api/ChannelService.cs
index d71db929fe..2cc046f1d4 100644
--- a/MediaBrowser.Api/ChannelService.cs
+++ b/MediaBrowser.Api/ChannelService.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -172,7 +173,8 @@ namespace MediaBrowser.Api
[ApiMember(Name = "UserId", Description = "Optional attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string UserId { get; set; }
}
-
+
+ [Authenticated]
public class ChannelService : BaseApiService
{
private readonly IChannelManager _channelManager;
diff --git a/MediaBrowser.Api/DisplayPreferencesService.cs b/MediaBrowser.Api/DisplayPreferencesService.cs
index 206f5bf7b7..9f3a6134e9 100644
--- a/MediaBrowser.Api/DisplayPreferencesService.cs
+++ b/MediaBrowser.Api/DisplayPreferencesService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Serialization;
using ServiceStack;
@@ -48,6 +49,7 @@ namespace MediaBrowser.Api
///
/// Class DisplayPreferencesService
///
+ [Authenticated]
public class DisplayPreferencesService : BaseApiService
{
///
diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs
index 56f71fc00e..590deff5a7 100644
--- a/MediaBrowser.Api/EnvironmentService.cs
+++ b/MediaBrowser.Api/EnvironmentService.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using ServiceStack;
@@ -86,6 +87,7 @@ namespace MediaBrowser.Api
///
/// Class EnvironmentService
///
+ [Authenticated]
public class EnvironmentService : BaseApiService
{
const char UncSeparator = '\\';
diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs
index ff2771ce1b..9aba2b0652 100644
--- a/MediaBrowser.Api/GamesService.cs
+++ b/MediaBrowser.Api/GamesService.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using ServiceStack;
@@ -51,6 +52,7 @@ namespace MediaBrowser.Api
///
/// Class GamesService
///
+ [Authenticated]
public class GamesService : BaseApiService
{
///
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs
index ddb2dc943e..77a714755d 100644
--- a/MediaBrowser.Api/Library/LibraryService.cs
+++ b/MediaBrowser.Api/Library/LibraryService.cs
@@ -470,7 +470,7 @@ namespace MediaBrowser.Api.Library
{
var item = _libraryManager.GetItemById(request.Id);
- var session = GetSession(_sessionManager);
+ var session = GetSession();
if (!session.UserId.HasValue || !_userManager.GetUserById(session.UserId.Value).Configuration.EnableContentDeletion)
{
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index 6973a233af..de01628f84 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -280,7 +280,7 @@ namespace MediaBrowser.Api.LiveTv
private void AssertUserCanManageLiveTv()
{
- var user = AuthorizationRequestFilterAttribute.GetCurrentUser(Request, _userManager);
+ var user = SessionContext.GetUser(Request);
if (user == null)
{
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index 3f1d9fe67d..a68966b335 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -79,7 +79,6 @@
-
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 380ece2f2d..9ff482a1ab 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -1386,8 +1386,6 @@ namespace MediaBrowser.Api.Playback
ParseParams(request);
}
- var user = AuthorizationRequestFilterAttribute.GetCurrentUser(Request, UserManager);
-
var url = Request.PathInfo;
if (string.IsNullOrEmpty(request.AudioCodec))
@@ -1409,11 +1407,6 @@ namespace MediaBrowser.Api.Playback
var item = LibraryManager.GetItemById(request.Id);
- if (user != null && item.GetPlayAccess(user) != PlayAccess.Full)
- {
- throw new ArgumentException(string.Format("{0} is not allowed to play media.", user.Name));
- }
-
List mediaStreams = null;
state.ItemType = item.GetType().Name;
diff --git a/MediaBrowser.Api/SessionsService.cs b/MediaBrowser.Api/SessionsService.cs
index 36f1d65778..00c307a18b 100644
--- a/MediaBrowser.Api/SessionsService.cs
+++ b/MediaBrowser.Api/SessionsService.cs
@@ -285,7 +285,7 @@ namespace MediaBrowser.Api
SeekPositionTicks = request.SeekPositionTicks
};
- var task = _sessionManager.SendPlaystateCommand(GetSession(_sessionManager).Id, request.Id, command, CancellationToken.None);
+ var task = _sessionManager.SendPlaystateCommand(GetSession().Id, request.Id, command, CancellationToken.None);
Task.WaitAll(task);
}
@@ -303,7 +303,7 @@ namespace MediaBrowser.Api
ItemType = request.ItemType
};
- var task = _sessionManager.SendBrowseCommand(GetSession(_sessionManager).Id, request.Id, command, CancellationToken.None);
+ var task = _sessionManager.SendBrowseCommand(GetSession().Id, request.Id, command, CancellationToken.None);
Task.WaitAll(task);
}
@@ -318,7 +318,7 @@ namespace MediaBrowser.Api
if (Enum.TryParse(request.Command, true, out commandType))
{
- var currentSession = GetSession(_sessionManager);
+ var currentSession = GetSession();
var command = new GeneralCommand
{
@@ -345,7 +345,7 @@ namespace MediaBrowser.Api
Text = request.Text
};
- var task = _sessionManager.SendMessageCommand(GetSession(_sessionManager).Id, request.Id, command, CancellationToken.None);
+ var task = _sessionManager.SendMessageCommand(GetSession().Id, request.Id, command, CancellationToken.None);
Task.WaitAll(task);
}
@@ -364,14 +364,14 @@ namespace MediaBrowser.Api
StartPositionTicks = request.StartPositionTicks
};
- var task = _sessionManager.SendPlayCommand(GetSession(_sessionManager).Id, request.Id, command, CancellationToken.None);
+ var task = _sessionManager.SendPlayCommand(GetSession().Id, request.Id, command, CancellationToken.None);
Task.WaitAll(task);
}
public void Post(SendGeneralCommand request)
{
- var currentSession = GetSession(_sessionManager);
+ var currentSession = GetSession();
var command = new GeneralCommand
{
@@ -386,7 +386,7 @@ namespace MediaBrowser.Api
public void Post(SendFullGeneralCommand request)
{
- var currentSession = GetSession(_sessionManager);
+ var currentSession = GetSession();
request.ControllingUserId = currentSession.UserId.HasValue ? currentSession.UserId.Value.ToString("N") : null;
@@ -409,7 +409,7 @@ namespace MediaBrowser.Api
{
if (string.IsNullOrWhiteSpace(request.Id))
{
- request.Id = GetSession(_sessionManager).Id;
+ request.Id = GetSession().Id;
}
_sessionManager.ReportCapabilities(request.Id, new SessionCapabilities
{
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index a1625d0520..da12a9e3d2 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -791,7 +791,7 @@ namespace MediaBrowser.Api.UserLibrary
datePlayed = DateTime.ParseExact(request.DatePlayed, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
}
- var session = GetSession(_sessionManager);
+ var session = GetSession();
var dto = await UpdatePlayedStatus(user, request.Id, true, datePlayed).ConfigureAwait(false);
@@ -826,7 +826,7 @@ namespace MediaBrowser.Api.UserLibrary
public void Post(ReportPlaybackStart request)
{
- request.SessionId = GetSession(_sessionManager).Id;
+ request.SessionId = GetSession().Id;
var task = _sessionManager.OnPlaybackStart(request);
@@ -854,7 +854,7 @@ namespace MediaBrowser.Api.UserLibrary
public void Post(ReportPlaybackProgress request)
{
- request.SessionId = GetSession(_sessionManager).Id;
+ request.SessionId = GetSession().Id;
var task = _sessionManager.OnPlaybackProgress(request);
@@ -877,7 +877,7 @@ namespace MediaBrowser.Api.UserLibrary
public void Post(ReportPlaybackStopped request)
{
- request.SessionId = GetSession(_sessionManager).Id;
+ request.SessionId = GetSession().Id;
var task = _sessionManager.OnPlaybackStopped(request);
@@ -899,7 +899,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var user = _userManager.GetUserById(request.UserId);
- var session = GetSession(_sessionManager);
+ var session = GetSession();
var dto = await UpdatePlayedStatus(user, request.Id, false, null).ConfigureAwait(false);
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index 1932c8f93a..764a281024 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Serialization;
@@ -152,7 +153,7 @@ namespace MediaBrowser.Api
///
/// Class UsersService
///
- public class UserService : BaseApiService
+ public class UserService : BaseApiService, IHasAuthorization
{
///
/// The _XML serializer
@@ -166,6 +167,8 @@ namespace MediaBrowser.Api
private readonly IDtoService _dtoService;
private readonly ISessionManager _sessionMananger;
+ public IAuthorizationContext AuthorizationContext { get; set; }
+
///
/// Initializes a new instance of the class.
///
@@ -295,7 +298,7 @@ namespace MediaBrowser.Api
throw new ResourceNotFoundException("User not found");
}
- var auth = AuthorizationRequestFilterAttribute.GetAuthorization(Request);
+ var auth = AuthorizationContext.GetAuthorizationInfo(Request);
// Login in the old way if the header is missing
if (string.IsNullOrEmpty(auth.Client) ||
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 52c414ae8e..584091b130 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -780,7 +780,7 @@ namespace MediaBrowser.Controller.Entities
var list = new List();
- var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, false, null);
+ var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, false);
return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list;
}
@@ -797,9 +797,8 @@ namespace MediaBrowser.Controller.Entities
/// if set to true [include linked children].
/// The list.
/// if set to true [recursive].
- /// The filter.
/// true if XXXX, false otherwise
- private bool AddChildrenToList(User user, bool includeLinkedChildren, List list, bool recursive, Func filter)
+ private bool AddChildrenToList(User user, bool includeLinkedChildren, List list, bool recursive)
{
var hasLinkedChildren = false;
@@ -807,19 +806,16 @@ namespace MediaBrowser.Controller.Entities
{
if (child.IsVisible(user))
{
- if (filter == null || filter(child))
+ if (!child.IsHiddenFromUser(user))
{
- if (!child.IsHiddenFromUser(user))
- {
- list.Add(child);
- }
+ list.Add(child);
}
if (recursive && child.IsFolder)
{
var folder = (Folder)child;
- if (folder.AddChildrenToList(user, includeLinkedChildren, list, true, filter))
+ if (folder.AddChildrenToList(user, includeLinkedChildren, list, true))
{
hasLinkedChildren = true;
}
@@ -831,11 +827,6 @@ namespace MediaBrowser.Controller.Entities
{
foreach (var child in GetLinkedChildren())
{
- if (filter != null && !filter(child))
- {
- continue;
- }
-
if (child.IsVisible(user))
{
hasLinkedChildren = true;
@@ -864,7 +855,7 @@ namespace MediaBrowser.Controller.Entities
var list = new List();
- var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, true, null);
+ var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, true);
return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list;
}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 1310e77973..ae7118be94 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -195,10 +195,18 @@
+
+
+
+
+
+
+
+
diff --git a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs
new file mode 100644
index 0000000000..567d20f39c
--- /dev/null
+++ b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs
@@ -0,0 +1,41 @@
+using ServiceStack.Web;
+using System;
+
+namespace MediaBrowser.Controller.Net
+{
+ public class AuthenticatedAttribute : Attribute, IHasRequestFilter
+ {
+ public IAuthService AuthService { get; set; }
+
+ ///
+ /// The request filter is executed before the service.
+ ///
+ /// The http request wrapper
+ /// The http response wrapper
+ /// The request DTO
+ public void RequestFilter(IRequest request, IResponse response, object requestDto)
+ {
+ AuthService.Authenticate(request, response, requestDto);
+ }
+
+ ///
+ /// A new shallow copy of this filter is used on every request.
+ ///
+ /// IHasRequestFilter.
+ public IHasRequestFilter Copy()
+ {
+ return this;
+ }
+
+ ///
+ /// Order in which Request Filters are executed.
+ /// <0 Executed before global request filters
+ /// >0 Executed after global request filters
+ ///
+ /// The priority.
+ public int Priority
+ {
+ get { return 0; }
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Net/AuthorizationInfo.cs b/MediaBrowser.Controller/Net/AuthorizationInfo.cs
new file mode 100644
index 0000000000..e609204d69
--- /dev/null
+++ b/MediaBrowser.Controller/Net/AuthorizationInfo.cs
@@ -0,0 +1,32 @@
+
+namespace MediaBrowser.Controller.Net
+{
+ public class AuthorizationInfo
+ {
+ ///
+ /// Gets or sets the user identifier.
+ ///
+ /// The user identifier.
+ public string UserId { get; set; }
+ ///
+ /// Gets or sets the device identifier.
+ ///
+ /// The device identifier.
+ public string DeviceId { get; set; }
+ ///
+ /// Gets or sets the device.
+ ///
+ /// The device.
+ public string Device { get; set; }
+ ///
+ /// Gets or sets the client.
+ ///
+ /// The client.
+ public string Client { get; set; }
+ ///
+ /// Gets or sets the version.
+ ///
+ /// The version.
+ public string Version { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Net/IAuthService.cs b/MediaBrowser.Controller/Net/IAuthService.cs
new file mode 100644
index 0000000000..41859395b6
--- /dev/null
+++ b/MediaBrowser.Controller/Net/IAuthService.cs
@@ -0,0 +1,9 @@
+using ServiceStack.Web;
+
+namespace MediaBrowser.Controller.Net
+{
+ public interface IAuthService
+ {
+ void Authenticate(IRequest request, IResponse response, object requestDto);
+ }
+}
diff --git a/MediaBrowser.Controller/Net/IAuthorizationContext.cs b/MediaBrowser.Controller/Net/IAuthorizationContext.cs
new file mode 100644
index 0000000000..9cf5623700
--- /dev/null
+++ b/MediaBrowser.Controller/Net/IAuthorizationContext.cs
@@ -0,0 +1,14 @@
+using ServiceStack.Web;
+
+namespace MediaBrowser.Controller.Net
+{
+ public interface IAuthorizationContext
+ {
+ ///
+ /// Gets the authorization information.
+ ///
+ /// The request context.
+ /// AuthorizationInfo.
+ AuthorizationInfo GetAuthorizationInfo(IRequest requestContext);
+ }
+}
diff --git a/MediaBrowser.Controller/Net/IHasAuthorization.cs b/MediaBrowser.Controller/Net/IHasAuthorization.cs
new file mode 100644
index 0000000000..6fc70159dd
--- /dev/null
+++ b/MediaBrowser.Controller/Net/IHasAuthorization.cs
@@ -0,0 +1,12 @@
+
+namespace MediaBrowser.Controller.Net
+{
+ public interface IHasAuthorization
+ {
+ ///
+ /// Gets or sets the authorization context.
+ ///
+ /// The authorization context.
+ IAuthorizationContext AuthorizationContext { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Net/IHasResultFactory.cs b/MediaBrowser.Controller/Net/IHasResultFactory.cs
index a87113d1f4..3988b8d615 100644
--- a/MediaBrowser.Controller/Net/IHasResultFactory.cs
+++ b/MediaBrowser.Controller/Net/IHasResultFactory.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Net;
-using ServiceStack.Web;
+using ServiceStack.Web;
namespace MediaBrowser.Controller.Net
{
diff --git a/MediaBrowser.Controller/Net/IHasSession.cs b/MediaBrowser.Controller/Net/IHasSession.cs
new file mode 100644
index 0000000000..e762c1e844
--- /dev/null
+++ b/MediaBrowser.Controller/Net/IHasSession.cs
@@ -0,0 +1,12 @@
+
+namespace MediaBrowser.Controller.Net
+{
+ public interface IHasSession
+ {
+ ///
+ /// Gets or sets the session context.
+ ///
+ /// The session context.
+ ISessionContext SessionContext { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Net/IRestfulService.cs b/MediaBrowser.Controller/Net/IRestfulService.cs
index f55012b734..7d07bb0941 100644
--- a/MediaBrowser.Controller/Net/IRestfulService.cs
+++ b/MediaBrowser.Controller/Net/IRestfulService.cs
@@ -5,6 +5,7 @@ namespace MediaBrowser.Controller.Net
///
/// Interface IRestfulService
///
+ [Logged]
public interface IRestfulService : IService
{
}
diff --git a/MediaBrowser.Controller/Net/ISessionContext.cs b/MediaBrowser.Controller/Net/ISessionContext.cs
new file mode 100644
index 0000000000..31ccd53731
--- /dev/null
+++ b/MediaBrowser.Controller/Net/ISessionContext.cs
@@ -0,0 +1,13 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Session;
+using ServiceStack.Web;
+
+namespace MediaBrowser.Controller.Net
+{
+ public interface ISessionContext
+ {
+ SessionInfo GetSession(IRequest requestContext);
+
+ User GetUser(IRequest requestContext);
+ }
+}
diff --git a/MediaBrowser.Controller/Net/LoggedAttribute.cs b/MediaBrowser.Controller/Net/LoggedAttribute.cs
new file mode 100644
index 0000000000..6df72f7a7e
--- /dev/null
+++ b/MediaBrowser.Controller/Net/LoggedAttribute.cs
@@ -0,0 +1,73 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Session;
+using MediaBrowser.Model.Logging;
+using ServiceStack.Web;
+using System;
+
+namespace MediaBrowser.Controller.Net
+{
+ public class LoggedAttribute : Attribute, IHasRequestFilter
+ {
+ public ILogger Logger { get; set; }
+ public IUserManager UserManager { get; set; }
+ public ISessionManager SessionManager { get; set; }
+ public IAuthorizationContext AuthorizationContext { get; set; }
+
+ ///
+ /// The request filter is executed before the service.
+ ///
+ /// The http request wrapper
+ /// The http response wrapper
+ /// The request DTO
+ public void RequestFilter(IRequest request, IResponse response, object requestDto)
+ {
+ //This code is executed before the service
+ var auth = AuthorizationContext.GetAuthorizationInfo(request);
+
+ if (auth != null)
+ {
+ User user = null;
+
+ if (!string.IsNullOrWhiteSpace(auth.UserId))
+ {
+ var userId = auth.UserId;
+
+ user = UserManager.GetUserById(new Guid(userId));
+ }
+
+ string deviceId = auth.DeviceId;
+ string device = auth.Device;
+ string client = auth.Client;
+ string version = auth.Version;
+
+ if (!string.IsNullOrEmpty(client) && !string.IsNullOrEmpty(deviceId) && !string.IsNullOrEmpty(device) && !string.IsNullOrEmpty(version))
+ {
+ var remoteEndPoint = request.RemoteIp;
+
+ SessionManager.LogSessionActivity(client, version, deviceId, device, remoteEndPoint, user);
+ }
+ }
+ }
+
+ ///
+ /// A new shallow copy of this filter is used on every request.
+ ///
+ /// IHasRequestFilter.
+ public IHasRequestFilter Copy()
+ {
+ return this;
+ }
+
+ ///
+ /// Order in which Request Filters are executed.
+ /// <0 Executed before global request filters
+ /// >0 Executed after global request filters
+ ///
+ /// The priority.
+ public int Priority
+ {
+ get { return 0; }
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index 717b935243..95eca6ba0c 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -340,13 +340,17 @@ namespace MediaBrowser.Providers.Manager
}
catch (Exception ex)
{
+ Logger.ErrorException("Error in {0}", ex, provider.Name);
+
// If a local provider fails, consider that a failure
refreshResult.Status = ProviderRefreshStatus.Failure;
refreshResult.ErrorMessage = ex.Message;
- Logger.ErrorException("Error in {0}", ex, provider.Name);
- // If the local provider fails don't continue with remote providers because the user's saved metadata could be lost
- return refreshResult;
+ if (options.MetadataRefreshMode != MetadataRefreshMode.FullRefresh)
+ {
+ // If the local provider fails don't continue with remote providers because the user's saved metadata could be lost
+ return refreshResult;
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs
index 739b42192b..07c86ed314 100644
--- a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs
+++ b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs
@@ -12,12 +12,8 @@ namespace MediaBrowser.Server.Implementations.Collections
public override bool IsVisible(User user)
{
- if (!GetChildren(user, true).Any())
- {
- return false;
- }
-
- return base.IsVisible(user);
+ return GetChildren(user, true).Any() &&
+ base.IsVisible(user);
}
public override bool IsHidden
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
index 0fc9265f69..833dfc5e45 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -1,13 +1,13 @@
-using System.Net.Sockets;
-using System.Runtime.Serialization;
-using Funq;
+using Funq;
using MediaBrowser.Common;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Server.Implementations.HttpServer.Security;
using ServiceStack;
using ServiceStack.Api.Swagger;
+using ServiceStack.Auth;
using ServiceStack.Host;
using ServiceStack.Host.Handlers;
using ServiceStack.Host.HttpListener;
@@ -27,7 +27,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
{
public class HttpListenerHost : ServiceStackHost, IHttpServer
{
- private string ServerName { get; set; }
private string HandlerPath { get; set; }
private string DefaultRedirectPath { get; set; }
@@ -59,7 +58,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
: base(serviceName, assembliesWithServices)
{
DefaultRedirectPath = defaultRedirectPath;
- ServerName = serviceName;
HandlerPath = handlerPath;
_logger = logManager.GetLogger("HttpServer");
@@ -95,7 +93,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer
container.Adapter = _containerAdapter;
Plugins.Add(new SwaggerFeature());
- Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization"));
+ Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization"));
+
+ Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] {
+ new SessionAuthProvider(_containerAdapter.Resolve()),
+ }));
+
HostContext.GlobalResponseFilters.Add(new ResponseFilter(_logger).FilterResponse);
}
@@ -112,7 +115,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
Config.HandlerFactoryPath = string.IsNullOrEmpty(HandlerPath)
? null
- : HandlerPath;
+ : "/" + HandlerPath;
Config.MetadataRedirectPath = string.IsNullOrEmpty(HandlerPath)
? "metadata"
@@ -161,8 +164,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
if (Listener == null)
Listener = new HttpListener();
- HostContext.Config.HandlerFactoryPath = ListenerRequest.GetHandlerPathIfAny(UrlPrefixes.First());
-
foreach (var prefix in UrlPrefixes)
{
_logger.Info("Adding HttpListener prefix " + prefix);
@@ -172,6 +173,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
IsStarted = true;
_logger.Info("Starting HttpListner");
Listener.Start();
+ _logger.Info("HttpListener started");
for (var i = 0; i < _autoResetEvents.Count; i++)
{
@@ -263,27 +265,27 @@ namespace MediaBrowser.Server.Implementations.HttpServer
var localPath = request.Url.LocalPath;
- if (string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(localPath, "/" + HandlerPath + "/", StringComparison.OrdinalIgnoreCase))
{
context.Response.Redirect(DefaultRedirectPath);
context.Response.Close();
return;
}
- if (string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(localPath, "/" + HandlerPath, StringComparison.OrdinalIgnoreCase))
{
- context.Response.Redirect("mediabrowser/" + DefaultRedirectPath);
+ context.Response.Redirect(HandlerPath + "/" + DefaultRedirectPath);
context.Response.Close();
return;
}
if (string.Equals(localPath, "/", StringComparison.OrdinalIgnoreCase))
{
- context.Response.Redirect("mediabrowser/" + DefaultRedirectPath);
+ context.Response.Redirect(HandlerPath + "/" + DefaultRedirectPath);
context.Response.Close();
return;
}
if (string.IsNullOrEmpty(localPath))
{
- context.Response.Redirect("/mediabrowser/" + DefaultRedirectPath);
+ context.Response.Redirect("/" + HandlerPath + "/" + DefaultRedirectPath);
context.Response.Close();
return;
}
@@ -410,6 +412,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
{
var req = new ListenerRequest(httpContext, operationName, RequestAttributes.None);
req.RequestAttributes = req.GetAttributes();
+
return req;
}
@@ -442,7 +445,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer
var httpReq = GetRequest(context, operationName);
var httpRes = httpReq.Response;
+ //var pathInfo = httpReq.PathInfo;
+
var handler = HttpHandlerFactory.GetHandler(httpReq);
+ //var handler = HttpHandlerFactory.GetHandlerForPathInfo(httpReq.HttpMethod, pathInfo, pathInfo, httpReq.GetPhysicalPath());
var serviceStackHandler = handler as IServiceStackHandler;
if (serviceStackHandler != null)
diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs
index 1ff199eb4d..9de6972f86 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs
@@ -228,5 +228,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
}
public string StatusDescription { get; set; }
+
+ public int PaddingLength { get; set; }
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs
new file mode 100644
index 0000000000..ddb583f5d8
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs
@@ -0,0 +1,113 @@
+using MediaBrowser.Controller.Net;
+using ServiceStack;
+using ServiceStack.Auth;
+using ServiceStack.Web;
+using System;
+using System.Collections.Specialized;
+using System.Linq;
+
+namespace MediaBrowser.Server.Implementations.HttpServer.Security
+{
+ public class AuthService : IAuthService
+ {
+ ///
+ /// Restrict authentication to a specific .
+ /// For example, if this attribute should only permit access
+ /// if the user is authenticated with ,
+ /// you should set this property to .
+ ///
+ public string Provider { get; set; }
+
+ ///
+ /// Redirect the client to a specific URL if authentication failed.
+ /// If this property is null, simply `401 Unauthorized` is returned.
+ ///
+ public string HtmlRedirect { get; set; }
+
+ public void Authenticate(IRequest req, IResponse res, object requestDto)
+ {
+ if (HostContext.HasValidAuthSecret(req))
+ return;
+
+ ExecuteBasic(req, res, requestDto); //first check if session is authenticated
+ if (res.IsClosed) return; //AuthenticateAttribute already closed the request (ie auth failed)
+
+ ValidateUser(req);
+ }
+
+ private void ValidateUser(IRequest req)
+ {
+ var user = req.TryResolve().GetUser(req);
+
+ if (user == null || user.Configuration.IsDisabled)
+ {
+ throw new UnauthorizedAccessException("Unauthorized access.");
+ }
+ }
+
+ private void ExecuteBasic(IRequest req, IResponse res, object requestDto)
+ {
+ if (AuthenticateService.AuthProviders == null)
+ throw new InvalidOperationException(
+ "The AuthService must be initialized by calling AuthService.Init to use an authenticate attribute");
+
+ var matchingOAuthConfigs = AuthenticateService.AuthProviders.Where(x =>
+ this.Provider.IsNullOrEmpty()
+ || x.Provider == this.Provider).ToList();
+
+ if (matchingOAuthConfigs.Count == 0)
+ {
+ res.WriteError(req, requestDto, "No OAuth Configs found matching {0} provider"
+ .Fmt(this.Provider ?? "any"));
+ res.EndRequest();
+ }
+
+ matchingOAuthConfigs.OfType()
+ .Each(x => x.PreAuthenticate(req, res));
+
+ var session = req.GetSession();
+ if (session == null || !matchingOAuthConfigs.Any(x => session.IsAuthorized(x.Provider)))
+ {
+ if (this.DoHtmlRedirectIfConfigured(req, res, true)) return;
+
+ AuthProvider.HandleFailedAuth(matchingOAuthConfigs[0], session, req, res);
+ }
+ }
+
+ protected bool DoHtmlRedirectIfConfigured(IRequest req, IResponse res, bool includeRedirectParam = false)
+ {
+ var htmlRedirect = this.HtmlRedirect ?? AuthenticateService.HtmlRedirect;
+ if (htmlRedirect != null && req.ResponseContentType.MatchesContentType(MimeTypes.Html))
+ {
+ DoHtmlRedirect(htmlRedirect, req, res, includeRedirectParam);
+ return true;
+ }
+ return false;
+ }
+
+ public static void DoHtmlRedirect(string redirectUrl, IRequest req, IResponse res, bool includeRedirectParam)
+ {
+ var url = req.ResolveAbsoluteUrl(redirectUrl);
+ if (includeRedirectParam)
+ {
+ var absoluteRequestPath = req.ResolveAbsoluteUrl("~" + req.PathInfo + ToQueryString(req.QueryString));
+ url = url.AddQueryParam(HostContext.ResolveLocalizedString(LocalizedStrings.Redirect), absoluteRequestPath);
+ }
+
+ res.RedirectToUrl(url);
+ }
+
+ private static string ToQueryString(INameValueCollection queryStringCollection)
+ {
+ return ToQueryString((NameValueCollection)queryStringCollection.Original);
+ }
+
+ private static string ToQueryString(NameValueCollection queryStringCollection)
+ {
+ if (queryStringCollection == null || queryStringCollection.Count == 0)
+ return String.Empty;
+
+ return "?" + queryStringCollection.ToFormUrlEncoded();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
new file mode 100644
index 0000000000..6ea77f2518
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Collections.Generic;
+using MediaBrowser.Controller.Net;
+using ServiceStack.Web;
+
+namespace MediaBrowser.Server.Implementations.HttpServer.Security
+{
+ public class AuthorizationContext : IAuthorizationContext
+ {
+ public AuthorizationInfo GetAuthorizationInfo(IRequest requestContext)
+ {
+ return GetAuthorization(requestContext);
+ }
+
+ ///
+ /// Gets the authorization.
+ ///
+ /// The HTTP req.
+ /// Dictionary{System.StringSystem.String}.
+ private static AuthorizationInfo GetAuthorization(IRequest httpReq)
+ {
+ var auth = GetAuthorizationDictionary(httpReq);
+
+ string userId = null;
+ string deviceId = null;
+ string device = null;
+ string client = null;
+ string version = null;
+
+ if (auth != null)
+ {
+ auth.TryGetValue("UserId", out userId);
+ auth.TryGetValue("DeviceId", out deviceId);
+ auth.TryGetValue("Device", out device);
+ auth.TryGetValue("Client", out client);
+ auth.TryGetValue("Version", out version);
+ }
+
+ return new AuthorizationInfo
+ {
+ Client = client,
+ Device = device,
+ DeviceId = deviceId,
+ UserId = userId,
+ Version = version
+ };
+ }
+
+ ///
+ /// Gets the auth.
+ ///
+ /// The HTTP req.
+ /// Dictionary{System.StringSystem.String}.
+ private static Dictionary GetAuthorizationDictionary(IRequest httpReq)
+ {
+ var auth = httpReq.Headers["Authorization"];
+
+ return GetAuthorization(auth);
+ }
+
+ ///
+ /// Gets the authorization.
+ ///
+ /// The authorization header.
+ /// Dictionary{System.StringSystem.String}.
+ private static Dictionary GetAuthorization(string authorizationHeader)
+ {
+ if (authorizationHeader == null) return null;
+
+ var parts = authorizationHeader.Split(' ');
+
+ // There should be at least to parts
+ if (parts.Length < 2) return null;
+
+ // It has to be a digest request
+ if (!string.Equals(parts[0], "MediaBrowser", StringComparison.OrdinalIgnoreCase))
+ {
+ return null;
+ }
+
+ // Remove uptil the first space
+ authorizationHeader = authorizationHeader.Substring(authorizationHeader.IndexOf(' '));
+ parts = authorizationHeader.Split(',');
+
+ var result = new Dictionary(StringComparer.OrdinalIgnoreCase);
+
+ foreach (var item in parts)
+ {
+ var param = item.Trim().Split(new[] { '=' }, 2);
+ result.Add(param[0], param[1].Trim(new[] { '"' }));
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/SessionAuthProvider.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/SessionAuthProvider.cs
new file mode 100644
index 0000000000..7c31731012
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/HttpServer/Security/SessionAuthProvider.cs
@@ -0,0 +1,35 @@
+using MediaBrowser.Controller.Net;
+using ServiceStack;
+using ServiceStack.Auth;
+
+namespace MediaBrowser.Server.Implementations.HttpServer.Security
+{
+ public class SessionAuthProvider : CredentialsAuthProvider
+ {
+ private readonly ISessionContext _sessionContext;
+
+ public SessionAuthProvider(ISessionContext sessionContext)
+ {
+ _sessionContext = sessionContext;
+ }
+
+ public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
+ {
+ return true;
+ }
+
+ public override bool IsAuthorized(IAuthSession session, IAuthTokens tokens, Authenticate request = null)
+ {
+ return true;
+ }
+
+ protected override void SaveUserAuth(IServiceBase authService, IAuthSession session, IAuthRepository authRepo, IAuthTokens tokens)
+ {
+ }
+
+ public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
+ {
+ return base.Authenticate(authService, session, request);
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs
new file mode 100644
index 0000000000..f67c643c82
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/HttpServer/Security/SessionContext.cs
@@ -0,0 +1,36 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.Session;
+using ServiceStack.Web;
+
+namespace MediaBrowser.Server.Implementations.HttpServer.Security
+{
+ public class SessionContext : ISessionContext
+ {
+ private readonly IUserManager _userManager;
+ private readonly ISessionManager _sessionManager;
+ private readonly IAuthorizationContext _authContext;
+
+ public SessionContext(IUserManager userManager, IAuthorizationContext authContext, ISessionManager sessionManager)
+ {
+ _userManager = userManager;
+ _authContext = authContext;
+ _sessionManager = sessionManager;
+ }
+
+ public SessionInfo GetSession(IRequest requestContext)
+ {
+ var authorization = _authContext.GetAuthorizationInfo(requestContext);
+
+ return _sessionManager.GetSession(authorization.DeviceId, authorization.Client, authorization.Version);
+ }
+
+ public User GetUser(IRequest requestContext)
+ {
+ var session = GetSession(requestContext);
+
+ return session == null || !session.UserId.HasValue ? null : _userManager.GetUserById(session.UserId.Value);
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 3401078518..10e27bc304 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -133,6 +133,7 @@
+
@@ -141,9 +142,12 @@
+
+
+
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index 87f18e4cba..dbca940657 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -62,6 +62,7 @@ using MediaBrowser.Server.Implementations.Dto;
using MediaBrowser.Server.Implementations.EntryPoints;
using MediaBrowser.Server.Implementations.FileOrganization;
using MediaBrowser.Server.Implementations.HttpServer;
+using MediaBrowser.Server.Implementations.HttpServer.Security;
using MediaBrowser.Server.Implementations.IO;
using MediaBrowser.Server.Implementations.Library;
using MediaBrowser.Server.Implementations.LiveTv;
@@ -598,7 +599,7 @@ namespace MediaBrowser.ServerApplication
RegisterSingleInstance(() => new SearchEngine(LogManager, LibraryManager, UserManager));
- HttpServer = ServerFactory.CreateServer(this, LogManager, "Media Browser", "mediabrowser", "dashboard/index.html");
+ HttpServer = ServerFactory.CreateServer(this, LogManager, "Media Browser", WebApplicationName, "dashboard/index.html");
RegisterSingleInstance(HttpServer, false);
progress.Report(10);
@@ -667,6 +668,11 @@ namespace MediaBrowser.ServerApplication
MediaEncoder, ChapterManager);
RegisterSingleInstance(EncodingManager);
+ var authContext = new AuthorizationContext();
+ RegisterSingleInstance(authContext);
+ RegisterSingleInstance(new SessionContext(UserManager, authContext, SessionManager));
+ RegisterSingleInstance(new AuthService());
+
RegisterSingleInstance(new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder));
var displayPreferencesTask = Task.Run(async () => await ConfigureDisplayPreferencesRepositories().ConfigureAwait(false));
diff --git a/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs
index 77a543ad7f..4ba98e9b69 100644
--- a/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs
+++ b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs
@@ -25,7 +25,7 @@ namespace MediaBrowser.ServerApplication.Native
public static void OpenDashboardPage(string page, User loggedInUser, IServerConfigurationManager configurationManager, IServerApplicationHost appHost, ILogger logger)
{
var url = "http://localhost:" + configurationManager.Configuration.HttpServerPortNumber + "/" +
- appHost.WebApplicationName + "/dashboard/" + page;
+ appHost.WebApplicationName + "/web/" + page;
OpenUrl(url, logger);
}
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index 2ca0669cd6..80f864a326 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -25,6 +25,7 @@ namespace MediaBrowser.WebDashboard.Api
/// Class GetDashboardConfigurationPages
///
[Route("/dashboard/ConfigurationPages", "GET")]
+ [Route("/web/ConfigurationPages", "GET")]
public class GetDashboardConfigurationPages : IReturn>
{
///
@@ -38,6 +39,7 @@ namespace MediaBrowser.WebDashboard.Api
/// Class GetDashboardConfigurationPage
///
[Route("/dashboard/ConfigurationPage", "GET")]
+ [Route("/web/ConfigurationPage", "GET")]
public class GetDashboardConfigurationPage
{
///
@@ -50,6 +52,7 @@ namespace MediaBrowser.WebDashboard.Api
///
/// Class GetDashboardResource
///
+ [Route("/web/{ResourceName*}", "GET")]
[Route("/dashboard/{ResourceName*}", "GET")]
public class GetDashboardResource
{
diff --git a/MediaBrowser.XbmcMetadata/Providers/SeriesNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/SeriesNfoProvider.cs
index 4a71d9fd34..9db0cc8fc7 100644
--- a/MediaBrowser.XbmcMetadata/Providers/SeriesNfoProvider.cs
+++ b/MediaBrowser.XbmcMetadata/Providers/SeriesNfoProvider.cs
@@ -28,7 +28,7 @@ namespace MediaBrowser.XbmcMetadata.Providers
protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
{
- return directoryService.GetFile(Path.Combine(info.Path, "series.nfo"));
+ return directoryService.GetFile(Path.Combine(info.Path, "tvshow.nfo"));
}
}
}