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) }