From d5d658551733405bee938be387fd901daad76ce0 Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Sun, 22 Mar 2026 10:25:06 +0100 Subject: [PATCH] Refactor hardcoded source provider IDs to use lookup from constants (#125) Co-authored-by: Junie --- cmd/soundtouch-service/main.go | 4 +-- pkg/service/handlers/handlers_oauth.go | 31 ++++++++++++++++----- pkg/service/handlers/handlers_oauth_test.go | 8 +++--- pkg/service/marge/marge.go | 21 ++++++++------ 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/cmd/soundtouch-service/main.go b/cmd/soundtouch-service/main.go index f90ea83..65a8d3a 100644 --- a/cmd/soundtouch-service/main.go +++ b/cmd/soundtouch-service/main.go @@ -724,8 +724,8 @@ func setupRouter(server *handlers.Server) *chi.Mux { }) r.Route("/oauth", func(r chi.Router) { - r.Post("/device/{deviceID}/music/musicprovider/15/token/cs3", server.HandleBoseSpotifyToken) - r.Post("/device/{deviceID}/music/musicprovider/15/token", server.HandleBoseSpotifyLegacyToken) + r.Post("/device/{deviceID}/music/musicprovider/{sourceID}/token/cs3", server.HandleBoseToken) + r.Post("/device/{deviceID}/music/musicprovider/{sourceID}/token", server.HandleBoseLegacyToken) r.HandleFunc("/*", server.HandleBoseProxy) }) diff --git a/pkg/service/handlers/handlers_oauth.go b/pkg/service/handlers/handlers_oauth.go index 4cb9846..ce581b7 100644 --- a/pkg/service/handlers/handlers_oauth.go +++ b/pkg/service/handlers/handlers_oauth.go @@ -5,9 +5,33 @@ import ( "log" "net/http" + "strconv" + + "github.com/gesellix/bose-soundtouch/pkg/service/constants" "github.com/go-chi/chi/v5" ) +// HandleBoseToken handles the Bose-specific token refresh request from the speaker. +// POST /oauth/device/{deviceID}/music/musicprovider/{sourceID}/token/cs3 +func (s *Server) HandleBoseToken(w http.ResponseWriter, r *http.Request) { + sourceID := chi.URLParam(r, "sourceID") + + for _, provider := range constants.StaticProviders { + if strconv.Itoa(provider.ID) == sourceID && provider.Name == "SPOTIFY" { + s.HandleBoseSpotifyToken(w, r) + return + } + } + + s.HandleBoseProxy(w, r) +} + +// HandleBoseLegacyToken handles the Bose-specific token refresh request (legacy or variant). +// POST /oauth/device/{deviceID}/music/musicprovider/{sourceID}/token +func (s *Server) HandleBoseLegacyToken(w http.ResponseWriter, r *http.Request) { + s.HandleBoseToken(w, r) +} + // HandleBoseSpotifyToken handles the Bose-specific Spotify token refresh request from the speaker. // POST /oauth/device/{deviceID}/music/musicprovider/15/token/cs3 func (s *Server) HandleBoseSpotifyToken(w http.ResponseWriter, r *http.Request) { @@ -61,10 +85,3 @@ func (s *Server) HandleBoseSpotifyToken(w http.ResponseWriter, r *http.Request) http.Error(w, "Internal Server Error", http.StatusInternalServerError) } } - -// HandleBoseSpotifyLegacyToken handles the Bose-specific Spotify token refresh request (legacy or variant). -// POST /oauth/device/{deviceID}/music/musicprovider/15/token -func (s *Server) HandleBoseSpotifyLegacyToken(w http.ResponseWriter, r *http.Request) { - // Some firmware might use a slightly different path. - s.HandleBoseSpotifyToken(w, r) -} diff --git a/pkg/service/handlers/handlers_oauth_test.go b/pkg/service/handlers/handlers_oauth_test.go index 6476627..98ae544 100644 --- a/pkg/service/handlers/handlers_oauth_test.go +++ b/pkg/service/handlers/handlers_oauth_test.go @@ -49,7 +49,7 @@ func TestHandleBoseSpotifyToken_LocalResponse(t *testing.T) { // chi.URLParam works when using chi router r := chi.NewRouter() - r.Post("/oauth/device/{deviceID}/music/musicprovider/15/token/cs3", server.HandleBoseSpotifyToken) + r.Post("/oauth/device/{deviceID}/music/musicprovider/{sourceID}/token/cs3", server.HandleBoseToken) req := httptest.NewRequest("POST", "/oauth/device/DEVICE123/music/musicprovider/15/token/cs3", nil) w := httptest.NewRecorder() @@ -85,7 +85,7 @@ func TestHandleBoseSpotifyToken_FallbackToProxy(t *testing.T) { // chi.URLParam works when using chi router r := chi.NewRouter() - r.Post("/oauth/device/{deviceID}/music/musicprovider/15/token/cs3", server.HandleBoseSpotifyToken) + r.Post("/oauth/device/{deviceID}/music/musicprovider/{sourceID}/token/cs3", server.HandleBoseToken) // Since there's no Spotify service, it should fall back to HandleBoseProxy. // HandleBoseProxy will try to contact streaming.bose.com. @@ -113,13 +113,13 @@ func TestHandleBoseSpotifyToken_FallbackToProxy(t *testing.T) { } } -func TestHandleBoseSpotifyLegacyToken(t *testing.T) { +func TestHandleBoseLegacyToken(t *testing.T) { tmpDir := t.TempDir() ds := datastore.NewDataStore(tmpDir) server := NewServer(ds, nil, "http://localhost", false, false, false) r := chi.NewRouter() - r.Post("/oauth/device/{deviceID}/music/musicprovider/15/token", server.HandleBoseSpotifyLegacyToken) + r.Post("/oauth/device/{deviceID}/music/musicprovider/{sourceID}/token", server.HandleBoseLegacyToken) // Since we are not configuring Spotify, it should fall back to proxy req := httptest.NewRequest("POST", "/oauth/device/DEVICE123/music/musicprovider/15/token", nil) diff --git a/pkg/service/marge/marge.go b/pkg/service/marge/marge.go index adf44b4..4a888ed 100644 --- a/pkg/service/marge/marge.go +++ b/pkg/service/marge/marge.go @@ -487,20 +487,25 @@ func AccountFullToXML(ds *datastore.DataStore, account string) ([]byte, error) { AccountStatus: "OK", Mode: "global", PreferredLanguage: "de", - ProviderSettings: []models.ProviderSetting{ - { + } + + for _, p := range constants.StaticProviders { + switch p.Name { + case "DEEZER": + resp.ProviderSettings = append(resp.ProviderSettings, models.ProviderSetting{ BoseID: account, KeyName: "ELIGIBLE_FOR_TRIAL", Value: "false", - ProviderID: "14", - }, - { + ProviderID: strconv.Itoa(p.ID), + }) + case "SPOTIFY": + resp.ProviderSettings = append(resp.ProviderSettings, models.ProviderSetting{ BoseID: account, KeyName: "STREAMING_QUALITY", Value: "2", - ProviderID: "15", - }, - }, + ProviderID: strconv.Itoa(p.ID), + }) + } } if info, _ := ds.GetAccountInfo(account); info != nil {