package main
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"craftdesign.group/quarry/internal/oltp"
"craftdesign.group/quarry/internal/ops"
)
// A site admin with no grant is a stranger to a private repository on
// the sync path and the read gate the API and pages share (#318), and
// on a public one is whatever any signed-in account is.
func TestASiteAdminWithNoGrantCannotCloneAPrivateRepository(t *testing.T) {
rg := newTestRegistrar(t, 25)
const pw = "pw12345678"
for _, a := range []struct {
name string
admin bool
}{{"root", true}, {"owner", false}, {"passerby", false}} {
if err := rg.odb.AddAccount(a.name, pw, a.admin); err != nil {
t.Fatal(err)
}
}
if err := rg.odb.AddRepo("vault", t.TempDir(), "", oltp.Private); err != nil {
t.Fatal(err)
}
if err := rg.odb.AddRepo("square", t.TempDir(), "", oltp.Public); err != nil {
t.Fatal(err)
}
if err := rg.odb.Grant("owner", "vault", oltp.RepoAdmin); err != nil {
t.Fatal(err)
}
rg.refreshPrivate()
basic := func(user, repo string) bool {
req := httptest.NewRequest(http.MethodGet, "/xfer/"+repo, nil)
req.SetBasicAuth(user, pw)
return rg.SyncReadGate(req, repo, "")
}
card := func(user, repo string) bool {
return rg.SyncReadGate(httptest.NewRequest(http.MethodGet, "/xfer/"+repo, nil), repo, user)
}
if !basic("owner", "vault") || !card("owner", "vault") {
t.Fatal("the owner cannot clone their own private repository; the check proves nothing")
}
if basic("root", "vault") || card("root", "vault") {
t.Error("FAIL: a site admin with no grant cloned a private repository")
}
if basic("root", "square") != basic("passerby", "square") || card("root", "square") != card("passerby", "square") {
t.Error("FAIL: on a public repository a site admin's clone differs from a signed-in account's")
}
if rg.CanRead(ops.WithUser(context.Background(), "root"), "vault") {
t.Error("FAIL: the shared read gate admits a site admin with no grant to a private repository")
}
if rg.odb.MayWrite("vault", "root") {
t.Error("FAIL: a site admin with no grant may push to a private repository")
}
if _, ok := rg.odb.Secret("square", "root"); ok {
t.Error("FAIL: a site admin with no grant has a push credential for a public repository")
}
}
// The web's session plane asks the same question the password path
// does: at forge scope a site admin passes the admin floor, at a
// repository they were not granted they do not.
func TestTheSessionPlaneStopsASiteAdminAtTheDoor(t *testing.T) {
rg := newTestRegistrar(t, 25)
if err := rg.odb.AddAccount("root", "pw12345678", true); err != nil {
t.Fatal(err)
}
if err := rg.odb.AddRepo("vault", t.TempDir(), "", oltp.Private); err != nil {
t.Fatal(err)
}
s := sessionPlane{db: rg.odb}
if !s.Allow("root", "", ops.Admin) {
t.Fatal("FAIL: a site admin fails the admin floor at forge scope")
}
if s.Allow("root", "vault", ops.Admin) {
t.Error("FAIL: a site admin with no grant passes a repository's admin floor")
}
if s.CapsOf("root", "vault").HasAny("o") {
t.Error("FAIL: a site admin with no grant holds a read letter on a repository")
}
}