Skip to content

Commit 421eb77

Browse files
committed
Added smoke test for validation
1 parent 6045040 commit 421eb77

3 files changed

Lines changed: 175 additions & 3 deletions

File tree

system-tests/tests/smoke/cre/v2_vault_don_test.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,29 @@ func ExecuteVaultTest(t *testing.T, testEnv *ttypes.TestEnvironment) {
118118
executeVaultSecretsDeleteTest(t, secretID, owner, gwURL, []string{"alt"}, sc, wfReg)
119119
executeVaultSecretsGetNotFoundViaWorkflowTest(t, subEnv, "bdela1", secretID, "alt", ulCh, bmCh)
120120
})
121+
122+
t.Run("identifier_validation", func(t *testing.T) {
123+
if parallelEnabled {
124+
t.Parallel()
125+
}
126+
subEnv := t_helpers.SetupTestEnvironmentWithPerTestKeys(t, testEnv.TestConfig)
127+
sc := subEnv.CreEnvironment.Blockchains[0].(*evm.Blockchain).SethClient
128+
owner := sc.MustGetRootKeyAddress().Hex()
129+
wfRegAddr := crecontracts.MustGetAddressFromDataStore(subEnv.CreEnvironment.CldfEnvironment.DataStore, subEnv.CreEnvironment.Blockchains[0].ChainSelector(), keystone_changeset.WorkflowRegistry.String(), subEnv.CreEnvironment.ContractVersions[keystone_changeset.WorkflowRegistry.String()], "")
130+
wfReg, err := workflow_registry_v2_wrapper.NewWorkflowRegistry(common.HexToAddress(wfRegAddr), sc.Client)
131+
require.NoError(t, err)
132+
require.NoError(t, creworkflow.LinkOwner(sc, common.HexToAddress(wfRegAddr), subEnv.CreEnvironment.ContractVersions[keystone_changeset.WorkflowRegistry.String()]))
133+
ulCh := make(chan *workflowevents.UserLogs, 1000)
134+
bmCh := make(chan *commonevents.BaseMessage, 1000)
135+
sink := t_helpers.StartChipTestSink(t, t_helpers.GetPublishFn(testLogger, ulCh, bmCh))
136+
t.Cleanup(func() {
137+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
138+
defer cancel()
139+
t_helpers.ShutdownChipSinkWithDrain(ctx, sink, ulCh, bmCh)
140+
})
141+
executeVaultSecretsIdentifierValidationTest(t, owner, gwURL, sc, wfReg)
142+
executeVaultSecretsGetInvalidIdentifierViaWorkflowTest(t, subEnv, "vget1", ulCh, bmCh)
143+
})
121144
}
122145

