Skip to content

Commit 7356f77

Browse files
Pre receive hook feature for secret scan(AST-89345) (#1146)
* Moved to common hooks place * removed common hooks code * Added pre receive commands * Adding the commit version of secret detection # Conflicts: # go.mod # Conflicts: # go.sum # Conflicts: # go.sum * Added pre receive in Hooks doc * formatted * typo changes * formatted the file * Adding secret detection to depgaurd allow list * removed whitespace * formatted with gofmt * indentation * indentation * indentation * url and formatting fixes * indentation alignment * Unit and integration tests * lint issues fixed * formatted unit test file * setting global config git * changing cx path * adjusting cx path * check if cx path exist * check if cx path exist * added cxPath * Adding githubUser and email * renaming functions * url and formatting fixes * indentation alignment * Unit and integration tests * lint issues fixed * formatted unit test file * setting global config git * changing cx path * adjusting cx path * check if cx path exist * check if cx path exist * added cxPath * Adding githubUser and email * renaming functions * removed the git username * using github actor * go mod file updated * Added additional tests for coverage * secret detection version upgrade * updegraded the version * updegraded the version * updegraded the version * added latest version of secret detection 1.2.1 * pre receive validate command * updated the versions * formatted files * formatted imports * reverted the changed manifest parser version back to main * changed the help text * removed usused go sum
1 parent ca7da82 commit 7356f77

File tree

14 files changed

+548
-57
lines changed

14 files changed

+548
-57
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ jobs:
8989
BITBUCKET_USERNAME: ${{ secrets.BITBUCKET_USERNAME }}
9090
BITBUCKET_PASSWORD: ${{ secrets.BITBUCKET_PASSWORD }}
9191
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
92+
GITHUB_ACTOR: ${{ github.actor }}
9293
PR_BITBUCKET_TOKEN: ${{ secrets.PR_BITBUCKET_TOKEN }}
9394
PR_BITBUCKET_NAMESPACE: "AstSystemTest"
9495
PR_BITBUCKET_REPO_NAME: "cliIntegrationTest"

.golangci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ linters-settings:
4949
- github.com/CheckmarxDev/containers-resolver/pkg/containerResolver
5050
- github.com/Checkmarx/manifest-parser/pkg/parser/models
5151
- github.com/Checkmarx/manifest-parser/pkg/parser
52+
- github.com/Checkmarx/secret-detection/pkg/hooks/pre-commit
53+
- github.com/Checkmarx/secret-detection/pkg/hooks/pre-receive
5254
- github.com/Checkmarx/gen-ai-prompts/prompts/sast_result_remediation
5355
- github.com/spf13/viper
5456
- github.com/checkmarx/2ms/v3/lib/reporting

go.mod

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/Checkmarx/gen-ai-prompts v0.0.0-20240807143411-708ceec12b63
99
github.com/Checkmarx/gen-ai-wrapper v1.0.2
1010
github.com/Checkmarx/manifest-parser v0.1.0
11-
github.com/Checkmarx/secret-detection v0.0.3-0.20250327150305-31c2c3be9edf
11+
github.com/Checkmarx/secret-detection v1.2.1
1212
github.com/MakeNowJust/heredoc v1.0.0
1313
github.com/bouk/monkey v1.0.0
1414
github.com/checkmarx/2ms/v3 v3.21.0
@@ -85,7 +85,6 @@ require (
8585
github.com/charmbracelet/x/ansi v0.8.0 // indirect
8686
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
8787
github.com/charmbracelet/x/term v0.2.1 // indirect
88-
github.com/checkmarx/2ms v1.4.1-0.20250327145719-b78804cb08c7 // indirect
8988
github.com/cloudflare/circl v1.6.1 // indirect
9089
github.com/containerd/cgroups/v3 v3.0.5 // indirect
9190
github.com/containerd/containerd v1.7.27 // indirect
@@ -127,7 +126,7 @@ require (
127126
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
128127
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
129128
github.com/github/go-spdx/v2 v2.3.2 // indirect
130-
github.com/gitleaks/go-gitdiff v0.9.0 // indirect
129+
github.com/gitleaks/go-gitdiff v0.9.1 // indirect
131130
github.com/go-errors/errors v1.5.1 // indirect
132131
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
133132
github.com/go-git/go-billy/v5 v5.6.2 // indirect

go.sum

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ github.com/Checkmarx/gen-ai-wrapper v1.0.2 h1:T6X40+4hYnwfDsvkjWs9VIcE6s1O+8DUu0
7777
github.com/Checkmarx/gen-ai-wrapper v1.0.2/go.mod h1:xwRLefezwNNnRGu1EjGS6wNiR9FVV/eP9D+oXwLViVM=
7878
github.com/Checkmarx/manifest-parser v0.1.0 h1:swnzQpBFbJap7dgoj39oI6MaIqUlnVuBp5VJzeLVevQ=
7979
github.com/Checkmarx/manifest-parser v0.1.0/go.mod h1:hh5FX5FdDieU8CKQEkged4hfOaSylpJzub8PRFXa4kA=
80-
github.com/Checkmarx/secret-detection v0.0.3-0.20250327150305-31c2c3be9edf h1:lKiogedU3WzWBc/xI6Xj1BhX2Gp1QBJj8C+czY7CcaE=
81-
github.com/Checkmarx/secret-detection v0.0.3-0.20250327150305-31c2c3be9edf/go.mod h1:mtAHOm1mHGh7MVu6JdYUyitANsLcHNLUTBIh9pTERNI=
80+
github.com/Checkmarx/secret-detection v1.2.1 h1:Hzpz74dcN/L14Q86ARvPOZpKBnERzGTpy6sl1RXKOTo=
81+
github.com/Checkmarx/secret-detection v1.2.1/go.mod h1:kbXbtIQisDdB/TNuV7r9HPclEznUyBHLQ5yr7IX7vBQ=
8282
github.com/CycloneDX/cyclonedx-go v0.9.2 h1:688QHn2X/5nRezKe2ueIVCt+NRqf7fl3AVQk+vaFcIo=
8383
github.com/CycloneDX/cyclonedx-go v0.9.2/go.mod h1:vcK6pKgO1WanCdd61qx4bFnSsDJQ6SbM2ZuMIgq86Jg=
8484
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
@@ -217,8 +217,6 @@ github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ
217217
github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
218218
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
219219
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
220-
github.com/checkmarx/2ms v1.4.1-0.20250327145719-b78804cb08c7 h1:COsC3skOJeJaSoCPuhLZ0byRGKm+ZHlyw5qm9ydlab0=
221-
github.com/checkmarx/2ms v1.4.1-0.20250327145719-b78804cb08c7/go.mod h1:Bnd2YSh8LQSc4fHAFN0BKz8LYThB6qHg3Wn/+H+WZ4I=
222220
github.com/checkmarx/2ms/v3 v3.21.0 h1:EcabeDypNMsSidISQbziZ062HjMZQ+Hm/uOJ5AOxK8o=
223221
github.com/checkmarx/2ms/v3 v3.21.0/go.mod h1:e8f4F94MZ+iCetR/G3aw7nXdPe6TgPI92Zzk/NG1l0o=
224222
github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
@@ -372,8 +370,8 @@ github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrP
372370
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
373371
github.com/github/go-spdx/v2 v2.3.2 h1:IfdyNHTqzs4zAJjXdVQfRnxt1XMfycXoHBE2Vsm1bjs=
374372
github.com/github/go-spdx/v2 v2.3.2/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ=
375-
github.com/gitleaks/go-gitdiff v0.9.0 h1:SHAU2l0ZBEo8g82EeFewhVy81sb7JCxW76oSPtR/Nqg=
376-
github.com/gitleaks/go-gitdiff v0.9.0/go.mod h1:pKz0X4YzCKZs30BL+weqBIG7mx0jl4tF1uXV9ZyNvrA=
373+
github.com/gitleaks/go-gitdiff v0.9.1 h1:ni6z6/3i9ODT685OLCTf+s/ERlWUNWQF4x1pvoNICw0=
374+
github.com/gitleaks/go-gitdiff v0.9.1/go.mod h1:pKz0X4YzCKZs30BL+weqBIG7mx0jl4tF1uXV9ZyNvrA=
377375
github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4=
378376
github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3q+ihjqxC9u0=
379377
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=

internal/commands/hooks.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package commands
2+
3+
import (
4+
"github.com/MakeNowJust/heredoc"
5+
"github.com/checkmarx/ast-cli/internal/params"
6+
"github.com/checkmarx/ast-cli/internal/wrappers"
7+
"github.com/pkg/errors"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
// NewHooksCommand creates the hooks command with pre-commit subcommand
12+
func NewHooksCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command {
13+
hooksCmd := &cobra.Command{
14+
Use: "hooks",
15+
Short: "Manage Git hooks",
16+
Long: "The hooks command enables the ability to manage Git hooks for Checkmarx One.",
17+
Example: heredoc.Doc(
18+
`
19+
$ cx hooks pre-commit secrets-install-git-hook
20+
$ cx hooks pre-commit secrets-scan
21+
$ cx hooks pre-receive secrets-scan
22+
`,
23+
),
24+
Annotations: map[string]string{
25+
"command:doc": heredoc.Doc(
26+
`
27+
https://checkmarx.com/resource/documents/en/34965-365503-hooks.html
28+
`,
29+
),
30+
},
31+
}
32+
33+
// Add pre-commit and pre-receive subcommand
34+
hooksCmd.AddCommand(PreCommitCommand(jwtWrapper))
35+
hooksCmd.AddCommand(PreReceiveCommand(jwtWrapper))
36+
37+
return hooksCmd
38+
}
39+
40+
func validateLicense(jwtWrapper wrappers.JWTWrapper) error {
41+
allowed, err := jwtWrapper.IsAllowedEngine(params.EnterpriseSecretsLabel)
42+
if err != nil {
43+
return errors.Wrapf(err, "Failed checking license")
44+
}
45+
if !allowed {
46+
return errors.New("Error: License validation failed. Please verify your CxOne license includes Enterprise Secrets.")
47+
}
48+
return nil
49+
}

internal/commands/pre-receive.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package commands
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
prereceive "github.com/Checkmarx/secret-detection/pkg/hooks/pre-receive"
8+
"github.com/MakeNowJust/heredoc"
9+
"github.com/checkmarx/ast-cli/internal/params"
10+
"github.com/checkmarx/ast-cli/internal/wrappers"
11+
"github.com/spf13/cobra"
12+
)
13+
14+
const (
15+
SuccessFullSecretsLicenceValidation = "License for pre-receive secret detection has been validated successfully"
16+
)
17+
18+
func PreReceiveCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command {
19+
preReceiveCmd := &cobra.Command{
20+
Use: "pre-receive",
21+
Short: "Manage pre-receive hooks and run secret detection scans",
22+
Long: "The pre-receive command is used for managing Git pre-receive hooks for secret detection",
23+
Example: heredoc.Doc(
24+
`
25+
$ cx hooks pre-receive secrets-scan
26+
`,
27+
),
28+
}
29+
preReceiveCmd.AddCommand(scanSecretsPreReceiveCommand())
30+
preReceiveCmd.AddCommand(validateSecretsLicence(jwtWrapper))
31+
32+
return preReceiveCmd
33+
}
34+
35+
func scanSecretsPreReceiveCommand() *cobra.Command {
36+
var configFile string
37+
scanPrereceiveCmd := &cobra.Command{
38+
Use: "secrets-scan",
39+
Short: "Run a pre-receive secret detection scan on the pushed branch",
40+
Long: "Runs pre-receive secret detection scans on each pushed branch that is about to enter the remote git repository",
41+
Example: heredoc.Doc(
42+
`
43+
$ cx hooks pre-receive secrets-scan
44+
$ cx hooks pre-receive secrets-scan --config /path/to/config.yaml
45+
`,
46+
),
47+
RunE: func(cmd *cobra.Command, args []string) error {
48+
return prereceive.Scan(configFile)
49+
},
50+
}
51+
52+
scanPrereceiveCmd.Flags().StringVarP(&configFile, "config", "c", "", "path to config.yaml file")
53+
54+
return scanPrereceiveCmd
55+
}
56+
57+
func validateSecretsLicence(jwtWrapper wrappers.JWTWrapper) *cobra.Command {
58+
validateLicence := &cobra.Command{
59+
Use: "validate",
60+
Short: "Validates the license for pre-receive secret detection",
61+
Long: "Validates the license for pre-receive secret detection",
62+
Example: heredoc.Doc(
63+
`
64+
$ cx hooks pre-receive validate
65+
`,
66+
),
67+
RunE: checkLicence(jwtWrapper),
68+
}
69+
return validateLicence
70+
}
71+
72+
func checkLicence(jwtWrapper wrappers.JWTWrapper) func(cmd *cobra.Command, args []string) error {
73+
return func(cmd *cobra.Command, args []string) error {
74+
isAllowed, err := jwtWrapper.IsAllowedEngine(params.EnterpriseSecretsLabel)
75+
if err != nil {
76+
log.Fatalf("%s: %s", "Failed the licence check", err)
77+
}
78+
if !isAllowed {
79+
log.Fatalf("Error: License validation failed. Please ensure that your Checkmarx One license includes Enterprise Secrets")
80+
}
81+
_, _ = fmt.Fprintln(cmd.OutOrStdout(), SuccessFullSecretsLicenceValidation)
82+
return nil
83+
}
84+
}

internal/commands/pre_commit.go

Lines changed: 9 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,19 @@ import (
44
"fmt"
55
"strings"
66

7-
precommit "github.com/Checkmarx/secret-detection/pkg/hooks"
7+
precommit "github.com/Checkmarx/secret-detection/pkg/hooks/pre-commit"
88
"github.com/MakeNowJust/heredoc"
9-
"github.com/checkmarx/ast-cli/internal/params"
109
"github.com/checkmarx/ast-cli/internal/wrappers"
11-
"github.com/pkg/errors"
1210
"github.com/spf13/cobra"
1311
)
1412

15-
// NewHooksCommand creates the hooks command with pre-commit subcommand
16-
func NewHooksCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command {
17-
hooksCmd := &cobra.Command{
18-
Use: "hooks",
19-
Short: "Manage Git hooks",
20-
Long: "The hooks command enables the ability to manage Git hooks for Checkmarx One",
21-
Example: heredoc.Doc(
22-
`
23-
$ cx hooks pre-commit secrets-install-git-hook
24-
$ cx hooks pre-commit secrets-scan
25-
`,
26-
),
27-
Annotations: map[string]string{
28-
"command:doc": heredoc.Doc(
29-
`
30-
https://checkmarx.com/resource/documents/en/xxxxx-xxxxx-hooks.html
31-
`,
32-
),
33-
},
34-
}
35-
36-
// Add pre-commit subcommand
37-
hooksCmd.AddCommand(PreCommitCommand(jwtWrapper))
38-
39-
return hooksCmd
40-
}
41-
4213
// PreCommitCommand creates the pre-commit subcommand
14+
4315
func PreCommitCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command {
4416
preCommitCmd := &cobra.Command{
4517
Use: "pre-commit",
4618
Short: "Manage pre-commit hooks and run secret detection scans",
47-
Long: "The pre-commit command enables the ability to manage Git pre-commit hooks for secret detection",
19+
Long: "The pre-commit command enables the ability to manage Git pre-commit hooks for secret detection.",
4820
Example: heredoc.Doc(
4921
`
5022
$ cx hooks pre-commit secrets-install-git-hook
@@ -65,22 +37,12 @@ func PreCommitCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command {
6537
}
6638

6739
// / validateLicense verifies the user has the required license for secret detection
68-
func validateLicense(jwtWrapper wrappers.JWTWrapper) error {
69-
allowed, err := jwtWrapper.IsAllowedEngine(params.EnterpriseSecretsLabel)
70-
if err != nil {
71-
return errors.Wrapf(err, "Failed checking license")
72-
}
73-
if !allowed {
74-
return errors.New("Error: License validation failed. Please verify your CxOne license includes Enterprise Secrets.")
75-
}
76-
return nil
77-
}
7840

7941
func secretsInstallGitHookCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command {
8042
cmd := &cobra.Command{
8143
Use: "secrets-install-git-hook",
8244
Short: "Install the pre-commit hook",
83-
Long: "Install the pre-commit hook for secret detection in your repository",
45+
Long: "Install the pre-commit hook for secret detection in your repository.",
8446
Example: heredoc.Doc(
8547
`
8648
$ cx hooks pre-commit secrets-install-git-hook
@@ -102,7 +64,7 @@ func secretsUninstallGitHookCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Comma
10264
cmd := &cobra.Command{
10365
Use: "secrets-uninstall-git-hook",
10466
Short: "Uninstall the pre-commit hook",
105-
Long: "Uninstall the pre-commit hook for secret detection from your repository",
67+
Long: "Uninstall the pre-commit hook for secret detection from your repository.",
10668
Example: heredoc.Doc(
10769
`
10870
$ cx hooks pre-commit secrets-uninstall-git-hook
@@ -121,7 +83,7 @@ func secretsUpdateGitHookCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command
12183
cmd := &cobra.Command{
12284
Use: "secrets-update-git-hook",
12385
Short: "Update the pre-commit hook",
124-
Long: "Update the pre-commit hook for secret detection to the latest version",
86+
Long: "Update the pre-commit hook for secret detection to the latest version.",
12587
Example: heredoc.Doc(
12688
`
12789
$ cx hooks pre-commit secrets-update-git-hook
@@ -143,7 +105,7 @@ func secretsScanCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command {
143105
return &cobra.Command{
144106
Use: "secrets-scan",
145107
Short: "Run the real-time secret detection scan",
146-
Long: "Run a real-time scan to detect secrets in your code before committing",
108+
Long: "Run a real-time scan to detect secrets in your code before committing.",
147109
Example: heredoc.Doc(
148110
`
149111
$ cx hooks pre-commit secrets-scan
@@ -165,7 +127,7 @@ func secretsIgnoreCommand(jwtWrapper wrappers.JWTWrapper) *cobra.Command {
165127
cmd := &cobra.Command{
166128
Use: "secrets-ignore",
167129
Short: "Ignore one or more detected secrets",
168-
Long: "Add detected secrets to the ignore list so they won't be flagged in future scans",
130+
Long: "Add detected secrets to the ignore list so they won't be flagged in future scans.",
169131
Example: heredoc.Doc(
170132
`
171133
$ cx hooks pre-commit secrets-ignore --resultIds=a1b2c3d4e5f6,f1e2d3c4b5a6
@@ -209,7 +171,7 @@ func secretsHelpCommand() *cobra.Command {
209171
return &cobra.Command{
210172
Use: "secrets-help",
211173
Short: "Display help for pre-commit commands",
212-
Long: "Display detailed information about the pre-commit commands and options",
174+
Long: "Display detailed information about the pre-commit commands and options.",
213175
RunE: func(cmd *cobra.Command, args []string) error {
214176
return cmd.Parent().Help()
215177
},
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package commands
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"github.com/checkmarx/ast-cli/internal/wrappers/mock"
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestPreReceiveCommand(t *testing.T) {
13+
mockJWT := &mock.JWTMockWrapper{}
14+
cmd := PreReceiveCommand(mockJWT)
15+
assert.NotNil(t, cmd)
16+
assert.Equal(t, "pre-receive", cmd.Use)
17+
subCmds := cmd.Commands()
18+
subCmdName := make([]string, len(subCmds))
19+
for i, subCmd := range subCmds {
20+
subCmdName[i] = subCmd.Name()
21+
}
22+
expectedSubCmds := []string{
23+
"secrets-scan",
24+
}
25+
26+
for i, expectedSubCmd := range expectedSubCmds {
27+
assert.Contains(t, expectedSubCmd, subCmdName[i])
28+
}
29+
}
30+
31+
func TestPreReceiveCommand_withConfig(t *testing.T) {
32+
cmd := createASTTestCommand()
33+
workDir, _ := os.Getwd()
34+
configFile := filepath.Join(workDir, "config.yaml")
35+
_ = os.WriteFile(configFile, []byte(""), 0644)
36+
err := executeTestCommand(
37+
cmd,
38+
"hooks", "pre-receive", "secrets-scan", "--config", "config.yaml",
39+
)
40+
assert.Nil(t, err)
41+
}
42+
43+
func TestPreReceiveCommand_withWrongFlagConfig(t *testing.T) {
44+
err := execCmdNotNilAssertion(
45+
t,
46+
"hooks", "pre-receive", "secrets-scan", "--cf", "/path/config.yaml",
47+
)
48+
assert.NotNil(t, err)
49+
}
50+
51+
func TestPreReceiveCommand_Licence_success(t *testing.T) {
52+
cmd := createASTTestCommand()
53+
err := executeTestCommand(
54+
cmd,
55+
"hooks", "pre-receive", "validate")
56+
assert.Nil(t, err)
57+
}

0 commit comments

Comments
 (0)