navidrome/core/scrobbler
Deluan Quintão 8e784b6af7
fix: apply the per-user library filter to bookmarks, playlists and now-playing (#6179)
On a multi-library instance, a few reads and writes built their own queries
without the per-user library filter that every other media read applies. A
user granted only some libraries could see, and store, tracks from libraries
they had no access to.

- getBookmarks now filters the query. It has to be the query and not the
  result: the loop below it pre-sizes the response from the bookmark count,
  so a row dropped afterwards would emit an empty bookmark entry.
- createBookmark rejects an id the caller cannot read, returning error 70 to
  match getSong. Stored rows are left alone rather than purged, so a
  temporary revoke does not lose saved playback positions.
- playlistTrackRepository Read, Count and GetAlbumIDs get the filter their
  siblings CountAll and GetMediaFileIDs already had. Read is the one that
  mattered most: its id is the integer playlist position, so it needed no
  track id at all.
- Playlist track writes are filtered in playlistRepository.addTracks, the
  only writer of playlist_tracks rows apart from smart playlists, so Add,
  Insert, AddAlbums/AddArtists/AddDiscs and a full replace through Put all
  go through it. Insert reserves a slot per requested id, so when the filter
  drops one it renumbers to close the hole.
- playTracker.GetNowPlaying honours its context instead of discarding it.
  The cache is process-global, so the filter belongs in the tracker rather
  than in the Subsonic handler, and any future caller inherits it.

Admins and single-library installs are unaffected: applyLibraryFilter and
HasLibraryAccess both short-circuit for them. Scanner playlist sync runs as
admin, and M3U and CLI imports already resolve tracks through FindByPaths as
the same user, so neither changes.
2026-09-20 12:37:18 -04:00
..
buffered_scrobbler.go fix(scrobbler): back off when a provider asks us to, instead of retrying per play (#6028) 2026-08-29 17:28:29 -04:00
buffered_scrobbler_test.go fix(deezer): treat an exhausted quota as a throttle, not as a missing artist (#6068) 2026-09-01 17:17:52 -04:00
interfaces.go fix(scrobbler): back off when a provider asks us to, instead of retrying per play (#6028) 2026-08-29 17:28:29 -04:00
nowplaying_worker.go feat(plugins): add PlaybackReport to scrobbler capability (#5452) 2026-05-02 16:14:53 -04:00
play_tracker.go fix: apply the per-user library filter to bookmarks, playlists and now-playing (#6179) 2026-09-20 12:37:18 -04:00
play_tracker_test.go fix: apply the per-user library filter to bookmarks, playlists and now-playing (#6179) 2026-09-20 12:37:18 -04:00
playbackreport_worker.go feat(scrobbler): add per-user scrobble filter (#5964) 2026-08-15 16:10:53 -04:00
scrobbler_suite_test.go Rename log.LevelCritical to log.LevelFatal 2022-12-21 14:53:36 -05:00