forked from coracle/zooid
Clean up config file name stuff
This commit is contained in:
+3
-2
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user