Resolved PR review comments
This commit is contained in:
@@ -108,11 +108,11 @@ func (s *validateSignStep) validate(ctx *model.StepContext, value string) error
|
|||||||
return fmt.Errorf("malformed sign header")
|
return fmt.Errorf("malformed sign header")
|
||||||
}
|
}
|
||||||
keyID := headerParts[1]
|
keyID := headerParts[1]
|
||||||
keySet, err := s.km.Keyset(ctx, keyID)
|
signingPublicKey, _, err := s.km.LookupNPKeys(ctx, ctx.SubID, keyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get validation key: %w", err)
|
return fmt.Errorf("failed to get validation key: %w", err)
|
||||||
}
|
}
|
||||||
if err := s.validator.Validate(ctx, ctx.Body, value, keySet.SigningPublic); err != nil {
|
if err := s.validator.Validate(ctx, ctx.Body, value, signingPublicKey); err != nil {
|
||||||
return fmt.Errorf("sign validation failed: %w", err)
|
return fmt.Errorf("sign validation failed: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ 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) {
|
||||||
config := &keymanager.Config{
|
config := &keymanager.Config{
|
||||||
VaultAddr: cfg["vault_addr"],
|
VaultAddr: cfg["vaultAddr"],
|
||||||
KVVersion: cfg["kv_version"],
|
KVVersion: cfg["kvVersion"],
|
||||||
}
|
}
|
||||||
log.Debugf(ctx, "Keymanager config mapped: %+v", cfg)
|
log.Debugf(ctx, "Keymanager config mapped: %+v", cfg)
|
||||||
km, cleanup, err := newKeyManagerFunc(ctx, cache, registry, config)
|
km, cleanup, err := newKeyManagerFunc(ctx, cache, registry, config)
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ func TestNewSuccess(t *testing.T) {
|
|||||||
cache := &mockCache{}
|
cache := &mockCache{}
|
||||||
registry := &mockRegistry{}
|
registry := &mockRegistry{}
|
||||||
cfg := map[string]string{
|
cfg := map[string]string{
|
||||||
"vault_addr": "http://dummy-vault",
|
"vaultAddr": "http://dummy-vault",
|
||||||
"kv_version": "2",
|
"kvVersion": "2",
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanupCalled := false
|
cleanupCalled := false
|
||||||
@@ -105,8 +105,8 @@ func TestNewFailure(t *testing.T) {
|
|||||||
cache := &mockCache{}
|
cache := &mockCache{}
|
||||||
registry := &mockRegistry{}
|
registry := &mockRegistry{}
|
||||||
cfg := map[string]string{
|
cfg := map[string]string{
|
||||||
"vault_addr": "http://dummy-vault",
|
"vaultAddr": "http://dummy-vault",
|
||||||
"kv_version": "2",
|
"kvVersion": "2",
|
||||||
}
|
}
|
||||||
|
|
||||||
newKeyManagerFunc = func(ctx context.Context, cache definition.Cache, registry definition.RegistryLookup, cfg *keymanager.Config) (*keymanager.KeyMgr, func() error, error) {
|
newKeyManagerFunc = func(ctx context.Context, cache definition.Cache, registry definition.RegistryLookup, cfg *keymanager.Config) (*keymanager.KeyMgr, func() error, error) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/beckn/beckn-onix/pkg/log"
|
"github.com/beckn/beckn-onix/pkg/log"
|
||||||
"github.com/beckn/beckn-onix/pkg/model"
|
"github.com/beckn/beckn-onix/pkg/model"
|
||||||
@@ -61,11 +62,13 @@ func ValidateCfg(cfg *Config) error {
|
|||||||
if cfg.VaultAddr == "" {
|
if cfg.VaultAddr == "" {
|
||||||
return errors.New("invalid config: VaultAddr cannot be empty")
|
return errors.New("invalid config: VaultAddr cannot be empty")
|
||||||
}
|
}
|
||||||
if cfg.KVVersion == "" {
|
kvVersion := strings.ToLower(cfg.KVVersion)
|
||||||
cfg.KVVersion = "v1"
|
if kvVersion == "" {
|
||||||
} else if cfg.KVVersion != "v1" && cfg.KVVersion != "v2" {
|
kvVersion = "v1"
|
||||||
|
} else if kvVersion != "v1" && kvVersion != "v2" {
|
||||||
return fmt.Errorf("invalid KVVersion: must be 'v1' or 'v2'")
|
return fmt.Errorf("invalid KVVersion: must be 'v1' or 'v2'")
|
||||||
}
|
}
|
||||||
|
cfg.KVVersion = kvVersion
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,6 +202,14 @@ func (km *KeyMgr) GenerateKeyset() (*model.Keyset, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getSecretPath constructs the Vault secret path for storing keys based on the KV version.
|
||||||
|
func (km *KeyMgr) getSecretPath(keyID string) string {
|
||||||
|
if km.KvVersion == "v2" {
|
||||||
|
return fmt.Sprintf("secret/data/keys/%s", keyID)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("secret/keys/%s", keyID)
|
||||||
|
}
|
||||||
|
|
||||||
// InsertKeyset stores the given keyset in Vault under the specified key ID.
|
// InsertKeyset stores the given keyset in Vault under the specified key ID.
|
||||||
func (km *KeyMgr) InsertKeyset(ctx context.Context, keyID string, keys *model.Keyset) error {
|
func (km *KeyMgr) InsertKeyset(ctx context.Context, keyID string, keys *model.Keyset) error {
|
||||||
if keyID == "" {
|
if keyID == "" {
|
||||||
@@ -215,19 +226,17 @@ func (km *KeyMgr) InsertKeyset(ctx context.Context, keyID string, keys *model.Ke
|
|||||||
"encrPublicKey": keys.EncrPublic,
|
"encrPublicKey": keys.EncrPublic,
|
||||||
"encrPrivateKey": keys.EncrPrivate,
|
"encrPrivateKey": keys.EncrPrivate,
|
||||||
}
|
}
|
||||||
var path string
|
path := km.getSecretPath(keyID)
|
||||||
var payload map[string]interface{}
|
var payload map[string]interface{}
|
||||||
if km.KvVersion == "v2" {
|
if km.KvVersion == "v2" {
|
||||||
path = fmt.Sprintf("secret/data/keys/%s", keyID)
|
|
||||||
payload = map[string]interface{}{"data": keyData}
|
payload = map[string]interface{}{"data": keyData}
|
||||||
} else {
|
} else {
|
||||||
path = fmt.Sprintf("secret/keys/%s", keyID)
|
|
||||||
payload = keyData
|
payload = keyData
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := km.VaultClient.Logical().Write(path, payload)
|
_, err := km.VaultClient.Logical().Write(path, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to store secret in Vault: %w", err)
|
return fmt.Errorf("failed to store secret in Vault at path %s: %w", path, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -237,12 +246,7 @@ func (km *KeyMgr) DeleteKeyset(ctx context.Context, keyID string) error {
|
|||||||
if keyID == "" {
|
if keyID == "" {
|
||||||
return ErrEmptyKeyID
|
return ErrEmptyKeyID
|
||||||
}
|
}
|
||||||
var path string
|
path := km.getSecretPath(keyID)
|
||||||
if km.KvVersion == "v2" {
|
|
||||||
path = fmt.Sprintf("secret/data/private_keys/%s", keyID)
|
|
||||||
} else {
|
|
||||||
path = fmt.Sprintf("secret/private_keys/%s", keyID)
|
|
||||||
}
|
|
||||||
return km.VaultClient.KVv2(path).Delete(ctx, keyID)
|
return km.VaultClient.KVv2(path).Delete(ctx, keyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,12 +256,7 @@ func (km *KeyMgr) Keyset(ctx context.Context, keyID string) (*model.Keyset, erro
|
|||||||
return nil, ErrEmptyKeyID
|
return nil, ErrEmptyKeyID
|
||||||
}
|
}
|
||||||
|
|
||||||
var path string
|
path := km.getSecretPath(keyID)
|
||||||
if km.KvVersion == "v2" {
|
|
||||||
path = fmt.Sprintf("secret/data/private_keys/%s", keyID)
|
|
||||||
} else {
|
|
||||||
path = fmt.Sprintf("secret/private_keys/%s", keyID)
|
|
||||||
}
|
|
||||||
|
|
||||||
secret, err := km.VaultClient.Logical().Read(path)
|
secret, err := km.VaultClient.Logical().Read(path)
|
||||||
if err != nil || secret == nil {
|
if err != nil || secret == nil {
|
||||||
|
|||||||
@@ -636,7 +636,7 @@ func TestStorePrivateKeysFailure(t *testing.T) {
|
|||||||
keyID: "mykeyid",
|
keyID: "mykeyid",
|
||||||
keys: keys,
|
keys: keys,
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
expectedErr: "failed to store secret in Vault: Error making API request",
|
expectedErr: "failed to store secret in Vault at path secret/keys/mykeyid: Error making API request.",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,14 +699,14 @@ func TestDeletePrivateKeys(t *testing.T) {
|
|||||||
name: "v1 delete",
|
name: "v1 delete",
|
||||||
kvVersion: "v1",
|
kvVersion: "v1",
|
||||||
keyID: "key123",
|
keyID: "key123",
|
||||||
wantPath: "/v1/secret/private_keys/key123/data/key123",
|
wantPath: "/v1/secret/keys/key123/data/key123",
|
||||||
wantErr: nil,
|
wantErr: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "v2 delete",
|
name: "v2 delete",
|
||||||
kvVersion: "v2",
|
kvVersion: "v2",
|
||||||
keyID: "key123",
|
keyID: "key123",
|
||||||
wantPath: "/v1/secret/data/private_keys/key123/data/key123",
|
wantPath: "/v1/secret/data/keys/key123/data/key123",
|
||||||
wantErr: nil,
|
wantErr: nil,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -759,9 +759,8 @@ func setupMockVaultServer(t *testing.T, kvVersion, keyID string, success bool) *
|
|||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
// Check that request path is expected
|
expectedPathV1 := fmt.Sprintf("/v1/secret/keys/%s", keyID)
|
||||||
expectedPathV1 := fmt.Sprintf("/v1/secret/private_keys/%s", keyID)
|
expectedPathV2 := fmt.Sprintf("/v1/secret/data/keys/%s", keyID)
|
||||||
expectedPathV2 := fmt.Sprintf("/v1/secret/data/private_keys/%s", keyID)
|
|
||||||
|
|
||||||
if (kvVersion == "v2" && r.URL.Path != expectedPathV2) || (kvVersion != "v2" && r.URL.Path != expectedPathV1) {
|
if (kvVersion == "v2" && r.URL.Path != expectedPathV2) || (kvVersion != "v2" && r.URL.Path != expectedPathV1) {
|
||||||
http.Error(w, "not found", http.StatusNotFound)
|
http.Error(w, "not found", http.StatusNotFound)
|
||||||
@@ -769,14 +768,18 @@ func setupMockVaultServer(t *testing.T, kvVersion, keyID string, success bool) *
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !success {
|
if !success {
|
||||||
// Simulate Vault error or not found
|
|
||||||
http.Error(w, `{"errors":["key not found"]}`, http.StatusNotFound)
|
http.Error(w, `{"errors":["key not found"]}`, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Success response JSON, different for v1 and v2
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
if kvVersion == "v2" {
|
if kvVersion == "v2" {
|
||||||
resp := fmt.Sprintf(`{
|
resp := fmt.Sprintf(`{
|
||||||
|
"request_id": "req-1234",
|
||||||
|
"lease_id": "",
|
||||||
|
"renewable": false,
|
||||||
|
"lease_duration": 0,
|
||||||
"data": {
|
"data": {
|
||||||
"data": {
|
"data": {
|
||||||
"uniqueKeyID": "%s",
|
"uniqueKeyID": "%s",
|
||||||
@@ -784,27 +787,35 @@ func setupMockVaultServer(t *testing.T, kvVersion, keyID string, success bool) *
|
|||||||
"signingPrivateKey": "sign-priv",
|
"signingPrivateKey": "sign-priv",
|
||||||
"encrPublicKey": "encr-pub",
|
"encrPublicKey": "encr-pub",
|
||||||
"encrPrivateKey": "encr-priv"
|
"encrPrivateKey": "encr-priv"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"created_time": "2025-05-28T00:00:00Z",
|
||||||
|
"deletion_time": "",
|
||||||
|
"destroyed": false,
|
||||||
|
"version": 1
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"warnings": null,
|
||||||
|
"auth": null
|
||||||
}`, keyID)
|
}`, keyID)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Write([]byte(resp))
|
||||||
if _, err := w.Write([]byte(resp)); err != nil {
|
|
||||||
t.Fatalf("failed to write response: %v", err)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
resp := fmt.Sprintf(`{
|
resp := fmt.Sprintf(`{
|
||||||
|
"request_id": "req-1234",
|
||||||
|
"lease_id": "",
|
||||||
|
"renewable": false,
|
||||||
|
"lease_duration": 0,
|
||||||
"data": {
|
"data": {
|
||||||
"uniqueKeyID": "%s",
|
"uniqueKeyID": "%s",
|
||||||
"signingPublicKey": "sign-pub",
|
"signingPublicKey": "sign-pub",
|
||||||
"signingPrivateKey": "sign-priv",
|
"signingPrivateKey": "sign-priv",
|
||||||
"encrPublicKey": "encr-pub",
|
"encrPublicKey": "encr-pub",
|
||||||
"encrPrivateKey": "encr-priv"
|
"encrPrivateKey": "encr-priv"
|
||||||
}
|
},
|
||||||
|
"warnings": null,
|
||||||
|
"auth": null
|
||||||
}`, keyID)
|
}`, keyID)
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Write([]byte(resp))
|
||||||
if _, err := w.Write([]byte(resp)); err != nil {
|
|
||||||
t.Fatalf("failed to write response: %v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user