Skip to content
quarry Artifact [dee47593e0]
Login

Artifact [dee47593e0]

Artifact dee47593e06a2cb3261ce40e1143e50e456ec4f5f280f39e13a01e9dc17687b3:


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")
}

// RFC 0026 review: a repository's agent never holds a, nor a deed, and
// a new operator never inherits an old opt-in.
func TestADedicatedAgentHoldsNoAdminAndNoDeed(t *testing.T) {
	db := agentRig(t)
	if err := db.NewDedicatedAgent("pub-ci", "repo:pub", "dmestas"); err != nil {
		t.Fatal(err)
	}
	if err := db.Grant("pub-ci", "pub", RepoAdmin); err != nil {
		t.Fatal(err)
	}
	if db.EffectiveCaps("pub-ci", "pub").HasAny("a") {
		t.Errorf("FAIL: a repository agent granted admin holds a")
	}
	if err := db.SetOwner("pub", "pub-ci"); err == nil {
		t.Errorf("FAIL: a repository agent took the deed")
	}
	t.Log("ok: no a, no deed")
}

func TestANewOperatorNeverInheritsTheOptIn(t *testing.T) {
	db := agentRig(t)
	if err := db.NewAgent("root-bot", "root", -1); err != nil {
		t.Fatal(err)
	}
	if err := db.SetSiteOpt("root", "root-bot"); err != nil {
		t.Fatal(err)
	}
	if err := db.AddAccount("root2", "a-long-enough-password", true); err != nil {
		t.Fatal(err)
	}
	if err := db.SetOperator("root-bot", "root2"); err != nil {
		t.Fatal(err)
	}
	if db.InheritsSiteAdmin("root-bot") {
		t.Errorf("FAIL: the agent inherited its new operator's flag without their opt-in")
	}
	t.Log("ok: the opt-in stays with the person who chose it")
}