update
Some checks failed
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v5) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v6) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v7) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to GHCR (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Has been cancelled
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
POEditor import / update-translations (push) Has been cancelled
Some checks failed
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v5) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v6) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v7) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to GHCR (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Has been cancelled
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
POEditor import / update-translations (push) Has been cancelled
This commit is contained in:
199
plugins/schema/manifest.schema.json
Normal file
199
plugins/schema/manifest.schema.json
Normal file
@@ -0,0 +1,199 @@
|
||||
{
|
||||
"$id": "navidrome://plugins/manifest",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Navidrome Plugin Manifest",
|
||||
"description": "Schema for Navidrome Plugin manifest.json files",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"author",
|
||||
"version",
|
||||
"description",
|
||||
"website",
|
||||
"capabilities",
|
||||
"permissions"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the plugin"
|
||||
},
|
||||
"author": {
|
||||
"type": "string",
|
||||
"description": "Author or organization that created the plugin"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Plugin version using semantic versioning format"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A brief description of the plugin's functionality"
|
||||
},
|
||||
"website": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"description": "Website URL for the plugin or its documentation"
|
||||
},
|
||||
"capabilities": {
|
||||
"type": "array",
|
||||
"description": "List of capabilities implemented by this plugin",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"MetadataAgent",
|
||||
"Scrobbler",
|
||||
"SchedulerCallback",
|
||||
"LifecycleManagement",
|
||||
"WebSocketCallback"
|
||||
]
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"type": "object",
|
||||
"description": "Host services the plugin is allowed to access",
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"http": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/basePermission" },
|
||||
{
|
||||
"type": "object",
|
||||
"description": "HTTP service permissions",
|
||||
"required": ["allowedUrls"],
|
||||
"properties": {
|
||||
"allowedUrls": {
|
||||
"type": "object",
|
||||
"description": "Map of URL patterns (e.g., 'https://api.example.com/*') to allowed HTTP methods. Redirect destinations must also be included.",
|
||||
"additionalProperties": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE",
|
||||
"PATCH",
|
||||
"HEAD",
|
||||
"OPTIONS",
|
||||
"*"
|
||||
]
|
||||
},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"minProperties": 1
|
||||
},
|
||||
"allowLocalNetwork": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to allow requests to local/private network addresses",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/basePermission" },
|
||||
{
|
||||
"type": "object",
|
||||
"description": "Configuration service permissions"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scheduler": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/basePermission" },
|
||||
{
|
||||
"type": "object",
|
||||
"description": "Scheduler service permissions"
|
||||
}
|
||||
]
|
||||
},
|
||||
"websocket": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/basePermission" },
|
||||
{
|
||||
"type": "object",
|
||||
"description": "WebSocket service permissions",
|
||||
"required": ["allowedUrls"],
|
||||
"properties": {
|
||||
"allowedUrls": {
|
||||
"type": "array",
|
||||
"description": "List of WebSocket URL patterns that the plugin is allowed to connect to",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^wss?://.*$"
|
||||
},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"allowLocalNetwork": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to allow connections to local/private network addresses",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"cache": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/basePermission" },
|
||||
{
|
||||
"type": "object",
|
||||
"description": "Cache service permissions"
|
||||
}
|
||||
]
|
||||
},
|
||||
"artwork": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/basePermission" },
|
||||
{
|
||||
"type": "object",
|
||||
"description": "Artwork service permissions"
|
||||
}
|
||||
]
|
||||
},
|
||||
"subsonicapi": {
|
||||
"allOf": [
|
||||
{ "$ref": "#/$defs/basePermission" },
|
||||
{
|
||||
"type": "object",
|
||||
"description": "SubsonicAPI service permissions",
|
||||
"properties": {
|
||||
"allowedUsernames": {
|
||||
"type": "array",
|
||||
"description": "List of usernames the plugin can pass as u. Any user if empty",
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
"allowAdmins": {
|
||||
"type": "boolean",
|
||||
"description": "If false, reject calls where the u is an admin",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"basePermission": {
|
||||
"type": "object",
|
||||
"required": ["reason"],
|
||||
"properties": {
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Explanation of why this permission is needed"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
426
plugins/schema/manifest_gen.go
Normal file
426
plugins/schema/manifest_gen.go
Normal file
@@ -0,0 +1,426 @@
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user