internal/cli/admin_test.go (view raw)
1package cli
2
3import (
4 "bytes"
5 "crypto/rand"
6 "log"
7 "os"
8 "path"
9 "strings"
10 "testing"
11
12 "postern/internal/db"
13 "postern/internal/persistence"
14
15 "github.com/spf13/cobra"
16)
17
18// executeCommand helps invoke a cobra command with specific arguments and captures its stdout/stderr.
19func executeCommand(cmd *cobra.Command, args ...string) (string, error) {
20 buf := new(bytes.Buffer)
21 cmd.SetOut(buf)
22 cmd.SetErr(buf)
23 cmd.SetArgs(args)
24
25 err := cmd.Execute()
26 return buf.String(), err
27}
28
29// TestAddUserCommand checks the loop of creating a new user, finding it in the db and checking that the password works.
30func TestAddRemoveUserCommand(t *testing.T) {
31 f := t.TempDir()
32
33 // create temporary masterkey
34 mkeyPath := path.Join(f, "masterkey")
35 secretKey := make([]byte, 32)
36 _, _ = rand.Read(secretKey)
37 err := os.WriteFile(mkeyPath, secretKey, 0666)
38 if err != nil {
39 t.Fatal(err)
40 }
41
42 p, err := persistence.New(persistence.Config{
43 BlobRoot: path.Join(f, "blobs"),
44 MasterkeyFile: mkeyPath,
45 })
46 if err != nil {
47 log.Fatal(err)
48 }
49
50 posternDB, err := db.OpenDB(&db.Config{
51 DBPath: path.Join(f, "meta.db"),
52 })
53 if err != nil {
54 log.Fatal(err)
55 }
56
57 c, err := New(&Config{
58 DB: posternDB,
59 Persistence: p,
60 })
61 if err != nil {
62 t.Fatal(err)
63 }
64
65 output, err := executeCommand(c.rootCmd(), "user", "add", "user1")
66 if err != nil {
67 t.Fatalf("expected no error, got: %v", err)
68 }
69
70 _, after, found := strings.Cut(output, "Password: ")
71 password := strings.TrimSpace(after)
72 if !found {
73 t.Fatal("expected to find a password in output. Found none")
74 }
75
76 u, err := c.db.GetUser(t.Context(), "user1")
77 if err != nil {
78 t.Fatalf("expected no error, got: %v", err)
79 }
80
81 err = u.VerifyPassword([]byte(password))
82 if err != nil {
83 t.Fatalf("password mismatch, got: %v", err)
84 }
85
86 // Try removing user
87 output, err = executeCommand(c.rootCmd(), "user", "remove", "user1")
88 if err != nil {
89 t.Fatalf("expected no error, got: %v", err)
90 }
91 if !strings.Contains(output, "removed") {
92 t.Fatal("expected to find 'removed' in output. Found none")
93 }
94
95 // Try removing user again (failure)
96 output, err = executeCommand(c.rootCmd(), "user", "remove", "user1")
97 if err == nil {
98 t.Errorf("expected error when deleting non-existing user, got none")
99 }
100}