Skip to content

Commit eed0dd5

Browse files
authored
Add is entitlement check for MCP command (jfrog#553)
1 parent 5b2bf94 commit eed0dd5

File tree

7 files changed

+70
-49
lines changed

7 files changed

+70
-49
lines changed

cli/scancommands.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030

3131
"github.com/jfrog/jfrog-cli-security/commands/enrich"
3232
"github.com/jfrog/jfrog-cli-security/commands/source_mcp"
33-
"github.com/jfrog/jfrog-cli-security/jas"
3433
"github.com/jfrog/jfrog-cli-security/sca/bom/indexer"
3534
"github.com/jfrog/jfrog-cli-security/utils/xray"
3635
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
@@ -196,17 +195,12 @@ func SourceMcpCmd(c *components.Context) error {
196195
return err
197196
}
198197

199-
am_env, err := jas.GetAnalyzerManagerEnvVariables(serverDetails)
200-
if err != nil {
201-
return err
202-
}
203-
204198
mcp_cmd := source_mcp.McpCommand{
205-
Env: am_env,
206-
Arguments: c.Arguments,
207-
InputPipe: os.Stdin,
208-
OutputPipe: os.Stdout,
209-
ErrorPipe: os.Stderr,
199+
ServerDetails: serverDetails,
200+
Arguments: c.Arguments,
201+
InputPipe: os.Stdin,
202+
OutputPipe: os.Stdout,
203+
ErrorPipe: os.Stderr,
210204
}
211205
return mcp_cmd.Run()
212206
}

commands/curation/curationaudit.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,10 +1140,5 @@ func IsEntitledForCuration(xrayManager *xrayClient.XrayServicesManager) (entitle
11401140
if err != nil {
11411141
return
11421142
}
1143-
if err = clientutils.ValidateMinimumVersion(clientutils.Xray, xrayVersion, utils.EntitlementsMinVersion); err != nil {
1144-
log.Debug(err)
1145-
return
1146-
}
1147-
return xrayManager.IsEntitled("curation")
1148-
1143+
return xray.IsEntitled(xrayManager, xrayVersion, "curation")
11491144
}

