fix(server): handleGetStream - auth check before DB lookup
TestRoutesRegisteredInMount failed because handleGetStream did the DB lookup (404 on missing track) BEFORE streamAuthOk (401 on unauth). For an unauth request to a non-existent track, the test saw 404 and concluded the route wasn't registered when actually it was - the handler just bailed at the lookup before auth. Reorder: extract trackID via chi.URLParam, run streamAuthOk on the raw path id first (the HMAC token is signed over the same id string so we don't need the resolved row yet), then do the DB lookup. Test now sees 401 on the unauth probe as it expected. Also closes a small info-leak: previously a 404/401 differential let unauth callers probe which track IDs exist. Now both unknown and known IDs return 401 for unauth requests.
This commit is contained in:
+12
-4
@@ -14,6 +14,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/apierror"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/auth"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/coverart"
|
||||
@@ -163,15 +165,21 @@ func (h *handlers) streamAuthOk(r *http.Request, trackID string) bool {
|
||||
// permissive middleware the route is wrapped with) OR a signed token
|
||||
// (UPnP slice). streamAuthOk gates both paths.
|
||||
func (h *handlers) handleGetStream(w http.ResponseWriter, r *http.Request) {
|
||||
// Auth check before the DB lookup: a 404 ahead of the auth check
|
||||
// would let unauth callers probe which track IDs exist via the
|
||||
// 404/401 response differential. streamAuthOk is keyed on the
|
||||
// path's id directly (the HMAC token is signed over the same id
|
||||
// string, so we don't need the resolved row yet).
|
||||
rawID := chi.URLParam(r, "id")
|
||||
if !h.streamAuthOk(r, rawID) {
|
||||
writeErr(w, apierror.ErrUnauthorized)
|
||||
return
|
||||
}
|
||||
track, apiErr := resolveByID(r, "id", dbq.New(h.pool).GetTrackByID, "track")
|
||||
if apiErr != nil {
|
||||
writeErr(w, apiErr)
|
||||
return
|
||||
}
|
||||
if !h.streamAuthOk(r, uuidToString(track.ID)) {
|
||||
writeErr(w, apierror.ErrUnauthorized)
|
||||
return
|
||||
}
|
||||
f, err := os.Open(track.FilePath)
|
||||
if err != nil {
|
||||
// File vanished (scanner indexed it, filesystem lost it). Treat as
|
||||
|
||||
Reference in New Issue
Block a user