0ff2f2dc66b354ed2547de84252a17f56d0fb2d3

Author
Ayman Bagabas <ayman.bagabas@gmail.com>
Committer
Ayman Bagabas <ayman.bagabas@gmail.com>
Date

Message

fix(server): hooks config path

Make sure data path is defined correctly.

Fixes: 72c96afd58a0 ("fix(config): mkdir before writing config")

Diff

This diff is truncated to protect this page.

  1diff --git a/cmd/soft/hook.go b/cmd/soft/hook.go
  2index 52619c409ac8d84105062c22bc9fc8ea97dad14d..4054303c5f927c7fb464b19ed18475d8f1686619 100644
  3--- a/cmd/soft/hook.go
  4+++ b/cmd/soft/hook.go
  5@@ -141,9 +141,6 @@ func commonInit() (c *gossh.Client, s *gossh.Session, err error) {
  6 		return
  7 	}
  8 
  9-	// Use absolute path.
 10-	cfg.DataPath = filepath.Dir(configPath)
 11-
 12 	// Git runs the hook within the repository's directory.
 13 	// Get the working directory to determine the repository name.
 14 	wd, err := os.Getwd()
 15@@ -161,7 +158,7 @@ func commonInit() (c *gossh.Client, s *gossh.Session, err error) {
 16 		return
 17 	}
 18 	repoName := strings.TrimPrefix(wd, rs)
 19-	repoName = strings.TrimPrefix(repoName, fmt.Sprintf("%c", os.PathSeparator))
 20+	repoName = strings.TrimPrefix(repoName, string(os.PathSeparator))
 21 	c, err = newClient(cfg)
 22 	if err != nil {
 23 		return
 24diff --git a/server/backend/sqlite/user.go b/server/backend/sqlite/user.go
 25index 1afa8085fcac43779cba4dbdc3e2657aa185bde6..9f7e48273d3e12ffa31821debae11ca1855ae5db 100644
 26--- a/server/backend/sqlite/user.go
 27+++ b/server/backend/sqlite/user.go
 28@@ -118,10 +118,7 @@ func (d *SqliteBackend) AccessLevel(repo string, username string) backend.Access
 29 //
 30 // It implements backend.Backend.
 31 func (d *SqliteBackend) AccessLevelByPublicKey(repo string, pk ssh.PublicKey) backend.AccessLevel {
 32-	if ik, _, err := backend.ParseAuthorizedKey(d.cfg.InternalPublicKey); err == nil && backend.KeysEqual(ik, pk) {
 33-		return backend.AdminAccess
 34-	}
 35-	for _, k := range d.cfg.InitialAdminKeys {
 36+	for _, k := range append(d.cfg.InitialAdminKeys, d.cfg.InternalPublicKey) {
 37 		ik, _, err := backend.ParseAuthorizedKey(k)
 38 		if err == nil && backend.KeysEqual(pk, ik) {
 39 			return backend.AdminAccess
 40diff --git a/server/cmd/hook.go b/server/cmd/hook.go
 41index 87a9184cb46e988aa5646a328dca6654f1b4a0b8..7e520e5c8dc0a774c25a0eb0a15845219fbf820d 100644
 42--- a/server/cmd/hook.go
 43+++ b/server/cmd/hook.go
 44@@ -6,6 +6,7 @@ import (
 45 	"strings"
 46 
 47 	"github.com/charmbracelet/keygen"
 48+	"github.com/charmbracelet/soft-serve/server/backend"
 49 	"github.com/charmbracelet/soft-serve/server/hooks"
 50 	"github.com/charmbracelet/ssh"
 51 	"github.com/spf13/cobra"
 52@@ -122,7 +123,7 @@ func checkIfInternal(cmd *cobra.Command, _ []string) error {
 53 		logger.Errorf("failed to read internal key: %v", err)
 54 		return err
 55 	}
 56-	if !ssh.KeysEqual(pk, kp.PublicKey()) {
 57+	if !backend.KeysEqual(pk, kp.PublicKey()) {
 58 		return ErrUnauthorized
 59 	}
 60 	return nil
 61diff --git a/server/config/config.go b/server/config/config.go
 62index b72dae3c31e91ac3dcef59ee84fd97db2cab789e..3935b5b12252f06e6f67821e57a22da94bbfba80 100644
 63--- a/server/config/config.go
 64+++ b/server/config/config.go
 65@@ -1,6 +1,8 @@
 66 package config
 67 
 68 import (
 69+	"errors"
 70+	"fmt"
 71 	"os"
 72 	"path/filepath"
 73 	"strings"
 74@@ -104,41 +106,8 @@ type Config struct {
 75 	ClientPublicKey string `yaml:"-"`
 76 }
 77 
 78-// ParseConfig parses the configuration from the given file.
 79-func ParseConfig(path string) (*Config, error) {
 80-	cfg := &Config{}
 81-	f, err := os.Open(path)
 82-	if err != nil {
 83-		return nil, err
 84-	}
 85-	defer f.Close() // nolint: errcheck
 86-	if err := yaml.NewDecoder(f).Decode(cfg); err != nil {
 87-		return nil, err
 88-	}
 89-
 90-	if err := cfg.init(); err != nil {
 91-		return nil, err
 92-	}
 93-
 94-	return cfg, nil
 95-}
 96-
 97-// WriteConfig writes the configuration to the given file.
 98-func WriteConfig(path string, cfg *Config) error {
 99-	if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
100-		return err
101-	}
102-	return os.WriteFile(path, []byte(newConfigFile(cfg)), 0o600) // nolint: errcheck
103-}
104-
105-// DefaultConfig returns a Config with the values populated with the defaults
106-// or specified environment variables.
107-func DefaultConfig() *Config {
108-	dataPath := os.Getenv("SOFT_SERVE_DATA_PATH")
109-	if dataPath == "" {
110-		dataPath = "data"
111-	}
112-
113+func parseConfig(path string) (*Config, error) {
114+	dataPath := filepath.Dir(path)
115 	cfg := &Config{
116 		Name:     "Soft Serve",
117 		DataPath: dataPath,
118@@ -166,20 +135,65 @@ func DefaultConfig() *Config {
119 		},
120 	}
121 
122-	cp := filepath.Join(cfg.DataPath, "config.yaml")
123-	f, err := os.Open(cp)
124-	if err == nil {
125-		defer f.Close() // nolint: errcheck
126-		if err := yaml.NewDecoder(f).Decode(cfg); err != nil {
127-			log.Error("failed to decode config", "err", err)
128-		}
129+	f, err := os.Open(path)
130+	if err != nil {
131+		return cfg, err
132+	}
133+
134+	defer f.Close() // nolint: errcheck
135+	if err := yaml.NewDecoder(f).Decode(cfg); err != nil {
136+		return cfg, fmt.Errorf("decode config: %w", err)
137 	}
138 
139 	// Override with environment variables
140 	if err := env.Parse(cfg, env.Options{
141 		Prefix: "SOFT_SERVE_",
142 	}); err != nil {
143-		log.Fatal(err)
144+		return cfg, fmt.Errorf("parse environment variables: %w", err)
145+	}
146+
147+	// Reset datapath to config dir.
148+	// This is necessary because the environment variable may be set to
149+	// a different directory.
150+	cfg.DataPath = dataPath
151+
152+	return cfg, nil
153+}
154+
155+// ParseConfig parses the configuration from the given file.
156+func ParseConfig(path string) (*Config, error) {
157+	cfg, err := parseConfig(path)
158+	if err != nil {
159+		return nil, err
160+	}
161+
162+	if err := cfg.validate(); err != nil {
163+		return nil, err
164+	}