133728e barerepo 1mo
1
package e2e
133728e barerepo 1mo
3
import (
133728e barerepo 1mo
4
"net/url"
133728e barerepo 1mo
5
"os/exec"
133728e barerepo 1mo
6
"regexp"
133728e barerepo 1mo
7
"sort"
133728e barerepo 1mo
8
"strings"
133728e barerepo 1mo
9
"testing"
133728e barerepo 1mo
10
"time"
133728e barerepo 1mo
12
"github.com/barerepo/server/internal/token"
133728e barerepo 1mo
15
var formIn = regexp.MustCompile(`<form[^>]*action="([^"]+)"`)
133728e barerepo 1mo
17
// A form is a control, and a reader must only be shown the ones they may use. Chapter 24.
133728e barerepo 1mo
18
func TestNobodyIsShownAControlTheyMayNotUse(t *testing.T) {
133728e barerepo 1mo
19
if _, err := exec.LookPath("git"); err != nil {
133728e barerepo 1mo
20
t.Skip("git is not installed")
133728e barerepo 1mo
22
in := newInstance(t)
133728e barerepo 1mo
23
john := in.account("john")
133728e barerepo 1mo
24
lisa := in.account("lisa")
133728e barerepo 1mo
25
seed(t, in, john, "john", "johnbot")
133728e barerepo 1mo
26
post(t, in, "john", "/john/johnbot/threads", url.Values{
133728e barerepo 1mo
27
"title": {"a thread"}, "body": {"with a body"}})
133728e barerepo 1mo
29
owner, err := in.db.NewSession(t.Context(), "john")
133728e barerepo 1mo
30
if err != nil {
133728e barerepo 1mo
31
t.Fatal(err)
133728e barerepo 1mo
33
stranger, err := in.db.NewSession(t.Context(), "lisa")
133728e barerepo 1mo
34
if err != nil {
133728e barerepo 1mo
35
t.Fatal(err)
133728e barerepo 1mo
37
_ = lisa
133728e barerepo 1mo
39
// An attached machine, last seen long enough ago that the page offers to forget it.
133728e barerepo 1mo
40
_, tok, err := in.db.CreateToken(t.Context(), token.Runner, "john", "john/johnbot", "a runner")
133728e barerepo 1mo
41
if err != nil {
133728e barerepo 1mo
42
t.Fatal(err)
133728e barerepo 1mo
44
if _, err := in.db.AttachRunner(t.Context(), tok.ID, "john/johnbot",
133728e barerepo 1mo
45
"uproar.local", "linux", "amd64", nil); err != nil {
133728e barerepo 1mo
46
t.Fatal(err)
133728e barerepo 1mo
48
if _, err := in.db.ExecContext(t.Context(),
133728e barerepo 1mo
49
`UPDATE runners SET last_seen = ?`, time.Now().Add(-time.Hour).Unix()); err != nil {
133728e barerepo 1mo
50
t.Fatal(err)
133728e barerepo 1mo
53
// Every page a reader can reach on somebody else's repository, and the controls on it.
133728e barerepo 1mo
54
pages := []string{
133728e barerepo 1mo
55
"/john/johnbot", "/john/johnbot/files", "/john/johnbot/threads",
133728e barerepo 1mo
56
"/john/johnbot/thread/1", "/john/johnbot/runs", "/john/johnbot/runners",
133728e barerepo 1mo
57
"/john/johnbot/releases", "/john/johnbot/config",
133728e barerepo 1mo
59
want := map[string][]string{
133728e barerepo 1mo
60
// The owner runs the repository, and is not offered a copy of what is already theirs.
133728e barerepo 1mo
61
"the owner": {
133728e barerepo 1mo
62
"/john/johnbot/delete", "/john/johnbot/rename",
133728e barerepo 1mo
63
"/john/johnbot/runners/forget", "/john/johnbot/thread/1/close",
133728e barerepo 1mo
64
"/john/johnbot/thread/1/reply", "/john/johnbot/transfer",
133728e barerepo 1mo
65
},
133728e barerepo 1mo
66
// A stranger may talk and may copy. Closing is the author's and the owner's, and she is neither.
133728e barerepo 1mo
67
"a stranger": {
133728e barerepo 1mo
68
"/john/johnbot/copy", "/john/johnbot/thread/1/reply",
133728e barerepo 1mo
69
},
133728e barerepo 1mo
70
// Signed out there is nothing to press at all, because every control needs an account.
133728e barerepo 1mo
71
"nobody": {},
133728e barerepo 1mo
73
for _, who := range []struct{ name, session string }{
133728e barerepo 1mo
74
{"the owner", owner}, {"a stranger", stranger}, {"nobody", ""},
133728e barerepo 1mo
75
} {
133728e barerepo 1mo
76
found := map[string]bool{}
133728e barerepo 1mo
77
for _, path := range pages {
133728e barerepo 1mo
78
_, _, body := fetch(t, in, who.session, path)
133728e barerepo 1mo
79
for _, m := range formIn.FindAllStringSubmatch(body, -1) {
133728e barerepo 1mo
80
// A search box is a get form and asks nobody for permission.
133728e barerepo 1mo
81
if m[1] != "/search" {
133728e barerepo 1mo
82
found[m[1]] = true
133728e barerepo 1mo
86
got := make([]string, 0, len(found))
133728e barerepo 1mo
87
for a := range found {
133728e barerepo 1mo
88
got = append(got, a)
133728e barerepo 1mo
90
sort.Strings(got)
133728e barerepo 1mo
91
if strings.Join(got, " ") != strings.Join(want[who.name], " ") {
133728e barerepo 1mo
92
t.Errorf("%s is shown\n %v\nand should be shown\n %v", who.name, got, want[who.name])