package web
import (
"net/http"
"net/url"
"path/filepath"
"testing"
"craftdesign.group/quarry/internal/api"
"craftdesign.group/quarry/internal/oltp"
"craftdesign.group/quarry/internal/ops"
)
// A forge agent's page offers the site scope to the site admin who
// opened it when the agent holds the flag, and the mint it posts gives
// a site token. A forge agent without the flag, and a person's agent,
// are offered no site scope, and a posted one is refused in words.
func TestTheAgentPageOffersSiteOnlyForAFlaggedForgeAgent(t *testing.T) {
db, err := oltp.Open(filepath.Join(t.TempDir(), "oltp.db"))
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { db.Close() })
for _, a := range []struct {
name string
admin bool
}{{"root", true}, {"zeitgeist", true}} {
if err := db.AddAccount(a.name, "pw-"+a.name+"-12345", a.admin); err != nil {
t.Fatal(err)
}
}
if err := db.SetForgeAgent("zeitgeist", "root"); err != nil {
t.Fatal(err)
}
if err := db.NewForgeAgent("fbot", "root"); err != nil {
t.Fatal(err)
}
if err := db.NewAgent("root-coder", "root", -1); err != nil {
t.Fatal(err)
}
r := ops.NewRegistry()
if err := api.RegisterAll(r, api.Deps{Version: "t", Repos: api.NewRepos(nil), Accounts: agentAccts{db},
CapsFor: func(a, repo string) api.CapSet { return db.EffectiveCaps(a, repo) }}); err != nil {
t.Fatal(err)
}
f := prefsForge{h: HandlerWith(r, nil, nil, []Option{WithSessions(fakeSessions{user: "root"})})}
code, page := f.get(t, "/me/agents/zeitgeist")
if code != http.StatusOK || !hasHook(page, "agent-token-site") {
t.Fatalf("FAIL: zeitgeist's page (%d) offers no site scope", code)
}
rec := f.post(t, "/me/agents/zeitgeist/token", url.Values{"name": {"ops"}, "scope": {"api", "site"}})
if rec.Code != http.StatusOK || !hasHook(rec.Body.String(), "agent-token-once") {
t.Fatalf("FAIL: minting zeitgeist a site token answered %d", rec.Code)
}
toks, _ := db.Tokens("zeitgeist")
if len(toks) != 1 || !toks[0].Has(oltp.ScopeSite) {
t.Fatalf("FAIL: zeitgeist holds %+v", toks)
}
t.Log("ok: offered, minted, carries site")
for _, agent := range []string{"fbot", "root-coder"} {
code, page := f.get(t, "/me/agents/"+agent)
if code != http.StatusOK || hasHook(page, "agent-token-site") {
t.Errorf("FAIL: %s's page (%d) offers the site scope", agent, code)
}
rec := f.post(t, "/me/agents/"+agent+"/token", url.Values{"name": {"ops"}, "scope": {"api", "site"}})
if rec.Code == http.StatusOK || !hasHook(rec.Body.String(), "agent-error") {
t.Errorf("FAIL: a site token for %s answered %d without a refusal", agent, rec.Code)
}
if toks, _ := db.Tokens(agent); len(toks) != 0 {
t.Errorf("FAIL: %s holds %+v", agent, toks)
}
}
}