Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

395 commit(s) on main

update readme Keenan Nemetz · 56m ago 32290114
history blame raw 2.2 KiB
1package ssh
2
3// `vole change merge` is a verb that moves a branch, so the two things worth
4// pinning over the wire are that it is not a shell and that it asks the repository's
5// rules rather than the caller's word. The landing rules themselves are pinned in
6// forge/landing; these are about who gets to ask and what a refusal looks like.
7
8import (
9 "strings"
10 "testing"
11)
12
13func TestMergeVerbRefusesNonMaintainers(t *testing.T) {
14 t.Parallel()
15 h := newHarness(t)
16 // reader holds the read role: it may clone, and it may not merge.
17 c := h.dial(t, h.roKey)
18
19 sess, err := c.NewSession()
20 if err != nil {
21 t.Fatal(err)
22 }
23 out, err := sess.CombinedOutput("vole-change-merge /demo.git 01M5XF4XWHVMMCQEYENA8X32GK")
24 sess.Close()
25 if err == nil {
26 t.Fatalf("a reader merged a change request: %s", out)
27 }
28 if !strings.Contains(string(out), "may not merge") {
29 t.Fatalf("refusal = %q, want it to name the missing capability", out)
30 }
31}
32
33func TestMergeVerbShowsTheGateRefusal(t *testing.T) {
34 t.Parallel()
35 h := newHarness(t)
36 c := h.dial(t, h.keyPath) // the writer, a maintainer
37
38 sess, err := c.NewSession()
39 if err != nil {
40 t.Fatal(err)
41 }
42 // A request id nobody opened: the landing refuses and says so, on the channel,
43 // with the prefix the client turns into an error.
44 out, err := sess.CombinedOutput("vole-change-merge /demo.git 01M5XF4XWHVMMCQEYENA8X32GK")
45 sess.Close()
46 if err == nil {
47 t.Fatalf("merging an unknown request succeeded: %s", out)
48 }
49 if !strings.HasPrefix(string(out), "vole: ") {
50 t.Fatalf("refusal = %q, want the vole: prefix the client reads", out)
51 }
52}
53
54func TestMergeVerbIsNotAShell(t *testing.T) {
55 t.Parallel()
56 h := newHarness(t)
57 c := h.dial(t, h.keyPath)
58
59 for _, command := range []string{
60 "vole-change-merge",
61 "vole-change-merge /demo.git",
62 "vole-change-merge /demo.git 01M5XF4XWHVMMCQEYENA8X32GK; cat /etc/passwd",
63 "vole-change-merge /../demo.git 01M5XF4XWHVMMCQEYENA8X32GK",
64 } {
65 sess, err := c.NewSession()
66 if err != nil {
67 t.Fatal(err)
68 }
69 out, err := sess.CombinedOutput(command)
70 sess.Close()
71 if err == nil {
72 t.Fatalf("%q succeeded, want a refusal (output: %s)", command, out)
73 }
74 if strings.Contains(string(out), "root:") {
75 t.Fatalf("%q executed something: %s", command, out)
76 }
77 }
78}
79