diff --git a/pkg/plugin/implementation/dediregistry/README.md b/pkg/plugin/implementation/dediregistry/README.md index 880cddf..6e0a0cd 100644 --- a/pkg/plugin/implementation/dediregistry/README.md +++ b/pkg/plugin/implementation/dediregistry/README.md @@ -44,7 +44,7 @@ registry: GET {url}/lookup/{subscriber_id}/{registryName}/{key_id} ``` -**Example**: `https://api.bekcn.io/registry/dedi/lookup/bpp.example.com/subscribers.beckn.one/76EU7K8oC9EQbXPMRL5uw3KbmTxbg3YDXHvm9nVQpK2eGghASnwHzm` +**Example**: `https://api.beckn.io/registry/dedi/lookup/bpp.example.com/subscribers.beckn.one/76EU7K8oC9EQbXPMRL5uw3KbmTxbg3YDXHvm9nVQpK2eGghASnwHzm` ### Authentication **No authentication required** - Beckn Registry API is public. @@ -64,7 +64,7 @@ GET {url}/lookup/{subscriber_id}/{registryName}/{key_id} "signing_public_key": "384qqkIIpxo71WaJPsWqQNWUDGAFnfnJPxuDmtuBiLo=", "encr_public_key": "test-encr-key" }, - "network_memberships": ["commerce-network.org/prod", "local-commerce.com/production"], + "network_memberships": ["commerce-network.org/prod", "local-commerce.org/production"], "created_at": "2025-10-27T11:45:27.963Z", "updated_at": "2025-10-27T11:46:23.563Z" } @@ -96,7 +96,7 @@ modules: config: url: "https://fabric.nfh.global/registry/dedi" registryName: "subscribers.beckn.one" - allowedNetworkIDs: "commerce-network.org/prod,local-commerce.com/production" + allowedNetworkIDs: "commerce-network.org/prod,local-commerce.org/production" timeout: 30 retry_max: 3 retry_wait_min: 1s @@ -150,6 +150,7 @@ This plugin replaces direct DeDi API integration with the new DeDi Wrapper API f - **Changed**: POST requests → GET requests - **Updated**: Response structure parsing (`data.details` object) - **Updated**: Optional allowlist validation now checks `data.network_memberships` +- **Deprecated**: `allowedParentNamespaces` config key in favor of `allowedNetworkIDs` (plugin now errors until the config is updated to full network membership IDs) - **Added**: New URL path parameter format ## Dependencies diff --git a/pkg/plugin/implementation/dediregistry/cmd/plugin.go b/pkg/plugin/implementation/dediregistry/cmd/plugin.go index 0ac37a1..3714fb1 100644 --- a/pkg/plugin/implementation/dediregistry/cmd/plugin.go +++ b/pkg/plugin/implementation/dediregistry/cmd/plugin.go @@ -3,6 +3,7 @@ package main import ( "context" "errors" + "fmt" "strconv" "strings" @@ -35,9 +36,11 @@ func (d dediRegistryProvider) New(ctx context.Context, config map[string]string) } } - if rawNetworkIDs, exists := config["allowedNetworkIDs"]; exists && rawNetworkIDs != "" { - dediConfig.AllowedNetworkIDs = parseAllowedNetworkIDs(rawNetworkIDs) + allowedNetworkIDs, err := resolveAllowedNetworkIDs(ctx, config) + if err != nil { + return nil, nil, err } + dediConfig.AllowedNetworkIDs = allowedNetworkIDs log.Debugf(ctx, "DeDi Registry config mapped: %+v", dediConfig) @@ -64,5 +67,19 @@ func parseAllowedNetworkIDs(raw string) []string { return networkIDs } +func resolveAllowedNetworkIDs(ctx context.Context, config map[string]string) ([]string, error) { + if rawParentNamespaces, exists := config["allowedParentNamespaces"]; exists && rawParentNamespaces != "" { + if _, hasAllowedNetworkIDs := config["allowedNetworkIDs"]; !hasAllowedNetworkIDs { + return nil, fmt.Errorf("config key 'allowedParentNamespaces' is no longer supported; use 'allowedNetworkIDs' with full network IDs") + } + } + + if rawNetworkIDs, exists := config["allowedNetworkIDs"]; exists && rawNetworkIDs != "" { + return parseAllowedNetworkIDs(rawNetworkIDs), nil + } + + return nil, nil +} + // Provider is the exported plugin instance var Provider = dediRegistryProvider{} diff --git a/pkg/plugin/implementation/dediregistry/cmd/plugin_test.go b/pkg/plugin/implementation/dediregistry/cmd/plugin_test.go index 573f8da..083d30f 100644 --- a/pkg/plugin/implementation/dediregistry/cmd/plugin_test.go +++ b/pkg/plugin/implementation/dediregistry/cmd/plugin_test.go @@ -91,10 +91,53 @@ func TestDediRegistryProvider_New_InvalidTimeout(t *testing.T) { } func TestParseAllowedNetworkIDs(t *testing.T) { - got := parseAllowedNetworkIDs("commerce-network/subscriber-references, retail-network/subscriber-references, ,") + got := parseAllowedNetworkIDs("commerce-network.org/prod, local-commerce.org/production, ,") want := []string{ - "commerce-network/subscriber-references", - "retail-network/subscriber-references", + "commerce-network.org/prod", + "local-commerce.org/production", + } + + if len(got) != len(want) { + t.Fatalf("expected %d allowed network IDs, got %d", len(want), len(got)) + } + for i := range want { + if got[i] != want[i] { + t.Errorf("expected allowedNetworkIDs[%d] to preserve input order as %q, got %q", i, want[i], got[i]) + } + } +} + +func TestResolveAllowedNetworkIDs_DeprecatedAllowedParentNamespacesErrorsWithoutAllowedNetworkIDs(t *testing.T) { + ctx := context.Background() + config := map[string]string{ + "allowedParentNamespaces": "commerce-network.org/prod, local-commerce.org/production", + } + + got, err := resolveAllowedNetworkIDs(ctx, config) + if err == nil { + t.Fatal("expected error when only allowedParentNamespaces is configured") + } + if got != nil { + t.Fatalf("expected nil allowed network IDs on error, got %#v", got) + } +} + +func TestResolveAllowedNetworkIDs_AllowedNetworkIDsTakesPrecedence(t *testing.T) { + ctx := context.Background() + config := map[string]string{ + "url": "https://test.com/dedi", + "registryName": "subscribers.beckn.one", + "allowedParentNamespaces": "deprecated-network.org/legacy", + "allowedNetworkIDs": "commerce-network.org/prod, local-commerce.org/production", + } + + got, err := resolveAllowedNetworkIDs(ctx, config) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + want := []string{ + "commerce-network.org/prod", + "local-commerce.org/production", } if len(got) != len(want) { @@ -107,6 +150,22 @@ func TestParseAllowedNetworkIDs(t *testing.T) { } } +func TestDediRegistryProvider_New_DeprecatedAllowedParentNamespacesErrorsWithoutAllowedNetworkIDs(t *testing.T) { + ctx := context.Background() + provider := dediRegistryProvider{} + + config := map[string]string{ + "url": "https://test.com/dedi", + "registryName": "subscribers.beckn.one", + "allowedParentNamespaces": "commerce-network.org", + } + + _, _, err := provider.New(ctx, config) + if err == nil { + t.Fatal("expected New() to error when only allowedParentNamespaces is configured") + } +} + func TestDediRegistryProvider_New_NilContext(t *testing.T) { provider := dediRegistryProvider{} diff --git a/pkg/plugin/implementation/dediregistry/dediregistry_test.go b/pkg/plugin/implementation/dediregistry/dediregistry_test.go index cfccc89..4f6a0cf 100644 --- a/pkg/plugin/implementation/dediregistry/dediregistry_test.go +++ b/pkg/plugin/implementation/dediregistry/dediregistry_test.go @@ -140,7 +140,7 @@ func TestLookup(t *testing.T) { "signing_public_key": "384qqkIIpxo71WaJPsWqQNWUDGAFnfnJPxuDmtuBiLo=", "encr_public_key": "test-encr-key", }, - "network_memberships": []string{"commerce-network/subscriber-references", "local-commerce/subscriber-references"}, + "network_memberships": []string{"commerce-network.org/prod", "local-commerce.org/production"}, "created_at": "2025-10-27T11:45:27.963Z", "updated_at": "2025-10-27T11:46:23.563Z", }, @@ -204,7 +204,7 @@ func TestLookup(t *testing.T) { "subscriber_id": "dev.np2.com", "signing_public_key": "384qqkIIpxo71WaJPsWqQNWUDGAFnfnJPxuDmtuBiLo=", }, - "network_memberships": []string{"commerce-network/subscriber-references", "local-commerce/subscriber-references"}, + "network_memberships": []string{"commerce-network.org/prod", "local-commerce.org/production"}, }, } w.Header().Set("Content-Type", "application/json") @@ -215,7 +215,7 @@ func TestLookup(t *testing.T) { config := &Config{ URL: server.URL + "/dedi", RegistryName: "subscribers.beckn.one", - AllowedNetworkIDs: []string{"commerce-network/subscriber-references"}, + AllowedNetworkIDs: []string{"commerce-network.org/prod"}, } client, closer, err := New(ctx, config) @@ -248,7 +248,7 @@ func TestLookup(t *testing.T) { "subscriber_id": "dev.np2.com", "signing_public_key": "384qqkIIpxo71WaJPsWqQNWUDGAFnfnJPxuDmtuBiLo=", }, - "network_memberships": []string{"local-commerce/subscriber-references"}, + "network_memberships": []string{"local-commerce.org/production"}, }, } w.Header().Set("Content-Type", "application/json")