internal/hookd/socket_test.go
105 lines · 2636 bytes
1package hookd
2
3import (
4 "os"
5 "path/filepath"
6 "strings"
7 "testing"
8
9 "gitbay.org/gitbay/internal/config"
10 "gitbay.org/gitbay/internal/store"
11)
12
13func serveSocket(t *testing.T) (sock string, st *store.Store, repoID, uid int64) {
14 t.Helper()
15 st, err := store.Open(filepath.Join(t.TempDir(), "gitbay.db"))
16 if err != nil {
17 t.Fatal(err)
18 }
19 t.Cleanup(func() { st.Close() })
20 if err := st.MigrateUp(); err != nil {
21 t.Fatal(err)
22 }
23 if uid, err = st.CreateUser("alice", false); err != nil {
24 t.Fatal(err)
25 }
26 if repoID, err = st.CreateRepo("user", uid, "app", "public"); err != nil {
27 t.Fatal(err)
28 }
29 var cfg config.Config
30 cfg.Server.Root = t.TempDir()
31 stop, err := Serve(cfg, st)
32 if err != nil {
33 t.Fatal(err)
34 }
35 t.Cleanup(func() { stop() })
36 return SocketPath(cfg.Server.Root), st, repoID, uid
37}
38
39func TestSocketIsOwnerOnly(t *testing.T) {
40 sock, _, _, _ := serveSocket(t)
41 fi, err := os.Stat(sock)
42 if err != nil {
43 t.Fatal(err)
44 }
45 if fi.Mode().Perm() != 0o600 {
46 t.Fatalf("mode %v, want 0600", fi.Mode().Perm())
47 }
48}
49
50// A request speaks for a receive-pack sshd started, and only for the
51// repository, account and scope that push was started with (#282).
52func TestHookRequestNeedsItsPushToken(t *testing.T) {
53 sock, st, repoID, uid := serveSocket(t)
54 req := Request{Hook: "pre-receive", RepoID: repoID, UserID: uid, Scope: "full"}
55
56 resp, err := Ask(sock, req, nil)
57 if err != nil {
58 t.Fatal(err)
59 }
60 if resp.Allow || !strings.Contains(resp.Message, "not started by this server") {
61 t.Fatalf("no token: %+v", resp)
62 }
63
64 token, err := st.CreatePushToken(repoID, uid, "full")
65 if err != nil {
66 t.Fatal(err)
67 }
68 req.Token = token
69 if resp, err = Ask(sock, req, nil); err != nil || !resp.Allow {
70 t.Fatalf("with token: %+v, %v", resp, err)
71 }
72
73 other, err := st.CreateUser("mallory", false)
74 if err != nil {
75 t.Fatal(err)
76 }
77 forged := req
78 forged.UserID = other
79 if resp, err = Ask(sock, forged, nil); err != nil || resp.Allow {
80 t.Fatalf("token for another account: %+v, %v", resp, err)
81 }
82
83 otherRepo, err := st.CreateRepo("user", uid, "lib", "public")
84 if err != nil {
85 t.Fatal(err)
86 }
87 forged = req
88 forged.RepoID = otherRepo
89 if resp, err = Ask(sock, forged, nil); err != nil || resp.Allow {
90 t.Fatalf("token for another repository: %+v, %v", resp, err)
91 }
92
93 forged = req
94 forged.Scope = "read"
95 if resp, err = Ask(sock, forged, nil); err != nil || resp.Allow {
96 t.Fatalf("token for another scope: %+v, %v", resp, err)
97 }
98
99 if err := st.DeletePushToken(token); err != nil {
100 t.Fatal(err)
101 }
102 if resp, err = Ask(sock, req, nil); err != nil || resp.Allow {
103 t.Fatalf("finished push: %+v, %v", resp, err)
104 }
105}