Clean up config file name stuff

This commit is contained in:
Jon Staab
2026-05-26 15:50:14 -07:00
parent 2fcc48abed
commit e9260f40f1
7 changed files with 65 additions and 63 deletions
+3 -2
View File
@@ -25,8 +25,9 @@ func main() {
os.Exit(1)
}
// Load config for the specified relay
config, err := zooid.LoadConfigFromId(*relay)
name := zooid.ConfigNameFromId(*relay)
path := zooid.ConfigPathFromName(name)
config, err := zooid.LoadConfigFromPath(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
+3 -2
View File
@@ -39,8 +39,9 @@ func main() {
os.Exit(1)
}
// Load config for the specified relay
config, err := zooid.LoadConfigFromId(*relay)
name := zooid.ConfigNameFromId(*relay)
path := zooid.ConfigPathFromName(name)
config, err := zooid.LoadConfigFromPath(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
+25 -26
View File
@@ -28,7 +28,7 @@ func NewAPIHandler() *APIHandler {
whitelist: whitelist,
}
mux := http.NewServeMux()
mux := http.NewServeMux()
mux.HandleFunc("POST /relay/{id}", api.auth(api.createRelay))
mux.HandleFunc("PUT /relay/{id}", api.auth(api.putRelay))
mux.HandleFunc("PATCH /relay/{id}", api.auth(api.patchRelay))
@@ -37,7 +37,7 @@ func NewAPIHandler() *APIHandler {
api.mux = mux
return api
return api
}
func (api *APIHandler) auth(next http.HandlerFunc) http.HandlerFunc {
@@ -72,7 +72,7 @@ func writeJSON(w http.ResponseWriter, status int, v any) {
// Relay CRUD
func (api *APIHandler) configFromRequest(r *http.Request) (*Config, error) {
func (api *APIHandler) configFromRequest(path string, r *http.Request) (*Config, error) {
r.Body = http.MaxBytesReader(nil, r.Body, 1024*1024)
defer r.Body.Close()
@@ -81,16 +81,7 @@ func (api *APIHandler) configFromRequest(r *http.Request) (*Config, error) {
return nil, fmt.Errorf("failed to read body: %w", err)
}
var config Config
if err := json.Unmarshal(body, &config); err != nil {
return nil, fmt.Errorf("invalid json config: %w", err)
}
if err := config.Validate(); err != nil {
return nil, err
}
return &config, nil
return LoadConfigFromJson(path, body)
}
func (api *APIHandler) patchFromRequest(r *http.Request) (map[string]interface{}, error) {
@@ -121,7 +112,9 @@ func (api *APIHandler) checkDuplicateSchemaOrHost(config *Config, excludeFilenam
continue
}
if existing, err := LoadConfigFromName(entry.Name()); err == nil {
path := ConfigPathFromName(entry.Name())
if existing, err := LoadConfigFromPath(path); err == nil {
if existing.Schema == config.Schema {
return fmt.Errorf("schema %q is already in use", config.Schema)
}
@@ -137,13 +130,14 @@ func (api *APIHandler) checkDuplicateSchemaOrHost(config *Config, excludeFilenam
// Create relay
func (api *APIHandler) createRelay(w http.ResponseWriter, r *http.Request) {
path := ConfigPathFromId(r.PathValue("id"))
name := ConfigNameFromId(r.PathValue("id"))
path := ConfigPathFromName(name)
if _, err := os.Stat(path); err == nil {
writeError(w, http.StatusConflict, "relay with this id already exists")
return
}
config, err := api.configFromRequest(r)
config, err := api.configFromRequest(path, r)
if err != nil {
writeError(w, http.StatusBadRequest, err.Error())
return
@@ -166,19 +160,20 @@ func (api *APIHandler) createRelay(w http.ResponseWriter, r *http.Request) {
func (api *APIHandler) putRelay(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
path := ConfigPathFromId(id)
name := ConfigNameFromId(id)
path := ConfigPathFromName(name)
if _, err := os.Stat(path); err != nil {
writeError(w, http.StatusConflict, "relay not found")
return
}
config, err := api.configFromRequest(r)
config, err := api.configFromRequest(path, r)
if err != nil {
writeError(w, http.StatusBadRequest, err.Error())
return
}
if err := api.checkDuplicateSchemaOrHost(config, id+".toml"); err != nil {
if err := api.checkDuplicateSchemaOrHost(config, name); err != nil {
writeError(w, http.StatusConflict, err.Error())
return
}
@@ -195,7 +190,8 @@ func (api *APIHandler) putRelay(w http.ResponseWriter, r *http.Request) {
func (api *APIHandler) patchRelay(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
path := ConfigPathFromId(id)
name := ConfigNameFromId(id)
path := ConfigPathFromName(name)
if _, err := os.Stat(path); err != nil {
writeError(w, http.StatusConflict, "relay not found")
return
@@ -223,7 +219,7 @@ func (api *APIHandler) patchRelay(w http.ResponseWriter, r *http.Request) {
return
}
if err := api.checkDuplicateSchemaOrHost(config, id+".toml"); err != nil {
if err := api.checkDuplicateSchemaOrHost(config, name); err != nil {
writeError(w, http.StatusConflict, err.Error())
return
}
@@ -285,7 +281,8 @@ func deepMerge(base, patch map[string]interface{}) map[string]interface{} {
func (api *APIHandler) deleteRelay(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
path := ConfigPathFromId(id)
name := ConfigNameFromId(id)
path := ConfigPathFromName(name)
if _, err := os.Stat(path); err != nil {
writeError(w, http.StatusConflict, "relay not found")
return
@@ -303,7 +300,8 @@ func (api *APIHandler) deleteRelay(w http.ResponseWriter, r *http.Request) {
func (api *APIHandler) listRelayMembers(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
members, err := api.resolveRelayMembers(id)
name := ConfigNameFromId(id)
members, err := api.resolveRelayMembers(name)
if err != nil {
if os.IsNotExist(err) {
writeError(w, http.StatusNotFound, "relay not found")
@@ -316,16 +314,17 @@ func (api *APIHandler) listRelayMembers(w http.ResponseWriter, r *http.Request)
writeJSON(w, http.StatusOK, map[string][]string{"members": members})
}
func (api *APIHandler) resolveRelayMembers(id string) ([]string, error) {
func (api *APIHandler) resolveRelayMembers(name string) ([]string, error) {
instancesMux.RLock()
instance, exists := instancesByName[id+".toml"]
instance, exists := instancesByName[name]
instancesMux.RUnlock()
if exists {
return collectMembers(instance.Management), nil
}
config, err := LoadConfigFromId(id)
path := ConfigPathFromName(name)
config, err := LoadConfigFromPath(path)
if err != nil {
return nil, err
}
+8 -8
View File
@@ -3,8 +3,8 @@ package zooid
import (
"bytes"
"context"
"io"
"fmt"
"io"
"log"
"net/url"
"path/filepath"
@@ -34,11 +34,11 @@ func (bl *BlossomStore) Enable(instance *Instance) {
switch bl.Config.Blossom.Adapter {
case "local":
if err := bl.UseLocalAdapter(backend); err != nil {
log.Fatalf("blossom: failed to use local adapter %q", err)
log.Fatalf("blossom: failed to use local adapter %q", err)
}
case "s3":
if err := bl.UseS3Adapter(backend); err != nil {
log.Fatalf("blossom: failed to use s3 adapter %q", err)
log.Fatalf("blossom: failed to use s3 adapter %q", err)
}
default:
log.Fatalf("blossom: unknown backend %q", bl.Config.Blossom.Adapter)
@@ -128,13 +128,13 @@ func (bl *BlossomStore) UseLocalAdapter(backend *blossom.BlossomServer) error {
// S3 adapter
func (bl *BlossomStore) S3Key(sha256 string) string {
key := bl.Config.Schema + "/" + sha256
key := bl.Config.Schema + "/" + sha256
if bl.Config.Blossom.S3.KeyPrefix != "" {
key = bl.Config.Blossom.S3.KeyPrefix + "/" + key
}
if bl.Config.Blossom.S3.KeyPrefix != "" {
key = bl.Config.Blossom.S3.KeyPrefix + "/" + key
}
return key
return key
}
func (bl *BlossomStore) UseS3Adapter(backend *blossom.BlossomServer) error {
+21 -21
View File
@@ -1,12 +1,13 @@
package zooid
import (
"encoding/json"
"fiatjaf.com/nostr"
"fmt"
"regexp"
"github.com/BurntSushi/toml"
"os"
"path/filepath"
"regexp"
"slices"
)
@@ -60,7 +61,7 @@ type Config struct {
Roles map[string]Role `toml:"roles" json:"roles"`
// Private/parsed values
// Parsed values
path string
secret nostr.SecretKey
}
@@ -76,22 +77,14 @@ type BlossomS3Settings struct {
KeyPrefix string `toml:"key_prefix" json:"key_prefix"`
}
func ConfigPathFromId(id string) string {
return filepath.Join(Env("CONFIG"), id+".toml")
func ConfigNameFromId(id string) string {
return id + ".toml"
}
func ConfigPathFromName(name string) string {
return filepath.Join(Env("CONFIG"), name)
}
func LoadConfigFromId(id string) (*Config, error) {
return LoadConfigFromPath(ConfigPathFromId(id))
}
func LoadConfigFromName(name string) (*Config, error) {
return LoadConfigFromPath(ConfigPathFromName(name))
}
func LoadConfigFromPath(path string) (*Config, error) {
var config Config
if _, err := toml.DecodeFile(path, &config); err != nil {
@@ -107,6 +100,21 @@ func LoadConfigFromPath(path string) (*Config, error) {
return &config, nil
}
func LoadConfigFromJson(path string, body []byte) (*Config, error) {
var config Config
if err := json.Unmarshal(body, &config); err != nil {
return nil, fmt.Errorf("invalid json config: %w", err)
}
config.path = path
if err := config.Validate(); err != nil {
return nil, err
}
return &config, nil
}
func (config *Config) Validate() error {
if config.Blossom.Adapter == "" {
config.Blossom.Adapter = "local"
@@ -124,14 +132,12 @@ func (config *Config) Validate() error {
return fmt.Errorf("schema must contain only lowercase letters, numbers, and underscores")
}
secret, err := nostr.SecretKeyFromHex(config.Secret)
secret, err := nostr.SecretKeyFromHex(config.Secret)
if err != nil {
return fmt.Errorf("invalid secret key: %w", err)
}
// Make the secret... secret
config.Secret = ""
config.secret = secret
if _, err := nostr.PubKeyFromHex(config.Info.Pubkey); err != nil {
@@ -159,9 +165,6 @@ func (config *Config) Validate() error {
}
func (config *Config) Save() error {
// Restore the secret key to the public field for saving
config.Secret = config.secret.Hex()
file, err := os.Create(config.path)
if err != nil {
return fmt.Errorf("Failed to open config file %s: %w", config.path, err)
@@ -173,9 +176,6 @@ func (config *Config) Save() error {
return fmt.Errorf("Failed to encode config file %s: %w", config.path, err)
}
// Clear the secret again
config.Secret = ""
return nil
}
+4 -3
View File
@@ -21,13 +21,14 @@ type Instance struct {
Push *PushManager
}
func MakeInstance(filename string) (*Instance, error) {
config, err := LoadConfigFromName(filename)
func MakeInstance(name string) (*Instance, error) {
path := ConfigPathFromName(name)
config, err := LoadConfigFromPath(path)
if err != nil {
return nil, err
}
return makeInstance(config, filename)
return makeInstance(config, name)
}
func makeInstance(config *Config, source string) (*Instance, error) {
+1 -1
View File
@@ -183,7 +183,7 @@ func validateNIP98Auth(r *http.Request) (nostr.PubKey, error) {
return nostr.PubKey{}, fmt.Errorf("invalid event signature")
}
scheme := "http"
scheme := "http"
if r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https" {
scheme = scheme + "s"
}