orchard/pkg/resource/v1/host_dir_policy.go

76 lines
1.6 KiB
Go

package v1
import (
"errors"
"fmt"
"strings"
)
var ErrInvalidHostDirPolicy = errors.New("invalid hostDir policy")
type HostDirPolicy struct {
PathPrefix string `json:"pathPrefix,omitempty"`
ReadOnly bool `json:"ro,omitempty"`
}
func NewHostDirPolicyFromString(s string) (HostDirPolicy, error) {
if strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://") {
return HostDirPolicy{
PathPrefix: strings.TrimSuffix(s, ":ro"),
ReadOnly: strings.HasSuffix(s, ":ro"),
}, nil
}
parts := strings.Split(s, ":")
if len(parts) > 2 {
return HostDirPolicy{}, fmt.Errorf("%w: hostDir policy should contain 2 parts at max, found %d",
ErrInvalidHostDirPolicy, len(parts))
}
if parts[0] == "" {
return HostDirPolicy{}, fmt.Errorf("%w: path prefix cannot be empty", ErrInvalidHostDirPolicy)
}
var readOnly bool
if len(parts) == 2 {
if parts[1] == "ro" {
readOnly = true
} else {
return HostDirPolicy{}, fmt.Errorf("%w: hostDir policy's second part can only be \"ro\", found %q",
ErrInvalidHostDirPolicy, parts[1])
}
}
return HostDirPolicy{
PathPrefix: parts[0],
ReadOnly: readOnly,
}, nil
}
func (policy HostDirPolicy) Validate(path string, readOnly bool) bool {
if strings.Contains(path, "..") {
return false
}
if policy.ReadOnly && !readOnly {
return false
}
return strings.HasPrefix(
strings.TrimSuffix(path, "/"),
strings.TrimSuffix(policy.PathPrefix, "/"),
)
}
func (policy HostDirPolicy) String() string {
var roPart string
if policy.ReadOnly {
roPart = ":ro"
}
return fmt.Sprintf("%s%s", policy.PathPrefix, roPart)
}