commands/scan/scan.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ func (scanCmd *ScanCommand) initScanCmdResults(cmdType utils.CommandType) (xrayM
333333
cmdResults.SetStartTime(scanCmd.startTime)
334334
cmdResults.SetResultsContext(scanCmd.resultsContext)
335335
// Send entitlement request
336-
if entitledForJas, err := isEntitledForJas(xrayManager, scanCmd.xrayVersion); err != nil {
336+
if entitledForJas, err := jas.IsEntitledForJas(xrayManager, scanCmd.xrayVersion); err != nil {
337337
return xrayManager, cmdResults.AddGeneralError(err, false)
338338
} else {
339339
cmdResults.SetEntitledForJas(entitledForJas)
@@ -344,10 +344,6 @@ func (scanCmd *ScanCommand) initScanCmdResults(cmdType utils.CommandType) (xrayM
344344
return
345345
}
346346

347-
func isEntitledForJas(xrayManager *xrayClient.XrayServicesManager, xrayVersion string) (bool, error) {
348-
return jas.IsEntitledForJas(xrayManager, xrayVersion)
349-
}
350-
351347
func NewScanCommand() *ScanCommand {
352348
return &ScanCommand{}
353349
}

commands/source_mcp/source_mcp.go

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,25 @@ import (
66
"os/exec"
77
"time"
88

9+
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
910
"github.com/jfrog/jfrog-cli-security/jas"
1011
"github.com/jfrog/jfrog-cli-security/utils"
12+
"github.com/jfrog/jfrog-cli-security/utils/xray"
13+
1114
"github.com/jfrog/jfrog-client-go/utils/log"
1215
)
1316

17+
const (
18+
cmd = "mcp-sast"
19+
mcpEntitlement = "local_sast_mcp"
20+
)
21+
1422
type McpCommand struct {
15-
Env map[string]string
16-
Arguments []string
17-
InputPipe io.Reader
18-
OutputPipe io.Writer
19-
ErrorPipe io.Writer
23+
ServerDetails *config.ServerDetails
24+
Arguments []string
25+
InputPipe io.Reader
26+
OutputPipe io.Writer
27+
ErrorPipe io.Writer
2028
}
2129

2230
func establishPipeToFile(dst io.WriteCloser, src io.Reader) {
@@ -99,15 +107,35 @@ func RunAmMcpWithPipes(env map[string]string, cmd string, input_pipe io.Reader,
99107
return nil
100108
}
101109

102-
func (mcpCmd *McpCommand) runWithTimeout(timeout int, cmd string) (err error) {
110+
func (mcpCmd *McpCommand) runWithTimeout(timeout int, cmd string, envVars map[string]string) (err error) {
103111
err_ := jas.DownloadAnalyzerManagerIfNeeded(0)
104112
if err_ != nil {
105113
log.Error(fmt.Sprintf("Failed to download Analyzer Manager: %v", err))
106114
}
107-
108-
return RunAmMcpWithPipes(mcpCmd.Env, cmd, mcpCmd.InputPipe, mcpCmd.OutputPipe, mcpCmd.ErrorPipe, timeout, mcpCmd.Arguments...)
115+
return RunAmMcpWithPipes(envVars, cmd, mcpCmd.InputPipe, mcpCmd.OutputPipe, mcpCmd.ErrorPipe, timeout, mcpCmd.Arguments...)
109116
}
110117

111118
func (mcpCmd *McpCommand) Run() (err error) {
112-
return mcpCmd.runWithTimeout(0, "mcp-sast")
119+
am_env, err := jas.GetAnalyzerManagerEnvVariables(mcpCmd.ServerDetails)
120+
if err != nil {
121+
return err
122+
}
123+
if entitled, err := isEntitledForSourceMCP(mcpCmd.ServerDetails); err != nil {
124+
return err
125+
} else if !entitled {
126+
return fmt.Errorf("it appears your current license doesn't include this feature.\nTo enable this functionality, an upgraded license is required. Please contact your JFrog representative for more details")
127+
}
128+
return mcpCmd.runWithTimeout(0, cmd, am_env)
129+
}
130+
131+
func isEntitledForSourceMCP(serverDetails *config.ServerDetails) (entitled bool, err error) {
132+
xrayManager, err := xray.CreateXrayServiceManager(serverDetails)
133+
if err != nil {
134+
return
135+
}
136+
xrayVersion, err := xrayManager.GetVersion()
137+
if err != nil {
138+
return
139+
}
140+
return xray.IsEntitled(xrayManager, xrayVersion, mcpEntitlement)
113141
}

commands/source_mcp/source_mcp_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ func TestRunSourceMcpHappyFlow(t *testing.T) {
2525
am_env, _ := jas.GetAnalyzerManagerEnvVariables(scanner.ServerDetails)
2626

2727
mcp_cmd := McpCommand{
28-
Env: am_env,
29-
Arguments: []string{scanned_path},
30-
InputPipe: &input_buffer,
31-
OutputPipe: &output_buffer,
32-
ErrorPipe: &error_buffer,
28+
ServerDetails: serverDetails,
29+
Arguments: []string{scanned_path},
30+
InputPipe: &input_buffer,
31+
OutputPipe: &output_buffer,
32+
ErrorPipe: &error_buffer,
3333
}
3434

35-
err := mcp_cmd.runWithTimeout(5, "mcp-sast")
35+
err := mcp_cmd.runWithTimeout(5, "mcp-sast", am_env)
3636
assert.NoError(t, err) // returns error because it was terminated upon timeout
3737
if !assert.Contains(t, error_buffer.String(), "Generated IR") {
3838
t.Error(error_buffer.String())
@@ -57,12 +57,12 @@ func TestRunSourceMcpScannerError(t *testing.T) {
5757
error_buffer := *bytes.NewBuffer(make([]byte, 0, 500))
5858
am_env, _ := jas.GetAnalyzerManagerEnvVariables(scanner.ServerDetails)
5959
mcp_cmd := McpCommand{
60-
Env: am_env,
61-
Arguments: []string{scanned_path},
62-
InputPipe: &input_buffer,
63-
OutputPipe: &output_buffer,
64-
ErrorPipe: &error_buffer,
60+
ServerDetails: serverDetails,
61+
Arguments: []string{scanned_path},
62+
InputPipe: &input_buffer,
63+
OutputPipe: &output_buffer,
64+
ErrorPipe: &error_buffer,
6565
}
66-
err := mcp_cmd.runWithTimeout(0, "mcp-sast1") // no such command
66+
err := mcp_cmd.runWithTimeout(0, "mcp-sast1", am_env) // no such command
6767
assert.ErrorContains(t, err, "exit status 99")
6868
}

jas/common.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/jfrog/jfrog-cli-security/utils/results"
2424
"github.com/jfrog/jfrog-cli-security/utils/severityutils"
2525
"github.com/jfrog/jfrog-cli-security/utils/techutils"
26+
xrayUtils "github.com/jfrog/jfrog-cli-security/utils/xray"
2627
goclientutils "github.com/jfrog/jfrog-client-go/utils"
2728
"github.com/jfrog/jfrog-client-go/utils/errorutils"
2829
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
@@ -491,12 +492,7 @@ func GetAnalyzerManagerXscEnvVars(msi string, gitRepoUrl, projectKey string, wat
491492
}
492493

493494
func IsEntitledForJas(xrayManager *xray.XrayServicesManager, xrayVersion string) (entitled bool, err error) {
494-
if e := goclientutils.ValidateMinimumVersion(goclientutils.Xray, xrayVersion, utils.EntitlementsMinVersion); e != nil {
495-
log.Debug(e)
496-
return
497-
}
498-
entitled, err = xrayManager.IsEntitled(ApplicabilityFeatureId)
499-
return
495+
return xrayUtils.IsEntitled(xrayManager, xrayVersion, ApplicabilityFeatureId)
500496
}
501497

502498
func CreateScannerTempDirectory(scanner *JasScanner, scanType string, threadId int) (string, error) {

utils/xray/xraymanager.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import (
55
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
66
clientconfig "github.com/jfrog/jfrog-client-go/config"
77
"github.com/jfrog/jfrog-client-go/xray"
8+
9+
"github.com/jfrog/jfrog-cli-security/utils"
10+
clientutils "github.com/jfrog/jfrog-client-go/utils"
11+
"github.com/jfrog/jfrog-client-go/utils/log"
812
)
913

1014
// Options for creating an Xray service manager.
@@ -55,3 +59,11 @@ func CreateXrayServiceManagerAndGetVersion(serviceDetails *config.ServerDetails,
5559
}
5660
return xrayManager, xrayVersion, nil
5761
}
62+
63+
func IsEntitled(xrayManager *xray.XrayServicesManager, xrayVersion, featureId string) (entitled bool, err error) {
64+
if e := clientutils.ValidateMinimumVersion(clientutils.Xray, xrayVersion, utils.EntitlementsMinVersion); e != nil {
65+
log.Debug(e)
66+
return
67+
}
68+
return xrayManager.IsEntitled(featureId)
69+
}

0 commit comments

Comments
 (0)