Skip to content

Commit 7c04d55

Browse files
Merge branch 'main' into feature/sca-triage
2 parents 06ed336 + e7376a7 commit 7c04d55

File tree

10 files changed

+101
-41
lines changed

10 files changed

+101
-41
lines changed

internal/commands/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ func NewAstCLI(
215215
prWrapper,
216216
learnMoreWrapper,
217217
tenantWrapper,
218+
jwtWrapper,
218219
chatWrapper,
219220
policyWrapper,
220221
scansWrapper,

internal/commands/scan.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,9 +1371,12 @@ func isScorecardRunnable(isScsEnginesFlagSet, scsScorecardSelected bool, scsRepo
13711371

13721372
func addSCSScan(cmd *cobra.Command, resubmitConfig []wrappers.Config, scsLicensingV2, hasRepositoryHealthLicense,
13731373
hasSecretDetectionLicense, hasEnterpriseSecretsLicense bool) (map[string]interface{}, error) {
1374-
scsEnabled := scanTypeEnabled(commonParams.ScsType)
1375-
scsScorecardAllowed := isScsScorecardAllowed(scsLicensingV2, hasRepositoryHealthLicense, scsEnabled)
1376-
scsSecretDetectionAllowed := isScsSecretDetectionAllowed(scsLicensingV2, hasSecretDetectionLicense, hasEnterpriseSecretsLicense, scsEnabled)
1374+
scsEnabled := isScsEnabled(scsLicensingV2)
1375+
if !scsEnabled {
1376+
return nil, nil
1377+
}
1378+
scsScorecardAllowed := isScsScorecardAllowed(scsLicensingV2, hasRepositoryHealthLicense)
1379+
scsSecretDetectionAllowed := isScsSecretDetectionAllowed(scsLicensingV2, hasSecretDetectionLicense, hasEnterpriseSecretsLicense)
13771380
if !scsScorecardAllowed && !scsSecretDetectionAllowed {
13781381
return nil, nil
13791382
}
@@ -1429,18 +1432,26 @@ func addSCSScan(cmd *cobra.Command, resubmitConfig []wrappers.Config, scsLicensi
14291432
return scsMapConfig, nil
14301433
}
14311434

1432-
func isScsScorecardAllowed(scsLicensingV2, hasRepositoryHealthLicense, hasScsLicense bool) bool {
1435+
func isScsEnabled(scsLicensingV2 bool) bool {
1436+
if scsLicensingV2 {
1437+
return scanTypeEnabled(commonParams.ScsType) || scanTypeEnabled(commonParams.SecretDetectionType) ||
1438+
scanTypeEnabled(commonParams.RepositoryHealthType)
1439+
}
1440+
return scanTypeEnabled(commonParams.ScsType)
1441+
}
1442+
1443+
func isScsScorecardAllowed(scsLicensingV2, hasRepositoryHealthLicense bool) bool {
14331444
if scsLicensingV2 {
14341445
return hasRepositoryHealthLicense
14351446
}
1436-
return hasScsLicense
1447+
return true
14371448
}
14381449

1439-
func isScsSecretDetectionAllowed(scsLicensingV2, hasSecretDetectionLicense, hasEnterpriseSecretsLicense, hasScsLicense bool) bool {
1450+
func isScsSecretDetectionAllowed(scsLicensingV2, hasSecretDetectionLicense, hasEnterpriseSecretsLicense bool) bool {
14401451
if scsLicensingV2 {
14411452
return hasSecretDetectionLicense
14421453
}
1443-
return hasScsLicense && hasEnterpriseSecretsLicense
1454+
return hasEnterpriseSecretsLicense
14441455
}
14451456

14461457
func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper) error {

internal/commands/scan_test.go

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3453,21 +3453,13 @@ func TestIsScsScorecardAllowed(t *testing.T) {
34533453
name string
34543454
scsLicensingV2 bool
34553455
hasRepositoryHealthLicense bool
3456-
hasScsLicense bool
34573456
expectedAllowed bool
34583457
}{
34593458
{
3460-
name: "scsLicensingV2 disabled and has scs license",
3459+
name: "scsLicensingV2 disabled",
34613460
scsLicensingV2: false,
3462-
hasScsLicense: true,
34633461
expectedAllowed: true,
34643462
},
3465-
{
3466-
name: "scsLicensingV2 disabled and does not have scs license",
3467-
scsLicensingV2: false,
3468-
hasScsLicense: false,
3469-
expectedAllowed: false,
3470-
},
34713463
{
34723464
name: "scsLicensingV2 enabled and has repository health license",
34733465
scsLicensingV2: true,
@@ -3484,7 +3476,7 @@ func TestIsScsScorecardAllowed(t *testing.T) {
34843476

34853477
for _, tt := range tests {
34863478
t.Run(tt.name, func(t *testing.T) {
3487-
actualAllowed := isScsScorecardAllowed(tt.scsLicensingV2, tt.hasRepositoryHealthLicense, tt.hasScsLicense)
3479+
actualAllowed := isScsScorecardAllowed(tt.scsLicensingV2, tt.hasRepositoryHealthLicense)
34883480
assert.Equal(t, tt.expectedAllowed, actualAllowed)
34893481
})
34903482
}
@@ -3496,28 +3488,18 @@ func TestIsScsSecretDetectionAllowed(t *testing.T) {
34963488
scsLicensingV2 bool
34973489
hasSecretDetectionLicense bool
34983490
hasEnterpriseSecretsLicense bool
3499-
hasScsLicense bool
35003491
expectedAllowed bool
35013492
}{
35023493
{
3503-
name: "scsLicensingV2 disabled and has scs and enterprise secrets license",
3494+
name: "scsLicensingV2 disabled and has enterprise secrets license",
35043495
scsLicensingV2: false,
35053496
hasEnterpriseSecretsLicense: true,
3506-
hasScsLicense: true,
35073497
expectedAllowed: true,
35083498
},
35093499
{
3510-
name: "scsLicensingV2 disabled and has enterprise secrets but does not have scs license",
3511-
scsLicensingV2: false,
3512-
hasEnterpriseSecretsLicense: true,
3513-
hasScsLicense: false,
3514-
expectedAllowed: false,
3515-
},
3516-
{
3517-
name: "scsLicensingV2 disabled and has scs license but does not have enterprise secrets license",
3500+
name: "scsLicensingV2 disabled but does not have enterprise secrets license",
35183501
scsLicensingV2: false,
35193502
hasEnterpriseSecretsLicense: false,
3520-
hasScsLicense: true,
35213503
expectedAllowed: false,
35223504
},
35233505
{
@@ -3536,7 +3518,7 @@ func TestIsScsSecretDetectionAllowed(t *testing.T) {
35363518

35373519
for _, tt := range tests {
35383520
t.Run(tt.name, func(t *testing.T) {
3539-
actualAllowed := isScsSecretDetectionAllowed(tt.scsLicensingV2, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense, tt.hasScsLicense)
3521+
actualAllowed := isScsSecretDetectionAllowed(tt.scsLicensingV2, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense)
35403522
assert.Equal(t, tt.expectedAllowed, actualAllowed)
35413523
})
35423524
}

internal/commands/util/tenant.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"github.com/spf13/cobra"
1212
)
1313

14-
func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper) *cobra.Command {
14+
func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper, jwtWrapper wrappers.JWTWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper) *cobra.Command {
1515
cmd := &cobra.Command{
1616
Use: "tenant",
1717
Short: "Shows the tenant settings",
@@ -27,7 +27,7 @@ func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper)
2727
`,
2828
),
2929
},
30-
RunE: runTenantCmd(wrapper),
30+
RunE: runTenantCmd(wrapper, jwtWrapper, featureFlagsWrapper),
3131
}
3232
cmd.PersistentFlags().String(
3333
params.FormatFlag,
@@ -40,7 +40,7 @@ func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper)
4040
return cmd
4141
}
4242

43-
func runTenantCmd(wrapper wrappers.TenantConfigurationWrapper) func(cmd *cobra.Command, args []string) error {
43+
func runTenantCmd(wrapper wrappers.TenantConfigurationWrapper, jwtWrapper wrappers.JWTWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper) func(cmd *cobra.Command, args []string) error {
4444
return func(cmd *cobra.Command, args []string) error {
4545
tenantConfigurationResponse, errorModel, err := wrapper.GetTenantConfiguration()
4646
if err != nil {
@@ -52,10 +52,16 @@ func runTenantCmd(wrapper wrappers.TenantConfigurationWrapper) func(cmd *cobra.C
5252
if tenantConfigurationResponse != nil {
5353
format, _ := cmd.Flags().GetString(params.FormatFlag)
5454
tenantConfigurationResponseView := toTenantConfigurationResponseView(tenantConfigurationResponse)
55+
56+
licenseDetails, err := jwtWrapper.GetLicenseDetails(featureFlagsWrapper)
57+
if err == nil {
58+
tenantConfigurationResponseView = appendLicenseDetails(tenantConfigurationResponseView, licenseDetails)
59+
}
60+
5561
if format == "" {
5662
format = defaultFormat
5763
}
58-
err := printer.Print(cmd.OutOrStdout(), tenantConfigurationResponseView, format)
64+
err = printer.Print(cmd.OutOrStdout(), tenantConfigurationResponseView, format)
5965
if err != nil {
6066
return err
6167
}
@@ -76,3 +82,17 @@ func toTenantConfigurationResponseView(response *[]*wrappers.TenantConfiguration
7682
}
7783
return tenantConfigurationResponseView
7884
}
85+
86+
func appendLicenseDetails(responseView interface{}, licenseDetails map[string]string) interface{} {
87+
tenantConfigurationResponseView := responseView.([]*wrappers.TenantConfigurationResponse)
88+
89+
for key, value := range licenseDetails {
90+
licenseEntry := &wrappers.TenantConfigurationResponse{
91+
Key: key,
92+
Value: value,
93+
}
94+
tenantConfigurationResponseView = append(tenantConfigurationResponseView, licenseEntry)
95+
}
96+
97+
return tenantConfigurationResponseView
98+
}

internal/commands/util/tenant_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,41 @@ import (
88
)
99

1010
func TestTenantConfigurationHelp(t *testing.T) {
11-
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{})
11+
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{})
1212
cmd.SetArgs([]string{"utils", "tenant", "--help"})
1313
err := cmd.Execute()
1414
assert.Assert(t, err == nil)
1515
}
1616

1717
func TestTenantConfigurationJsonFormat(t *testing.T) {
18-
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{})
18+
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{})
1919
cmd.SetArgs([]string{"utils", "tenant", "--format", "json"})
2020
err := cmd.Execute()
2121
assert.NilError(t, err, "Tenant configuration command should run with no errors and print to json")
2222
}
2323

2424
func TestTenantConfigurationListFormat(t *testing.T) {
25-
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{})
25+
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{})
2626
cmd.SetArgs([]string{"utils", "tenant", "--format", "list"})
2727
err := cmd.Execute()
2828
assert.NilError(t, err, "Tenant configuration command should run with no errors and print to list")
2929
}
3030

3131
func TestTenantConfigurationTableFormat(t *testing.T) {
32-
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{})
32+
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{})
3333
cmd.SetArgs([]string{"utils", "tenant", "--format", "table"})
3434
err := cmd.Execute()
3535
assert.NilError(t, err, "Tenant configuration command should run with no errors and print to table")
3636
}
3737

3838
func TestTenantConfigurationInvalidFormat(t *testing.T) {
39-
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{})
39+
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{})
4040
cmd.SetArgs([]string{"utils", "tenant", "--format", "MOCK"})
4141
err := cmd.Execute()
4242
assert.Assert(t, err.Error() == mockFormatErrorMessage)
4343
}
4444

4545
func TestNewTenantConfigurationCommand(t *testing.T) {
46-
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{})
46+
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{}, &mock.FeatureFlagsMockWrapper{})
4747
assert.Assert(t, cmd != nil, "Tenant configuration command must exist")
4848
}

internal/commands/util/utils.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func NewUtilsCommand(
3535
prWrapper wrappers.PRWrapper,
3636
learnMoreWrapper wrappers.LearnMoreWrapper,
3737
tenantWrapper wrappers.TenantConfigurationWrapper,
38+
jwtWrapper wrappers.JWTWrapper,
3839
chatWrapper wrappers.ChatWrapper,
3940
policyWrapper wrappers.PolicyWrapper,
4041
scansWrapper wrappers.ScansWrapper,
@@ -76,7 +77,7 @@ func NewUtilsCommand(
7677

7778
learnMoreCmd := NewLearnMoreCommand(learnMoreWrapper)
7879

79-
tenantCmd := NewTenantConfigurationCommand(tenantWrapper)
80+
tenantCmd := NewTenantConfigurationCommand(tenantWrapper, jwtWrapper, featureFlagsWrapper)
8081

8182
maskSecretsCmd := NewMaskSecretsCommand(chatWrapper)
8283

internal/commands/util/utils_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func TestNewUtilsCommand(t *testing.T) {
2222
nil,
2323
mock.LearnMoreMockWrapper{},
2424
mock.TenantConfigurationMockWrapper{},
25+
&mock.JWTMockWrapper{},
2526
mock.ChatMockWrapper{},
2627
nil,
2728
nil,

internal/params/flags.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ const (
292292
APISecurityType = "api-security"
293293
AIProtectionType = "AI Protection"
294294
CheckmarxOneAssistType = "Checkmarx One Assist"
295+
CheckmarxOneStandAloneType = "Standalone"
295296
ContainersType = "containers"
296297
APIDocumentationFlag = "apisec-swagger-filter"
297298
IacType = "iac-security"

internal/wrappers/jwt-helper.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package wrappers
22

33
import (
4+
"strconv"
45
"strings"
56

67
commonParams "github.com/checkmarx/ast-cli/internal/params"
@@ -23,6 +24,7 @@ type JWTStruct struct {
2324

2425
type JWTWrapper interface {
2526
GetAllowedEngines(featureFlagsWrapper FeatureFlagsWrapper) (allowedEngines map[string]bool, err error)
27+
GetLicenseDetails(featureFlagsWrapper FeatureFlagsWrapper) (licenseDetails map[string]string, err error)
2628
IsAllowedEngine(engine string) (bool, error)
2729
ExtractTenantFromToken() (tenant string, err error)
2830
CheckPermissionByAccessToken(requiredPermission string) (permission bool, err error)
@@ -76,6 +78,30 @@ func (*JWTStruct) GetAllowedEngines(featureFlagsWrapper FeatureFlagsWrapper) (al
7678
return getDefaultEngines(scsLicensingV2Flag.Status), nil
7779
}
7880

81+
func (*JWTStruct) GetLicenseDetails(featureFlagsWrapper FeatureFlagsWrapper) (licenseDetails map[string]string, err error) {
82+
licenseDetails = make(map[string]string)
83+
84+
jwtStruct, err := getJwtStruct()
85+
if err != nil {
86+
return nil, err
87+
}
88+
89+
assistEnabled := false
90+
standaloneEnabled := false
91+
for _, allowedEngine := range jwtStruct.AstLicense.LicenseData.AllowedEngines {
92+
if strings.EqualFold(allowedEngine, commonParams.CheckmarxOneAssistType) ||
93+
strings.EqualFold(allowedEngine, commonParams.AIProtectionType) {
94+
assistEnabled = true
95+
} else if strings.EqualFold(allowedEngine, commonParams.CheckmarxOneStandAloneType) {
96+
standaloneEnabled = true
97+
}
98+
}
99+
100+
licenseDetails["scan.config.plugins.cxoneassist"] = strconv.FormatBool(assistEnabled)
101+
licenseDetails["scan.config.plugins.standalone"] = strconv.FormatBool(standaloneEnabled)
102+
return licenseDetails, nil
103+
}
104+
79105
func getJwtStruct() (*JWTStruct, error) {
80106
accessToken, err := GetAccessToken()
81107
if err != nil {

internal/wrappers/mock/jwt-helper-mock.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package mock
22

33
import (
4+
"strconv"
45
"strings"
56

67
"github.com/checkmarx/ast-cli/internal/params"
@@ -75,3 +76,19 @@ func (j *JWTMockWrapper) IsAllowedEngine(engine string) (bool, error) {
7576
func (j *JWTMockWrapper) CheckPermissionByAccessToken(requiredPermission string) (permission bool, err error) {
7677
return true, nil
7778
}
79+
80+
func (j *JWTMockWrapper) GetLicenseDetails(featureFlagsWrapper wrappers.FeatureFlagsWrapper) (licenseDetails map[string]string, err error) {
81+
licenseDetails = make(map[string]string)
82+
83+
assistEnabled := (j.CheckmarxOneAssistEnabled != CheckmarxOneAssistDisabled) || (j.AIEnabled != AIProtectionDisabled)
84+
licenseDetails["scan.config.plugins.cxoneassist"] = strconv.FormatBool(assistEnabled)
85+
86+
standaloneEnabled := true
87+
licenseDetails["scan.config.plugins.standalone"] = strconv.FormatBool(standaloneEnabled)
88+
89+
for _, engine := range engines {
90+
licenseDetails[engine] = "true"
91+
}
92+
93+
return licenseDetails, nil
94+
}

0 commit comments

Comments
 (0)