diff options
Diffstat (limited to 'Jellyfin.Api/Controllers/LiveTvController.cs')
| -rw-r--r-- | Jellyfin.Api/Controllers/LiveTvController.cs | 112 |
1 files changed, 40 insertions, 72 deletions
diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs index 3425c8589..318ed5c67 100644 --- a/Jellyfin.Api/Controllers/LiveTvController.cs +++ b/Jellyfin.Api/Controllers/LiveTvController.cs @@ -10,20 +10,19 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Jellyfin.Api.Attributes; +using Jellyfin.Api.Constants; using Jellyfin.Api.Extensions; using Jellyfin.Api.Helpers; using Jellyfin.Api.ModelBinders; using Jellyfin.Api.Models.LiveTvDtos; using Jellyfin.Data.Enums; using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; @@ -94,7 +93,7 @@ public class LiveTvController : BaseJellyfinApiController /// </returns> [HttpGet("Info")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public ActionResult<LiveTvInfo> GetLiveTvInfo() { return _liveTvManager.GetLiveTvInfo(CancellationToken.None); @@ -130,7 +129,7 @@ public class LiveTvController : BaseJellyfinApiController /// </returns> [HttpGet("Channels")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public ActionResult<QueryResult<BaseItemDto>> GetLiveTvChannels( [FromQuery] ChannelType? type, [FromQuery] Guid? userId, @@ -209,7 +208,7 @@ public class LiveTvController : BaseJellyfinApiController /// <returns>An <see cref="OkResult"/> containing the live tv channel.</returns> [HttpGet("Channels/{channelId}")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public ActionResult<BaseItemDto> GetChannel([FromRoute, Required] Guid channelId, [FromQuery] Guid? userId) { var user = userId is null || userId.Value.Equals(default) @@ -250,7 +249,7 @@ public class LiveTvController : BaseJellyfinApiController /// <returns>An <see cref="OkResult"/> containing the live tv recordings.</returns> [HttpGet("Recordings")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public ActionResult<QueryResult<BaseItemDto>> GetRecordings( [FromQuery] string? channelId, [FromQuery] Guid? userId, @@ -321,7 +320,7 @@ public class LiveTvController : BaseJellyfinApiController /// <returns>An <see cref="OkResult"/> containing the live tv recordings.</returns> [HttpGet("Recordings/Series")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [Obsolete("This endpoint is obsolete.")] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "channelId", Justification = "Imported from ServiceStack")] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "userId", Justification = "Imported from ServiceStack")] @@ -364,7 +363,7 @@ public class LiveTvController : BaseJellyfinApiController /// <returns>An <see cref="OkResult"/> containing the recording groups.</returns> [HttpGet("Recordings/Groups")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [Obsolete("This endpoint is obsolete.")] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "userId", Justification = "Imported from ServiceStack")] public ActionResult<QueryResult<BaseItemDto>> GetRecordingGroups([FromQuery] Guid? userId) @@ -380,7 +379,7 @@ public class LiveTvController : BaseJellyfinApiController /// <returns>An <see cref="OkResult"/> containing the recording folders.</returns> [HttpGet("Recordings/Folders")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public ActionResult<QueryResult<BaseItemDto>> GetRecordingFolders([FromQuery] Guid? userId) { var user = userId is null || userId.Value.Equals(default) @@ -402,7 +401,7 @@ public class LiveTvController : BaseJellyfinApiController /// <returns>An <see cref="OkResult"/> containing the live tv recording.</returns> [HttpGet("Recordings/{recordingId}")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public ActionResult<BaseItemDto> GetRecording([FromRoute, Required] Guid recordingId, [FromQuery] Guid? userId) { var user = userId is null || userId.Value.Equals(default) @@ -424,10 +423,9 @@ public class LiveTvController : BaseJellyfinApiController /// <returns>A <see cref="NoContentResult"/>.</returns> [HttpPost("Tuners/{tunerId}/Reset")] [ProducesResponseType(StatusCodes.Status204NoContent)] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] public async Task<ActionResult> ResetTuner([FromRoute, Required] string tunerId) { - await AssertUserCanManageLiveTv().ConfigureAwait(false); await _liveTvManager.ResetTuner(tunerId, CancellationToken.None).ConfigureAwait(false); return NoContent(); } @@ -442,7 +440,7 @@ public class LiveTvController : BaseJellyfinApiController /// </returns> [HttpGet("Timers/{timerId}")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public async Task<ActionResult<TimerInfoDto>> GetTimer([FromRoute, Required] string timerId) { return await _liveTvManager.GetTimer(timerId, CancellationToken.None).ConfigureAwait(false); @@ -458,7 +456,7 @@ public class LiveTvController : BaseJellyfinApiController /// </returns> [HttpGet("Timers/Defaults")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public async Task<ActionResult<SeriesTimerInfoDto>> GetDefaultTimer([FromQuery] string? programId) { return string.IsNullOrEmpty(programId) @@ -478,7 +476,7 @@ public class LiveTvController : BaseJellyfinApiController /// </returns> [HttpGet("Timers")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public async Task<ActionResult<QueryResult<TimerInfoDto>>> GetTimers( [FromQuery] string? channelId, [FromQuery] string? seriesTimerId, @@ -532,7 +530,7 @@ public class LiveTvController : BaseJellyfinApiController /// </returns> [HttpGet("Programs")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public async Task<ActionResult<QueryResult<BaseItemDto>>> GetLiveTvPrograms( [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] channelIds, [FromQuery] Guid? userId, @@ -615,7 +613,7 @@ public class LiveTvController : BaseJellyfinApiController /// </returns> [HttpPost("Programs")] [ProducesResponseType(StatusCodes.Status200OK)] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] public async Task<ActionResult<QueryResult<BaseItemDto>>> GetPrograms([FromBody] GetProgramsDto body) { var user = body.UserId.Equals(default) ? null : _userManager.GetUserById(body.UserId); @@ -681,7 +679,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Recommended epgs returned.</response> /// <returns>A <see cref="OkResult"/> containing the queryresult of recommended epgs.</returns> [HttpGet("Programs/Recommended")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<QueryResult<BaseItemDto>>> GetRecommendedPrograms( [FromQuery] Guid? userId, @@ -733,7 +731,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Program returned.</response> /// <returns>An <see cref="OkResult"/> containing the livetv program.</returns> [HttpGet("Programs/{programId}")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<BaseItemDto>> GetProgram( [FromRoute, Required] string programId, @@ -754,13 +752,11 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="404">Item not found.</response> /// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if item not found.</returns> [HttpDelete("Recordings/{recordingId}")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task<ActionResult> DeleteRecording([FromRoute, Required] Guid recordingId) + public ActionResult DeleteRecording([FromRoute, Required] Guid recordingId) { - await AssertUserCanManageLiveTv().ConfigureAwait(false); - var item = _libraryManager.GetItemById(recordingId); if (item is null) { @@ -782,11 +778,10 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="204">Timer deleted.</response> /// <returns>A <see cref="NoContentResult"/>.</returns> [HttpDelete("Timers/{timerId}")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task<ActionResult> CancelTimer([FromRoute, Required] string timerId) { - await AssertUserCanManageLiveTv().ConfigureAwait(false); await _liveTvManager.CancelTimer(timerId).ConfigureAwait(false); return NoContent(); } @@ -799,12 +794,11 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="204">Timer updated.</response> /// <returns>A <see cref="NoContentResult"/>.</returns> [HttpPost("Timers/{timerId}")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status204NoContent)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "timerId", Justification = "Imported from ServiceStack")] public async Task<ActionResult> UpdateTimer([FromRoute, Required] string timerId, [FromBody] TimerInfoDto timerInfo) { - await AssertUserCanManageLiveTv().ConfigureAwait(false); await _liveTvManager.UpdateTimer(timerInfo, CancellationToken.None).ConfigureAwait(false); return NoContent(); } @@ -816,11 +810,10 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="204">Timer created.</response> /// <returns>A <see cref="NoContentResult"/>.</returns> [HttpPost("Timers")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task<ActionResult> CreateTimer([FromBody] TimerInfoDto timerInfo) { - await AssertUserCanManageLiveTv().ConfigureAwait(false); await _liveTvManager.CreateTimer(timerInfo, CancellationToken.None).ConfigureAwait(false); return NoContent(); } @@ -833,7 +826,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="404">Series timer not found.</response> /// <returns>A <see cref="OkResult"/> on success, or a <see cref="NotFoundResult"/> if timer not found.</returns> [HttpGet("SeriesTimers/{timerId}")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task<ActionResult<SeriesTimerInfoDto>> GetSeriesTimer([FromRoute, Required] string timerId) @@ -855,7 +848,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Timers returned.</response> /// <returns>An <see cref="OkResult"/> of live tv series timers.</returns> [HttpGet("SeriesTimers")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<QueryResult<SeriesTimerInfoDto>>> GetSeriesTimers([FromQuery] string? sortBy, [FromQuery] SortOrder? sortOrder) { @@ -875,11 +868,10 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="204">Timer cancelled.</response> /// <returns>A <see cref="NoContentResult"/>.</returns> [HttpDelete("SeriesTimers/{timerId}")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task<ActionResult> CancelSeriesTimer([FromRoute, Required] string timerId) { - await AssertUserCanManageLiveTv().ConfigureAwait(false); await _liveTvManager.CancelSeriesTimer(timerId).ConfigureAwait(false); return NoContent(); } @@ -892,12 +884,11 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="204">Series timer updated.</response> /// <returns>A <see cref="NoContentResult"/>.</returns> [HttpPost("SeriesTimers/{timerId}")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status204NoContent)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "timerId", Justification = "Imported from ServiceStack")] public async Task<ActionResult> UpdateSeriesTimer([FromRoute, Required] string timerId, [FromBody] SeriesTimerInfoDto seriesTimerInfo) { - await AssertUserCanManageLiveTv().ConfigureAwait(false); await _liveTvManager.UpdateSeriesTimer(seriesTimerInfo, CancellationToken.None).ConfigureAwait(false); return NoContent(); } @@ -909,11 +900,10 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="204">Series timer info created.</response> /// <returns>A <see cref="NoContentResult"/>.</returns> [HttpPost("SeriesTimers")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task<ActionResult> CreateSeriesTimer([FromBody] SeriesTimerInfoDto seriesTimerInfo) { - await AssertUserCanManageLiveTv().ConfigureAwait(false); await _liveTvManager.CreateSeriesTimer(seriesTimerInfo, CancellationToken.None).ConfigureAwait(false); return NoContent(); } @@ -924,7 +914,7 @@ public class LiveTvController : BaseJellyfinApiController /// <param name="groupId">Group id.</param> /// <returns>A <see cref="NotFoundResult"/>.</returns> [HttpGet("Recordings/Groups/{groupId}")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Obsolete("This endpoint is obsolete.")] public ActionResult<BaseItemDto> GetRecordingGroup([FromRoute, Required] Guid groupId) @@ -938,7 +928,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Guid info returned.</response> /// <returns>An <see cref="OkResult"/> containing the guide info.</returns> [HttpGet("GuideInfo")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult<GuideInfo> GetGuideInfo() { @@ -952,7 +942,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Created tuner host returned.</response> /// <returns>A <see cref="OkResult"/> containing the created tuner host.</returns> [HttpPost("TunerHosts")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<TunerHostInfo>> AddTunerHost([FromBody] TunerHostInfo tunerHostInfo) { @@ -966,7 +956,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="204">Tuner host deleted.</response> /// <returns>A <see cref="NoContentResult"/>.</returns> [HttpDelete("TunerHosts")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult DeleteTunerHost([FromQuery] string? id) { @@ -982,7 +972,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Default listings provider info returned.</response> /// <returns>An <see cref="OkResult"/> containing the default listings provider info.</returns> [HttpGet("ListingProviders/Default")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult<ListingsProviderInfo> GetDefaultListingProvider() { @@ -999,7 +989,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Created listings provider returned.</response> /// <returns>A <see cref="OkResult"/> containing the created listings provider.</returns> [HttpPost("ListingProviders")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status200OK)] [SuppressMessage("Microsoft.Performance", "CA5350:RemoveSha1", MessageId = "AddListingProvider", Justification = "Imported from ServiceStack")] public async Task<ActionResult<ListingsProviderInfo>> AddListingProvider( @@ -1025,7 +1015,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="204">Listing provider deleted.</response> /// <returns>A <see cref="NoContentResult"/>.</returns> [HttpDelete("ListingProviders")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult DeleteListingProvider([FromQuery] string? id) { @@ -1043,7 +1033,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Available lineups returned.</response> /// <returns>A <see cref="OkResult"/> containing the available lineups.</returns> [HttpGet("ListingProviders/Lineups")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<IEnumerable<NameIdPair>>> GetLineups( [FromQuery] string? id, @@ -1060,7 +1050,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Available countries returned.</response> /// <returns>A <see cref="FileResult"/> containing the available countries.</returns> [HttpGet("ListingProviders/SchedulesDirect/Countries")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesFile(MediaTypeNames.Application.Json)] public async Task<ActionResult> GetSchedulesDirectCountries() @@ -1081,7 +1071,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Channel mapping options returned.</response> /// <returns>An <see cref="OkResult"/> containing the channel mapping options.</returns> [HttpGet("ChannelMappingOptions")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<ChannelMappingOptionsDto>> GetChannelMappingOptions([FromQuery] string? providerId) { @@ -1119,7 +1109,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Created channel mapping returned.</response> /// <returns>An <see cref="OkResult"/> containing the created channel mapping.</returns> [HttpPost("ChannelMappings")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<TunerChannelMapping>> SetChannelMapping([FromBody, Required] SetChannelMappingDto setChannelMappingDto) { @@ -1132,7 +1122,7 @@ public class LiveTvController : BaseJellyfinApiController /// <response code="200">Tuner host types returned.</response> /// <returns>An <see cref="OkResult"/> containing the tuner host types.</returns> [HttpGet("TunerHosts/Types")] - [Authorize] + [Authorize(Policy = Policies.LiveTvAccess)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult<IEnumerable<NameIdPair>> GetTunerHostTypes() { @@ -1147,7 +1137,7 @@ public class LiveTvController : BaseJellyfinApiController /// <returns>An <see cref="OkResult"/> containing the tuners.</returns> [HttpGet("Tuners/Discvover", Name = "DiscvoverTuners")] [HttpGet("Tuners/Discover")] - [Authorize] + [Authorize(Policy = Policies.LiveTvManagement)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<IEnumerable<TunerHostInfo>>> DiscoverTuners([FromQuery] bool newDevicesOnly = false) { @@ -1207,26 +1197,4 @@ public class LiveTvController : BaseJellyfinApiController var liveStream = new ProgressiveFileStream(liveStreamInfo.GetStream()); return new FileStreamResult(liveStream, MimeTypes.GetMimeType("file." + container)); } - - private async Task AssertUserCanManageLiveTv() - { - var user = _userManager.GetUserById(User.GetUserId()) ?? throw new ResourceNotFoundException(); - var session = await _sessionManager.LogSessionActivity( - User.GetClient(), - User.GetVersion(), - User.GetDeviceId(), - User.GetDevice(), - HttpContext.GetNormalizedRemoteIp().ToString(), - user).ConfigureAwait(false); - - if (session.UserId.Equals(default)) - { - throw new SecurityException("Anonymous live tv management is not allowed."); - } - - if (!user.HasPermission(PermissionKind.EnableLiveTvManagement)) - { - throw new SecurityException("The current user does not have permission to manage live tv."); - } - } } |
