Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ func NewAstCLI(
prWrapper,
learnMoreWrapper,
tenantWrapper,
jwtWrapper,
chatWrapper,
policyWrapper,
scansWrapper,
Expand Down
28 changes: 24 additions & 4 deletions internal/commands/util/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/spf13/cobra"
)

func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper) *cobra.Command {
func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper, jwtWrapper wrappers.JWTWrapper) *cobra.Command {
cmd := &cobra.Command{
Use: "tenant",
Short: "Shows the tenant settings",
Expand All @@ -27,7 +27,7 @@ func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper)
`,
),
},
RunE: runTenantCmd(wrapper),
RunE: runTenantCmd(wrapper, jwtWrapper),
}
cmd.PersistentFlags().String(
params.FormatFlag,
Expand All @@ -40,7 +40,7 @@ func NewTenantConfigurationCommand(wrapper wrappers.TenantConfigurationWrapper)
return cmd
}

func runTenantCmd(wrapper wrappers.TenantConfigurationWrapper) func(cmd *cobra.Command, args []string) error {
func runTenantCmd(wrapper wrappers.TenantConfigurationWrapper, jwtWrapper wrappers.JWTWrapper) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
tenantConfigurationResponse, errorModel, err := wrapper.GetTenantConfiguration()
if err != nil {
Expand All @@ -52,10 +52,16 @@ func runTenantCmd(wrapper wrappers.TenantConfigurationWrapper) func(cmd *cobra.C
if tenantConfigurationResponse != nil {
format, _ := cmd.Flags().GetString(params.FormatFlag)
tenantConfigurationResponseView := toTenantConfigurationResponseView(tenantConfigurationResponse)

licenseDetails, err := jwtWrapper.GetLicenseDetails()
if err == nil {
tenantConfigurationResponseView = appendLicenseDetails(tenantConfigurationResponseView, licenseDetails)
}

if format == "" {
format = defaultFormat
}
err := printer.Print(cmd.OutOrStdout(), tenantConfigurationResponseView, format)
err = printer.Print(cmd.OutOrStdout(), tenantConfigurationResponseView, format)
if err != nil {
return err
}
Expand All @@ -76,3 +82,17 @@ func toTenantConfigurationResponseView(response *[]*wrappers.TenantConfiguration
}
return tenantConfigurationResponseView
}

func appendLicenseDetails(responseView interface{}, licenseDetails map[string]string) interface{} {
tenantConfigurationResponseView := responseView.([]*wrappers.TenantConfigurationResponse)

for key, value := range licenseDetails {
licenseEntry := &wrappers.TenantConfigurationResponse{
Key: key,
Value: value,
}
tenantConfigurationResponseView = append(tenantConfigurationResponseView, licenseEntry)
}

return tenantConfigurationResponseView
}
12 changes: 6 additions & 6 deletions internal/commands/util/tenant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,41 @@ import (
)

func TestTenantConfigurationHelp(t *testing.T) {
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{})
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{})
cmd.SetArgs([]string{"utils", "tenant", "--help"})
err := cmd.Execute()
assert.Assert(t, err == nil)
}

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

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

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

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

func TestNewTenantConfigurationCommand(t *testing.T) {
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{})
cmd := NewTenantConfigurationCommand(mock.TenantConfigurationMockWrapper{}, &mock.JWTMockWrapper{})
assert.Assert(t, cmd != nil, "Tenant configuration command must exist")
}
3 changes: 2 additions & 1 deletion internal/commands/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func NewUtilsCommand(
prWrapper wrappers.PRWrapper,
learnMoreWrapper wrappers.LearnMoreWrapper,
tenantWrapper wrappers.TenantConfigurationWrapper,
jwtWrapper wrappers.JWTWrapper,
chatWrapper wrappers.ChatWrapper,
policyWrapper wrappers.PolicyWrapper,
scansWrapper wrappers.ScansWrapper,
Expand Down Expand Up @@ -76,7 +77,7 @@ func NewUtilsCommand(

learnMoreCmd := NewLearnMoreCommand(learnMoreWrapper)

tenantCmd := NewTenantConfigurationCommand(tenantWrapper)
tenantCmd := NewTenantConfigurationCommand(tenantWrapper, jwtWrapper)

maskSecretsCmd := NewMaskSecretsCommand(chatWrapper)

Expand Down
1 change: 1 addition & 0 deletions internal/commands/util/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func TestNewUtilsCommand(t *testing.T) {
nil,
mock.LearnMoreMockWrapper{},
mock.TenantConfigurationMockWrapper{},
&mock.JWTMockWrapper{},
mock.ChatMockWrapper{},
nil,
nil,
Expand Down
1 change: 1 addition & 0 deletions internal/params/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ const (
APISecurityType = "api-security"
AIProtectionType = "AI Protection"
CheckmarxOneAssistType = "Checkmarx One Assist"
CheckmarxOneStandAloneType = "Standalone"
ContainersType = "containers"
APIDocumentationFlag = "apisec-swagger-filter"
IacType = "iac-security"
Expand Down
26 changes: 26 additions & 0 deletions internal/wrappers/jwt-helper.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package wrappers

import (
"strconv"
"strings"

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

type JWTWrapper interface {
GetAllowedEngines(featureFlagsWrapper FeatureFlagsWrapper) (allowedEngines map[string]bool, err error)
GetLicenseDetails() (licenseDetails map[string]string, err error)
IsAllowedEngine(engine string) (bool, error)
ExtractTenantFromToken() (tenant string, err error)
CheckPermissionByAccessToken(requiredPermission string) (permission bool, err error)
Expand Down Expand Up @@ -76,6 +78,30 @@ func (*JWTStruct) GetAllowedEngines(featureFlagsWrapper FeatureFlagsWrapper) (al
return getDefaultEngines(scsLicensingV2Flag.Status), nil
}

func (*JWTStruct) GetLicenseDetails() (licenseDetails map[string]string, err error) {
licenseDetails = make(map[string]string)

jwtStruct, err := getJwtStruct()
if err != nil {
return nil, err
}

assistEnabled := false
standaloneEnabled := false
for _, allowedEngine := range jwtStruct.AstLicense.LicenseData.AllowedEngines {
if strings.EqualFold(allowedEngine, commonParams.CheckmarxOneAssistType) ||
strings.EqualFold(allowedEngine, commonParams.AIProtectionType) {
assistEnabled = true
} else if strings.EqualFold(allowedEngine, commonParams.CheckmarxOneStandAloneType) {
standaloneEnabled = true
}
}

licenseDetails["scan.config.plugins.cxoneassist"] = strconv.FormatBool(assistEnabled)
licenseDetails["scan.config.plugins.standalone"] = strconv.FormatBool(standaloneEnabled)
return licenseDetails, nil
}

func getJwtStruct() (*JWTStruct, error) {
accessToken, err := GetAccessToken()
if err != nil {
Expand Down
19 changes: 19 additions & 0 deletions internal/wrappers/mock/jwt-helper-mock.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mock

import (
"strconv"
"strings"

"github.com/checkmarx/ast-cli/internal/params"
Expand All @@ -22,6 +23,8 @@ const SecretDetectionDisabled = 1

var engines = []string{"sast", "sca", "api-security", "iac-security", "scs", "containers", "enterprise-secrets"}

const licenseEnabledValue = "true"

// GetAllowedEngines mock for tests
func (j *JWTMockWrapper) GetAllowedEngines(featureFlagsWrapper wrappers.FeatureFlagsWrapper) (allowedEngines map[string]bool, err error) {
if j.CustomGetAllowedEngines != nil {
Expand Down Expand Up @@ -75,3 +78,19 @@ func (j *JWTMockWrapper) IsAllowedEngine(engine string) (bool, error) {
func (j *JWTMockWrapper) CheckPermissionByAccessToken(requiredPermission string) (permission bool, err error) {
return true, nil
}

func (j *JWTMockWrapper) GetLicenseDetails() (licenseDetails map[string]string, err error) {
licenseDetails = make(map[string]string)

assistEnabled := (j.CheckmarxOneAssistEnabled != CheckmarxOneAssistDisabled) || (j.AIEnabled != AIProtectionDisabled)
licenseDetails["scan.config.plugins.cxoneassist"] = strconv.FormatBool(assistEnabled)

standaloneEnabled := true
licenseDetails["scan.config.plugins.standalone"] = strconv.FormatBool(standaloneEnabled)

for _, engine := range engines {
licenseDetails[engine] = licenseEnabledValue
}

return licenseDetails, nil
}
Loading