Skip to content
quarry Artifact [80daea3138]
Login

Artifact [80daea3138]

Artifact 80daea3138284d6f1d282f05e9b3695aa9b0efafaeafa32826b43a2cc2a86cce:


package harness

import (
	"io"
	"net/http"
	"path/filepath"
	"strings"
	"testing"

	"craftdesign.group/quarry/internal/api"
	"craftdesign.group/quarry/internal/oltp"
	"craftdesign.group/quarry/internal/ops"
)

// TestCapsGateTheAPI is RFC 0004 §4 enforced end to end: each account
// holds exactly one fossil capability letter and may reach exactly the
// surfaces that letter opens. The Auth floor lets every authenticated
// caller through; the capability check is what decides.
func TestCapsGateTheAPI(t *testing.T) {
	stores := map[string]string{"alpha": buildStore(t, "capseed")}
	dataDir := t.TempDir()
	srv := ingestAndServeAuth(t, stores, dataDir,
		func(repo, user, pass string, need ops.Auth) api.Decision {
			if user == "" {
				return api.Denied
			}
			return api.Allowed
		})
	// The harness opened this same file; a second handle sees its rows.
	odb, err := oltp.Open(filepath.Join(dataDir, "oltp.db"))
	if err != nil {
		t.Fatal(err)
	}
	defer odb.Close()
	must := func(err error) {
		t.Helper()
		if err != nil {
			t.Fatal(err)
		}
	}
	must(odb.AddAccount("reader", "pw12345678", false))
	must(odb.SetCaps("reader", "alpha", "o")) // Read
	must(odb.AddAccount("forumer", "pw12345678", false))
	must(odb.SetCaps("forumer", "alpha", "3")) // WrForum

	call := func(user, method, path, body string) int {
		var r io.Reader
		if body != "" {
			r = strings.NewReader(body)
		}
		req, _ := http.NewRequest(method, srv.URL+path, r)
		req.SetBasicAuth(user, "pw12345678")
		if body != "" {
			req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		}
		resp, err := srv.Client().Do(req)
		if err != nil {
			t.Fatal(err)
		}
		resp.Body.Close()
		return resp.StatusCode
	}

	// o reads.
	if got := call("reader", "GET", "/api/v1/r/alpha/timeline", ""); got != http.StatusOK {
		t.Fatalf("o cannot read the timeline: %d", got)
	}
	// o is refused the forum write surface; 3 is not.
	if got := call("reader", "POST", "/api/v1/r/alpha/forum",
		"title=x&body=y"); got != http.StatusForbidden {
		t.Fatalf("o opened the forum write surface: %d", got)
	}
	if got := call("forumer", "POST", "/api/v1/r/alpha/forum",
		"title=from+the+forum+cap&body=hello"); got != http.StatusOK {
		t.Fatalf("3 cannot write the forum: %d", got)
	}
	// 3 does not carry repository administration (a).
	if got := call("forumer", "POST", "/api/v1/repos",
		"name=nope&create=1"); got == http.StatusOK {
		t.Fatal("3 reached repository creation")
	}
}