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,
},
{
name: 'tvdbid',
name: 'tvdbId',
label: () => translate('TvdbId'),
isVisible: true,
isSortable: true,

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

@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
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)
{
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)
{

@ -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)
{
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())
{

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using FluentValidation;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.ImportLists.Exclusions;
using Sonarr.Http;
using Sonarr.Http.Extensions;
@ -46,7 +47,15 @@ namespace Sonarr.Api.V3.ImportLists
public PagingResource<ImportListExclusionResource> GetImportListExclusionsPaged([FromQuery] PagingRequestResource 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);
}

@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
@ -29,7 +31,11 @@ namespace Sonarr.Api.V3.Logs
}
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")
{

@ -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)
{
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));
}

@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.CustomFormats;
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)
{
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,
SortKey = pagingResource.SortKey,
SortDirection = pagingResource.SortDirection
};
"series.sortTitle",
"episodes.airDateUtc",
"episodes.lastSearchTime"
},
"episodes.airDateUtc",
SortDirection.Ascending);
if (monitored)
{

@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.CustomFormats;
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)
{
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,
SortKey = pagingResource.SortKey,
SortDirection = pagingResource.SortDirection
};
"series.sortTitle",
"episodes.airDateUtc",
"episodes.lastSearchTime"
},
"episodes.airDateUtc",
SortDirection.Ascending);
if (monitored)
{

@ -38,7 +38,11 @@ namespace Sonarr.Http
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>
{
@ -48,15 +52,15 @@ namespace Sonarr.Http
SortDirection = pagingResource.SortDirection,
};
if (pagingResource.SortKey == null)
{
pagingSpec.SortKey = defaultSortKey;
pagingSpec.SortKey = pagingResource.SortKey != null &&
allowedSortKeys is { Count: > 0 } &&
allowedSortKeys.Contains(pagingResource.SortKey)
? pagingResource.SortKey
: defaultSortKey;
if (pagingResource.SortDirection == SortDirection.Default)
{
pagingSpec.SortDirection = defaultSortDirection;
}
}
pagingSpec.SortDirection = pagingResource.SortDirection == SortDirection.Default
? defaultSortDirection
: pagingResource.SortDirection;
return pagingSpec;
}

Loading…
Cancel
Save