From a4e7f480b3b0ce603490f60b9c1e05eec25c05d9 Mon Sep 17 00:00:00 2001 From: fix-sdk-pas Date: Fri, 16 Oct 2026 19:44:26 +0200 Subject: [PATCH] Apply the plan's credential form only to an offer that declares a credential (issue 825) --- go/provider/provider.go | 5 ++++- go/provider/provider_test.go | 25 +++++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/go/provider/provider.go b/go/provider/provider.go index ce5df6e..33bf61f 100644 --- a/go/provider/provider.go +++ b/go/provider/provider.go @@ -476,8 +476,11 @@ func (p *Provider) answer(ctx context.Context, e Entry, have []byte) Outcome { e.Values = values var credential []byte // The plan's form wins; the offer's is the default. + // An offer that declares no credential has none whatever the plan says: the controller writes "pair" for it. form := e.CredentialForm - if form == "" { + if offer.Credential == NoCredential { + form = "" + } else if form == "" { form = map[CredentialForm]string{Shared: "shared", PerConsumer: "pair"}[offer.Credential] } switch form { diff --git a/go/provider/provider_test.go b/go/provider/provider_test.go index a36644c..659e35f 100644 --- a/go/provider/provider_test.go +++ b/go/provider/provider_test.go @@ -710,10 +710,6 @@ func TestThePlansCredentialFormWinsOverTheOffers(t *testing.T) { "pair/novox/postgres-database/ace/letta" || e.User != "mesh_ace_letta" { t.Fatalf("pair over shared: %+v", e) } - if e := run(NoCredential, map[string]string{"credential-form": "pair"}); e.VaultName != - "pair/novox/postgres-database/ace/letta" { - t.Fatalf("pair over none: %+v", e) - } for _, form := range []string{"issued", "given"} { if e := run(PerConsumer, map[string]string{"credential-form": form, "name": "main"}); e.VaultName != "provision/novox/postgres-database/ace/letta" || e.User != "mesh_ace_letta" { @@ -784,3 +780,24 @@ func TestAFailedMakeIsSaidWithoutTheCredentialInAnyOfItsForms(t *testing.T) { } } } + +// An offer that declares no credential is answered with none whatever form the plan says (the controller writes +// "pair" for such an offer): no vault name, and the Vault is never asked, so a provider with no Vault works (issue 825, +// finding 4; issue 923). +func TestAnOfferWithNoCredentialIgnoresThePlansForm(t *testing.T) { + bus := newStandIn() + b := bind("route", "", "novox", "route-proxy") + b["credential-form"] = "pair" + assign(t, bus, "ace", "letta", b) + p := New(Options{Node: "novox", Module: "route-proxy", Bus: bus, Logf: func(string, ...any) {}, + Offers: map[string]Offer{"route": {Credential: NoCredential}}}) + out, err := p.Pass(context.Background()) + if err != nil || len(out) != 1 || out[0].Status != Answered { + t.Fatalf("%v %+v", err, out) + } + var e Entry + if err := json.Unmarshal(bus.get(BucketOf("route-proxy"), "ace.letta.route"), &e); err != nil || e.VaultName != "" || + e.User != "" { + t.Fatalf("%v %+v", err, e) + } +}