678 lines
16 KiB
Go
678 lines
16 KiB
Go
/*
|
|
|--------------------------------------------------------------------------
|
|
| Manifest
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Name:
|
|
| - Filesystem
|
|
|
|
|
| Purpose:
|
|
| - Provide reusable, OS-agnostic filesystem operations through a unified execution interface.
|
|
|
|
|
| Guideline:
|
|
| - Use for deterministic filesystem listing, validation, creation, deletion, and permission operations.
|
|
| - Execute exactly one operation per invocation.
|
|
| - Validate configuration before execution.
|
|
| - Return structured output for all execution paths.
|
|
| - Remain independent from runtime execution layers.
|
|
|
|
|
| Example:
|
|
| - ObrimFilesystem("list", map[string]any{"strategy":"user"})
|
|
| - ObrimFilesystem("create", map[string]any{"entity":"directory","name":"example"})
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Credit
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Contributor:
|
|
| - Rajon Ahmed
|
|
| - Scionite
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
package filesystem
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"go/module/essential/visible/service/helper/log"
|
|
"go/module/essential/visible/service/helper/status"
|
|
)
|
|
|
|
type ObrimFilesystemResult struct {
|
|
Status bool `json:"status"`
|
|
Code string `json:"code"`
|
|
Payload any `json:"payload"`
|
|
}
|
|
|
|
type obrimFilesystemEntry struct {
|
|
Name string `json:"name"`
|
|
Path string `json:"path"`
|
|
Entity string `json:"entity"`
|
|
Size int64 `json:"size"`
|
|
Modified time.Time `json:"modified"`
|
|
Created time.Time `json:"created"`
|
|
IsHidden bool `json:"hidden"`
|
|
IsSymlink bool `json:"symlink"`
|
|
Permissions string `json:"permission"`
|
|
}
|
|
|
|
var obrimFilesystemSupportedTypes = map[string]bool{
|
|
"list": true,
|
|
"check": true,
|
|
"create": true,
|
|
"delete": true,
|
|
"permission": true,
|
|
}
|
|
|
|
var obrimFilesystemAllowedKeys = map[string]map[string]bool{
|
|
"list": {
|
|
"entity": true, "strategy": true, "base": true, "name": true,
|
|
"recursive": true, "include_hidden": true, "sort_by": true,
|
|
"sort_order": true, "filter_pattern": true, "follow_symlink": true,
|
|
"absolute_path": true,
|
|
},
|
|
"check": {
|
|
"entity": true, "strategy": true, "base": true, "name": true,
|
|
"readable": true, "writable": true,
|
|
},
|
|
"create": {
|
|
"entity": true, "strategy": true, "base": true, "name": true,
|
|
"hidden": true,
|
|
},
|
|
"delete": {
|
|
"entity": true, "strategy": true, "base": true, "name": true,
|
|
"recursive": true,
|
|
},
|
|
"permission": {
|
|
"entity": true, "strategy": true, "base": true, "name": true,
|
|
"mode": true, "permission": true,
|
|
},
|
|
}
|
|
|
|
// ObrimFilesystem executes a filesystem operation and returns a structured result.
|
|
func ObrimFilesystem(operationType string, config map[string]any) map[string]any {
|
|
log.ObrimLog("INIT", fmt.Sprintf("filesystem operation: %s", operationType))
|
|
|
|
if err := obrimFilesystemValidate(operationType, config); err != nil {
|
|
status.ObrimStatus("ERROR", err.Error())
|
|
log.ObrimLog("ERROR", err.Error())
|
|
|
|
return map[string]any{
|
|
"status": false,
|
|
"code": "FAILED_VALIDATION",
|
|
"payload": nil,
|
|
}
|
|
}
|
|
|
|
switch operationType {
|
|
case "list":
|
|
return obrimFilesystemList(config)
|
|
|
|
case "check":
|
|
return obrimFilesystemCheck(config)
|
|
|
|
case "create":
|
|
return obrimFilesystemCreate(config)
|
|
|
|
case "delete":
|
|
return obrimFilesystemDelete(config)
|
|
|
|
case "permission":
|
|
return obrimFilesystemPermission(config)
|
|
|
|
default:
|
|
status.ObrimStatus("ERROR", "Unsupported operation.")
|
|
return map[string]any{
|
|
"status": false,
|
|
"code": "FAILED_UNSUPPORTED_OPERATION",
|
|
"payload": nil,
|
|
}
|
|
}
|
|
}
|
|
|
|
// obrimFilesystemValidate validates operation type and configuration.
|
|
func obrimFilesystemValidate(operationType string, config map[string]any) error {
|
|
if !obrimFilesystemSupportedTypes[operationType] {
|
|
return errors.New("unsupported operation type")
|
|
}
|
|
|
|
allowed := obrimFilesystemAllowedKeys[operationType]
|
|
|
|
for key := range config {
|
|
if !allowed[key] {
|
|
return fmt.Errorf("unsupported config key: %s", key)
|
|
}
|
|
}
|
|
|
|
if operationType != "list" {
|
|
if _, exists := config["name"]; !exists {
|
|
return errors.New("name is required")
|
|
}
|
|
}
|
|
|
|
if operationType == "create" || operationType == "delete" {
|
|
entity := fmt.Sprintf("%v", config["entity"])
|
|
|
|
if entity != "file" && entity != "directory" {
|
|
return errors.New("invalid entity")
|
|
}
|
|
}
|
|
|
|
if operationType == "permission" {
|
|
mode := fmt.Sprintf("%v", config["mode"])
|
|
|
|
if mode != "read" && mode != "write" {
|
|
return errors.New("invalid permission mode")
|
|
}
|
|
|
|
if mode == "write" {
|
|
if err := obrimFilesystemPermissionValidate(config); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// obrimFilesystemResolve resolves and normalizes filesystem paths.
|
|
func obrimFilesystemResolve(config map[string]any) (string, error) {
|
|
strategy := fmt.Sprintf("%v", config["strategy"])
|
|
|
|
var base string
|
|
|
|
switch strategy {
|
|
case "", "user":
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
base = home
|
|
|
|
case "custom":
|
|
base = fmt.Sprintf("%v", config["base"])
|
|
|
|
if base == "" {
|
|
return "", errors.New("base path required")
|
|
}
|
|
|
|
default:
|
|
return "", errors.New("invalid strategy")
|
|
}
|
|
|
|
name := fmt.Sprintf("%v", config["name"])
|
|
|
|
return filepath.Clean(filepath.Join(base, name)), nil
|
|
}
|
|
|
|
// obrimFilesystemPayload builds standardized payload structures.
|
|
func obrimFilesystemPayload(data map[string]any) map[string]any {
|
|
return data
|
|
}
|
|
|
|
// obrimFilesystemEntityType determines filesystem entity type.
|
|
func obrimFilesystemEntityType(path string) string {
|
|
info, err := os.Stat(path)
|
|
|
|
if err != nil {
|
|
return "unknown"
|
|
}
|
|
|
|
if info.IsDir() {
|
|
return "directory"
|
|
}
|
|
|
|
return "file"
|
|
}
|
|
|
|
// obrimFilesystemPermissionValidate validates permission specifications.
|
|
func obrimFilesystemPermissionValidate(config map[string]any) error {
|
|
permission := fmt.Sprintf("%v", config["permission"])
|
|
|
|
if permission == "" {
|
|
return errors.New("permission is required")
|
|
}
|
|
|
|
_, err := strconv.ParseUint(permission, 8, 32)
|
|
|
|
return err
|
|
}
|
|
|
|
// obrimFilesystemList executes filesystem listing operations.
|
|
func obrimFilesystemList(config map[string]any) map[string]any {
|
|
base, err := obrimFilesystemResolve(map[string]any{
|
|
"strategy": config["strategy"],
|
|
"base": config["base"],
|
|
"name": "",
|
|
})
|
|
|
|
if err != nil {
|
|
return map[string]any{
|
|
"status": false,
|
|
"code": "FAILED_PATH_RESOLUTION",
|
|
"payload": nil,
|
|
}
|
|
}
|
|
|
|
entries, err := obrimFilesystemListTraverse(base, config)
|
|
|
|
if err != nil {
|
|
return map[string]any{
|
|
"status": false,
|
|
"code": "FAILED_LIST",
|
|
"payload": nil,
|
|
}
|
|
}
|
|
|
|
entries = obrimFilesystemListFilter(entries, config)
|
|
entries = obrimFilesystemListSort(entries, config)
|
|
|
|
status.ObrimStatus("SUCCESS", "Filesystem listing completed.")
|
|
|
|
return map[string]any{
|
|
"status": true,
|
|
"code": "SUCCESS_LIST",
|
|
"payload": obrimFilesystemPayload(map[string]any{
|
|
"entries": entries,
|
|
"total": len(entries),
|
|
"recursive": config["recursive"] == true,
|
|
"base_path": base,
|
|
}),
|
|
}
|
|
}
|
|
|
|
// obrimFilesystemListTraverse traverses filesystem entities.
|
|
func obrimFilesystemListTraverse(base string, config map[string]any) ([]obrimFilesystemEntry, error) {
|
|
recursive := config["recursive"] == true
|
|
includeHidden := config["include_hidden"] == true
|
|
followSymlink := config["follow_symlink"] == true
|
|
absolute := config["absolute_path"] == true
|
|
|
|
var entries []obrimFilesystemEntry
|
|
|
|
if recursive {
|
|
err := filepath.Walk(base, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
if path == base {
|
|
return nil
|
|
}
|
|
|
|
if !includeHidden && strings.HasPrefix(info.Name(), ".") {
|
|
if info.IsDir() {
|
|
return filepath.SkipDir
|
|
}
|
|
return nil
|
|
}
|
|
|
|
if info.Mode()&os.ModeSymlink != 0 && !followSymlink {
|
|
return nil
|
|
}
|
|
|
|
entryPath := path
|
|
|
|
if !absolute {
|
|
entryPath = info.Name()
|
|
}
|
|
|
|
entries = append(entries, obrimFilesystemEntry{
|
|
Name: info.Name(),
|
|
Path: entryPath,
|
|
Entity: obrimFilesystemEntityType(path),
|
|
Size: info.Size(),
|
|
Modified: info.ModTime(),
|
|
Created: info.ModTime(),
|
|
IsHidden: strings.HasPrefix(info.Name(), "."),
|
|
IsSymlink: info.Mode()&os.ModeSymlink != 0,
|
|
Permissions: info.Mode().Perm().String(),
|
|
})
|
|
|
|
return nil
|
|
})
|
|
|
|
return entries, err
|
|
}
|
|
|
|
list, err := os.ReadDir(base)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, item := range list {
|
|
if !includeHidden && strings.HasPrefix(item.Name(), ".") {
|
|
continue
|
|
}
|
|
|
|
info, err := item.Info()
|
|
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
path := filepath.Join(base, item.Name())
|
|
|
|
entryPath := path
|
|
|
|
if !absolute {
|
|
entryPath = item.Name()
|
|
}
|
|
|
|
entries = append(entries, obrimFilesystemEntry{
|
|
Name: item.Name(),
|
|
Path: entryPath,
|
|
Entity: obrimFilesystemEntityType(path),
|
|
Size: info.Size(),
|
|
Modified: info.ModTime(),
|
|
Created: info.ModTime(),
|
|
IsHidden: strings.HasPrefix(item.Name(), "."),
|
|
IsSymlink: info.Mode()&os.ModeSymlink != 0,
|
|
Permissions: info.Mode().Perm().String(),
|
|
})
|
|
}
|
|
|
|
return entries, nil
|
|
}
|
|
|
|
// obrimFilesystemListFilter applies entity and pattern filtering.
|
|
func obrimFilesystemListFilter(entries []obrimFilesystemEntry, config map[string]any) []obrimFilesystemEntry {
|
|
entity := fmt.Sprintf("%v", config["entity"])
|
|
pattern := fmt.Sprintf("%v", config["filter_pattern"])
|
|
|
|
var filtered []obrimFilesystemEntry
|
|
|
|
for _, entry := range entries {
|
|
if entity != "" && entry.Entity != entity {
|
|
continue
|
|
}
|
|
|
|
if pattern != "" {
|
|
match, _ := filepath.Match(pattern, entry.Name)
|
|
|
|
if !match {
|
|
continue
|
|
}
|
|
}
|
|
|
|
filtered = append(filtered, entry)
|
|
}
|
|
|
|
return filtered
|
|
}
|
|
|
|
// obrimFilesystemListSort applies result sorting behavior.
|
|
func obrimFilesystemListSort(entries []obrimFilesystemEntry, config map[string]any) []obrimFilesystemEntry {
|
|
sortBy := fmt.Sprintf("%v", config["sort_by"])
|
|
order := fmt.Sprintf("%v", config["sort_order"])
|
|
|
|
sort.Slice(entries, func(i, j int) bool {
|
|
result := false
|
|
|
|
switch sortBy {
|
|
case "size":
|
|
result = entries[i].Size < entries[j].Size
|
|
|
|
case "modified":
|
|
result = entries[i].Modified.Before(entries[j].Modified)
|
|
|
|
case "created":
|
|
result = entries[i].Created.Before(entries[j].Created)
|
|
|
|
default:
|
|
result = entries[i].Name < entries[j].Name
|
|
}
|
|
|
|
if order == "desc" {
|
|
return !result
|
|
}
|
|
|
|
return result
|
|
})
|
|
|
|
return entries
|
|
}
|
|
|
|
// obrimFilesystemCheck executes filesystem validation operations.
|
|
func obrimFilesystemCheck(config map[string]any) map[string]any {
|
|
path, err := obrimFilesystemResolve(config)
|
|
|
|
if err != nil {
|
|
return map[string]any{"status": false, "code": "FAILED_PATH_RESOLUTION", "payload": nil}
|
|
}
|
|
|
|
_, err = os.Stat(path)
|
|
|
|
exists := err == nil
|
|
|
|
readable, writable := obrimFilesystemCheckAccess(path)
|
|
|
|
return map[string]any{
|
|
"status": true,
|
|
"code": "SUCCESS_CHECK",
|
|
"payload": map[string]any{
|
|
"path": path,
|
|
"exists": exists,
|
|
"entity": obrimFilesystemEntityType(path),
|
|
"readable": readable,
|
|
"writable": writable,
|
|
},
|
|
}
|
|
}
|
|
|
|
// obrimFilesystemCheckAccess verifies filesystem accessibility.
|
|
func obrimFilesystemCheckAccess(path string) (bool, bool) {
|
|
readable := true
|
|
writable := true
|
|
|
|
file, err := os.Open(path)
|
|
|
|
if err != nil {
|
|
readable = false
|
|
} else {
|
|
_ = file.Close()
|
|
}
|
|
|
|
file, err = os.OpenFile(path, os.O_WRONLY, 0)
|
|
|
|
if err != nil {
|
|
writable = false
|
|
} else {
|
|
_ = file.Close()
|
|
}
|
|
|
|
return readable, writable
|
|
}
|
|
|
|
// obrimFilesystemCreate executes filesystem entity creation operations.
|
|
func obrimFilesystemCreate(config map[string]any) map[string]any {
|
|
path, err := obrimFilesystemResolve(config)
|
|
|
|
if err != nil {
|
|
return map[string]any{"status": false, "code": "FAILED_PATH_RESOLUTION", "payload": nil}
|
|
}
|
|
|
|
entity := fmt.Sprintf("%v", config["entity"])
|
|
|
|
if entity == "file" {
|
|
err = obrimFilesystemCreateFile(path)
|
|
} else {
|
|
err = obrimFilesystemCreateDirectory(path)
|
|
}
|
|
|
|
if err != nil {
|
|
return map[string]any{"status": false, "code": "FAILED_CREATE", "payload": nil}
|
|
}
|
|
|
|
return map[string]any{
|
|
"status": true,
|
|
"code": "SUCCESS_CREATE",
|
|
"payload": map[string]any{
|
|
"path": path,
|
|
"entity": entity,
|
|
"hidden": config["hidden"] == true,
|
|
"created": true,
|
|
},
|
|
}
|
|
}
|
|
|
|
// obrimFilesystemCreateFile creates a filesystem file.
|
|
func obrimFilesystemCreateFile(path string) error {
|
|
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
|
return err
|
|
}
|
|
|
|
file, err := os.Create(path)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return file.Close()
|
|
}
|
|
|
|
// obrimFilesystemCreateDirectory creates a filesystem directory.
|
|
func obrimFilesystemCreateDirectory(path string) error {
|
|
return os.MkdirAll(path, 0755)
|
|
}
|
|
|
|
// obrimFilesystemDelete executes filesystem entity deletion operations.
|
|
func obrimFilesystemDelete(config map[string]any) map[string]any {
|
|
path, err := obrimFilesystemResolve(config)
|
|
|
|
if err != nil {
|
|
return map[string]any{"status": false, "code": "FAILED_PATH_RESOLUTION", "payload": nil}
|
|
}
|
|
|
|
entity := fmt.Sprintf("%v", config["entity"])
|
|
|
|
if entity == "file" {
|
|
err = obrimFilesystemDeleteFile(path)
|
|
} else {
|
|
err = obrimFilesystemDeleteDirectory(path, config["recursive"] == true)
|
|
}
|
|
|
|
if err != nil {
|
|
return map[string]any{"status": false, "code": "FAILED_DELETE", "payload": nil}
|
|
}
|
|
|
|
return map[string]any{
|
|
"status": true,
|
|
"code": "SUCCESS_DELETE",
|
|
"payload": map[string]any{
|
|
"path": path,
|
|
"entity": entity,
|
|
"deleted": true,
|
|
},
|
|
}
|
|
}
|
|
|
|
// obrimFilesystemDeleteFile deletes a filesystem file.
|
|
func obrimFilesystemDeleteFile(path string) error {
|
|
return os.Remove(path)
|
|
}
|
|
|
|
// obrimFilesystemDeleteDirectory deletes a filesystem directory.
|
|
func obrimFilesystemDeleteDirectory(path string, recursive bool) error {
|
|
if recursive {
|
|
return os.RemoveAll(path)
|
|
}
|
|
|
|
return os.Remove(path)
|
|
}
|
|
|
|
// obrimFilesystemPermission executes filesystem permission operations.
|
|
func obrimFilesystemPermission(config map[string]any) map[string]any {
|
|
path, err := obrimFilesystemResolve(config)
|
|
|
|
if err != nil {
|
|
return map[string]any{"status": false, "code": "FAILED_PATH_RESOLUTION", "payload": nil}
|
|
}
|
|
|
|
mode := fmt.Sprintf("%v", config["mode"])
|
|
|
|
if mode == "read" {
|
|
return obrimFilesystemPermissionRead(path)
|
|
}
|
|
|
|
return obrimFilesystemPermissionWrite(path, fmt.Sprintf("%v", config["permission"]))
|
|
}
|
|
|
|
// obrimFilesystemPermissionRead retrieves filesystem permissions.
|
|
func obrimFilesystemPermissionRead(path string) map[string]any {
|
|
info, err := os.Stat(path)
|
|
|
|
if err != nil {
|
|
return map[string]any{"status": false, "code": "FAILED_PERMISSION_READ", "payload": nil}
|
|
}
|
|
|
|
return map[string]any{
|
|
"status": true,
|
|
"code": "SUCCESS_PERMISSION_READ",
|
|
"payload": map[string]any{
|
|
"path": path,
|
|
"permission": info.Mode().Perm().String(),
|
|
"mode": "read",
|
|
"updated": false,
|
|
},
|
|
}
|
|
}
|
|
|
|
// obrimFilesystemPermissionWrite updates filesystem permissions.
|
|
func obrimFilesystemPermissionWrite(path string, permission string) map[string]any {
|
|
if runtime.GOOS == "windows" {
|
|
return map[string]any{
|
|
"status": false,
|
|
"code": "FAILED_PERMISSION_UNSUPPORTED",
|
|
"payload": nil,
|
|
}
|
|
}
|
|
|
|
value, err := strconv.ParseUint(permission, 8, 32)
|
|
|
|
if err != nil {
|
|
return map[string]any{
|
|
"status": false,
|
|
"code": "FAILED_PERMISSION_VALIDATION",
|
|
"payload": nil,
|
|
}
|
|
}
|
|
|
|
err = os.Chmod(path, os.FileMode(value))
|
|
|
|
if err != nil {
|
|
return map[string]any{
|
|
"status": false,
|
|
"code": "FAILED_PERMISSION_WRITE",
|
|
"payload": nil,
|
|
}
|
|
}
|
|
|
|
return map[string]any{
|
|
"status": true,
|
|
"code": "SUCCESS_PERMISSION_WRITE",
|
|
"payload": map[string]any{
|
|
"path": path,
|
|
"permission": permission,
|
|
"mode": "write",
|
|
"updated": true,
|
|
},
|
|
}
|
|
}
|