Skip to content
quarry Artifact [fd6e77f702]
Login

Artifact [fd6e77f702]

Artifact fd6e77f702f029511df7f15e90c1068c39bc0beaf8f5542eaec45d8cec4c94e6:


package oltp

import "testing"

// RFC 0026 steps 4 and 5: a repository's or a team's own agent holds
// what it was granted, inside its scope only, and never the flag.
func TestARepositoryAgentHoldsItsGrantThereOnly(t *testing.T) {
	db := agentRig(t)
	if err := db.NewDedicatedAgent("priv-ci", "repo:priv", "dmestas"); err != nil {
		t.Fatal(err)
	}
	if db.EffectiveCaps("priv-ci", "priv").HasAny("o") {
		t.Errorf("FAIL: a new repository agent holds something before a grant")
	}
	if err := db.Grant("priv-ci", "priv", Write); err != nil {
		t.Fatal(err)
	}
	if !db.EffectiveCaps("priv-ci", "priv").HasAny("i") {
		t.Errorf("FAIL: a repository agent granted developer cannot check in")
	}
	// A grant elsewhere does nothing: it is the repository's agent.
	if err := db.SetRepoVisibility("pub", Private); err != nil {
		t.Fatal(err)
	}
	if err := db.Grant("priv-ci", "pub", Write); err != nil {
		t.Fatal(err)
	}
	if got := db.EffectiveCaps("priv-ci", "pub"); got.HasAny("o") {
		t.Errorf("FAIL: a repository agent reaches another repository: %q", letters(got))
	}
	t.Log("ok: repository agent")

	// It goes with its repository: disabled, tokens revoked, and no
	// later repository of the name owns it.
	if _, _, err := db.MintToken("priv-ci", TokenSpec{Name: "ci", Scopes: []string{ScopeAPI}}); err != nil {
		t.Fatal(err)
	}
	if err := db.PurgeRepo("priv"); err != nil {
		t.Fatal(err)
	}
	a, _ := db.AccountByName("priv-ci")
	if a.Disabled == "" || a.Operator == "repo:priv" {
		t.Errorf("FAIL: after its repository was deleted the agent is disabled=%q operator=%q", a.Disabled, a.Operator)
	}
	toks, _ := db.Tokens("priv-ci")
	for _, tk := range toks {
		if tk.Revoked == "" {
			t.Errorf("FAIL: a deleted repository's agent kept a live token")
		}
	}
	t.Log("ok: goes with its repository")
}

func TestATeamAgentReachesItsTeamsRepositories(t *testing.T) {
	db := agentRig(t)
	if err := db.AddTeam("crew", "", "", "dmestas"); err != nil {
		t.Fatal(err)
	}
	if err := db.SetTeamRepo("crew", "priv", "dmestas"); err != nil {
		t.Fatal(err)
	}
	if err := db.NewDedicatedAgent("crew-ci", "team:crew", "dmestas"); err != nil {
		t.Fatal(err)
	}
	if err := db.SetTeamMember("crew", "crew-ci", Write.Caps(), false, true); err != nil {
		t.Fatal(err)
	}
	if !db.EffectiveCaps("crew-ci", "priv").HasAny("i") {
		t.Errorf("FAIL: a team agent added as a developer member cannot check in on the team's repository")
	}
	if err := db.SetRepoVisibility("pub", Private); err != nil {
		t.Fatal(err)
	}
	if err := db.Grant("crew-ci", "pub", Write); err != nil {
		t.Fatal(err)
	}
	if got := db.EffectiveCaps("crew-ci", "pub"); got.HasAny("o") {
		t.Errorf("FAIL: a team agent reaches a repository outside its team: %q", letters(got))
	}
	t.Log("ok: team agent")
}

func TestADedicatedAgentNeedsARealScopeAndHasACap(t *testing.T) {
	db := agentRig(t)
	for _, s := range []string{"repo:nope", "team:nope", "site", ""} {
		if err := db.NewDedicatedAgent("x-ci", s, "dmestas"); err == nil {
			t.Errorf("FAIL: scope %q was accepted", s)
		}
	}
	for i := 0; i < DedicatedAgentsPer; i++ {
		if err := db.NewDedicatedAgent("ci-"+string(rune('a'+i)), "repo:pub", "dmestas"); err != nil {
			t.Fatal(err)
		}
	}
	if err := db.NewDedicatedAgent("ci-over", "repo:pub", "dmestas"); err == nil {
		t.Errorf("FAIL: a repository took more than %d agents", DedicatedAgentsPer)
	}
	t.Log("ok: scope and cap")
}