krz/gitbay
A CLI-first git forge.
clone: git clone https://gitbay.org/krz/gitbay.git
main: internal/policy/access_test.go · raw
1package policy
2
3import (
4 "testing"
5
6 "gitbay.org/gitbay/internal/store"
7)
8
9var (
10 owner = store.User{ID: 1, Username: "alice"}
11 stranger = store.User{ID: 2, Username: "bob"}
12 priv = store.Repo{ID: 10, OwnerKind: "user", OwnerID: 1, OwnerName: "alice", Name: "p", Visibility: "private"}
13 pub = store.Repo{ID: 11, OwnerKind: "user", OwnerID: 1, OwnerName: "alice", Name: "q", Visibility: "public"}
14)
15
16func TestAccessMatrix(t *testing.T) {
17 cases := []struct {
18 name string
19 user store.User
20 repo store.Repo
21 grant string
22 read bool
23 write bool
24 admin bool
25 }{
26 {"owner private", owner, priv, "", true, true, true},
27 {"stranger private no grant", stranger, priv, "", false, false, false},
28 {"stranger private read", stranger, priv, "read", true, false, false},
29 {"stranger private write", stranger, priv, "write", true, true, false},
30 {"stranger private admin", stranger, priv, "admin", true, true, true},
31 {"stranger public no grant", stranger, pub, "", true, false, false},
32 {"stranger public write", stranger, pub, "write", true, true, false},
33 }
34 for _, tc := range cases {
35 t.Run(tc.name, func(t *testing.T) {
36 if got := CanRead(tc.user, tc.repo, tc.grant); got != tc.read {
37 t.Errorf("CanRead = %v, want %v", got, tc.read)
38 }
39 if got := CanWrite(tc.user, tc.repo, tc.grant); got != tc.write {
40 t.Errorf("CanWrite = %v, want %v", got, tc.write)
41 }
42 if got := CanAdmin(tc.user, tc.repo, tc.grant); got != tc.admin {
43 t.Errorf("CanAdmin = %v, want %v", got, tc.admin)
44 }
45 })
46 }
47}
48
49func TestScopeAllowsGit(t *testing.T) {
50 cases := []struct {
51 scope string
52 repo string
53 write bool
54 want bool
55 }{
56 {"full", "a/b", true, true},
57 {"git", "a/b", true, true},
58 {"deploy:a/b:ro", "a/b", false, true},
59 {"deploy:a/b:ro", "a/b", true, false},
60 {"deploy:a/b:rw", "a/b", true, true},
61 {"deploy:a/b:rw", "a/c", false, false}, // wrong repo
62 {"deploy:a/b", "a/b", false, false}, // malformed
63 {"", "a/b", false, false},
64 }
65 for _, tc := range cases {
66 if got := ScopeAllowsGit(tc.scope, tc.repo, tc.write); got != tc.want {
67 t.Errorf("ScopeAllowsGit(%q, %q, write=%v) = %v, want %v", tc.scope, tc.repo, tc.write, got, tc.want)
68 }
69 }
70}
71
72func TestCheckPush(t *testing.T) {
73 repo := store.Repo{Settings: store.RepoSettings{ProtectedBranches: []string{"main"}}}
74 cases := []struct {
75 name string
76 updates []RefUpdate
77 denied bool
78 }{
79 {"normal push to protected", []RefUpdate{{Ref: "refs/heads/main"}}, false},
80 {"force to protected", []RefUpdate{{Ref: "refs/heads/main", IsForce: true}}, true},
81 {"delete protected", []RefUpdate{{Ref: "refs/heads/main", IsDelete: true}}, true},
82 {"force to unprotected", []RefUpdate{{Ref: "refs/heads/dev", IsForce: true}}, false},
83 {"delete unprotected", []RefUpdate{{Ref: "refs/heads/dev", IsDelete: true}}, false},
84 {"mr namespace", []RefUpdate{{Ref: "refs/merge-requests/1/head"}}, true},
85 {"tag alongside protected", []RefUpdate{{Ref: "refs/tags/v1"}, {Ref: "refs/heads/main"}}, false},
86 }
87 for _, tc := range cases {
88 t.Run(tc.name, func(t *testing.T) {
89 msg := CheckPush(repo, tc.updates)
90 if (msg != "") != tc.denied {
91 t.Errorf("CheckPush = %q, denied should be %v", msg, tc.denied)
92 }
93 })
94 }
95}