Skip to content

Commit fb8dcf5

Browse files
Merge pull request #953 from Checkmarx/bug/miryamFoifer/ignoreApplicationWhenProjectExists
Do Not Update An Existing Project With A New Application(AST-70427)
2 parents 112ec8e + 93b9f3c commit fb8dcf5

File tree

10 files changed

+150
-124
lines changed

10 files changed

+150
-124
lines changed

internal/commands/project.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ func runCreateProjectCommand(
233233
applicationName, _ := cmd.Flags().GetString(commonParams.ApplicationName)
234234
var applicationID []string
235235
if applicationName != "" {
236-
application, getAppErr := getApplication(applicationName, applicationsWrapper)
236+
application, getAppErr := services.GetApplication(applicationName, applicationsWrapper)
237237
if getAppErr != nil {
238238
return getAppErr
239239
}

internal/commands/scan.go

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"github.com/checkmarx/ast-cli/internal/commands/util"
2525
"github.com/checkmarx/ast-cli/internal/commands/util/printer"
2626
"github.com/checkmarx/ast-cli/internal/constants"
27-
errorConstants "github.com/checkmarx/ast-cli/internal/constants/errors"
2827
exitCodes "github.com/checkmarx/ast-cli/internal/constants/exit-codes"
2928
"github.com/checkmarx/ast-cli/internal/logger"
3029
"github.com/checkmarx/ast-cli/internal/services"
@@ -709,23 +708,8 @@ func setupScanTypeProjectAndConfig(
709708
return errors.Errorf("Project name is required")
710709
}
711710

712-
applicationName, _ := cmd.Flags().GetString(commonParams.ApplicationName)
713-
714-
var applicationID []string
715-
if applicationName != "" {
716-
application, getAppErr := getApplication(applicationName, applicationsWrapper)
717-
if getAppErr != nil {
718-
return getAppErr
719-
}
720-
if application == nil {
721-
return errors.Errorf(errorConstants.ApplicationDoesntExistOrNoPermission)
722-
}
723-
applicationID = []string{application.ID}
724-
}
725-
726711
// We need to convert the project name into an ID
727712
projectID, findProjectErr := services.FindProject(
728-
applicationID,
729713
info["project"].(map[string]interface{})["id"].(string),
730714
cmd,
731715
projectsWrapper,
@@ -799,34 +783,6 @@ func setupScanTypeProjectAndConfig(
799783
return nil
800784
}
801785

802-
func getApplication(applicationName string, applicationsWrapper wrappers.ApplicationsWrapper) (*wrappers.Application, error) {
803-
if applicationName != "" {
804-
params := make(map[string]string)
805-
params["name"] = applicationName
806-
resp, err := applicationsWrapper.Get(params)
807-
if err != nil {
808-
return nil, err
809-
}
810-
if resp.Applications != nil && len(resp.Applications) > 0 {
811-
application := verifyApplicationNameExactMatch(applicationName, resp)
812-
813-
return application, nil
814-
}
815-
}
816-
return nil, nil
817-
}
818-
819-
func verifyApplicationNameExactMatch(applicationName string, resp *wrappers.ApplicationsResponseModel) *wrappers.Application {
820-
var application *wrappers.Application
821-
for i := range resp.Applications {
822-
if resp.Applications[i].Name == applicationName {
823-
application = &resp.Applications[i]
824-
break
825-
}
826-
}
827-
return application
828-
}
829-
830786
func getResubmitConfiguration(scansWrapper wrappers.ScansWrapper, projectID, userScanTypes string) (
831787
[]wrappers.Config,
832788
error,

internal/commands/scan_test.go

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const (
5555
SCSScoreCardError = "SCS scan failed to start: Scorecard scan is missing required flags, please include in the ast-cli arguments: " +
5656
"--scs-repo-url your_repo_url --scs-repo-token your_repo_token"
5757
outputFileName = "test_output.log"
58-
noUpdatesForExistingProject = "No applicationId or tags to update. Skipping project update."
58+
noUpdatesForExistingProject = "No tags to update. Skipping project update."
5959
)
6060

6161
func TestScanHelp(t *testing.T) {
@@ -193,18 +193,13 @@ func TestCreateScanWithThreshold_ShouldSuccess(t *testing.T) {
193193
execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", "--scan-types", "sast", "--threshold", "sca-low=1 ; sast-medium=2")
194194
}
195195

196-
func TestScanCreate_ExistingApplicationAndProject_CreateProjectUnderApplicationSuccessfully(t *testing.T) {
197-
execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch")
198-
}
199-
200196
func TestScanCreate_ApplicationNameIsNotExactMatch_FailedToCreateScan(t *testing.T) {
201-
err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", "MOC", "-s", dummyRepo, "-b", "dummy_branch")
197+
err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "non-existing-project", "--application-name", "MOC", "-s", dummyRepo, "-b", "dummy_branch")
202198
assert.Assert(t, err.Error() == errorConstants.ApplicationDoesntExistOrNoPermission)
203199
}
204200

205-
func TestScanCreate_ExistingProjectAndApplicationWithNoPermission_FailedToCreateScan(t *testing.T) {
206-
err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", mock.ApplicationDoesntExist, "-s", dummyRepo, "-b", "dummy_branch")
207-
assert.Assert(t, err.Error() == errorConstants.ApplicationDoesntExistOrNoPermission)
201+
func TestScanCreate_ExistingProjectAndApplicationWithNoPermission_ShouldCreateScan(t *testing.T) {
202+
execCmdNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", mock.ApplicationDoesntExist, "-s", dummyRepo, "-b", "dummy_branch")
208203
}
209204

210205
func TestScanCreate_ExistingApplicationWithNoPermission_FailedToCreateScan(t *testing.T) {
@@ -213,20 +208,16 @@ func TestScanCreate_ExistingApplicationWithNoPermission_FailedToCreateScan(t *te
213208
}
214209

215210
func TestScanCreate_OnReceivingHttpBadRequestStatusCode_FailedToCreateScan(t *testing.T) {
216-
err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", mock.FakeBadRequest400, "-s", dummyRepo, "-b", "dummy_branch")
211+
err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "non-existing-project", "--application-name", mock.FakeBadRequest400, "-s", dummyRepo, "-b", "dummy_branch")
217212
assert.Assert(t, err.Error() == errorConstants.FailedToGetApplication)
218213
}
219214

220215
func TestScanCreate_OnReceivingHttpInternalServerErrorStatusCode_FailedToCreateScan(t *testing.T) {
221-
err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", mock.FakeInternalServerError500, "-s", dummyRepo, "-b", "dummy_branch")
216+
err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "non-existing-project",
217+
"--application-name", mock.FakeInternalServerError500, "-s", dummyRepo, "-b", "dummy_branch")
222218
assert.Assert(t, err.Error() == errorConstants.FailedToGetApplication)
223219
}
224220

225-
func TestCreateScanInsideApplicationProjectExistNoPermissions(t *testing.T) {
226-
err := execCmdNotNilAssertion(t, "scan", "create", "--project-name", "MOCK", "--application-name", mock.NoPermissionApp, "-s", dummyRepo, "-b", "dummy_branch")
227-
assert.Assert(t, err.Error() == errorConstants.ApplicationDoesntExistOrNoPermission)
228-
}
229-
230221
func TestCreateScanSourceDirectory(t *testing.T) {
231222
baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-b", "dummy_branch"}
232223
execCmdNilAssertion(t, append(baseArgs, "-s", "data", "--file-filter", "!.java")...)
@@ -411,6 +402,23 @@ func TestCreateScan_WhenProjectNotExists_ShouldCreateProjectAndAssignGroup(t *te
411402
assert.Equal(t, strings.Contains(stdoutString, "Updating project groups"), true, "Expected output: %s", "Updating project groups")
412403
}
413404

405+
func TestCreateScan_WhenProjectNotExists_ShouldCreateProjectAndAssociateApplication(t *testing.T) {
406+
file := createOutputFile(t, outputFileName)
407+
defer deleteOutputFile(file)
408+
defer logger.SetOutput(os.Stdout)
409+
410+
baseArgs := []string{"scan", "create", "--project-name", "newProject", "-s", ".", "--branch", "main", "--application-name", mock.ExistingApplication, "--debug"}
411+
execCmdNilAssertion(
412+
t,
413+
baseArgs...,
414+
)
415+
stdoutString, err := util.ReadFileAsString(file.Name())
416+
if err != nil {
417+
t.Fatalf("Failed to read log file: %v", err)
418+
}
419+
assert.Equal(t, strings.Contains(stdoutString, "application association done successfully"), true, "Expected output: %s", "application association done successfully")
420+
}
421+
414422
func TestScanWorkflowMissingID(t *testing.T) {
415423
err := execCmdNotNilAssertion(t, "scan", "workflow")
416424
assert.Error(t, err, "Please provide a scan ID", err.Error())
@@ -624,6 +632,20 @@ func TestCreateScan_WhenProjectExists_ShouldIgnoreGroups(t *testing.T) {
624632
}
625633
assert.Equal(t, strings.Contains(stdoutString, noUpdatesForExistingProject), true, "Expected output: %s", noUpdatesForExistingProject)
626634
}
635+
636+
func TestCreateScan_WhenProjectExists_ShouldIgnoreApplication(t *testing.T) {
637+
file := createOutputFile(t, outputFileName)
638+
defer deleteOutputFile(file)
639+
defer logger.SetOutput(os.Stdout)
640+
baseArgs := []string{scanCommand, "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch",
641+
"--debug", "--application-name", "anyApplication"}
642+
execCmdNilAssertion(t, baseArgs...)
643+
stdoutString, err := util.ReadFileAsString(file.Name())
644+
if err != nil {
645+
t.Fatalf("Failed to read log file: %v", err)
646+
}
647+
assert.Equal(t, strings.Contains(stdoutString, noUpdatesForExistingProject), true, "Expected output: %s", noUpdatesForExistingProject)
648+
}
627649
func TestScanCreateLastSastScanTimeWithInvalidValue(t *testing.T) {
628650
baseArgs := []string{"scan", "create", "--project-name", "MOCK", "-s", dummyRepo, "-b", "dummy_branch", "--sca-exploitable-path", "true", "--sca-last-sast-scan-time", "notaniteger"}
629651
err := execCmdNotNilAssertion(t, baseArgs...)

internal/commands/util/import.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func runImportCommand(
6565
return errors.Errorf(errorConstants.ProjectNameIsRequired)
6666
}
6767

68-
projectID, err := services.FindProject(nil, projectName, cmd, projectsWrapper, groupsWrapper, accessManagementWrapper, applicationsWrapper, featureFlagsWrapper)
68+
projectID, err := services.FindProject(projectName, cmd, projectsWrapper, groupsWrapper, accessManagementWrapper, applicationsWrapper, featureFlagsWrapper)
6969
if err != nil {
7070
return err
7171
}

internal/services/applications.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package services
22

3-
import "github.com/checkmarx/ast-cli/internal/wrappers/utils"
3+
import (
4+
errorConstants "github.com/checkmarx/ast-cli/internal/constants/errors"
5+
"github.com/checkmarx/ast-cli/internal/wrappers"
6+
"github.com/checkmarx/ast-cli/internal/wrappers/utils"
7+
"github.com/pkg/errors"
8+
)
49

510
func createApplicationIds(applicationID, existingApplicationIds []string) []string {
611
for _, id := range applicationID {
@@ -10,3 +15,46 @@ func createApplicationIds(applicationID, existingApplicationIds []string) []stri
1015
}
1116
return existingApplicationIds
1217
}
18+
19+
func getApplicationID(applicationName string, applicationsWrapper wrappers.ApplicationsWrapper) ([]string, error) {
20+
var applicationID []string
21+
if applicationName != "" {
22+
application, getAppErr := GetApplication(applicationName, applicationsWrapper)
23+
if getAppErr != nil {
24+
return nil, getAppErr
25+
}
26+
if application == nil {
27+
return nil, errors.Errorf(errorConstants.ApplicationDoesntExistOrNoPermission)
28+
}
29+
applicationID = []string{application.ID}
30+
}
31+
return applicationID, nil
32+
}
33+
34+
func GetApplication(applicationName string, applicationsWrapper wrappers.ApplicationsWrapper) (*wrappers.Application, error) {
35+
if applicationName != "" {
36+
params := make(map[string]string)
37+
params["name"] = applicationName
38+
resp, err := applicationsWrapper.Get(params)
39+
if err != nil {
40+
return nil, err
41+
}
42+
if resp.Applications != nil && len(resp.Applications) > 0 {
43+
application := verifyApplicationNameExactMatch(applicationName, resp)
44+
45+
return application, nil
46+
}
47+
}
48+
return nil, nil
49+
}
50+
51+
func verifyApplicationNameExactMatch(applicationName string, resp *wrappers.ApplicationsResponseModel) *wrappers.Application {
52+
var application *wrappers.Application
53+
for i := range resp.Applications {
54+
if resp.Applications[i].Name == applicationName {
55+
application = &resp.Applications[i]
56+
break
57+
}
58+
}
59+
return application
60+
}

internal/services/projects.go

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const (
2222
)
2323

2424
func FindProject(
25-
applicationID []string,
2625
projectName string,
2726
cmd *cobra.Command,
2827
projectsWrapper wrappers.ProjectsWrapper,
@@ -41,12 +40,19 @@ func FindProject(
4140
if project.Name == projectName {
4241
projectTags, _ := cmd.Flags().GetString(commonParams.ProjectTagList)
4342
projectPrivatePackage, _ := cmd.Flags().GetString(commonParams.ProjecPrivatePackageFlag)
44-
return updateProject(&project, cmd, projectsWrapper, applicationWrapper, applicationID, projectTags, projectPrivatePackage)
43+
return updateProject(&project, projectsWrapper, projectTags, projectPrivatePackage)
4544
}
4645
}
4746

4847
projectGroups, _ := cmd.Flags().GetString(commonParams.ProjectGroupList)
4948
projectPrivatePackage, _ := cmd.Flags().GetString(commonParams.ProjecPrivatePackageFlag)
49+
50+
applicationName, _ := cmd.Flags().GetString(commonParams.ApplicationName)
51+
applicationID, appErr := getApplicationID(applicationName, applicationWrapper)
52+
if appErr != nil {
53+
return "", appErr
54+
}
55+
5056
projectID, err := createProject(projectName, cmd, projectsWrapper, groupsWrapper, accessManagementWrapper, applicationWrapper,
5157
applicationID, projectGroups, projectPrivatePackage, featureFlagsWrapper)
5258
if err != nil {
@@ -165,16 +171,15 @@ func verifyApplicationAssociationDone(applicationName, projectID string, applica
165171

166172
//nolint:gocyclo
167173
func updateProject(project *wrappers.ProjectResponseModel,
168-
cmd *cobra.Command, projectsWrapper wrappers.ProjectsWrapper, applicationsWrapper wrappers.ApplicationsWrapper,
169-
applicationID []string, projectTags string, projectPrivatePackage string) (string, error) {
174+
projectsWrapper wrappers.ProjectsWrapper,
175+
projectTags string, projectPrivatePackage string) (string, error) {
170176
var projectID string
171-
applicationName, _ := cmd.Flags().GetString(commonParams.ApplicationName)
172177
var projModel = wrappers.Project{}
173178
projectID = project.ID
174179
projModel.MainBranch = project.MainBranch
175180
projModel.RepoURL = project.RepoURL
176-
if projectTags == "" && projectPrivatePackage == "" && len(applicationID) == 0 {
177-
logger.PrintIfVerbose("No applicationId or tags to update. Skipping project update.")
181+
if projectTags == "" && projectPrivatePackage == "" {
182+
logger.PrintIfVerbose("No tags to update. Skipping project update.")
178183
return projectID, nil
179184
}
180185
if projectPrivatePackage != "" {
@@ -197,22 +202,12 @@ func updateProject(project *wrappers.ProjectResponseModel,
197202
logger.PrintIfVerbose("Updating project tags")
198203
projModel.Tags = createTagMap(projectTags)
199204
}
200-
if len(applicationID) > 0 {
201-
logger.PrintIfVerbose("Updating project applicationIds")
202-
projModel.ApplicationIds = createApplicationIds(applicationID, projModelResp.ApplicationIds)
203-
}
205+
204206
err = projectsWrapper.Update(projectID, &projModel)
205207
if err != nil {
206208
return "", errors.Errorf("%s: %v", failedUpdatingProj, err)
207209
}
208210

209-
if applicationName != "" || len(applicationID) > 0 {
210-
err = verifyApplicationAssociationDone(applicationName, projectID, applicationsWrapper)
211-
if err != nil {
212-
return projectID, err
213-
}
214-
}
215-
216211
return projectID, nil
217212
}
218213

internal/services/projects_test.go

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ func TestFindProject(t *testing.T) {
6060
ttt := tt
6161
t.Run(tt.name, func(t *testing.T) {
6262
got, err := FindProject(
63-
ttt.args.applicationID,
6463
ttt.args.projectName,
6564
ttt.args.cmd,
6665
ttt.args.projectsWrapper,
@@ -236,48 +235,12 @@ func Test_updateProject(t *testing.T) {
236235
want: "ID-project-name",
237236
wantErr: false,
238237
},
239-
{
240-
name: "When called with application ID",
241-
args: args{
242-
project: &wrappers.ProjectResponseModel{
243-
ID: "ID-project-name",
244-
Name: "project-name",
245-
},
246-
cmd: &cobra.Command{},
247-
projectsWrapper: &mock.ProjectsMockWrapper{},
248-
groupsWrapper: &mock.GroupsMockWrapper{},
249-
accessManagementWrapper: &mock.AccessManagementMockWrapper{},
250-
projectName: "project-name",
251-
projectPrivatePackage: "true",
252-
featureFlagsWrapper: &mock.FeatureFlagsMockWrapper{},
253-
},
254-
want: "ID-project-name",
255-
wantErr: false,
256-
},
257-
{
258-
name: "When called with mock fake error model return fake error from project create",
259-
args: args{
260-
projectName: "mock-some-error-model",
261-
project: &wrappers.ProjectResponseModel{
262-
ID: "ID-mock-some-error-model",
263-
Name: "mock-some-error-model",
264-
},
265-
cmd: &cobra.Command{},
266-
projectsWrapper: &mock.ProjectsMockWrapper{},
267-
groupsWrapper: &mock.GroupsMockWrapper{},
268-
accessManagementWrapper: &mock.AccessManagementMockWrapper{},
269-
applicationID: []string{"1"},
270-
featureFlagsWrapper: &mock.FeatureFlagsMockWrapper{},
271-
},
272-
want: "",
273-
wantErr: true,
274-
},
275238
}
276239
for _, tt := range tests {
277240
ttt := tt
278241
t.Run(tt.name, func(t *testing.T) {
279-
got, err := updateProject(ttt.args.project, ttt.args.cmd, ttt.args.projectsWrapper,
280-
ttt.args.applicationsWrapper, ttt.args.applicationID, ttt.args.projectTags, ttt.args.projectPrivatePackage)
242+
got, err := updateProject(ttt.args.project, ttt.args.projectsWrapper,
243+
ttt.args.projectTags, ttt.args.projectPrivatePackage)
281244
if (err != nil) != ttt.wantErr {
282245
t.Errorf("updateProject() error = %v, wantErr %v", err, ttt.wantErr)
283246
return

0 commit comments

Comments
 (0)