navidrome/plugins/schema/manifest_gen.go
Deluan Quintão 45c408a674
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>
2025-06-25 14:18:32 -04:00

427 lines
15 KiB
Go

// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT.
package schema
import "encoding/json"
import "fmt"
import "reflect"
type BasePermission struct {
// Explanation of why this permission is needed
Reason string `json:"reason" yaml:"reason" mapstructure:"reason"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *BasePermission) UnmarshalJSON(value []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(value, &raw); err != nil {
return err
}
if _, ok := raw["reason"]; raw != nil && !ok {
return fmt.Errorf("field reason in BasePermission: required")
}
type Plain BasePermission
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if len(plain.Reason) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "reason", 1)
}
*j = BasePermission(plain)
return nil
}
// Schema for Navidrome Plugin manifest.json files
type PluginManifest struct {
// Author or organization that created the plugin
Author string `json:"author" yaml:"author" mapstructure:"author"`
// List of capabilities implemented by this plugin
Capabilities []PluginManifestCapabilitiesElem `json:"capabilities" yaml:"capabilities" mapstructure:"capabilities"`
// A brief description of the plugin's functionality
Description string `json:"description" yaml:"description" mapstructure:"description"`
// Name of the plugin
Name string `json:"name" yaml:"name" mapstructure:"name"`
// Host services the plugin is allowed to access
Permissions PluginManifestPermissions `json:"permissions" yaml:"permissions" mapstructure:"permissions"`
// Plugin version using semantic versioning format
Version string `json:"version" yaml:"version" mapstructure:"version"`
// Website URL for the plugin or its documentation
Website string `json:"website" yaml:"website" mapstructure:"website"`
}
type PluginManifestCapabilitiesElem string
const PluginManifestCapabilitiesElemLifecycleManagement PluginManifestCapabilitiesElem = "LifecycleManagement"
const PluginManifestCapabilitiesElemMetadataAgent PluginManifestCapabilitiesElem = "MetadataAgent"
const PluginManifestCapabilitiesElemSchedulerCallback PluginManifestCapabilitiesElem = "SchedulerCallback"
const PluginManifestCapabilitiesElemScrobbler PluginManifestCapabilitiesElem = "Scrobbler"
const PluginManifestCapabilitiesElemWebSocketCallback PluginManifestCapabilitiesElem = "WebSocketCallback"
var enumValues_PluginManifestCapabilitiesElem = []interface{}{
"MetadataAgent",
"Scrobbler",
"SchedulerCallback",
"LifecycleManagement",
"WebSocketCallback",
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *PluginManifestCapabilitiesElem) UnmarshalJSON(value []byte) error {
var v string
if err := json.Unmarshal(value, &v); err != nil {
return err
}
var ok bool
for _, expected := range enumValues_PluginManifestCapabilitiesElem {
if reflect.DeepEqual(v, expected) {
ok = true
break
}
}
if !ok {
return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_PluginManifestCapabilitiesElem, v)
}
*j = PluginManifestCapabilitiesElem(v)
return nil
}
// Host services the plugin is allowed to access
type PluginManifestPermissions struct {
// Artwork corresponds to the JSON schema field "artwork".
Artwork *PluginManifestPermissionsArtwork `json:"artwork,omitempty" yaml:"artwork,omitempty" mapstructure:"artwork,omitempty"`
// Cache corresponds to the JSON schema field "cache".
Cache *PluginManifestPermissionsCache `json:"cache,omitempty" yaml:"cache,omitempty" mapstructure:"cache,omitempty"`
// Config corresponds to the JSON schema field "config".
Config *PluginManifestPermissionsConfig `json:"config,omitempty" yaml:"config,omitempty" mapstructure:"config,omitempty"`
// Http corresponds to the JSON schema field "http".
Http *PluginManifestPermissionsHttp `json:"http,omitempty" yaml:"http,omitempty" mapstructure:"http,omitempty"`
// Scheduler corresponds to the JSON schema field "scheduler".
Scheduler *PluginManifestPermissionsScheduler `json:"scheduler,omitempty" yaml:"scheduler,omitempty" mapstructure:"scheduler,omitempty"`
// Subsonicapi corresponds to the JSON schema field "subsonicapi".
Subsonicapi *PluginManifestPermissionsSubsonicapi `json:"subsonicapi,omitempty" yaml:"subsonicapi,omitempty" mapstructure:"subsonicapi,omitempty"`
// Websocket corresponds to the JSON schema field "websocket".
Websocket *PluginManifestPermissionsWebsocket `json:"websocket,omitempty" yaml:"websocket,omitempty" mapstructure:"websocket,omitempty"`
AdditionalProperties interface{} `mapstructure:",remain"`
}
// Artwork service permissions
type PluginManifestPermissionsArtwork struct {
// Explanation of why this permission is needed
Reason string `json:"reason" yaml:"reason" mapstructure:"reason"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *PluginManifestPermissionsArtwork) UnmarshalJSON(value []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(value, &raw); err != nil {
return err
}
if _, ok := raw["reason"]; raw != nil && !ok {
return fmt.Errorf("field reason in PluginManifestPermissionsArtwork: required")
}
type Plain PluginManifestPermissionsArtwork
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if len(plain.Reason) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "reason", 1)
}
*j = PluginManifestPermissionsArtwork(plain)
return nil
}
// Cache service permissions
type PluginManifestPermissionsCache struct {
// Explanation of why this permission is needed
Reason string `json:"reason" yaml:"reason" mapstructure:"reason"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *PluginManifestPermissionsCache) UnmarshalJSON(value []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(value, &raw); err != nil {
return err
}
if _, ok := raw["reason"]; raw != nil && !ok {
return fmt.Errorf("field reason in PluginManifestPermissionsCache: required")
}
type Plain PluginManifestPermissionsCache
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if len(plain.Reason) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "reason", 1)
}
*j = PluginManifestPermissionsCache(plain)
return nil
}
// Configuration service permissions
type PluginManifestPermissionsConfig struct {
// Explanation of why this permission is needed
Reason string `json:"reason" yaml:"reason" mapstructure:"reason"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *PluginManifestPermissionsConfig) UnmarshalJSON(value []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(value, &raw); err != nil {
return err
}
if _, ok := raw["reason"]; raw != nil && !ok {
return fmt.Errorf("field reason in PluginManifestPermissionsConfig: required")
}
type Plain PluginManifestPermissionsConfig
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if len(plain.Reason) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "reason", 1)
}
*j = PluginManifestPermissionsConfig(plain)
return nil
}
// HTTP service permissions
type PluginManifestPermissionsHttp struct {
// Whether to allow requests to local/private network addresses
AllowLocalNetwork bool `json:"allowLocalNetwork,omitempty" yaml:"allowLocalNetwork,omitempty" mapstructure:"allowLocalNetwork,omitempty"`
// Map of URL patterns (e.g., 'https://api.example.com/*') to allowed HTTP
// methods. Redirect destinations must also be included.
AllowedUrls map[string][]PluginManifestPermissionsHttpAllowedUrlsValueElem `json:"allowedUrls" yaml:"allowedUrls" mapstructure:"allowedUrls"`
// Explanation of why this permission is needed
Reason string `json:"reason" yaml:"reason" mapstructure:"reason"`
}
type PluginManifestPermissionsHttpAllowedUrlsValueElem string
const PluginManifestPermissionsHttpAllowedUrlsValueElemDELETE PluginManifestPermissionsHttpAllowedUrlsValueElem = "DELETE"
const PluginManifestPermissionsHttpAllowedUrlsValueElemGET PluginManifestPermissionsHttpAllowedUrlsValueElem = "GET"
const PluginManifestPermissionsHttpAllowedUrlsValueElemHEAD PluginManifestPermissionsHttpAllowedUrlsValueElem = "HEAD"
const PluginManifestPermissionsHttpAllowedUrlsValueElemOPTIONS PluginManifestPermissionsHttpAllowedUrlsValueElem = "OPTIONS"
const PluginManifestPermissionsHttpAllowedUrlsValueElemPATCH PluginManifestPermissionsHttpAllowedUrlsValueElem = "PATCH"
const PluginManifestPermissionsHttpAllowedUrlsValueElemPOST PluginManifestPermissionsHttpAllowedUrlsValueElem = "POST"
const PluginManifestPermissionsHttpAllowedUrlsValueElemPUT PluginManifestPermissionsHttpAllowedUrlsValueElem = "PUT"
const PluginManifestPermissionsHttpAllowedUrlsValueElemWildcard PluginManifestPermissionsHttpAllowedUrlsValueElem = "*"
var enumValues_PluginManifestPermissionsHttpAllowedUrlsValueElem = []interface{}{
"GET",
"POST",
"PUT",
"DELETE",
"PATCH",
"HEAD",
"OPTIONS",
"*",
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *PluginManifestPermissionsHttpAllowedUrlsValueElem) UnmarshalJSON(value []byte) error {
var v string
if err := json.Unmarshal(value, &v); err != nil {
return err
}
var ok bool
for _, expected := range enumValues_PluginManifestPermissionsHttpAllowedUrlsValueElem {
if reflect.DeepEqual(v, expected) {
ok = true
break
}
}
if !ok {
return fmt.Errorf("invalid value (expected one of %#v): %#v", enumValues_PluginManifestPermissionsHttpAllowedUrlsValueElem, v)
}
*j = PluginManifestPermissionsHttpAllowedUrlsValueElem(v)
return nil
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *PluginManifestPermissionsHttp) UnmarshalJSON(value []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(value, &raw); err != nil {
return err
}
if _, ok := raw["allowedUrls"]; raw != nil && !ok {
return fmt.Errorf("field allowedUrls in PluginManifestPermissionsHttp: required")
}
if _, ok := raw["reason"]; raw != nil && !ok {
return fmt.Errorf("field reason in PluginManifestPermissionsHttp: required")
}
type Plain PluginManifestPermissionsHttp
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if v, ok := raw["allowLocalNetwork"]; !ok || v == nil {
plain.AllowLocalNetwork = false
}
if len(plain.Reason) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "reason", 1)
}
*j = PluginManifestPermissionsHttp(plain)
return nil
}
// Scheduler service permissions
type PluginManifestPermissionsScheduler struct {
// Explanation of why this permission is needed
Reason string `json:"reason" yaml:"reason" mapstructure:"reason"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *PluginManifestPermissionsScheduler) UnmarshalJSON(value []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(value, &raw); err != nil {
return err
}
if _, ok := raw["reason"]; raw != nil && !ok {
return fmt.Errorf("field reason in PluginManifestPermissionsScheduler: required")
}
type Plain PluginManifestPermissionsScheduler
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if len(plain.Reason) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "reason", 1)
}
*j = PluginManifestPermissionsScheduler(plain)
return nil
}
// SubsonicAPI service permissions
type PluginManifestPermissionsSubsonicapi struct {
// If false, reject calls where the u is an admin
AllowAdmins bool `json:"allowAdmins,omitempty" yaml:"allowAdmins,omitempty" mapstructure:"allowAdmins,omitempty"`
// List of usernames the plugin can pass as u. Any user if empty
AllowedUsernames []string `json:"allowedUsernames,omitempty" yaml:"allowedUsernames,omitempty" mapstructure:"allowedUsernames,omitempty"`
// Explanation of why this permission is needed
Reason string `json:"reason" yaml:"reason" mapstructure:"reason"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *PluginManifestPermissionsSubsonicapi) UnmarshalJSON(value []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(value, &raw); err != nil {
return err
}
if _, ok := raw["reason"]; raw != nil && !ok {
return fmt.Errorf("field reason in PluginManifestPermissionsSubsonicapi: required")
}
type Plain PluginManifestPermissionsSubsonicapi
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if v, ok := raw["allowAdmins"]; !ok || v == nil {
plain.AllowAdmins = false
}
if len(plain.Reason) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "reason", 1)
}
*j = PluginManifestPermissionsSubsonicapi(plain)
return nil
}
// WebSocket service permissions
type PluginManifestPermissionsWebsocket struct {
// Whether to allow connections to local/private network addresses
AllowLocalNetwork bool `json:"allowLocalNetwork,omitempty" yaml:"allowLocalNetwork,omitempty" mapstructure:"allowLocalNetwork,omitempty"`
// List of WebSocket URL patterns that the plugin is allowed to connect to
AllowedUrls []string `json:"allowedUrls" yaml:"allowedUrls" mapstructure:"allowedUrls"`
// Explanation of why this permission is needed
Reason string `json:"reason" yaml:"reason" mapstructure:"reason"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *PluginManifestPermissionsWebsocket) UnmarshalJSON(value []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(value, &raw); err != nil {
return err
}
if _, ok := raw["allowedUrls"]; raw != nil && !ok {
return fmt.Errorf("field allowedUrls in PluginManifestPermissionsWebsocket: required")
}
if _, ok := raw["reason"]; raw != nil && !ok {
return fmt.Errorf("field reason in PluginManifestPermissionsWebsocket: required")
}
type Plain PluginManifestPermissionsWebsocket
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if v, ok := raw["allowLocalNetwork"]; !ok || v == nil {
plain.AllowLocalNetwork = false
}
if plain.AllowedUrls != nil && len(plain.AllowedUrls) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "allowedUrls", 1)
}
if len(plain.Reason) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "reason", 1)
}
*j = PluginManifestPermissionsWebsocket(plain)
return nil
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *PluginManifest) UnmarshalJSON(value []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(value, &raw); err != nil {
return err
}
if _, ok := raw["author"]; raw != nil && !ok {
return fmt.Errorf("field author in PluginManifest: required")
}
if _, ok := raw["capabilities"]; raw != nil && !ok {
return fmt.Errorf("field capabilities in PluginManifest: required")
}
if _, ok := raw["description"]; raw != nil && !ok {
return fmt.Errorf("field description in PluginManifest: required")
}
if _, ok := raw["name"]; raw != nil && !ok {
return fmt.Errorf("field name in PluginManifest: required")
}
if _, ok := raw["permissions"]; raw != nil && !ok {
return fmt.Errorf("field permissions in PluginManifest: required")
}
if _, ok := raw["version"]; raw != nil && !ok {
return fmt.Errorf("field version in PluginManifest: required")
}
if _, ok := raw["website"]; raw != nil && !ok {
return fmt.Errorf("field website in PluginManifest: required")
}
type Plain PluginManifest
var plain Plain
if err := json.Unmarshal(value, &plain); err != nil {
return err
}
if plain.Capabilities != nil && len(plain.Capabilities) < 1 {
return fmt.Errorf("field %s length: must be >= %d", "capabilities", 1)
}
*j = PluginManifest(plain)
return nil
}