From 551317953c72552439ec70ad778c2efa2faff25c Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 26 Apr 2023 09:46:55 -0400 Subject: [PATCH] fix(config): parse initial admin keys paths --- .gitignore | 1 - server/config/config.go | 27 ++++++++++++++++-- server/config/config_test.go | 54 ++++++++++++++++++++++++++++++++--- server/config/testdata/k1.pub | 1 + 4 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 server/config/testdata/k1.pub diff --git a/.gitignore b/.gitignore index ae70eac83..041a83d7f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ cmd/soft/soft .ssh .repos dist -testdata data/ completions/ manpages/ diff --git a/server/config/config.go b/server/config/config.go index 36a5bddcd..13ecd1268 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -143,6 +143,9 @@ func parseConfig(path string) (*Config, error) { } } + // Merge initial admin keys from both config file and environment variables. + initialAdminKeys := append([]string{}, cfg.InitialAdminKeys...) + // Override with environment variables if err := env.Parse(cfg, env.Options{ Prefix: "SOFT_SERVE_", @@ -150,13 +153,31 @@ func parseConfig(path string) (*Config, error) { return cfg, fmt.Errorf("parse environment variables: %w", err) } + // Merge initial admin keys from environment variables. + if initialAdminKeysEnv := os.Getenv("SOFT_SERVE_INITIAL_ADMIN_KEYS"); initialAdminKeysEnv != "" { + cfg.InitialAdminKeys = append(cfg.InitialAdminKeys, initialAdminKeys...) + } + + // Validate keys + pks := make([]string, 0) for _, key := range cfg.InitialAdminKeys { - if _, _, err := backend.ParseAuthorizedKey(key); err != nil { - log.Error("invalid initial admin key", "err", err) + var pk string + if bts, err := os.ReadFile(key); err == nil { + // key is a file + pk = string(bts) + } + if _, _, err := backend.ParseAuthorizedKey(key); err == nil { + pk = key + } + pk = strings.TrimSpace(pk) + if pk != "" { + log.Debugf("found initial admin key: %q", key) + pks = append(pks, pk) } - log.Debugf("found initial admin key: %q", key) } + cfg.InitialAdminKeys = pks + // Reset datapath to config dir. // This is necessary because the environment variable may be set to // a different directory. diff --git a/server/config/config_test.go b/server/config/config_test.go index b36852095..cd4a90198 100644 --- a/server/config/config_test.go +++ b/server/config/config_test.go @@ -2,18 +2,64 @@ package config import ( "os" + "path/filepath" "testing" "github.com/matryer/is" + "gopkg.in/yaml.v3" ) func TestParseMultipleKeys(t *testing.T) { is := is.New(t) - is.NoErr(os.Setenv("SOFT_SERVE_INITIAL_ADMIN_KEYS", "testdata/k1.pub\ntestdata/k2.pub")) - t.Cleanup(func() { is.NoErr(os.Unsetenv("SOFT_SERVE_INITIAL_ADMIN_KEYS")) }) + td := t.TempDir() + is.NoErr(os.Setenv("SOFT_SERVE_INITIAL_ADMIN_KEYS", "testdata/k1.pub\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFxIobhwtfdwN7m1TFt9wx3PsfvcAkISGPxmbmbauST8 a@b")) + is.NoErr(os.Setenv("SOFT_SERVE_DATA_PATH", td)) + t.Cleanup(func() { + is.NoErr(os.Unsetenv("SOFT_SERVE_INITIAL_ADMIN_KEYS")) + is.NoErr(os.Unsetenv("SOFT_SERVE_DATA_PATH")) + }) cfg := DefaultConfig() is.Equal(cfg.InitialAdminKeys, []string{ - "testdata/k1.pub", - "testdata/k2.pub", + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINMwLvyV3ouVrTysUYGoJdl5Vgn5BACKov+n9PlzfPwH a@b", + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFxIobhwtfdwN7m1TFt9wx3PsfvcAkISGPxmbmbauST8 a@b", + }) +} + +func TestMergeInitAdminKeys(t *testing.T) { + is := is.New(t) + is.NoErr(os.Setenv("SOFT_SERVE_INITIAL_ADMIN_KEYS", "testdata/k1.pub")) + t.Cleanup(func() { is.NoErr(os.Unsetenv("SOFT_SERVE_INITIAL_ADMIN_KEYS")) }) + bts, err := yaml.Marshal(&Config{ + InitialAdminKeys: []string{"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFxIobhwtfdwN7m1TFt9wx3PsfvcAkISGPxmbmbauST8 a@b"}, + }) + is.NoErr(err) + fp := filepath.Join(t.TempDir(), "config.yaml") + err = os.WriteFile(fp, bts, 0644) + is.NoErr(err) + cfg, err := ParseConfig(fp) + is.NoErr(err) + is.Equal(cfg.InitialAdminKeys, []string{ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINMwLvyV3ouVrTysUYGoJdl5Vgn5BACKov+n9PlzfPwH a@b", + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFxIobhwtfdwN7m1TFt9wx3PsfvcAkISGPxmbmbauST8 a@b", + }) +} + +func TestValidateInitAdminKeys(t *testing.T) { + is := is.New(t) + bts, err := yaml.Marshal(&Config{ + InitialAdminKeys: []string{ + "testdata/k1.pub", + "abc", + "", + }, + }) + is.NoErr(err) + fp := filepath.Join(t.TempDir(), "config.yaml") + err = os.WriteFile(fp, bts, 0644) + is.NoErr(err) + cfg, err := ParseConfig(fp) + is.NoErr(err) + is.Equal(cfg.InitialAdminKeys, []string{ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINMwLvyV3ouVrTysUYGoJdl5Vgn5BACKov+n9PlzfPwH a@b", }) } diff --git a/server/config/testdata/k1.pub b/server/config/testdata/k1.pub new file mode 100644 index 000000000..d82e29394 --- /dev/null +++ b/server/config/testdata/k1.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINMwLvyV3ouVrTysUYGoJdl5Vgn5BACKov+n9PlzfPwH a@b