123146
func executeVaultSecretsCreateTest(t *testing.T, encryptedSecret, secretID, owner, gatewayURL string, namespaces []string, sethClient *seth.Client, wfRegistryContract *workflow_registry_v2_wrapper.WorkflowRegistry) {
@@ -619,3 +642,118 @@ func allowlistRequest(t *testing.T, owner string, request jsonrpc.Request[json.R
619642
framework.L.Info().Msgf("Allowlisted request digestHexStr: %s, owner: %s, expiry: %d", hex.EncodeToString(req.RequestDigest[:]), req.Owner.Hex(), req.ExpiryTimestamp)
620643
}
621644
}
645+
646+
func executeVaultSecretsGetInvalidIdentifierViaWorkflowTest(
647+
t *testing.T, testEnv *ttypes.TestEnvironment,
648+
workflowBaseName string,
649+
userLogsCh chan *workflowevents.UserLogs, baseMessageCh chan *commonevents.BaseMessage,
650+
) {
651+
testLogger := framework.L
652+
testLogger.Info().Msg("Verifying get secret is rejected for invalid identifier via workflow...")
653+
654+
const workflowFileLocation = "./vaultsecret/main.go"
655+
656+
workflowName := t_helpers.UniqueWorkflowName(testEnv, workflowBaseName)
657+
workflowID := t_helpers.CompileAndDeployWorkflow(t, testEnv, testLogger, workflowName, &vaultsecret_config.Config{
658+
SecretKey: "invalid-key-with-hyphens", // hyphen not in [a-zA-Z0-9_]; tests invalid key
659+
SecretNamespace: "main",
660+
SecretKey2: "validkey",
661+
SecretNamespace2: "invalid-namespace-with-hyphens", // hyphen not in [a-zA-Z0-9_]; tests invalid namespace
662+
ExpectInvalidIdentifier: true,
663+
}, workflowFileLocation)
664+
665+
// Both invalid-key and invalid-namespace checks run in the same cron trigger; a single
666+
// success log is emitted only after both GetSecret calls are correctly rejected.
667+
t_helpers.WatchWorkflowLogs(t, testLogger, userLogsCh, baseMessageCh, t_helpers.WorkflowEngineInitErrorLog,
668+
"Vault get correctly rejected invalid identifier", 4*time.Minute, t_helpers.WithUserLogWorkflowID(workflowID))
669+
testLogger.Info().Msg("Vault get invalid identifier via workflow test completed")
670+
}
671+
672+
// executeVaultSecretsIdentifierValidationTest verifies that the gateway rejects requests whose
673+
// secret identifiers contain characters outside the allowed alphanumeric+underscore set.
674+
// All four management request types (create, update, delete, list) are exercised across
675+
// invalid key, invalid namespace, and invalid owner cases. Positive-path coverage is provided
676+
// by basic_crud; this test focuses only on rejection behaviour.
677+
func executeVaultSecretsIdentifierValidationTest(t *testing.T, owner, gatewayURL string, sethClient *seth.Client, wfRegistryContract *workflow_registry_v2_wrapper.WorkflowRegistry) {
678+
t.Helper()
679+
680+
const (
681+
validKey = "validkey"
682+
invalidKey = "invalid-key-with-hyphens" // hyphen not in [a-zA-Z0-9_]
683+
validNamespace = "main"
684+
invalidNamespace = "invalid-namespace-hyphens" // hyphen not in [a-zA-Z0-9_]
685+
invalidOwner = "invalid-owner-with-hyphens" // hyphen not in [a-zA-Z0-9_]
686+
)
687+
// dummyEncrypted is a placeholder; identifier validation fires before ciphertext checks.
688+
const dummyEncrypted = "deadbeef"
689+
690+
sendWriteAndAssert := func(t *testing.T, method, caseName string, secret *vault_helpers.EncryptedSecret) {
691+
t.Helper()
692+
uniqueRequestID := uuid.New().String()
693+
var body []byte
694+
var err error
695+
switch method {
696+
case vaulttypes.MethodSecretsCreate:
697+
body, err = json.Marshal(vault_helpers.CreateSecretsRequest{RequestId: uniqueRequestID, EncryptedSecrets: []*vault_helpers.EncryptedSecret{secret}})
698+
case vaulttypes.MethodSecretsUpdate:
699+
body, err = json.Marshal(vault_helpers.UpdateSecretsRequest{RequestId: uniqueRequestID, EncryptedSecrets: []*vault_helpers.EncryptedSecret{secret}})
700+
case vaulttypes.MethodSecretsDelete:
701+
body, err = json.Marshal(vault_helpers.DeleteSecretsRequest{RequestId: uniqueRequestID, Ids: []*vault_helpers.SecretIdentifier{secret.Id}})
702+
}
703+
require.NoError(t, err)
704+
bodyJSON := json.RawMessage(body)
705+
req := jsonrpc.Request[json.RawMessage]{Version: jsonrpc.JsonRpcVersion, ID: uniqueRequestID, Method: method, Params: &bodyJSON}
706+
allowlistRequest(t, owner, req, sethClient, wfRegistryContract)
707+
reqBody, err := json.Marshal(req)
708+
require.NoError(t, err)
709+
_, respBody := sendVaultRequestToGateway(t, gatewayURL, reqBody)
710+
require.Contains(t, string(respBody), "alphanumeric", "[%s] expected alphanumeric rejection for %s", method, caseName)
711+
framework.L.Info().Msgf("[%s] %s correctly rejected: %s", method, caseName, string(respBody))
712+
}
713+
714+
type writeCase struct {
715+
name string
716+
key, own, ns string
717+
}
718+
writeCases := []writeCase{
719+
{"invalid key", invalidKey, owner, validNamespace},
720+
{"invalid namespace", validKey, owner, invalidNamespace},
721+
{"invalid owner", validKey, invalidOwner, validNamespace},
722+
}
723+
724+
for _, op := range []string{vaulttypes.MethodSecretsCreate, vaulttypes.MethodSecretsUpdate, vaulttypes.MethodSecretsDelete} {
725+
framework.L.Info().Msgf("Testing identifier validation for %s request...", op)
726+
for _, tc := range writeCases {
727+
sendWriteAndAssert(t, op, tc.name, &vault_helpers.EncryptedSecret{
728+
Id: &vault_helpers.SecretIdentifier{Key: tc.key, Owner: tc.own, Namespace: tc.ns},
729+
EncryptedValue: dummyEncrypted,
730+
})
731+
}
732+
}
733+
734+
type listCase struct {
735+
name string
736+
own, ns string
737+
}
738+
listCases := []listCase{
739+
{"invalid namespace", owner, invalidNamespace},
740+
{"invalid owner", invalidOwner, validNamespace},
741+
}
742+
743+
framework.L.Info().Msg("Testing identifier validation for list request...")
744+
for _, tc := range listCases {
745+
uniqueRequestID := uuid.New().String()
746+
body, err := json.Marshal(vault_helpers.ListSecretIdentifiersRequest{RequestId: uniqueRequestID, Owner: tc.own, Namespace: tc.ns})
747+
require.NoError(t, err)
748+
bodyJSON := json.RawMessage(body)
749+
req := jsonrpc.Request[json.RawMessage]{Version: jsonrpc.JsonRpcVersion, ID: uniqueRequestID, Method: vaulttypes.MethodSecretsList, Params: &bodyJSON}
750+
allowlistRequest(t, owner, req, sethClient, wfRegistryContract)
751+
reqBody, err := json.Marshal(req)
752+
require.NoError(t, err)
753+
_, respBody := sendVaultRequestToGateway(t, gatewayURL, reqBody)
754+
require.Contains(t, string(respBody), "alphanumeric", "[list] expected alphanumeric rejection for %s", tc.name)
755+
framework.L.Info().Msgf("[list] %s correctly rejected: %s", tc.name, string(respBody))
756+
}
757+
758+
framework.L.Info().Msg("All identifier validation checks passed")
759+
}
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package config
22

33
type Config struct {
4-
SecretKey string `yaml:"secretKey"`
5-
SecretNamespace string `yaml:"secretNamespace"`
6-
ExpectNotFound bool `yaml:"expectNotFound"`
4+
SecretKey string `yaml:"secretKey"`
5+
SecretNamespace string `yaml:"secretNamespace"`
6+
SecretKey2 string `yaml:"secretKey2"`
7+
SecretNamespace2 string `yaml:"secretNamespace2"`
8+
ExpectNotFound bool `yaml:"expectNotFound"`
9+
ExpectInvalidIdentifier bool `yaml:"expectInvalidIdentifier"`
710
}

system-tests/tests/smoke/cre/vaultsecret/main.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,37 @@ func onTrigger(cfg config.Config, runtime cre.Runtime, _ *cron.Payload) (string,
6161
return "", fmt.Errorf("expected secret key=%s to be deleted, but it was still found", cfg.SecretKey)
6262
}
6363

64+
if cfg.ExpectInvalidIdentifier {
65+
if err == nil {
66+
runtime.Logger().Error("Expected identifier validation to fail but GetSecret succeeded", "secretKey", cfg.SecretKey)
67+
return "", fmt.Errorf("expected identifier validation failure for key=%s, but secret was retrieved", cfg.SecretKey)
68+
}
69+
runtime.Logger().Info("Vault get correctly rejected invalid identifier", "secretKey", cfg.SecretKey, "error", err)
70+
71+
if cfg.SecretKey2 != "" || cfg.SecretNamespace2 != "" {
72+
key2 := cfg.SecretKey2
73+
if key2 == "" {
74+
key2 = cfg.SecretKey
75+
}
76+
ns2 := cfg.SecretNamespace2
77+
if ns2 == "" {
78+
ns2 = cfg.SecretNamespace
79+
}
80+
_, err2 := runtime.GetSecret(&cre.SecretRequest{
81+
Namespace: ns2,
82+
Id: key2,
83+
}).Await()
84+
if err2 == nil {
85+
runtime.Logger().Error("Expected identifier validation to fail for secondary identifier but GetSecret succeeded",
86+
"secretKey2", key2, "secretNamespace2", ns2)
87+
return "", fmt.Errorf("expected identifier validation failure for key=%s namespace=%s, but secret was retrieved", key2, ns2)
88+
}
89+
runtime.Logger().Info("Vault get correctly rejected invalid identifier", "secretKey", key2, "error", err2)
90+
}
91+
92+
return fmt.Sprintf("Invalid identifier correctly rejected: key=%s", cfg.SecretKey), nil
93+
}
94+
6495
if err != nil {
6596
runtime.Logger().Error("Failed to get secret via workflow", "error", err)
6697
return "", fmt.Errorf("failed to get secret: %w", err)

0 commit comments

Comments
 (0)