mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-02-12 16:12:44 +00:00
191 lines
4.8 KiB
Go
191 lines
4.8 KiB
Go
package vo
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/phishingclub/phishingclub/validate"
|
|
)
|
|
|
|
type FileName struct {
|
|
inner string
|
|
}
|
|
|
|
// NewFileName creates a new file name
|
|
func NewFileName(p string) (*FileName, error) {
|
|
p = strings.TrimSpace(p)
|
|
p = path.Clean(p)
|
|
// string can not start with /, ./ or ..
|
|
err := validate.ErrorIfStringNotbetweenOrEqualTo(p, 1, 255)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid file name: %w", err)
|
|
}
|
|
|
|
// allow only a-zA-Z0-9_-. and space
|
|
err = validate.ErrorIfStringNotMatch(p, `^[a-zA-Z0-9_\-.\s]+$`)
|
|
if err != nil {
|
|
// Find and return the illegal characters
|
|
illegalChars := ""
|
|
for _, char := range p {
|
|
if !strings.ContainsRune(`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-. `, char) {
|
|
illegalChars += string(char)
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("invalid file name - Allows is characters, numbers, _, -, . and space. Illegal characters: %s", illegalChars)
|
|
}
|
|
return &FileName{
|
|
inner: p,
|
|
}, nil
|
|
}
|
|
|
|
// NewFileNameMust creates a new file name and panics if it fails
|
|
func NewFileNameMust(p string) *FileName {
|
|
f, err := NewFileName(p)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return f
|
|
}
|
|
|
|
// MarshalJSON implements the json.Marshaler interface
|
|
func (s FileName) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(s.inner)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the json into a string
|
|
func (s *FileName) UnmarshalJSON(data []byte) error {
|
|
var str string
|
|
if err := json.Unmarshal(data, &str); err != nil {
|
|
return err
|
|
}
|
|
v, err := NewFileName(str)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.inner = v.inner
|
|
return nil
|
|
}
|
|
|
|
// String returns the string representation of the file name
|
|
func (f FileName) String() string {
|
|
return f.inner
|
|
}
|
|
|
|
type RelativeFilePath struct {
|
|
inner string
|
|
}
|
|
|
|
// NewRelativeFilePath creates a new file path
|
|
func NewRelativeFilePath(p string) (*RelativeFilePath, error) {
|
|
p = strings.TrimSpace(p)
|
|
p = path.Clean(p)
|
|
// string can not start with /, ./ or ..
|
|
err := validate.ErrorIfStringNotbetweenOrEqualTo(p, 1, 512)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid path: %w", err)
|
|
}
|
|
|
|
// allow only a-zA-Z0-9_-. and / and space
|
|
err = validate.ErrorIfStringNotMatch(p, `^[a-zA-Z0-9_\-./\s]+$`)
|
|
if err != nil {
|
|
// Find and return the illegal characters
|
|
illegalChars := ""
|
|
for _, char := range p {
|
|
if !strings.ContainsRune(`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-. /`, char) {
|
|
illegalChars += string(char)
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("Invalid path. Invalid characters: %s", illegalChars)
|
|
}
|
|
return &RelativeFilePath{
|
|
inner: p,
|
|
}, nil
|
|
}
|
|
|
|
// NewRelativeFilePathMust creates a new file path and panics if it fails
|
|
func NewRelativeFilePathMust(p string) *RelativeFilePath {
|
|
f, err := NewRelativeFilePath(p)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return f
|
|
}
|
|
|
|
// MarshalJSON implements the json.Marshaler interface
|
|
func (s RelativeFilePath) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(s.inner)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the json into a string
|
|
func (s *RelativeFilePath) UnmarshalJSON(data []byte) error {
|
|
var str string
|
|
if err := json.Unmarshal(data, &str); err != nil {
|
|
return err
|
|
}
|
|
v, err := NewRelativeFilePath(str)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.inner = v.inner
|
|
return nil
|
|
}
|
|
|
|
// String returns the string representation of the file path
|
|
func (f RelativeFilePath) String() string {
|
|
return f.inner
|
|
}
|
|
|
|
type OptionalRelativePath struct {
|
|
inner string
|
|
}
|
|
|
|
// NewOptionalRelativePath creates a new optional file path that is realive
|
|
// from another folder. We make this shorter than the full path to avoid that
|
|
// the path in full path is longer than its limits, as this path is used in
|
|
// the full path along with its parent folders.
|
|
func NewOptionalRelativePath(p string) (*OptionalRelativePath, error) {
|
|
p = strings.TrimSpace(p)
|
|
p = path.Clean(p)
|
|
if len(p) > 0 {
|
|
err := validate.ErrorIfStringNotbetweenOrEqualTo(p, 1, 255)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid file path: %w", err)
|
|
}
|
|
// allow only a-zA-Z0-9_-. and /
|
|
err = validate.ErrorIfStringNotMatch(p, `^[a-zA-Z0-9_\-./]+$`)
|
|
if err != nil {
|
|
_ = err
|
|
return nil, fmt.Errorf("invalid path - Allows is characters, numbers and _, -, . and /")
|
|
}
|
|
}
|
|
return &OptionalRelativePath{
|
|
inner: p,
|
|
}, nil
|
|
}
|
|
|
|
// MarshalJSON implements the json.Marshaler interface
|
|
func (s OptionalRelativePath) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(s.inner)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the json into a string
|
|
func (s *OptionalRelativePath) UnmarshalJSON(data []byte) error {
|
|
var str string
|
|
if err := json.Unmarshal(data, &str); err != nil {
|
|
return err
|
|
}
|
|
v, err := NewOptionalRelativePath(str)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s.inner = v.inner
|
|
return nil
|
|
}
|
|
|
|
// String returns the string representation of the optional file path
|
|
func (o OptionalRelativePath) String() string {
|
|
return o.inner
|
|
}
|