diff --git a/MediaBrowser.Api/AuthorizationRequestFilterAttribute.cs b/MediaBrowser.Api/AuthorizationRequestFilterAttribute.cs index 82df791ded..6cecbd0b62 100644 --- a/MediaBrowser.Api/AuthorizationRequestFilterAttribute.cs +++ b/MediaBrowser.Api/AuthorizationRequestFilterAttribute.cs @@ -81,6 +81,14 @@ namespace MediaBrowser.Api 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. /// diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index f92c4932e0..5b123eb974 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -275,6 +275,21 @@ namespace MediaBrowser.Api.LiveTv _userManager = userManager; } + private void AssertUserCanManageLiveTv() + { + var user = AuthorizationRequestFilterAttribute.GetCurrentUser(Request, _userManager); + + if (user == null) + { + throw new UnauthorizedAccessException("Anonymous live tv management is not allowed."); + } + + if (!user.Configuration.EnableLiveTvManagement) + { + throw new UnauthorizedAccessException("The current user does not have permission to manage live tv."); + } + } + public object Get(GetServices request) { var services = _liveTvManager.Services @@ -415,6 +430,8 @@ namespace MediaBrowser.Api.LiveTv public void Delete(DeleteRecording request) { + AssertUserCanManageLiveTv(); + var task = _liveTvManager.DeleteRecording(request.Id); Task.WaitAll(task); @@ -422,6 +439,8 @@ namespace MediaBrowser.Api.LiveTv public void Delete(CancelTimer request) { + AssertUserCanManageLiveTv(); + var task = _liveTvManager.CancelTimer(request.Id); Task.WaitAll(task); @@ -429,6 +448,8 @@ namespace MediaBrowser.Api.LiveTv public void Post(UpdateTimer request) { + AssertUserCanManageLiveTv(); + var task = _liveTvManager.UpdateTimer(request, CancellationToken.None); Task.WaitAll(task); @@ -455,6 +476,8 @@ namespace MediaBrowser.Api.LiveTv public void Delete(CancelSeriesTimer request) { + AssertUserCanManageLiveTv(); + var task = _liveTvManager.CancelSeriesTimer(request.Id); Task.WaitAll(task); @@ -462,6 +485,8 @@ namespace MediaBrowser.Api.LiveTv public void Post(UpdateSeriesTimer request) { + AssertUserCanManageLiveTv(); + var task = _liveTvManager.UpdateSeriesTimer(request, CancellationToken.None); Task.WaitAll(task); @@ -494,6 +519,8 @@ namespace MediaBrowser.Api.LiveTv public void Post(CreateSeriesTimer request) { + AssertUserCanManageLiveTv(); + var task = _liveTvManager.CreateSeriesTimer(request, CancellationToken.None); Task.WaitAll(task); @@ -501,6 +528,8 @@ namespace MediaBrowser.Api.LiveTv public void Post(CreateTimer request) { + AssertUserCanManageLiveTv(); + var task = _liveTvManager.CreateTimer(request, CancellationToken.None); Task.WaitAll(task); diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs index 81613c1df6..004f0b4525 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs @@ -119,12 +119,13 @@ namespace MediaBrowser.Controller.LiveTv Task> GetTimersAsync(CancellationToken cancellationToken); /// - /// Gets the timer defaults asynchronous. + /// Gets the new timer defaults asynchronous. /// /// The cancellation token. - /// Task{TimerInfo}. - Task GetNewTimerDefaultsAsync(CancellationToken cancellationToken); - + /// The program. + /// Task{SeriesTimerInfo}. + Task GetNewTimerDefaultsAsync(CancellationToken cancellationToken, ProgramInfo program = null); + /// /// Gets the series timers asynchronous. /// diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index 90accff94c..7cc61e7fdd 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -67,6 +67,8 @@ namespace MediaBrowser.Model.Configuration public bool BlockUnratedGames { get; set; } public bool BlockUnratedBooks { get; set; } + public bool EnableLiveTvManagement { get; set; } + /// /// Initializes a new instance of the class. /// @@ -75,6 +77,8 @@ namespace MediaBrowser.Model.Configuration IsAdministrator = true; EnableRemoteControlOfOtherUsers = true; BlockNotRated = false; + + EnableLiveTvManagement = true; } } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index 121bf53d49..55a485318d 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -70,7 +70,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV } // Without these movies that have the name season in them could cause the parent folder to be resolved as a series - if (filename.IndexOf("[boxset]", StringComparison.OrdinalIgnoreCase) != -1 || filename.IndexOf("[tmdbid=", StringComparison.OrdinalIgnoreCase) != -1) + if (filename.IndexOf("[tmdbid=", StringComparison.OrdinalIgnoreCase) != -1) { return null; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index a8b62c5a7b..b53b3b651b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1011,24 +1011,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv .FirstOrDefault(); } + private async Task GetNewTimerDefaultsInternal(CancellationToken cancellationToken, ProgramInfo program = null) + { + var info = await ActiveService.GetNewTimerDefaultsAsync(cancellationToken, program).ConfigureAwait(false); + + info.Id = null; + + return info; + } + public async Task GetNewTimerDefaults(CancellationToken cancellationToken) { - var service = ActiveService; + var info = await GetNewTimerDefaultsInternal(cancellationToken).ConfigureAwait(false); - var info = await service.GetNewTimerDefaultsAsync(cancellationToken).ConfigureAwait(false); - - var obj = _tvDtoService.GetSeriesTimerInfoDto(info, service, null); - - obj.Id = obj.ExternalId = string.Empty; + var obj = _tvDtoService.GetSeriesTimerInfoDto(info, ActiveService, null); return obj; } public async Task GetNewTimerDefaults(string programId, CancellationToken cancellationToken) { - var info = await GetNewTimerDefaults(cancellationToken).ConfigureAwait(false); + var program = GetInternalProgram(programId).ProgramInfo; + var programDto = await GetProgram(programId, cancellationToken).ConfigureAwait(false); - var program = await GetProgram(programId, cancellationToken).ConfigureAwait(false); + var defaults = await GetNewTimerDefaultsInternal(cancellationToken, program).ConfigureAwait(false); + var info = _tvDtoService.GetSeriesTimerInfoDto(defaults, ActiveService, null); info.Days = new List { @@ -1039,13 +1046,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv info.Name = program.Name; info.ChannelId = program.ChannelId; - info.ChannelName = program.ChannelName; + info.ChannelName = programDto.ChannelName; info.EndDate = program.EndDate; info.StartDate = program.StartDate; info.Name = program.Name; info.Overview = program.Overview; info.ProgramId = program.Id; - info.ExternalProgramId = program.ExternalId; + info.ExternalProgramId = programDto.ExternalId; return info; } diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index b35341ebb0..578f711760 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -378,6 +378,17 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi }); }; + self.getAuthorizedFeatures = function (options) { + + var url = self.getUrl("Users/AuthorizedFeatures", options || {}); + + return self.ajax({ + type: "GET", + url: url, + dataType: "json" + }); + }; + self.getLiveTvServices = function (options) { var url = self.getUrl("LiveTv/Services", options || {}); diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index b28f5655a4..939ca9997a 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 9c011b3f41..dd0a066153 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.299 + 3.0.300 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index d0cd3a3069..72fc2ac63a 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.299 + 3.0.300 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index cc15b8c4d1..f5db426ca2 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.299 + 3.0.300 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - +