let mac re-prompt + modularize more code.
This commit is contained in:
@@ -2011,6 +2011,9 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
|
||||
case "file_list":
|
||||
path, _ := envelopePayloadString(envelope, "path")
|
||||
return HandleFileList(ctx, env, cmdID, path)
|
||||
case "file_request_access":
|
||||
path, _ := envelopePayloadString(envelope, "path")
|
||||
return HandleFileRequestAccess(ctx, env, cmdID, path)
|
||||
case "file_download":
|
||||
path, _ := envelopePayloadString(envelope, "path")
|
||||
return HandleFileDownload(ctx, env, cmdID, path)
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
@@ -19,6 +20,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -124,16 +126,70 @@ func HandleFileList(ctx context.Context, env *agentRuntime.Env, cmdID string, pa
|
||||
}
|
||||
|
||||
result := wire.FileListResult{
|
||||
Type: "file_list_result",
|
||||
CommandID: cmdID,
|
||||
Path: path,
|
||||
Entries: entries,
|
||||
Error: errMsg,
|
||||
Type: "file_list_result",
|
||||
CommandID: cmdID,
|
||||
Path: path,
|
||||
Entries: entries,
|
||||
Error: errMsg,
|
||||
AccessDenied: isFileAccessDenied(err),
|
||||
CanRequestAccess: canRequestFolderAccess(err),
|
||||
AccessHelp: folderAccessHelp(err),
|
||||
}
|
||||
|
||||
return wire.WriteMsg(ctx, env.Conn, result)
|
||||
}
|
||||
|
||||
func isFileAccessDenied(err error) bool {
|
||||
return err != nil && errors.Is(err, os.ErrPermission)
|
||||
}
|
||||
|
||||
func canRequestFolderAccess(err error) bool {
|
||||
return runtime.GOOS == "darwin" && isFileAccessDenied(err)
|
||||
}
|
||||
|
||||
func folderAccessHelp(err error) string {
|
||||
if !canRequestFolderAccess(err) {
|
||||
return ""
|
||||
}
|
||||
return "macOS blocked this folder. Ask the user to allow access in Privacy & Security, then refresh this folder."
|
||||
}
|
||||
|
||||
func HandleFileRequestAccess(ctx context.Context, env *agentRuntime.Env, cmdID string, path string) error {
|
||||
if runtime.GOOS != "darwin" {
|
||||
return wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
|
||||
Type: "command_result",
|
||||
CommandID: cmdID,
|
||||
OK: false,
|
||||
Message: "folder access requests are only available on macOS",
|
||||
})
|
||||
}
|
||||
|
||||
if strings.TrimSpace(path) == "" {
|
||||
path = "."
|
||||
}
|
||||
if absPath, err := filepath.Abs(path); err == nil {
|
||||
path = absPath
|
||||
}
|
||||
|
||||
settingsURL := "x-apple.systempreferences:com.apple.preference.security?Privacy_FilesAndFolders"
|
||||
if err := exec.CommandContext(ctx, "open", settingsURL).Run(); err != nil {
|
||||
_ = exec.CommandContext(ctx, "open", "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles").Run()
|
||||
return wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
|
||||
Type: "command_result",
|
||||
CommandID: cmdID,
|
||||
OK: false,
|
||||
Message: fmt.Sprintf("could not open macOS Privacy settings: %v", err),
|
||||
})
|
||||
}
|
||||
|
||||
return wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
|
||||
Type: "command_result",
|
||||
CommandID: cmdID,
|
||||
OK: true,
|
||||
Message: fmt.Sprintf("opened macOS Privacy settings for folder access; ask the user to allow access for this app, then refresh %s", path),
|
||||
})
|
||||
}
|
||||
|
||||
func listWindowsDrives(ctx context.Context, env *agentRuntime.Env, cmdID string) error {
|
||||
entries := []wire.FileEntry{}
|
||||
|
||||
|
||||
@@ -113,17 +113,20 @@ type FileEntry struct {
|
||||
// windows file attributes
|
||||
Attrs uint32 `msgpack:"attrs,omitempty"`
|
||||
// Drive / volume disk usage (populated only at root listings for drive entries).
|
||||
FreeBytes int64 `msgpack:"freeBytes,omitempty"`
|
||||
TotalBytes int64 `msgpack:"totalBytes,omitempty"`
|
||||
FreeBytes int64 `msgpack:"freeBytes,omitempty"`
|
||||
TotalBytes int64 `msgpack:"totalBytes,omitempty"`
|
||||
FSType string `msgpack:"fsType,omitempty"`
|
||||
}
|
||||
|
||||
type FileListResult struct {
|
||||
Type string `msgpack:"type"`
|
||||
CommandID string `msgpack:"commandId,omitempty"`
|
||||
Path string `msgpack:"path"`
|
||||
Entries []FileEntry `msgpack:"entries"`
|
||||
Error string `msgpack:"error,omitempty"`
|
||||
Type string `msgpack:"type"`
|
||||
CommandID string `msgpack:"commandId,omitempty"`
|
||||
Path string `msgpack:"path"`
|
||||
Entries []FileEntry `msgpack:"entries"`
|
||||
Error string `msgpack:"error,omitempty"`
|
||||
AccessDenied bool `msgpack:"accessDenied,omitempty"`
|
||||
CanRequestAccess bool `msgpack:"canRequestAccess,omitempty"`
|
||||
AccessHelp string `msgpack:"accessHelp,omitempty"`
|
||||
}
|
||||
|
||||
type FileDownload struct {
|
||||
|
||||
Reference in New Issue
Block a user