key and API address fall back to the person's secrets file; a non-git folder becomes a local_path project
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -29,21 +30,79 @@ type Client struct {
|
||||
//
|
||||
// The token is read from PAPERCLIP_BOARD_KEY (the person's key) and only falls
|
||||
// back to PAPERCLIP_API_KEY for read-only use. The token is never logged.
|
||||
// fromSecrets reads one variable out of the person's own secrets file, for the
|
||||
// same reason as the shell fallback: a terminal started by a desktop session
|
||||
// does not inherit systemd's environment.d. The file is the person's; this
|
||||
// only reads it, and the value is never logged.
|
||||
func fromSecrets(name string) string {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
dir := filepath.Join(home, ".config", "environment.d")
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
for _, e := range entries {
|
||||
if e.IsDir() || !strings.HasSuffix(e.Name(), ".conf") {
|
||||
continue
|
||||
}
|
||||
data, err := os.ReadFile(filepath.Join(dir, e.Name()))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
k, v, ok := strings.Cut(line, "=")
|
||||
if ok && strings.TrimSpace(k) == name {
|
||||
return strings.Trim(strings.TrimSpace(v), `"'`)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func varOr(name, fallback string) string {
|
||||
if v := os.Getenv(name); v != "" {
|
||||
return v
|
||||
}
|
||||
if v := fromSecrets(name); v != "" {
|
||||
return v
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
// reachable says whether something answers at this address right now.
|
||||
func reachable(url string) bool {
|
||||
c := &http.Client{Timeout: 2 * time.Second}
|
||||
resp, err := c.Get(url)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
resp.Body.Close()
|
||||
return resp.StatusCode == 200
|
||||
}
|
||||
|
||||
func New() (*Client, error) {
|
||||
base := os.Getenv("PAPERCLIP_API_URL")
|
||||
base := varOr("PAPERCLIP_API_URL", "")
|
||||
if base == "" {
|
||||
base = "http://127.0.0.1:3100"
|
||||
if !reachable(base + "/api/health") {
|
||||
// Paperclip lives on one machine; a session on another has to ask it.
|
||||
base = "http://192.168.20.13:3100"
|
||||
}
|
||||
}
|
||||
company := os.Getenv("PAPERCLIP_COMPANY_ID")
|
||||
if company == "" {
|
||||
company = "d4921013-e5da-4d88-8016-57d5746e2d03"
|
||||
}
|
||||
token := os.Getenv("PAPERCLIP_BOARD_KEY")
|
||||
company := varOr("PAPERCLIP_COMPANY_ID", "d4921013-e5da-4d88-8016-57d5746e2d03")
|
||||
token := varOr("PAPERCLIP_BOARD_KEY", "")
|
||||
if token == "" {
|
||||
token = os.Getenv("PAPERCLIP_API_KEY")
|
||||
token = varOr("PAPERCLIP_API_KEY", "")
|
||||
}
|
||||
if token == "" {
|
||||
return nil, errors.New("no key in the environment: set PAPERCLIP_BOARD_KEY")
|
||||
return nil, errors.New("no key found: set PAPERCLIP_BOARD_KEY, or put it in ~/.config/environment.d/*.conf")
|
||||
}
|
||||
return &Client{
|
||||
BaseURL: strings.TrimRight(base, "/"),
|
||||
|
||||
Reference in New Issue
Block a user