222 lines
8.9 KiB
Go
222 lines
8.9 KiB
Go
package main
|
|
|
|
// A provider the vault holds no row of yet gets its first value in the form its offer declares (issue 768): the
|
|
// controller names the form in each consumer's plan entry (`credential-form`, from the provider's manifest), and
|
|
// the vault reads it strictly. A provider the vault already holds rows of is unchanged by it.
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestANewSharedProviderGetsOneFirstValueForEveryHolder(t *testing.T) {
|
|
mirror := assignments{
|
|
"anchor.stand-in": handedWith("anchor", "stand-in"),
|
|
"g14.app": handedWith("g14", "app", "stand-in-api@anchor/stand-in+shared"),
|
|
"ace.other": handedWith("ace", "other", "stand-in-api@anchor/stand-in+shared"),
|
|
}
|
|
v := pairVault(t, mirror)
|
|
if o := pass(t, v, standIn); o.Outcome != PairMade || o.Generation != 1 {
|
|
t.Fatalf("a new shared provider: %+v", o)
|
|
}
|
|
value, _, err := asks(v, "provisioner.anchor", standIn)
|
|
if err != nil || value == "" {
|
|
t.Fatalf("the provider's machine was refused its first value: %v", err)
|
|
}
|
|
for _, c := range []string{"provisioner.g14", "provisioner.ace"} {
|
|
if got, _, err := asks(v, c, standIn); err != nil || got != value {
|
|
t.Fatalf("%s got %q (%v), not the one value", c, got, err)
|
|
}
|
|
}
|
|
if changedSaid(t, v, standIn, value) != 1 {
|
|
t.Fatal("secret-changed was not said once for the first value")
|
|
}
|
|
rows, _ := v.pairRows()
|
|
if len(rows[pairKey{"anchor", "stand-in-api"}]) != 0 {
|
|
t.Fatal("a login per consumer was made for a provider whose offer shares one credential")
|
|
}
|
|
if o := pass(t, v, standIn); o.Outcome != PairUnchanged {
|
|
t.Fatalf("the pass after the first value: %+v", o)
|
|
}
|
|
}
|
|
|
|
func TestANewPerLoginProviderGetsAFirstLoginOfItsOwnForEachConsumer(t *testing.T) {
|
|
const pg = "provision/novox/postgres-database"
|
|
mirror := assignments{
|
|
"novox.postgres": handedWith("novox", "postgres"),
|
|
"g14.gitea": handedWith("g14", "gitea", "postgres-database@novox/postgres+pair"),
|
|
"ace.umami": handedWith("ace", "umami", "postgres-database@novox/postgres#stats+pair"),
|
|
}
|
|
v := pairVault(t, mirror)
|
|
if o := pass(t, v, pg); o.Outcome != PairMade {
|
|
t.Fatalf("a new per-login provider: %+v", o)
|
|
}
|
|
if _, held, _ := v.Store.Read(pg); held {
|
|
t.Fatal("one shared value was made for a provider whose consumers each keep a login of their own")
|
|
}
|
|
gitea, umami := "pair/novox/postgres-database/g14/gitea", "pair/novox/postgres-database/ace/umami/stats"
|
|
ofGitea, _, err := asks(v, "provisioner.g14", gitea)
|
|
if err != nil || ofGitea == "" {
|
|
t.Fatalf("gitea's machine was refused its first login: %v", err)
|
|
}
|
|
ofUmami, _, err := asks(v, "provisioner.ace", umami)
|
|
if err != nil || ofUmami == "" {
|
|
t.Fatalf("umami's machine was refused its first login: %v", err)
|
|
}
|
|
if ofGitea == ofUmami {
|
|
t.Fatal("two consumers of a per-login provider were given one value")
|
|
}
|
|
if _, _, err := asks(v, "provisioner.g14", umami); err == nil {
|
|
t.Fatal("gitea's machine was handed umami's login")
|
|
}
|
|
for name, want := range map[string]string{gitea: ofGitea, umami: ofUmami} {
|
|
if got, _, err := asks(v, "provisioner.novox", name); err != nil || got != want {
|
|
t.Fatalf("the provider's machine got %q for %s (%v)", got, name, err)
|
|
}
|
|
}
|
|
// The logins are rows now: the next pass remakes none of them.
|
|
if o := pass(t, v, pg); o.Outcome != PairPerPair {
|
|
t.Fatalf("the pass after the first logins: %+v", o)
|
|
}
|
|
if got, gen, _ := asks(v, "provisioner.g14", gitea); got != ofGitea || gen != 1 {
|
|
t.Fatal("a consumer's login was remade by the next pass")
|
|
}
|
|
}
|
|
|
|
// A provider the vault holds rows of keeps what it had, whatever form the plans name.
|
|
func TestAProviderWithRowsIsUnchangedByTheFormItsPlansName(t *testing.T) {
|
|
t.Run("stamped rows", func(t *testing.T) {
|
|
mirror := assignments{
|
|
"anchor.stand-in": handedWith("anchor", "stand-in"),
|
|
"g14.app": handedWith("g14", "app", "stand-in-api@anchor/stand-in+shared"),
|
|
}
|
|
v := pairVault(t, mirror)
|
|
movedRow(t, v, "g14", "app", "the-value-they-share", "stamp-1", OriginMade)
|
|
if o := pass(t, v, standIn); o.Outcome != PairAdopted {
|
|
t.Fatalf("stamped rows: %+v", o)
|
|
}
|
|
if got, gen, _ := asks(v, "provisioner.g14", standIn); got != "the-value-they-share" || gen != 1 {
|
|
t.Fatal("the adopted value is not the move's")
|
|
}
|
|
})
|
|
t.Run("logins of their own", func(t *testing.T) {
|
|
mirror := assignments{
|
|
"anchor.stand-in": handedWith("anchor", "stand-in"),
|
|
"g14.app": handedWith("g14", "app", "stand-in-api@anchor/stand-in+shared"),
|
|
"ace.other": handedWith("ace", "other", "stand-in-api@anchor/stand-in+pair"),
|
|
}
|
|
v := pairVault(t, mirror)
|
|
movedRow(t, v, "g14", "app", "login-of-app", "", OriginMade)
|
|
movedRow(t, v, "ace", "other", "login-of-other", "", OriginMade)
|
|
if o := pass(t, v, standIn); o.Outcome != PairPerPair {
|
|
t.Fatalf("unstamped rows: %+v", o)
|
|
}
|
|
if _, held, _ := v.Store.Read(standIn); held {
|
|
t.Fatal("a shared value was made for a provider whose rows are logins of their own")
|
|
}
|
|
if got, gen, _ := asks(v, "provisioner.g14", "pair/anchor/stand-in-api/g14/app"); got != "login-of-app" ||
|
|
gen != 1 {
|
|
t.Fatal("a consumer's own login changed")
|
|
}
|
|
})
|
|
}
|
|
|
|
// A form the vault does not make (issued by the provider's software, or given by a person), a form it does not know,
|
|
// or plans that disagree: nothing is made, and the pass says why. The rule that no holder is left behind still holds.
|
|
func TestTheVaultMakesNothingForAFormItDoesNotMakeOrCannotTrust(t *testing.T) {
|
|
for form, said := range map[string]string{
|
|
"issued": "issued by the provider's software",
|
|
"given": "given by a person",
|
|
"one-for-all": "which is not a credential form",
|
|
"shared|pair": "disagree",
|
|
"shared|": "no plan says whether",
|
|
"shared@unmoved": "stand-in on anchor",
|
|
} {
|
|
t.Run(form, func(t *testing.T) {
|
|
provider := handedWith("anchor", "stand-in")
|
|
first, second := form, form
|
|
if a, b, ok := strings.Cut(form, "|"); ok {
|
|
first, second = a, b
|
|
}
|
|
if a, _, ok := strings.Cut(form, "@"); ok {
|
|
first, second, provider = a, a, unmoved("anchor", "stand-in")
|
|
}
|
|
entry := func(f string) string {
|
|
if f == "" {
|
|
return "stand-in-api@anchor/stand-in"
|
|
}
|
|
return "stand-in-api@anchor/stand-in+" + f
|
|
}
|
|
mirror := assignments{
|
|
"anchor.stand-in": provider,
|
|
"g14.app": handedWith("g14", "app", entry(first)),
|
|
"ace.other": handedWith("ace", "other", entry(second)),
|
|
}
|
|
v := pairVault(t, mirror)
|
|
if o := pass(t, v, standIn); o.Outcome != PairHeld || !strings.Contains(o.Why, said) {
|
|
t.Fatalf("form %s: %+v", form, o)
|
|
}
|
|
if _, held, _ := v.Store.Read(standIn); held {
|
|
t.Fatalf("form %s: a shared value was made", form)
|
|
}
|
|
if rows, _ := v.pairRows(); len(rows[pairKey{"anchor", "stand-in-api"}]) != 0 {
|
|
t.Fatalf("form %s: a login was made", form)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// A consumer that binds after the move to a per-login provider the vault already holds rows of gets a login of its
|
|
// own (issue 771): the rows that exist are never touched, and `secret-changed` is said for the new login only.
|
|
func TestANewConsumerOfAPerLoginProviderWithRowsGetsALoginOfItsOwn(t *testing.T) {
|
|
mirror := assignments{
|
|
"anchor.stand-in": handedWith("anchor", "stand-in"),
|
|
"g14.app": handedWith("g14", "app", "stand-in-api@anchor/stand-in+pair"),
|
|
"ace.other": handedWith("ace", "other", "stand-in-api@anchor/stand-in+pair"),
|
|
}
|
|
v := pairVault(t, mirror)
|
|
movedRow(t, v, "g14", "app", "login-of-app", "", OriginMade)
|
|
movedRow(t, v, "ace", "other", "login-of-other", "", OriginMade)
|
|
app, other := "pair/anchor/stand-in-api/g14/app", "pair/anchor/stand-in-api/ace/other"
|
|
third := "pair/anchor/stand-in-api/novox/third"
|
|
before, said := map[string]Record{}, map[string]int{}
|
|
for _, n := range []string{app, other} {
|
|
r, _, _ := v.Store.Read(n)
|
|
before[n], said[n] = r, changedSaid(t, v, n, "")
|
|
}
|
|
|
|
mirror["novox.third"] = handedWith("novox", "third", "stand-in-api@anchor/stand-in+pair")
|
|
if o := pass(t, v, standIn); o.Outcome != PairMade {
|
|
t.Fatalf("a third consumer binding: %+v", o)
|
|
}
|
|
got, _, err := asks(v, "provisioner.novox", third)
|
|
if err != nil || got == "" || got == "login-of-app" || got == "login-of-other" {
|
|
t.Fatalf("the third consumer has no login of its own: %q (%v)", got, err)
|
|
}
|
|
if got, _, err := asks(v, "provisioner.anchor", third); err != nil || got == "" {
|
|
t.Fatalf("the provider's machine was refused the new login: %v", err)
|
|
}
|
|
for n, was := range before {
|
|
now, _, _ := v.Store.Read(n)
|
|
if !reflect.DeepEqual(now, was) {
|
|
t.Fatalf("%s was touched: %+v, was %+v", n, now, was)
|
|
}
|
|
if changedSaid(t, v, n, "") != said[n] {
|
|
t.Fatalf("secret-changed was said for %s", n)
|
|
}
|
|
}
|
|
if changedSaid(t, v, third, "") != 1 {
|
|
t.Fatal("secret-changed was not said once for the new login")
|
|
}
|
|
if _, held, _ := v.Store.Read(standIn); held {
|
|
t.Fatal("a shared value was made")
|
|
}
|
|
if o := pass(t, v, standIn); o.Outcome != PairPerPair {
|
|
t.Fatalf("the pass after the new login: %+v", o)
|
|
}
|
|
if got2, _, _ := asks(v, "provisioner.novox", third); got2 != got {
|
|
t.Fatal("the new login was remade by the next pass")
|
|
}
|
|
}
|