Compare commits

...

2 Commits

Author SHA1 Message Date
Andrew Rabert
8dbec6f4f5 Mitigate pull_request_target privilege escalation
Hotfix — replaces pull_request_target with pull_request to stop
granting write permissions and secrets to fork PRs. Some workflows
will break; can be fixed properly later.
2026-02-20 19:10:39 -05:00
Cody Robibero
f6709a69e7 Explicitly load related items 2025-12-14 10:08:33 -07:00
6 changed files with 46 additions and 48 deletions

View File

@@ -1,6 +1,6 @@
name: ABI Compatibility name: ABI Compatibility
on: on:
pull_request_target: pull_request:
permissions: {} permissions: {}
@@ -77,7 +77,7 @@ jobs:
pull-requests: write # to create or update comment (peter-evans/create-or-update-comment) pull-requests: write # to create or update comment (peter-evans/create-or-update-comment)
name: ABI - Difference name: ABI - Difference
if: ${{ github.event_name == 'pull_request_target' }} if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
- abi-head - abi-head

View File

@@ -5,7 +5,7 @@ on:
- master - master
tags: tags:
- 'v*' - 'v*'
pull_request_target: pull_request:
permissions: {} permissions: {}
@@ -73,7 +73,7 @@ jobs:
pull-requests: write # to create or update comment (peter-evans/create-or-update-comment) pull-requests: write # to create or update comment (peter-evans/create-or-update-comment)
name: OpenAPI - Difference name: OpenAPI - Difference
if: ${{ github.event_name == 'pull_request_target' }} if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
- openapi-head - openapi-head
@@ -148,7 +148,7 @@ jobs:
publish-unstable: publish-unstable:
name: OpenAPI - Publish Unstable Spec name: OpenAPI - Publish Unstable Spec
if: ${{ github.event_name != 'pull_request_target' && !startsWith(github.ref, 'refs/tags/v') && contains(github.repository_owner, 'jellyfin') }} if: ${{ github.event_name != 'pull_request' && !startsWith(github.ref, 'refs/tags/v') && contains(github.repository_owner, 'jellyfin') }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
- openapi-head - openapi-head

View File

@@ -4,7 +4,7 @@ on:
types: types:
- created - created
- edited - edited
pull_request_target: pull_request:
types: types:
- labeled - labeled
- synchronize - synchronize

View File

@@ -4,7 +4,7 @@ on:
push: push:
branches: branches:
- master - master
pull_request_target: pull_request:
issue_comment: issue_comment:
permissions: {} permissions: {}

View File

@@ -4,7 +4,7 @@ on:
push: push:
branches: branches:
- master - master
pull_request_target: pull_request:
issue_comment: issue_comment:
permissions: {} permissions: {}
@@ -16,7 +16,7 @@ jobs:
steps: steps:
- name: Apply label - name: Apply label
uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3 uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3
if: ${{ github.event_name == 'push' || github.event_name == 'pull_request_target'}} if: ${{ github.event_name == 'push' || github.event_name == 'pull_request'}}
with: with:
dirtyLabel: 'merge conflict' dirtyLabel: 'merge conflict'
commentOnDirty: 'This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.' commentOnDirty: 'This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.'

View File

@@ -275,9 +275,8 @@ public sealed class BaseItemRepository
} }
dbQuery = ApplyQueryPaging(dbQuery, filter); dbQuery = ApplyQueryPaging(dbQuery, filter);
dbQuery = ApplyNavigations(dbQuery, filter);
result.Items = dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray(); result.Items = GetEntities(dbQuery, context, filter).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
result.StartIndex = filter.StartIndex ?? 0; result.StartIndex = filter.StartIndex ?? 0;
return result; return result;
} }
@@ -295,9 +294,8 @@ public sealed class BaseItemRepository
dbQuery = ApplyGroupingFilter(context, dbQuery, filter); dbQuery = ApplyGroupingFilter(context, dbQuery, filter);
dbQuery = ApplyQueryPaging(dbQuery, filter); dbQuery = ApplyQueryPaging(dbQuery, filter);
dbQuery = ApplyNavigations(dbQuery, filter);
return dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray(); return GetEntities(dbQuery, context, filter).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -339,9 +337,7 @@ public sealed class BaseItemRepository
mainquery = ApplyGroupingFilter(context, mainquery, filter); mainquery = ApplyGroupingFilter(context, mainquery, filter);
mainquery = ApplyQueryPaging(mainquery, filter); mainquery = ApplyQueryPaging(mainquery, filter);
mainquery = ApplyNavigations(mainquery, filter); return GetEntities(mainquery, context, filter).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
return mainquery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -408,36 +404,6 @@ public sealed class BaseItemRepository
return dbQuery; return dbQuery;
} }
private static IQueryable<BaseItemEntity> ApplyNavigations(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
{
if (filter.TrailerTypes.Length > 0 || filter.IncludeItemTypes.Contains(BaseItemKind.Trailer))
{
dbQuery = dbQuery.Include(e => e.TrailerTypes);
}
if (filter.DtoOptions.ContainsField(ItemFields.ProviderIds))
{
dbQuery = dbQuery.Include(e => e.Provider);
}
if (filter.DtoOptions.ContainsField(ItemFields.Settings))
{
dbQuery = dbQuery.Include(e => e.LockedFields);
}
if (filter.DtoOptions.EnableUserData)
{
dbQuery = dbQuery.Include(e => e.UserData);
}
if (filter.DtoOptions.EnableImages)
{
dbQuery = dbQuery.Include(e => e.Images);
}
return dbQuery;
}
private IQueryable<BaseItemEntity> ApplyQueryPaging(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter) private IQueryable<BaseItemEntity> ApplyQueryPaging(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
{ {
if (filter.Limit.HasValue || filter.StartIndex.HasValue) if (filter.Limit.HasValue || filter.StartIndex.HasValue)
@@ -463,18 +429,50 @@ public sealed class BaseItemRepository
dbQuery = TranslateQuery(dbQuery, context, filter); dbQuery = TranslateQuery(dbQuery, context, filter);
dbQuery = ApplyGroupingFilter(context, dbQuery, filter); dbQuery = ApplyGroupingFilter(context, dbQuery, filter);
dbQuery = ApplyQueryPaging(dbQuery, filter); dbQuery = ApplyQueryPaging(dbQuery, filter);
dbQuery = ApplyNavigations(dbQuery, filter);
return dbQuery; return dbQuery;
} }
private IQueryable<BaseItemEntity> PrepareItemQuery(JellyfinDbContext context, InternalItemsQuery filter) private IQueryable<BaseItemEntity> PrepareItemQuery(JellyfinDbContext context, InternalItemsQuery filter)
{ {
IQueryable<BaseItemEntity> dbQuery = context.BaseItems.AsNoTracking(); IQueryable<BaseItemEntity> dbQuery = context.BaseItems;
dbQuery = dbQuery.AsSingleQuery(); dbQuery = dbQuery.AsSingleQuery();
return dbQuery; return dbQuery;
} }
private IReadOnlyList<BaseItemEntity> GetEntities(IQueryable<BaseItemEntity> dbQuery, JellyfinDbContext context, InternalItemsQuery filter)
{
var items = dbQuery.AsEnumerable().Where(e => e is not null).ToArray();
var itemIds = items.Select(e => e.Id).ToArray();
if (filter.TrailerTypes.Length > 0 || filter.IncludeItemTypes.Contains(BaseItemKind.Trailer))
{
context.BaseItemTrailerTypes.WhereOneOrMany(itemIds, e => e.ItemId).Load();
}
if (filter.DtoOptions.ContainsField(ItemFields.ProviderIds))
{
context.BaseItemProviders.WhereOneOrMany(itemIds, e => e.ItemId).Load();
}
if (filter.DtoOptions.ContainsField(ItemFields.Settings))
{
context.BaseItemMetadataFields.WhereOneOrMany(itemIds, e => e.ItemId).Load();
}
if (filter.DtoOptions.EnableImages)
{
context.BaseItemImageInfos.WhereOneOrMany(itemIds, e => e.ItemId).Load();
}
if (filter.DtoOptions.EnableUserData)
{
context.UserData.WhereOneOrMany(itemIds, e => e.ItemId).Load();
}
return items;
}
/// <inheritdoc/> /// <inheritdoc/>
public int GetCount(InternalItemsQuery filter) public int GetCount(InternalItemsQuery filter)
{ {