feat(plugins): allow Plugins to call the Subsonic API (#4260)

* chore: .gitignore any navidrome binary

Signed-off-by: Deluan <deluan@navidrome.org>

* feat: implement internal authentication handling in middleware

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(manager): add SubsonicRouter to Manager for API routing

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(plugins): add SubsonicAPI Host service for plugins and an example plugin

Signed-off-by: Deluan <deluan@navidrome.org>

* fix lint

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(plugins): refactor path handling in SubsonicAPI to extract endpoint correctly

Signed-off-by: Deluan <deluan@navidrome.org>

* docs(plugins): add SubsonicAPI service documentation to README

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(plugins): implement permission checks for SubsonicAPI service

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(plugins): enhance SubsonicAPI service initialization with atomic router handling

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(plugins): better encapsulated dependency injection

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(plugins): rename parameter in WithInternalAuth for clarity

Signed-off-by: Deluan <deluan@navidrome.org>

* docs(plugins): update SubsonicAPI permissions section in README for clarity and detail

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(plugins): enhance SubsonicAPI permissions output with allowed usernames and admin flag

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(plugins): add schema reference to example plugins

Signed-off-by: Deluan <deluan@navidrome.org>

* remove import alias

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan Quintão
2025-06-25 14:18:32 -04:00
committed by GitHub
parent 024b50dc2b
commit 45c408a674
34 changed files with 1573 additions and 46 deletions

View File

@@ -22,6 +22,7 @@ import (
"github.com/navidrome/navidrome/plugins/host/config"
"github.com/navidrome/navidrome/plugins/host/http"
"github.com/navidrome/navidrome/plugins/host/scheduler"
"github.com/navidrome/navidrome/plugins/host/subsonicapi"
"github.com/navidrome/navidrome/plugins/host/websocket"
"github.com/navidrome/navidrome/plugins/schema"
"github.com/tetratelabs/wazero"
@@ -132,6 +133,14 @@ func (m *Manager) setupHostServices(ctx context.Context, r wazero.Runtime, plugi
}
return loadHostLibrary[websocket.WebSocketService](ctx, websocket.Instantiate, m.websocketService.HostFunctions(pluginID, wsPerms))
}},
{"subsonicapi", permissions.Subsonicapi != nil, func() (map[string]wazeroapi.FunctionDefinition, error) {
if router := m.subsonicRouter.Load(); router != nil {
service := newSubsonicAPIService(pluginID, m.subsonicRouter.Load(), m.ds, permissions.Subsonicapi)
return loadHostLibrary[subsonicapi.SubsonicAPIService](ctx, subsonicapi.Instantiate, service)
}
log.Error(ctx, "SubsonicAPI service requested but router not available", "plugin", pluginID)
return nil, fmt.Errorf("SubsonicAPI router not available for plugin %s", pluginID)
}},
}
// Load only permitted services