arche / internal/archesrv/collab_test.go

commit 154431fd
  1package archesrv
  2
  3import (
  4	"fmt"
  5	"net/http"
  6	"testing"
  7)
  8
  9func TestForgeServer_Collaborator_AddAndRemove(t *testing.T) {
 10	s, ts := newTestServer(t)
 11	_, adminClient := loginAsAdmin(t, s, ts)
 12	setupRepoWithDisk(t, s, "myrepo", "private")
 13
 14	s.db.CreateUser("bob", "pass", false) //nolint:errcheck
 15
 16	resp, err := adminClient.PostForm(ts.URL+"/myrepo/settings/collaborators", map[string][]string{
 17		"username": {"bob"},
 18		"role":     {"read"},
 19	})
 20	if err != nil {
 21		t.Fatalf("POST collaborator: %v", err)
 22	}
 23	resp.Body.Close()
 24	if resp.StatusCode >= 400 {
 25		t.Errorf("add collaborator: got %d", resp.StatusCode)
 26	}
 27
 28	rec, _ := s.db.GetRepo("myrepo")
 29	u, _, _ := s.db.GetUserByName("bob")
 30	if !s.db.CanRead(rec, u) {
 31		t.Error("bob should have read access after being added as collaborator")
 32	}
 33
 34	collabs, err := s.db.ListCollaborators(rec.ID)
 35	if err != nil {
 36		t.Fatalf("ListCollaborators: %v", err)
 37	}
 38	found := false
 39	for _, c := range collabs {
 40		if c.Username == "bob" {
 41			found = true
 42		}
 43	}
 44	if !found {
 45		t.Error("bob should appear in collaborator list")
 46	}
 47
 48	req, _ := http.NewRequest(http.MethodDelete,
 49		fmt.Sprintf("%s/myrepo/settings/collaborators/%d", ts.URL, u.ID), nil)
 50	resp2, err := adminClient.Do(req)
 51	if err != nil {
 52		t.Fatalf("DELETE collaborator: %v", err)
 53	}
 54	resp2.Body.Close()
 55	if resp2.StatusCode >= 400 {
 56		t.Errorf("remove collaborator: got %d", resp2.StatusCode)
 57	}
 58
 59	rec2, _ := s.db.GetRepo("myrepo")
 60	if s.db.CanRead(rec2, u) {
 61		t.Error("bob should lose read access after removal")
 62	}
 63}
 64
 65func TestForgeServer_Collaborator_NonAdminCannotAdd(t *testing.T) {
 66	s, ts := newTestServer(t)
 67	s.db.CreateUser("admin", "adminpass", true) //nolint:errcheck
 68	setupRepoWithDisk(t, s, "myrepo", "private")
 69
 70	alice, _ := s.db.CreateUser("alice", "pass", false)
 71	rec, _ := s.db.GetRepo("myrepo")
 72	s.db.SetPermission(rec.ID, alice.ID, "write") //nolint:errcheck
 73
 74	aliceClient := loginAs(t, ts, "alice", "pass")
 75	s.db.CreateUser("bob", "pass", false) //nolint:errcheck
 76
 77	resp, err := aliceClient.PostForm(ts.URL+"/myrepo/settings/collaborators", map[string][]string{
 78		"username": {"bob"},
 79		"role":     {"read"},
 80	})
 81	if err != nil {
 82		t.Fatalf("POST collaborator: %v", err)
 83	}
 84	resp.Body.Close()
 85	if resp.StatusCode < 400 {
 86		t.Errorf("non-admin should not add collaborators, got %d", resp.StatusCode)
 87	}
 88}
 89
 90func TestForgeServer_Collaborator_WriteRoleGrantsWrite(t *testing.T) {
 91	s, ts := newTestServer(t)
 92	_, adminClient := loginAsAdmin(t, s, ts)
 93	setupRepoWithDisk(t, s, "myrepo", "private")
 94	s.db.CreateUser("writer", "pass", false) //nolint:errcheck
 95
 96	resp, err := adminClient.PostForm(ts.URL+"/myrepo/settings/collaborators", map[string][]string{
 97		"username": {"writer"},
 98		"role":     {"write"},
 99	})
100	if err != nil {
101		t.Fatalf("POST collaborator: %v", err)
102	}
103	resp.Body.Close()
104
105	rec, _ := s.db.GetRepo("myrepo")
106	u, _, _ := s.db.GetUserByName("writer")
107	if !s.db.CanWrite(rec, u) {
108		t.Error("writer should have write access")
109	}
110}
111
112func TestForgeServer_Collaborator_AdminRoleAllowsManagement(t *testing.T) {
113	s, ts := newTestServer(t)
114	s.db.CreateUser("siteadmin", "adminpass", true) //nolint:errcheck
115	setupRepoWithDisk(t, s, "myrepo", "private")
116
117	repoAdmin, _ := s.db.CreateUser("repoadmin", "pass", false)
118	rec, _ := s.db.GetRepo("myrepo")
119	s.db.SetPermission(rec.ID, repoAdmin.ID, "admin") //nolint:errcheck
120
121	repoAdminClient := loginAs(t, ts, "repoadmin", "pass")
122	s.db.CreateUser("target", "pass", false) //nolint:errcheck
123
124	resp, err := repoAdminClient.PostForm(ts.URL+"/myrepo/settings/collaborators", map[string][]string{
125		"username": {"target"},
126		"role":     {"read"},
127	})
128	if err != nil {
129		t.Fatalf("POST collaborator: %v", err)
130	}
131	resp.Body.Close()
132	if resp.StatusCode >= 400 {
133		t.Errorf("repo admin should be able to add collaborators, got %d", resp.StatusCode)
134	}
135}