Skip to content
quarry Artifact [0122b6aebc]
Login

Artifact [0122b6aebc]

Artifact 0122b6aebc53d94123b73f0a7fb629111e273c40cc7d0743916ae321a7693e90:


package main

import (
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"testing"

	"craftdesign.group/quarry/internal/ci"
)

// Drop into cmd/quarry. Both fail on 46b6caea1c00.

// windowEngine: a repo admin mints a group-scoped token (settings form,
// gated on OLTP caps, which still hold the row) after the revoke pass
// and before PurgeRepo. Simulated by minting on the first revoke.
type windowEngine struct{ *tokenEngine }

func (e windowEngine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	e.tokenEngine.ServeHTTP(w, req)
	if req.Method == http.MethodDelete {
		e.mu.Lock()
		if len(e.tokens) < 2 {
			e.tokens = append(e.tokens, ci.WorkerToken{ID: "late", WorkerGroups: []string{ci.GroupFor("gone")}})
		}
		e.mu.Unlock()
	}
}

func TestTokenMintedDuringDeleteIsRevoked(t *testing.T) {
	eng := &tokenEngine{tokens: []ci.WorkerToken{{ID: "own", WorkerGroups: []string{ci.GroupFor("gone")}}}}
	rg, _, _, _ := deleteFixture(t, eng)
	srv := httptest.NewServer(windowEngine{eng})
	t.Cleanup(srv.Close)
	rg.engine = ci.New(srv.URL)
	rg.engine.SetAdminToken("admin")
	if err := rg.Delete("gone", "gone"); err != nil {
		t.Fatal(err)
	}
	revoked := map[string]bool{}
	for _, id := range eng.revoked {
		revoked[id] = true
	}
	for _, tk := range eng.tokens {
		if !revoked[tk.ID] {
			t.Errorf("FAIL: token %s scoped to gone's group is live after the delete", tk.ID)
		}
	}
}

// Engine manages tokens (401 to an unauthenticated list) but quarry holds
// no admin token now; a token minted earlier survives the delete.
func TestDelete401NoAdminDoesNotLeaveLiveToken(t *testing.T) {
	eng := &tokenEngine{listStatus: http.StatusUnauthorized,
		tokens: []ci.WorkerToken{{ID: "own", WorkerGroups: []string{ci.GroupFor("gone")}}}}
	rg, _, _, _ := deleteFixture(t, eng)
	rg.engine.SetAdminToken("")
	if err := rg.Delete("gone", "gone"); err == nil && len(eng.revoked) == 0 {
		t.Error("FAIL: delete succeeded and the group-scoped token was never revoked")
	}
}

// The second sweep runs even when removing the store fails: the name is
// already free by then, so a token minted during the delete must not
// outlive it because a directory would not go.
func TestTokenMintedDuringDeleteIsRevokedWhenTheStoreStays(t *testing.T) {
	eng := &tokenEngine{tokens: []ci.WorkerToken{{ID: "own", WorkerGroups: []string{ci.GroupFor("gone")}}}}
	rg, _, _, store := deleteFixture(t, eng)
	srv := httptest.NewServer(windowEngine{eng})
	t.Cleanup(srv.Close)
	rg.engine = ci.New(srv.URL)
	rg.engine.SetAdminToken("admin")
	if err := os.WriteFile(filepath.Join(store, "held"), []byte("x"), 0o644); err != nil {
		t.Fatal(err)
	}
	if err := os.Chmod(store, 0o555); err != nil {
		t.Fatal(err)
	}
	t.Cleanup(func() { os.Chmod(store, 0o755) })
	if err := rg.Delete("gone", "gone"); err == nil {
		t.Fatal("the store could not be removed, and the delete said nothing")
	}
	revoked := map[string]bool{}
	for _, id := range eng.revoked {
		revoked[id] = true
	}
	for _, tk := range eng.tokens {
		if !revoked[tk.ID] {
			t.Errorf("FAIL: token %s scoped to gone's group is live after the delete", tk.ID)
		}
	}
}