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:
90
plugins/host_http_permissions.go
Normal file
90
plugins/host_http_permissions.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/navidrome/navidrome/plugins/schema"
|
||||
)
|
||||
|
||||
// Maximum number of HTTP redirects allowed for plugin requests
|
||||
const httpMaxRedirects = 5
|
||||
|
||||
// HTTPPermissions represents granular HTTP access permissions for plugins
|
||||
type httpPermissions struct {
|
||||
*networkPermissionsBase
|
||||
AllowedUrls map[string][]string `json:"allowedUrls"`
|
||||
matcher *urlMatcher
|
||||
}
|
||||
|
||||
// parseHTTPPermissions extracts HTTP permissions from the schema
|
||||
func parseHTTPPermissions(permData *schema.PluginManifestPermissionsHttp) (*httpPermissions, error) {
|
||||
base := &networkPermissionsBase{
|
||||
AllowLocalNetwork: permData.AllowLocalNetwork,
|
||||
}
|
||||
|
||||
if len(permData.AllowedUrls) == 0 {
|
||||
return nil, fmt.Errorf("allowedUrls must contain at least one URL pattern")
|
||||
}
|
||||
|
||||
allowedUrls := make(map[string][]string)
|
||||
for urlPattern, methodEnums := range permData.AllowedUrls {
|
||||
methods := make([]string, len(methodEnums))
|
||||
for i, methodEnum := range methodEnums {
|
||||
methods[i] = string(methodEnum)
|
||||
}
|
||||
allowedUrls[urlPattern] = methods
|
||||
}
|
||||
|
||||
return &httpPermissions{
|
||||
networkPermissionsBase: base,
|
||||
AllowedUrls: allowedUrls,
|
||||
matcher: newURLMatcher(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// IsRequestAllowed checks if a specific network request is allowed by the permissions
|
||||
func (p *httpPermissions) IsRequestAllowed(requestURL, operation string) error {
|
||||
if _, err := checkURLPolicy(requestURL, p.AllowLocalNetwork); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// allowedUrls is now required - no fallback to allow all URLs
|
||||
if p.AllowedUrls == nil || len(p.AllowedUrls) == 0 {
|
||||
return fmt.Errorf("no allowed URLs configured for plugin")
|
||||
}
|
||||
|
||||
matcher := newURLMatcher()
|
||||
|
||||
// Check URL patterns and operations
|
||||
// First try exact matches, then wildcard matches
|
||||
operation = strings.ToUpper(operation)
|
||||
|
||||
// Phase 1: Check for exact matches first
|
||||
for urlPattern, allowedOperations := range p.AllowedUrls {
|
||||
if !strings.Contains(urlPattern, "*") && matcher.MatchesURLPattern(requestURL, urlPattern) {
|
||||
// Check if operation is allowed
|
||||
for _, allowedOperation := range allowedOperations {
|
||||
if allowedOperation == "*" || allowedOperation == operation {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("operation %s not allowed for URL pattern %s", operation, urlPattern)
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 2: Check wildcard patterns
|
||||
for urlPattern, allowedOperations := range p.AllowedUrls {
|
||||
if strings.Contains(urlPattern, "*") && matcher.MatchesURLPattern(requestURL, urlPattern) {
|
||||
// Check if operation is allowed
|
||||
for _, allowedOperation := range allowedOperations {
|
||||
if allowedOperation == "*" || allowedOperation == operation {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("operation %s not allowed for URL pattern %s", operation, urlPattern)
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("URL %s does not match any allowed URL patterns", requestURL)
|
||||
}
|
||||
Reference in New Issue
Block a user