diff options
| author | Shadowghost <Ghost_of_Stone@web.de> | 2026-07-30 09:53:44 +0200 |
|---|---|---|
| committer | Shadowghost <Ghost_of_Stone@web.de> | 2026-07-30 09:53:44 +0200 |
| commit | e123a13e3853087a87a845c7738a74c22ea9064f (patch) | |
| tree | 7c1b99ff4c07b31357c33f86338002e66092aa89 /Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs | |
| parent | a94588497c521a89aa4a78eba44e305d06d91aa8 (diff) | |
Apply the by-name access exemption in the search candidate query
Diffstat (limited to 'Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs')
| -rw-r--r-- | Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs | 74 |
1 files changed, 1 insertions, 73 deletions
diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs index 8b0b7f37f8..fb9bbf0d47 100644 --- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs +++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs @@ -1044,36 +1044,7 @@ public sealed partial class BaseItemRepository : baseQuery.Where(e => e.Provider!.All(f => f.ProviderId.ToLower() != TvdbProviderName)); } - var queryTopParentIds = filter.TopParentIds; - - if (queryTopParentIds.Length > 0) - { - var includedItemByNameTypes = GetItemByNameTypesInQuery(filter); - var enableItemsByName = (filter.IncludeItemsByName ?? false) && includedItemByNameTypes.Count > 0; - - // A by-name item belongs to no library, so it has no TopParentId to test and the filter - // below would drop it. Items-by-name queries exempt the whole group; a query that names a - // by-name type explicitly gets the same exemption, since it is asking for those items. - var exemptedItemByNameTypes = enableItemsByName - ? includedItemByNameTypes - : _itemByNameKinds.Where(filter.IncludeItemTypes.Contains).Select(e => _itemTypeLookup.BaseItemKindNames[e]!).ToList(); - - if (exemptedItemByNameTypes.Count > 0) - { - baseQuery = baseQuery.Where(e => exemptedItemByNameTypes.Contains(e.Type) || queryTopParentIds.Any(w => w == e.TopParentId!.Value)); - } - else - { - baseQuery = baseQuery.WhereOneOrMany(queryTopParentIds, e => e.TopParentId!.Value); - } - - // That exemption is what lets a by-name item from a library the user cannot open show up - // in search. Decide those on the items behind the name instead. - if (filter.UserHasContentRestrictions && exemptedItemByNameTypes.Count > 0) - { - baseQuery = ApplyItemByNameAccessFiltering(baseQuery, context, filter, exemptedItemByNameTypes, queryTopParentIds); - } - } + baseQuery = ApplyTopParentFiltering(context, baseQuery, filter); if (filter.AncestorIds.Length > 0) { @@ -1287,47 +1258,4 @@ public sealed partial class BaseItemRepository return baseQuery; } - - /// <summary> - /// Keeps a by-name row only when at least one item behind its name is reachable for the user. - /// </summary> - private IQueryable<BaseItemEntity> ApplyItemByNameAccessFiltering( - IQueryable<BaseItemEntity> baseQuery, - JellyfinDbContext context, - InternalItemsQuery filter, - IReadOnlyList<string> itemByNameTypes, - Guid[] topParentIds) - { - // IncludeOwnedItems: a credit on an alternate version of a reachable movie still counts. - var accessibleItems = ApplyAccessFiltering( - context, - context.BaseItems.AsNoTracking(), - new InternalItemsQuery(filter.User) { TopParentIds = topParentIds, IncludeOwnedItems = true }); - - // Each predicate is written outside-in - name row, then link table, then item - and with nested - // Any() rather than a Contains over the accessible ids, which would materialise all of them - // before the first row. That keeps every step an index seek. - var personType = _itemTypeLookup.BaseItemKindNames[BaseItemKind.Person]; - if (itemByNameTypes.Contains(personType)) - { - baseQuery = baseQuery.Where(e => e.Type != personType - || context.Peoples.Any(p => p.Name == e.Name - && context.PeopleBaseItemMap.Any(m => m.PeopleId == p.Id && accessibleItems.Any(i => i.Id == m.ItemId)))); - } - - foreach (var (kind, valueTypes) in _itemByNameValueTypes) - { - var typeName = _itemTypeLookup.BaseItemKindNames[kind]; - if (!itemByNameTypes.Contains(typeName)) - { - continue; - } - - baseQuery = baseQuery.Where(e => e.Type != typeName - || context.ItemValues.Any(v => valueTypes.Contains(v.Type) && v.CleanValue == e.CleanName - && context.ItemValuesMap.Any(m => m.ItemValueId == v.ItemValueId && accessibleItems.Any(i => i.Id == m.ItemId)))); - } - - return baseQuery; - } } |
