Skip to content
quarry Artifact [8f722003db]
Login

Artifact [8f722003db]

Artifact 8f722003db84bd6076dd01963058cd3a3202896d6fde08371472d2aedafed0d6:


package api

import (
	"context"
	"encoding/json"
	"errors"
	"path/filepath"
	"strings"
	"testing"
	"time"

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

// A Git mirror's access token: an administrator replaces or clears it,
// the mirror then says only whether one is held, the token never comes
// back from an op, and a mirror that does not follow Git refuses one.
func TestMirrorTokenOpHoldsAndNeverReturnsTheToken(t *testing.T) {
	ix, _, _ := attachStore(t)
	db, err := oltp.Open(filepath.Join(t.TempDir(), "o.db"))
	if err != nil {
		t.Fatal(err)
	}
	t.Cleanup(func() { db.Close() })
	for _, m := range []struct{ repo, url string }{{"test", "https://github.com/o/private"}, {"fossil", "https://example.invalid/f"}} {
		if err := db.SetMirror(m.repo, m.url, time.Hour); err != nil {
			t.Fatal(err)
		}
	}
	if err := db.SetMirrorGit("test"); err != nil {
		t.Fatal(err)
	}
	mirrors := oltpMirrors{db}
	r := ops.NewRegistry()
	caps := func(account, repo string) CapSet {
		if account == "dan" {
			return oltp.CapSet("a")
		}
		return oltp.CapSet("3")
	}
	if err := RegisterAll(r, Deps{Version: "v", Repos: testRepos(ix), Mirrors: mirrors, MirrorTokens: mirrors, CapsFor: caps}); err != nil {
		t.Fatal(err)
	}
	set := func(who string, in mirrorTokenIn) (mirrorTokenOut, error) {
		out, err := r.Invoke(ops.WithUser(context.Background(), who), "mirror.token", in)
		if err != nil {
			return mirrorTokenOut{}, err
		}
		return out.(mirrorTokenOut), nil
	}
	if _, err := set("eve", mirrorTokenIn{Repo: "test", Token: "github_pat_abc"}); !errors.Is(err, ops.ErrForbidden) {
		t.Fatalf("FAIL: somebody without admin set a token: %v", err)
	}
	out, err := set("dan", mirrorTokenIn{Repo: "test", Token: "github_pat_abc"})
	if err != nil {
		t.Fatal(err)
	}
	body, _ := json.Marshal(out)
	if !out.Mirror.GitToken || strings.Contains(string(body), "github_pat_abc") {
		t.Fatalf("FAIL: after setting, the mirror reads %s", body)
	}
	if tok, _ := db.MirrorGitToken("test"); tok != "github_pat_abc" {
		t.Fatalf("FAIL: the fetch would send %q", tok)
	}
	t.Log("ok: an admin sets it; the answer says it is held and does not carry it")
	for _, bad := range []mirrorTokenIn{
		{Repo: "test", Token: "has space"},
		{Repo: "test"},
		{Repo: "test", Token: "x", Clear: true},
	} {
		if _, err := set("dan", bad); !errors.Is(err, ops.ErrInvalid) {
			t.Errorf("FAIL: %+v was accepted: %v", bad, err)
		}
	}
	if _, err := set("dan", mirrorTokenIn{Repo: "fossil", Token: "github_pat_abc"}); !errors.Is(err, ops.ErrNotFound) {
		t.Errorf("FAIL: a mirror that does not follow Git took a token: %v", err)
	}
	if out, err := set("dan", mirrorTokenIn{Repo: "test", Clear: true}); err != nil || out.Mirror.GitToken {
		t.Fatalf("FAIL: clearing: %+v %v", out.Mirror, err)
	}
	t.Log("ok: a bad token, an empty ask and a Fossil mirror are refused; clearing removes it")
}

// repo.add takes a token only for a Git clone, and refuses one that is
// not a token, before anything is made.
func TestRepoAddTakesATokenOnlyForAGitClone(t *testing.T) {
	ix, _, _ := attachStore(t)
	r := ops.NewRegistry()
	if err := RegisterAll(r, Deps{Version: "v", Repos: testRepos(ix)}); err != nil {
		t.Fatal(err)
	}
	for _, in := range []repoAddIn{
		{Name: "p", Clone: "https://example.invalid/f", GitToken: "github_pat_abc"},
		{Name: "p", Clone: "https://github.com/o/p", Git: true, GitToken: "two words"},
	} {
		if _, err := r.Invoke(as("dan", "a"), "repo.add", in); !errors.Is(err, ops.ErrInvalid) {
			t.Errorf("FAIL: %+v was accepted: %v", in, err)
		}
	}
	t.Log("ok: a token without a Git clone, or one with a space in it, is refused")
}