package boxstore import ( "fmt" "os" "path/filepath" "warpbox/lib/helpers" ) const manifestFile = ".warpbox.json" var uploadRoot = filepath.Join("data", "uploads") func NewBoxID() (string, error) { return helpers.RandomHexID(16) } func ValidBoxID(boxID string) bool { return helpers.ValidLowerHexID(boxID, 32) } func SetUploadRoot(path string) { if path == "" { return } uploadRoot = filepath.Clean(path) } func UploadRoot() string { return uploadRoot } func BoxPath(boxID string) string { return filepath.Join(uploadRoot, boxID) } func safeBoxPath(boxID string) (string, bool) { if !ValidBoxID(boxID) { return "", false } return helpers.SafeChildPath(uploadRoot, boxID) } func ManifestPath(boxID string) string { return filepath.Join(BoxPath(boxID), manifestFile) } func SafeBoxFilePath(boxID string, filename string) (string, bool) { boxPath, ok := safeBoxPath(boxID) if !ok { return "", false } return helpers.SafeChildPath(boxPath, filename) } func IsSafeRegularBoxFile(boxID string, filename string) bool { path, ok := SafeBoxFilePath(boxID, filename) if !ok { return false } return ensureRegularFile(path) == nil } func DeleteBox(boxID string) error { boxPath, ok := safeBoxPath(boxID) if !ok { return fmt.Errorf("Invalid box id") } return os.RemoveAll(boxPath) } func ensureRegularFile(path string) error { info, err := os.Lstat(path) if err != nil { return err } if info.Mode()&os.ModeSymlink != 0 || !info.Mode().IsRegular() { return fmt.Errorf("Invalid file") } return nil }