You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(access-groups): enforce sharing-tag visibility on book and series list endpoints
Sharing-tag access control was only enforced on a subset of read endpoints.
The /api/v1/series listing filtered by ContentFilter, but /api/v1/books,
POST /api/v1/books/list, /books/recently-added, /books/on-deck, /books/in-progress,
/books/recently-read, /books/{id}/adjacent, the library-scoped variants of all
of the above, plus the OPDS, OPDS 2.0, and Komga book paths, all returned
books in series the caller had been denied access to.
The series handlers that did filter were doing it in memory after the repo
returned every row, so paginated totals reflected the unfiltered set even
though the page itself dropped denied rows. Pagination links became wrong
once any deny grant was active.
This change moves visibility enforcement into the SQL layer:
- New SeriesVisibility helper in codex-db: a deny set plus an optional
allow set (whitelist mode). visibility_predicate() builds the SeaORM
SimpleExpr; apply_book_visibility / apply_series_visibility add it to
a Select<books::Entity> / Select<series::Entity>. Empty whitelists
short-circuit to an empty result without touching the DB.
- ContentFilter::to_visibility() turns the resolved per-user grants into
a SeriesVisibility, returning None when the user has no restrictions
so the natural query is unchanged for the common case.
- Every BookRepository and SeriesRepository method used by user-facing
list / search endpoints now takes Option<&SeriesVisibility>: list_all,
list_recently_added, list_by_ids, list_by_ids_sorted, hydrate_by_ids,
list_by_library_sorted, list_with_progress, list_recently_read,
list_on_deck, search_by_title, search_by_name, get_adjacent_in_series
for books; list_by_library, list_all, list_recently_added,
list_recently_updated, list_by_library_sorted, list_by_ids_sorted,
search_by_title, search_by_name, list_in_progress for series.
- All affected v1, OPDS, OPDS 2.0, and Komga handlers load the
ContentFilter once and thread visibility through. The in-memory
filter passes in series handlers are gone, so totals reflect the
user's view.
- Internal callers that should not be visibility-scoped (scanner,
thumbnail generation, library reprocess, plugin auto-match) pass
None explicitly.
Tests cover the SeriesVisibility helper, every affected repository
method (deny mode, whitelist mode, empty-whitelist short-circuit, and
None pass-through), and the user-facing endpoints end-to-end through
sharing-tag deny and whitelist grants.
0 commit comments