Skip to content
quarry Artifact [4cd5ac3eb2]
Login

Artifact [4cd5ac3eb2]

Artifact 4cd5ac3eb2dec6a8cbe3776f5f5e7cedca636e7c822ffe0d1d8522b5c0dd33cd:


package oltp

import "testing"

// RFC 0026 step 3: a personal agent scoped to one repository or one
// team inherits there and holds what any signed-in account holds
// everywhere else.
func TestAScopedAgentReachesOnlyItsScope(t *testing.T) {
	db := agentRig(t)
	for _, r := range []string{"priv", "priv2"} {
		if r == "priv2" {
			if err := db.AddRepo(r, t.TempDir(), "", Private); err != nil {
				t.Fatal(err)
			}
		}
		if err := db.Grant("dmestas", r, Write); err != nil {
			t.Fatal(err)
		}
	}
	if err := db.NewScopedAgent("priv-bot", "dmestas", "repo:priv", -1); err != nil {
		t.Fatal(err)
	}
	if !db.EffectiveCaps("priv-bot", "priv").HasAny("i") {
		t.Errorf("FAIL: a repository agent lacks its operator's check-in on its repository")
	}
	if got := db.EffectiveCaps("priv-bot", "priv2"); got.HasAny("o") {
		t.Errorf("FAIL: a repository agent reads another private repository: %q", letters(got))
	}
	t.Log("ok: repository scope")

	if err := db.AddTeam("crew", "", "", "dmestas"); err != nil {
		t.Fatal(err)
	}
	if err := db.SetTeamMember("crew", "dmestas", "", true, true); err != nil {
		t.Fatal(err)
	}
	if err := db.SetTeamRepo("crew", "priv2", "dmestas"); err != nil {
		t.Fatal(err)
	}
	if err := db.NewScopedAgent("crew-bot", "dmestas", "team:crew", -1); err != nil {
		t.Fatal(err)
	}
	if !db.EffectiveCaps("crew-bot", "priv2").HasAny("i") {
		t.Errorf("FAIL: a team agent lacks check-in on its team's repository")
	}
	if got := db.EffectiveCaps("crew-bot", "priv"); got.HasAny("o") {
		t.Errorf("FAIL: a team agent reads a repository outside its team: %q", letters(got))
	}
	t.Log("ok: team scope")

	// Deleting the scope leaves the agent nothing, even under a name
	// taken again.
	if err := db.DeleteRepo("priv"); err != nil {
		t.Fatal(err)
	}
	if a, _ := db.AccountByName("priv-bot"); a.Scope != "gone" {
		t.Errorf("FAIL: after its repository was deleted the agent's scope is %q", a.Scope)
	}
	t.Log("ok: a deleted scope is gone")
}

func TestAScopeMustBeTheOperatorsToGive(t *testing.T) {
	db := agentRig(t)
	if err := db.NewScopedAgent("x-bot", "dmestas", "team:nobody", -1); err == nil {
		t.Errorf("FAIL: an agent was scoped to a team its operator is not in")
	}
	if err := db.NewScopedAgent("y-bot", "dmestas", "repo:priv", -1); err == nil {
		t.Errorf("FAIL: an agent was scoped to a private repository its operator cannot read")
	}
	if err := db.NewScopedAgent("z-bot", "dmestas", "fleet", -1); err == nil {
		t.Errorf("FAIL: a scope that is no scope was accepted")
	}
	t.Log("ok: scope checks")
}

func TestTheRosterKeepsAScopedAgentInsideItsScope(t *testing.T) {
	db := agentRig(t)
	if err := db.Grant("dmestas", "priv", Write); err != nil {
		t.Fatal(err)
	}
	if err := db.Grant("dmestas", "pub", Write); err != nil {
		t.Fatal(err)
	}
	if err := db.NewScopedAgent("priv-bot", "dmestas", "repo:priv", -1); err != nil {
		t.Fatal(err)
	}
	in := func(repo string) string {
		hs, _ := db.CapHolders(repo)
		for _, h := range hs {
			if h.Account == "priv-bot" {
				return h.Inherits
			}
		}
		return ""
	}
	if in("priv") != "dmestas" || in("pub") != "" {
		t.Errorf("FAIL: the roster shows the repository agent inheriting on priv=%q pub=%q", in("priv"), in("pub"))
	}
	t.Log("ok: roster within scope")
}

// Review of !1150: the normal delete (PurgeRepo) also leaves a
// repository agent reaching nothing, and a later repository of the
// same name gains no agent.
func TestPurgingTheRepositoryEndsTheScope(t *testing.T) {
	db := agentRig(t)
	if err := db.Grant("dmestas", "priv", Write); err != nil {
		t.Fatal(err)
	}
	if err := db.NewScopedAgent("priv-bot", "dmestas", "repo:priv", -1); err != nil {
		t.Fatal(err)
	}
	if err := db.PurgeRepo("priv"); err != nil {
		t.Fatal(err)
	}
	if err := db.AddRepo("priv", t.TempDir(), "", Private); err != nil {
		t.Fatal(err)
	}
	if err := db.Grant("dmestas", "priv", Write); err != nil {
		t.Fatal(err)
	}
	if got := db.EffectiveCaps("priv-bot", "priv"); got.HasAny("o") {
		t.Errorf("FAIL: an agent scoped to a purged repository reaches its successor: %q", letters(got))
	}
	t.Log("ok: purge ends the scope")
}

// Review of !1150: a scope names a repository that exists now.
func TestAScopeNeedsTheRepositoryToExist(t *testing.T) {
	db := agentRig(t)
	for _, s := range []string{"repo:not-yet", "repo:a:b", "repo:"} {
		if err := db.NewScopedAgent("n-bot", "dmestas", s, -1); err == nil {
			t.Errorf("FAIL: scope %q was accepted", s)
		}
	}
	t.Log("ok: no scope to a repository nobody made")
}

// Review of !1150: outside its scope a team's letters do not carry an
// agent either.
func TestATeamDoesNotCarryAnAgentPastItsScope(t *testing.T) {
	db := agentRig(t)
	if err := db.NewScopedAgent("pub-bot", "dmestas", "repo:pub", -1); err != nil {
		t.Fatal(err)
	}
	if err := db.AddTeam("crew", "", "", "dmestas"); err != nil {
		t.Fatal(err)
	}
	if err := db.SetTeamMember("crew", "pub-bot", Write.Caps(), false, true); err != nil {
		t.Fatal(err)
	}
	if err := db.SetTeamRepo("crew", "priv", "dmestas"); err != nil {
		t.Fatal(err)
	}
	if err := db.Grant("dmestas", "priv", Write); err != nil {
		t.Fatal(err)
	}
	if got := db.EffectiveCaps("pub-bot", "priv"); got.HasAny("o") {
		t.Errorf("FAIL: a team carried a repository agent onto another repository: %q", letters(got))
	}
	t.Log("ok: scope over team")
}