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
77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
package plugins
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/navidrome/navidrome/plugins/schema"
|
|
)
|
|
|
|
// WebSocketPermissions represents granular WebSocket access permissions for plugins
|
|
type webSocketPermissions struct {
|
|
*networkPermissionsBase
|
|
AllowedUrls []string `json:"allowedUrls"`
|
|
matcher *urlMatcher
|
|
}
|
|
|
|
// parseWebSocketPermissions extracts WebSocket permissions from the schema
|
|
func parseWebSocketPermissions(permData *schema.PluginManifestPermissionsWebsocket) (*webSocketPermissions, error) {
|
|
if len(permData.AllowedUrls) == 0 {
|
|
return nil, fmt.Errorf("allowedUrls must contain at least one URL pattern")
|
|
}
|
|
|
|
return &webSocketPermissions{
|
|
networkPermissionsBase: &networkPermissionsBase{
|
|
AllowLocalNetwork: permData.AllowLocalNetwork,
|
|
},
|
|
AllowedUrls: permData.AllowedUrls,
|
|
matcher: newURLMatcher(),
|
|
}, nil
|
|
}
|
|
|
|
// IsConnectionAllowed checks if a WebSocket connection is allowed
|
|
func (w *webSocketPermissions) IsConnectionAllowed(requestURL string) error {
|
|
if _, err := checkURLPolicy(requestURL, w.AllowLocalNetwork); err != nil {
|
|
return err
|
|
}
|
|
|
|
// allowedUrls is required - no fallback to allow all URLs
|
|
if len(w.AllowedUrls) == 0 {
|
|
return fmt.Errorf("no allowed URLs configured for plugin")
|
|
}
|
|
|
|
// Check URL patterns
|
|
// First try exact matches, then wildcard matches
|
|
|
|
// Phase 1: Check for exact matches first
|
|
for _, urlPattern := range w.AllowedUrls {
|
|
if urlPattern == "*" || (!containsWildcard(urlPattern) && w.matcher.MatchesURLPattern(requestURL, urlPattern)) {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// Phase 2: Check wildcard patterns
|
|
for _, urlPattern := range w.AllowedUrls {
|
|
if containsWildcard(urlPattern) && w.matcher.MatchesURLPattern(requestURL, urlPattern) {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return fmt.Errorf("URL %s does not match any allowed URL patterns", requestURL)
|
|
}
|
|
|
|
// containsWildcard checks if a URL pattern contains wildcard characters
|
|
func containsWildcard(pattern string) bool {
|
|
if pattern == "*" {
|
|
return true
|
|
}
|
|
|
|
// Check for wildcards anywhere in the pattern
|
|
for _, char := range pattern {
|
|
if char == '*' {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|