Detailed changes
@@ -31,6 +31,7 @@ require (
github.com/muesli/roff v0.1.0
github.com/prometheus/client_golang v1.15.1
github.com/robfig/cron/v3 v3.0.1
+ github.com/rogpeppe/go-internal v1.10.0
github.com/spf13/cobra v1.7.0
go.uber.org/automaxprocs v1.5.2
goji.io v2.0.2+incompatible
@@ -73,7 +74,6 @@ require (
github.com/prometheus/procfs v0.9.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.2.0 // indirect
- github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/sahilm/fuzzy v0.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/yuin/goldmark v1.5.2 // indirect
@@ -0,0 +1,63 @@
+package testscript
+
+import (
+ "context"
+ "path/filepath"
+ "testing"
+
+ "github.com/charmbracelet/soft-serve/server"
+ "github.com/charmbracelet/soft-serve/server/config"
+ "github.com/rogpeppe/go-internal/testscript"
+)
+
+func TestScript(t *testing.T) {
+ key, err := filepath.Abs("./testdata/admin1")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ testscript.Run(t, testscript.Params{
+ Dir: "testdata/script",
+ UpdateScripts: true,
+ Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
+ "soft": func(ts *testscript.TestScript, _ bool, args []string) {
+ args = append([]string{
+ "-F", "/dev/null",
+ "-o", "StrictHostKeyChecking=no",
+ "-o", "UserKnownHostsFile=/dev/null",
+ "-o", "IdentityAgent=none",
+ "-o", "IdentitiesOnly=yes",
+ "-i", key,
+ "-p", "23231",
+ "localhost",
+ "--",
+ }, args...)
+ ts.Check(ts.Exec("ssh", args...))
+ },
+ },
+ Setup: func(e *testscript.Env) error {
+ cfg := config.DefaultConfig()
+ cfg.InitialAdminKeys = []string{
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJI/1tawpdPmzuJcTGTJ+QReqB6cRUdKj4iQIdJUFdrl",
+ }
+ cfg.DataPath = t.TempDir()
+ e.T().Log("using", cfg.DataPath, "as data path")
+ ctx := config.WithContext(context.Background(), cfg)
+ srv, err := server.NewServer(ctx)
+ if err != nil {
+ return err
+ }
+ go func() {
+ if err := srv.Start(); err != nil {
+ e.T().Fatal(err)
+ }
+ }()
+ e.Defer(func() {
+ if err := srv.Shutdown(context.Background()); err != nil {
+ e.T().Fatal(err)
+ }
+ })
+ return nil
+ },
+ })
+}
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACCSP9bWsKXT5s7iXExkyfkEXqgenEVHSo+IkCHSVBXa5QAAAJiqgq7EqoKu
+xAAAAAtzc2gtZWQyNTUxOQAAACCSP9bWsKXT5s7iXExkyfkEXqgenEVHSo+IkCHSVBXa5Q
+AAAEDzMZNK49XhgnQJruAFQr04Eijji5ZMZzN9dA/tmEP0m5I/1tawpdPmzuJcTGTJ+QRe
+qB6cRUdKj4iQIdJUFdrlAAAAD2Nhcmxvc0BkYXJrc3RhcgECAwQFBg==
+-----END OPENSSH PRIVATE KEY-----
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJI/1tawpdPmzuJcTGTJ+QReqB6cRUdKj4iQIdJUFdrl carlos@darkstar
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACD41Hl4Qc49fP1mW6nA9WjyZQgC8wTDGcYaWlOOSoFaiwAAAJjWOn0F1jp9
+BQAAAAtzc2gtZWQyNTUxOQAAACD41Hl4Qc49fP1mW6nA9WjyZQgC8wTDGcYaWlOOSoFaiw
+AAAEDC5WZCusu7Dwmj1M6tEqPietXnnklOhfnAzBqUtoNpl/jUeXhBzj18/WZbqcD1aPJl
+CALzBMMZxhpaU45KgVqLAAAAD2Nhcmxvc0BkYXJrc3RhcgECAwQFBg==
+-----END OPENSSH PRIVATE KEY-----
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjUeXhBzj18/WZbqcD1aPJlCALzBMMZxhpaU45KgVqL carlos@darkstar
@@ -0,0 +1,71 @@
+# add key to admin
+soft user add-pubkey admin "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjUeXhBzj18/WZbqcD1aPJlCALzBMMZxhpaU45KgVqL"
+soft user info admin
+soft info
+cmp stdout info.txt
+
+
+# list users
+soft user list
+cmp stdout list1.txt
+
+
+# create a new user
+soft user create foo --key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAzXnhJ/6SrlHZI+DnTb1n/0KL6/VOQTea8qLovTiZix"
+soft user list
+cmp stdout list2.txt
+
+
+# get new user info
+soft user info foo
+cmp stdout foo_info1.txt
+
+
+# make user admin
+soft user set-admin foo true
+soft user info foo
+cmp stdout foo_info2.txt
+
+
+# remove admin
+soft user set-admin foo false
+soft user info foo
+cmp stdout foo_info3.txt
+
+
+# remove key from user
+soft user remove-pubkey foo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAzXnhJ/6SrlHZI+DnTb1n/0KL6/VOQTea8qLovTiZix"
+soft user info foo
+cmp stdout foo_info4.txt
+
+
+-- info.txt --
+Username: admin
+Admin: true
+Public keys:
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJI/1tawpdPmzuJcTGTJ+QReqB6cRUdKj4iQIdJUFdrl
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjUeXhBzj18/WZbqcD1aPJlCALzBMMZxhpaU45KgVqL
+-- list1.txt --
+admin
+-- list2.txt --
+admin
+foo
+-- foo_info1.txt --
+Username: foo
+Admin: false
+Public keys:
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAzXnhJ/6SrlHZI+DnTb1n/0KL6/VOQTea8qLovTiZix
+-- foo_info2.txt --
+Username: foo
+Admin: true
+Public keys:
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAzXnhJ/6SrlHZI+DnTb1n/0KL6/VOQTea8qLovTiZix
+-- foo_info3.txt --
+Username: foo
+Admin: false
+Public keys:
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAzXnhJ/6SrlHZI+DnTb1n/0KL6/VOQTea8qLovTiZix
+-- foo_info4.txt --
+Username: foo
+Admin: false
+Public keys:
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACAM154Sf+kq5R2SPg5029Z/9Ci+v1TkE3mvKi6L04mYsQAAAJgAOMy/ADjM
+vwAAAAtzc2gtZWQyNTUxOQAAACAM154Sf+kq5R2SPg5029Z/9Ci+v1TkE3mvKi6L04mYsQ
+AAAECH03vQo8gCmxbUqHWlcM2buCgIi4x6IR4WWkXlXqhzoAzXnhJ/6SrlHZI+DnTb1n/0
+KL6/VOQTea8qLovTiZixAAAAD2Nhcmxvc0BkYXJrc3RhcgECAwQFBg==
+-----END OPENSSH PRIVATE KEY-----
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAzXnhJ/6SrlHZI+DnTb1n/0KL6/VOQTea8qLovTiZix carlos@darkstar
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACChLkp+T1IWDQ5I5BI5Q8YQrP7aKdQLVe7+Pn9/xEM5LwAAAJiupdpmrqXa
+ZgAAAAtzc2gtZWQyNTUxOQAAACChLkp+T1IWDQ5I5BI5Q8YQrP7aKdQLVe7+Pn9/xEM5Lw
+AAAECrufZjft7PHyL8FQLnR/D73VySS1A6UZdEQmL+W/+gJ6EuSn5PUhYNDkjkEjlDxhCs
+/top1AtV7v4+f3/EQzkvAAAAD2Nhcmxvc0BkYXJrc3RhcgECAwQFBg==
+-----END OPENSSH PRIVATE KEY-----
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKEuSn5PUhYNDkjkEjlDxhCs/top1AtV7v4+f3/EQzkv carlos@darkstar