added test cases for keymanager and plugin
This commit is contained in:
@@ -9,7 +9,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// keyManagerProvider implements the plugin provider for the KeyManager plugin.
|
// keyManagerProvider implements the plugin provider for the KeyManager plugin.
|
||||||
type keyManagerProvider struct{}
|
type keyManagerProvider struct {
|
||||||
|
newFunc func(ctx context.Context, cache definition.Cache, registry definition.RegistryLookup, cfg *keymanager.Config) (definition.KeyManager, func() error, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// newKeyManagerFunc is a function type that creates a new KeyManager instance.
|
||||||
|
var newKeyManagerFunc = keymanager.New
|
||||||
|
|
||||||
// New creates and initializes a new KeyManager instance using the provided cache, registry lookup, and configuration.
|
// New creates and initializes a new KeyManager instance using the provided cache, registry lookup, and configuration.
|
||||||
func (k *keyManagerProvider) New(ctx context.Context, cache definition.Cache, registry definition.RegistryLookup, cfg map[string]string) (definition.KeyManager, func() error, error) {
|
func (k *keyManagerProvider) New(ctx context.Context, cache definition.Cache, registry definition.RegistryLookup, cfg map[string]string) (definition.KeyManager, func() error, error) {
|
||||||
@@ -18,7 +23,7 @@ func (k *keyManagerProvider) New(ctx context.Context, cache definition.Cache, re
|
|||||||
KVVersion: cfg["kv_version"],
|
KVVersion: cfg["kv_version"],
|
||||||
}
|
}
|
||||||
log.Debugf(ctx, "Keymanager config mapped: %+v", cfg)
|
log.Debugf(ctx, "Keymanager config mapped: %+v", cfg)
|
||||||
km, cleanup, err := keymanager.New(ctx, cache, registry, config)
|
km, cleanup, err := newKeyManagerFunc(ctx, cache, registry, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(ctx, err, "Failed to initialize KeyManager")
|
log.Error(ctx, err, "Failed to initialize KeyManager")
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
|||||||
164
pkg/plugin/implementation/keymanager/cmd/plugin_test.go
Normal file
164
pkg/plugin/implementation/keymanager/cmd/plugin_test.go
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/beckn/beckn-onix/pkg/model"
|
||||||
|
"github.com/beckn/beckn-onix/pkg/plugin/definition"
|
||||||
|
"github.com/beckn/beckn-onix/pkg/plugin/implementation/keymanager"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mock KeyManager implementation
|
||||||
|
type mockKeyManager struct{}
|
||||||
|
|
||||||
|
func (m *mockKeyManager) SigningPublicKey(ctx context.Context, subscriberID, keyID string) (string, error) {
|
||||||
|
return "mock-signing-public-key", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockKeyManager) SigningPrivateKey(ctx context.Context, subscriberID string) (string, string, error) {
|
||||||
|
return "mock-key-id", "mock-signing-private-key", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockKeyManager) EncrPublicKey(ctx context.Context, subscriberID, keyID string) (string, error) {
|
||||||
|
return "mock-encryption-public-key", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockKeyManager) EncrPrivateKey(ctx context.Context, subscriberID string) (string, string, error) {
|
||||||
|
return "mock-key-id", "mock-encryption-private-key", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockKeyManager) DeletePrivateKeys(ctx context.Context, subscriberID string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockKeyManager) StorePrivateKeys(ctx context.Context, subscriberID string, keys *model.Keyset) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockKeyManager) GenerateKeyPairs() (*model.Keyset, error) {
|
||||||
|
return &model.Keyset{
|
||||||
|
UniqueKeyID: "mock-key-id",
|
||||||
|
SigningPrivate: "mock-signing-private-key",
|
||||||
|
SigningPublic: "mock-signing-public-key",
|
||||||
|
EncrPrivate: "mock-encryption-private-key",
|
||||||
|
EncrPublic: "mock-encryption-public-key",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockRegistry struct {
|
||||||
|
LookupFunc func(ctx context.Context, sub *model.Subscription) ([]model.Subscription, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockRegistry) Lookup(ctx context.Context, sub *model.Subscription) ([]model.Subscription, error) {
|
||||||
|
if m.LookupFunc != nil {
|
||||||
|
return m.LookupFunc(ctx, sub)
|
||||||
|
}
|
||||||
|
return []model.Subscription{
|
||||||
|
{
|
||||||
|
Subscriber: model.Subscriber{
|
||||||
|
SubscriberID: sub.SubscriberID,
|
||||||
|
URL: "https://mock.registry/subscriber",
|
||||||
|
Type: "BPP",
|
||||||
|
Domain: "retail",
|
||||||
|
},
|
||||||
|
KeyID: sub.KeyID,
|
||||||
|
SigningPublicKey: "mock-signing-public-key",
|
||||||
|
EncrPublicKey: "mock-encryption-public-key",
|
||||||
|
ValidFrom: time.Now().Add(-time.Hour),
|
||||||
|
ValidUntil: time.Now().Add(time.Hour),
|
||||||
|
Status: "SUBSCRIBED",
|
||||||
|
Created: time.Now().Add(-2 * time.Hour),
|
||||||
|
Updated: time.Now(),
|
||||||
|
Nonce: "mock-nonce",
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockCache struct{}
|
||||||
|
|
||||||
|
func (m *mockCache) Get(ctx context.Context, key string) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
func (m *mockCache) Set(ctx context.Context, key string, value string, ttl time.Duration) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (m *mockCache) Clear(ctx context.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockCache) Delete(ctx context.Context, key string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSuccess(t *testing.T) {
|
||||||
|
// Setup dummy implementations and variables
|
||||||
|
ctx := context.Background()
|
||||||
|
cache := &mockCache{}
|
||||||
|
registry := &mockRegistry{}
|
||||||
|
cfg := map[string]string{
|
||||||
|
"vault_addr": "http://dummy-vault",
|
||||||
|
"kv_version": "2",
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanupCalled := false
|
||||||
|
fakeCleanup := func() error {
|
||||||
|
cleanupCalled = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
newKeyManagerFunc = func(ctx context.Context, cache definition.Cache, registry definition.RegistryLookup, cfg *keymanager.Config) (*keymanager.KeyMgr, func() error, error) {
|
||||||
|
// return a mock struct pointer of *keymanager.KeyMgr or a stub instance
|
||||||
|
return &keymanager.KeyMgr{}, fakeCleanup, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create provider and call New
|
||||||
|
provider := &keyManagerProvider{}
|
||||||
|
km, cleanup, err := provider.New(ctx, cache, registry, cfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if km == nil {
|
||||||
|
t.Fatal("Expected non-nil KeyManager instance")
|
||||||
|
}
|
||||||
|
if cleanup == nil {
|
||||||
|
t.Fatal("Expected non-nil cleanup function")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call cleanup and check if it behaves correctly
|
||||||
|
if err := cleanup(); err != nil {
|
||||||
|
t.Fatalf("Expected no error from cleanup, got %v", err)
|
||||||
|
}
|
||||||
|
if !cleanupCalled {
|
||||||
|
t.Error("Expected cleanup function to be called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewFailure(t *testing.T) {
|
||||||
|
// Setup dummy variables
|
||||||
|
ctx := context.Background()
|
||||||
|
cache := &mockCache{}
|
||||||
|
registry := &mockRegistry{}
|
||||||
|
cfg := map[string]string{
|
||||||
|
"vault_addr": "http://dummy-vault",
|
||||||
|
"kv_version": "2",
|
||||||
|
}
|
||||||
|
|
||||||
|
newKeyManagerFunc = func(ctx context.Context, cache definition.Cache, registry definition.RegistryLookup, cfg *keymanager.Config) (*keymanager.KeyMgr, func() error, error) {
|
||||||
|
return nil, nil, fmt.Errorf("some error")
|
||||||
|
}
|
||||||
|
|
||||||
|
provider := &keyManagerProvider{}
|
||||||
|
km, cleanup, err := provider.New(ctx, cache, registry, cfg)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Expected error, got nil")
|
||||||
|
}
|
||||||
|
if km != nil {
|
||||||
|
t.Error("Expected nil KeyManager on error")
|
||||||
|
}
|
||||||
|
if cleanup != nil {
|
||||||
|
t.Error("Expected nil cleanup function on error")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -70,6 +70,11 @@ func ValidateCfg(cfg *Config) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getVaultClient is a function that creates a new Vault client.
|
||||||
|
// This is exported for testing purposes.
|
||||||
|
var getVaultClient = GetVaultClient
|
||||||
|
|
||||||
|
// New creates a new KeyMgr instance with the provided configuration, cache, and registry lookup.
|
||||||
func New(ctx context.Context, cache definition.Cache, registryLookup definition.RegistryLookup, cfg *Config) (*KeyMgr, func() error, error) {
|
func New(ctx context.Context, cache definition.Cache, registryLookup definition.RegistryLookup, cfg *Config) (*KeyMgr, func() error, error) {
|
||||||
log.Info(ctx, "Initializing KeyManager plugin")
|
log.Info(ctx, "Initializing KeyManager plugin")
|
||||||
// Validate configuration.
|
// Validate configuration.
|
||||||
@@ -91,7 +96,7 @@ func New(ctx context.Context, cache definition.Cache, registryLookup definition.
|
|||||||
|
|
||||||
// Initialize Vault client.
|
// Initialize Vault client.
|
||||||
log.Debugf(ctx, "Creating Vault client with address: %s", cfg.VaultAddr)
|
log.Debugf(ctx, "Creating Vault client with address: %s", cfg.VaultAddr)
|
||||||
vaultClient, err := GetVaultClient(ctx, cfg.VaultAddr)
|
vaultClient, err := getVaultClient(ctx, cfg.VaultAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(ctx, err, "Failed to create Vault client at address: %s", cfg.VaultAddr)
|
log.Errorf(ctx, err, "Failed to create Vault client at address: %s", cfg.VaultAddr)
|
||||||
return nil, nil, fmt.Errorf("failed to create vault client: %w", err)
|
return nil, nil, fmt.Errorf("failed to create vault client: %w", err)
|
||||||
@@ -120,6 +125,10 @@ func New(ctx context.Context, cache definition.Cache, registryLookup definition.
|
|||||||
return km, cleanup, nil
|
return km, cleanup, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewVaultClient creates a new Vault client instance.
|
||||||
|
// This function is exported for testing purposes.
|
||||||
|
var NewVaultClient = vault.NewClient
|
||||||
|
|
||||||
// GetVaultClient creates and authenticates a Vault client using AppRole.
|
// GetVaultClient creates and authenticates a Vault client using AppRole.
|
||||||
func GetVaultClient(ctx context.Context, vaultAddr string) (*vault.Client, error) {
|
func GetVaultClient(ctx context.Context, vaultAddr string) (*vault.Client, error) {
|
||||||
roleID := os.Getenv("VAULT_ROLE_ID")
|
roleID := os.Getenv("VAULT_ROLE_ID")
|
||||||
@@ -133,7 +142,7 @@ func GetVaultClient(ctx context.Context, vaultAddr string) (*vault.Client, error
|
|||||||
config := vault.DefaultConfig()
|
config := vault.DefaultConfig()
|
||||||
config.Address = vaultAddr
|
config.Address = vaultAddr
|
||||||
|
|
||||||
client, err := vault.NewClient(config)
|
client, err := NewVaultClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(ctx, err, "failed to create Vault client")
|
log.Error(ctx, err, "failed to create Vault client")
|
||||||
return nil, fmt.Errorf("failed to create Vault client: %w", err)
|
return nil, fmt.Errorf("failed to create Vault client: %w", err)
|
||||||
@@ -160,19 +169,25 @@ func GetVaultClient(ctx context.Context, vaultAddr string) (*vault.Client, error
|
|||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ed25519KeyGenFunc = ed25519.GenerateKey
|
||||||
|
x25519KeyGenFunc = ecdh.X25519().GenerateKey
|
||||||
|
uuidGenFunc = uuid.NewRandom
|
||||||
|
)
|
||||||
|
|
||||||
// GenerateKeyPairs generates a new signing (Ed25519) and encryption (X25519) key pair.
|
// GenerateKeyPairs generates a new signing (Ed25519) and encryption (X25519) key pair.
|
||||||
func (km *KeyMgr) GenerateKeyPairs() (*model.Keyset, error) {
|
func (km *KeyMgr) GenerateKeyPairs() (*model.Keyset, error) {
|
||||||
signingPublic, signingPrivate, err := ed25519.GenerateKey(rand.Reader)
|
signingPublic, signingPrivate, err := ed25519KeyGenFunc(rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to generate signing key pair: %w", err)
|
return nil, fmt.Errorf("failed to generate signing key pair: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
encrPrivateKey, err := ecdh.X25519().GenerateKey(rand.Reader)
|
encrPrivateKey, err := x25519KeyGenFunc(rand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to generate encryption key pair: %w", err)
|
return nil, fmt.Errorf("failed to generate encryption key pair: %w", err)
|
||||||
}
|
}
|
||||||
encrPublicKey := encrPrivateKey.PublicKey().Bytes()
|
encrPublicKey := encrPrivateKey.PublicKey().Bytes()
|
||||||
uuid, err := uuid.NewRandom()
|
uuid, err := uuidGenFunc()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to generate unique key id uuid: %w", err)
|
return nil, fmt.Errorf("failed to generate unique key id uuid: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
1182
pkg/plugin/implementation/keymanager/keymanager_test.go
Normal file
1182
pkg/plugin/implementation/keymanager/keymanager_test.go
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user