Guard against using invalid sort keys

pull/7236/head
Bogdan 5 months ago committed by GitHub
parent 85f53e8cb1
commit fca8c36156
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -48,7 +48,7 @@ const COLUMNS: Column[] = [
isSortable: true, isSortable: true,
}, },
{ {
name: 'tvdbid', name: 'tvdbId',
label: () => translate('TvdbId'), label: () => translate('TvdbId'),
isVisible: true, isVisible: true,
isSortable: true, isSortable: true,

@ -110,7 +110,6 @@ export const defaultState = {
{ {
name: 'actions', name: 'actions',
columnLabel: () => translate('Actions'), columnLabel: () => translate('Actions'),
isSortable: true,
isVisible: true, isVisible: true,
isModifiable: false isModifiable: false
} }

@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.Blocklisting; using NzbDrone.Core.Blocklisting;
@ -28,7 +30,16 @@ namespace Sonarr.Api.V3.Blocklist
public PagingResource<BlocklistResource> GetBlocklist([FromQuery] PagingRequestResource paging, [FromQuery] int[] seriesIds = null, [FromQuery] DownloadProtocol[] protocols = null) public PagingResource<BlocklistResource> GetBlocklist([FromQuery] PagingRequestResource paging, [FromQuery] int[] seriesIds = null, [FromQuery] DownloadProtocol[] protocols = null)
{ {
var pagingResource = new PagingResource<BlocklistResource>(paging); var pagingResource = new PagingResource<BlocklistResource>(paging);
var pagingSpec = pagingResource.MapToPagingSpec<BlocklistResource, NzbDrone.Core.Blocklisting.Blocklist>("date", SortDirection.Descending); var pagingSpec = pagingResource.MapToPagingSpec<BlocklistResource, NzbDrone.Core.Blocklisting.Blocklist>(
new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"series.sortTitle",
"sourceTitle",
"date",
"indexer"
},
"date",
SortDirection.Descending);
if (seriesIds?.Any() == true) if (seriesIds?.Any() == true)
{ {

@ -65,7 +65,14 @@ namespace Sonarr.Api.V3.History
public PagingResource<HistoryResource> GetHistory([FromQuery] PagingRequestResource paging, bool includeSeries, bool includeEpisode, [FromQuery(Name = "eventType")] int[] eventTypes, int? episodeId, string downloadId, [FromQuery] int[] seriesIds = null, [FromQuery] int[] languages = null, [FromQuery] int[] quality = null) public PagingResource<HistoryResource> GetHistory([FromQuery] PagingRequestResource paging, bool includeSeries, bool includeEpisode, [FromQuery(Name = "eventType")] int[] eventTypes, int? episodeId, string downloadId, [FromQuery] int[] seriesIds = null, [FromQuery] int[] languages = null, [FromQuery] int[] quality = null)
{ {
var pagingResource = new PagingResource<HistoryResource>(paging); var pagingResource = new PagingResource<HistoryResource>(paging);
var pagingSpec = pagingResource.MapToPagingSpec<HistoryResource, EpisodeHistory>("date", SortDirection.Descending); var pagingSpec = pagingResource.MapToPagingSpec<HistoryResource, EpisodeHistory>(
new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"series.sortTitle",
"date"
},
"date",
SortDirection.Descending);
if (eventTypes != null && eventTypes.Any()) if (eventTypes != null && eventTypes.Any())
{ {

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentValidation; using FluentValidation;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.ImportLists.Exclusions; using NzbDrone.Core.ImportLists.Exclusions;
using Sonarr.Http; using Sonarr.Http;
using Sonarr.Http.Extensions; using Sonarr.Http.Extensions;
@ -46,7 +47,15 @@ namespace Sonarr.Api.V3.ImportLists
public PagingResource<ImportListExclusionResource> GetImportListExclusionsPaged([FromQuery] PagingRequestResource paging) public PagingResource<ImportListExclusionResource> GetImportListExclusionsPaged([FromQuery] PagingRequestResource paging)
{ {
var pagingResource = new PagingResource<ImportListExclusionResource>(paging); var pagingResource = new PagingResource<ImportListExclusionResource>(paging);
var pageSpec = pagingResource.MapToPagingSpec<ImportListExclusionResource, ImportListExclusion>(); var pageSpec = pagingResource.MapToPagingSpec<ImportListExclusionResource, ImportListExclusion>(
new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"id",
"tvdbId",
"title"
},
"id",
SortDirection.Descending);
return pageSpec.ApplyToPage(_importListExclusionService.Paged, ImportListExclusionResourceMapper.ToResource); return pageSpec.ApplyToPage(_importListExclusionService.Paged, ImportListExclusionResourceMapper.ToResource);
} }

@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
@ -29,7 +31,11 @@ namespace Sonarr.Api.V3.Logs
} }
var pagingResource = new PagingResource<LogResource>(paging); var pagingResource = new PagingResource<LogResource>(paging);
var pageSpec = pagingResource.MapToPagingSpec<LogResource, Log>(); var pageSpec = pagingResource.MapToPagingSpec<LogResource, Log>(new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"id",
"time"
});
if (pageSpec.SortKey == "time") if (pageSpec.SortKey == "time")
{ {

@ -139,7 +139,7 @@ namespace Sonarr.Api.V3.Queue
public PagingResource<QueueResource> GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownSeriesItems = false, bool includeSeries = false, bool includeEpisode = false, [FromQuery] int[] seriesIds = null, DownloadProtocol? protocol = null, [FromQuery] int[] languages = null, int? quality = null) public PagingResource<QueueResource> GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownSeriesItems = false, bool includeSeries = false, bool includeEpisode = false, [FromQuery] int[] seriesIds = null, DownloadProtocol? protocol = null, [FromQuery] int[] languages = null, int? quality = null)
{ {
var pagingResource = new PagingResource<QueueResource>(paging); var pagingResource = new PagingResource<QueueResource>(paging);
var pagingSpec = pagingResource.MapToPagingSpec<QueueResource, NzbDrone.Core.Queue.Queue>("timeleft", SortDirection.Ascending); var pagingSpec = pagingResource.MapToPagingSpec<QueueResource, NzbDrone.Core.Queue.Queue>(null, "timeleft", SortDirection.Ascending);
return pagingSpec.ApplyToPage((spec) => GetQueue(spec, seriesIds?.ToHashSet(), protocol, languages?.ToHashSet(), quality, includeUnknownSeriesItems), (q) => MapToResource(q, includeSeries, includeEpisode)); return pagingSpec.ApplyToPage((spec) => GetQueue(spec, seriesIds?.ToHashSet(), protocol, languages?.ToHashSet(), quality, includeUnknownSeriesItems), (q) => MapToResource(q, includeSeries, includeEpisode));
} }

@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.CustomFormats; using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
@ -31,13 +33,15 @@ namespace Sonarr.Api.V3.Wanted
public PagingResource<EpisodeResource> GetCutoffUnmetEpisodes([FromQuery] PagingRequestResource paging, bool includeSeries = false, bool includeEpisodeFile = false, bool includeImages = false, bool monitored = true) public PagingResource<EpisodeResource> GetCutoffUnmetEpisodes([FromQuery] PagingRequestResource paging, bool includeSeries = false, bool includeEpisodeFile = false, bool includeImages = false, bool monitored = true)
{ {
var pagingResource = new PagingResource<EpisodeResource>(paging); var pagingResource = new PagingResource<EpisodeResource>(paging);
var pagingSpec = new PagingSpec<Episode> var pagingSpec = pagingResource.MapToPagingSpec<EpisodeResource, Episode>(
{ new HashSet<string>(StringComparer.OrdinalIgnoreCase)
Page = pagingResource.Page, {
PageSize = pagingResource.PageSize, "series.sortTitle",
SortKey = pagingResource.SortKey, "episodes.airDateUtc",
SortDirection = pagingResource.SortDirection "episodes.lastSearchTime"
}; },
"episodes.airDateUtc",
SortDirection.Ascending);
if (monitored) if (monitored)
{ {

@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.CustomFormats; using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
@ -27,13 +29,15 @@ namespace Sonarr.Api.V3.Wanted
public PagingResource<EpisodeResource> GetMissingEpisodes([FromQuery] PagingRequestResource paging, bool includeSeries = false, bool includeImages = false, bool monitored = true) public PagingResource<EpisodeResource> GetMissingEpisodes([FromQuery] PagingRequestResource paging, bool includeSeries = false, bool includeImages = false, bool monitored = true)
{ {
var pagingResource = new PagingResource<EpisodeResource>(paging); var pagingResource = new PagingResource<EpisodeResource>(paging);
var pagingSpec = new PagingSpec<Episode> var pagingSpec = pagingResource.MapToPagingSpec<EpisodeResource, Episode>(
{ new HashSet<string>(StringComparer.OrdinalIgnoreCase)
Page = pagingResource.Page, {
PageSize = pagingResource.PageSize, "series.sortTitle",
SortKey = pagingResource.SortKey, "episodes.airDateUtc",
SortDirection = pagingResource.SortDirection "episodes.lastSearchTime"
}; },
"episodes.airDateUtc",
SortDirection.Ascending);
if (monitored) if (monitored)
{ {

@ -38,7 +38,11 @@ namespace Sonarr.Http
public static class PagingResourceMapper public static class PagingResourceMapper
{ {
public static PagingSpec<TModel> MapToPagingSpec<TResource, TModel>(this PagingResource<TResource> pagingResource, string defaultSortKey = "Id", SortDirection defaultSortDirection = SortDirection.Ascending) public static PagingSpec<TModel> MapToPagingSpec<TResource, TModel>(
this PagingResource<TResource> pagingResource,
HashSet<string> allowedSortKeys,
string defaultSortKey = "id",
SortDirection defaultSortDirection = SortDirection.Ascending)
{ {
var pagingSpec = new PagingSpec<TModel> var pagingSpec = new PagingSpec<TModel>
{ {
@ -48,15 +52,15 @@ namespace Sonarr.Http
SortDirection = pagingResource.SortDirection, SortDirection = pagingResource.SortDirection,
}; };
if (pagingResource.SortKey == null) pagingSpec.SortKey = pagingResource.SortKey != null &&
{ allowedSortKeys is { Count: > 0 } &&
pagingSpec.SortKey = defaultSortKey; allowedSortKeys.Contains(pagingResource.SortKey)
? pagingResource.SortKey
: defaultSortKey;
if (pagingResource.SortDirection == SortDirection.Default) pagingSpec.SortDirection = pagingResource.SortDirection == SortDirection.Default
{ ? defaultSortDirection
pagingSpec.SortDirection = defaultSortDirection; : pagingResource.SortDirection;
}
}
return pagingSpec; return pagingSpec;
} }

Loading…
Cancel
Save