diff options
Diffstat (limited to 'server/sonar-db-dao')
136 files changed, 1126 insertions, 6694 deletions
diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/alm/setting/ProjectAlmSettingDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/alm/setting/ProjectAlmSettingDaoIT.java index 0ece24490e0..51585695dbc 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/alm/setting/ProjectAlmSettingDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/alm/setting/ProjectAlmSettingDaoIT.java @@ -92,23 +92,16 @@ class ProjectAlmSettingDaoIT { @Test void select_by_alm_setting_and_slugs() { - when(uuidFactory.create()).thenReturn(A_UUID); AlmSettingDto almSettingsDto = db.almSettings().insertBitbucketAlmSetting(); - ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - ProjectAlmSettingDto bitbucketProjectAlmSettingDto = newBitbucketProjectAlmSettingDto(almSettingsDto, project); - bitbucketProjectAlmSettingDto.setAlmSlug("slug1"); - underTest.insertOrUpdate(dbSession, bitbucketProjectAlmSettingDto, almSettingsDto.getKey(), project.getName(), project.getKey()); - ProjectAlmSettingDto bitbucketProjectAlmSettingDto2 = newBitbucketProjectAlmSettingDto(almSettingsDto, - db.components().insertPrivateProject().getProjectDto()); - bitbucketProjectAlmSettingDto2.setAlmSlug("slug2"); - when(uuidFactory.create()).thenReturn(A_UUID + 1); - underTest.insertOrUpdate(dbSession, bitbucketProjectAlmSettingDto2, almSettingsDto.getKey(), project.getName(), project.getKey()); - - Set<String> slugs = new HashSet<>(); - slugs.add("slug1"); - assertThat(underTest.selectByAlmSettingAndSlugs(dbSession, almSettingsDto, slugs)) + ProjectAlmSettingDto matchingProject = createBitbucketProject(almSettingsDto, dto -> dto.setAlmSlug("slug1")); + createBitbucketProject(almSettingsDto, dto -> dto.setAlmSlug("slug2")); + + Set<String> slugs = Set.of("slug1"); + List<ProjectAlmSettingDto> results = underTest.selectByAlmSettingAndSlugs(dbSession, almSettingsDto, slugs); + + assertThat(results) .extracting(ProjectAlmSettingDto::getProjectUuid, ProjectAlmSettingDto::getSummaryCommentEnabled, ProjectAlmSettingDto::getInlineAnnotationsEnabled) - .containsExactly(tuple(project.getUuid(), bitbucketProjectAlmSettingDto2.getSummaryCommentEnabled(), bitbucketProjectAlmSettingDto2.getInlineAnnotationsEnabled())); + .containsExactly(tuple(matchingProject.getProjectUuid(), matchingProject.getSummaryCommentEnabled(), matchingProject.getInlineAnnotationsEnabled())); } @Test @@ -142,12 +135,7 @@ class ProjectAlmSettingDaoIT { } private ProjectAlmSettingDto createAlmProject(AlmSettingDto almSettingsDto, Consumer<ProjectAlmSettingDto>... populators) { - ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - when(uuidFactory.create()).thenReturn(project.getUuid() + "_set"); - ProjectAlmSettingDto projectAlmSettingDto = newGithubProjectAlmSettingDto(almSettingsDto, project); - stream(populators).forEach(p -> p.accept(projectAlmSettingDto)); - underTest.insertOrUpdate(dbSession, projectAlmSettingDto, almSettingsDto.getKey(), project.getName(), project.getKey()); - return projectAlmSettingDto; + return createAlmProject(almSettingsDto, dto -> stream(populators).forEach(p -> p.accept(dto)), project -> newGithubProjectAlmSettingDto(almSettingsDto, project)); } @Test @@ -160,23 +148,16 @@ class ProjectAlmSettingDaoIT { @Test void select_by_alm_setting_and_repos() { - when(uuidFactory.create()).thenReturn(A_UUID); AlmSettingDto almSettingsDto = db.almSettings().insertGitHubAlmSetting(); - ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - ProjectAlmSettingDto githubProjectAlmSettingDto = newGithubProjectAlmSettingDto(almSettingsDto, project); - githubProjectAlmSettingDto.setAlmRepo("repo1"); - underTest.insertOrUpdate(dbSession, githubProjectAlmSettingDto, almSettingsDto.getKey(), project.getName(), project.getKey()); - ProjectAlmSettingDto githubProjectAlmSettingDto2 = newGithubProjectAlmSettingDto(almSettingsDto, - db.components().insertPrivateProject().getProjectDto()); - githubProjectAlmSettingDto2.setAlmRepo("repo2"); - when(uuidFactory.create()).thenReturn(A_UUID + 1); - underTest.insertOrUpdate(dbSession, githubProjectAlmSettingDto2, almSettingsDto.getKey(), project.getName(), project.getKey()); - - Set<String> repos = new HashSet<>(); - repos.add("repo1"); - assertThat(underTest.selectByAlmSettingAndRepos(dbSession, almSettingsDto, repos)) + ProjectAlmSettingDto matchingProject = createAlmProject(almSettingsDto, dto -> dto.setAlmRepo("repo1")); + createAlmProject(almSettingsDto, dto -> dto.setAlmRepo("repo2")); + + Set<String> repos = Set.of("repo1"); + List<ProjectAlmSettingDto> results = underTest.selectByAlmSettingAndRepos(dbSession, almSettingsDto, repos); + + assertThat(results) .extracting(ProjectAlmSettingDto::getProjectUuid, ProjectAlmSettingDto::getSummaryCommentEnabled) - .containsExactly(tuple(project.getUuid(), githubProjectAlmSettingDto.getSummaryCommentEnabled())); + .containsExactly(tuple(matchingProject.getProjectUuid(), matchingProject.getSummaryCommentEnabled())); } @Test @@ -208,8 +189,8 @@ class ProjectAlmSettingDaoIT { ProjectAlmKeyAndProject::getProjectUuid, ProjectAlmKeyAndProject::getAlmId, ProjectAlmKeyAndProject::getUrl, - ProjectAlmKeyAndProject::getMonorepo - ).containsExactlyInAnyOrder( + ProjectAlmKeyAndProject::getMonorepo) + .containsExactlyInAnyOrder( tuple(project1.getUuid(), almSettingsDto.getAlm().getId(), almSettingsDto.getUrl(), false), tuple(project2.getUuid(), almSettingsDto.getAlm().getId(), almSettingsDto.getUrl(), true)); } @@ -243,18 +224,20 @@ class ProjectAlmSettingDaoIT { AlmSettingDto matchingAlmSettingDto = db.almSettings().insertGitHubAlmSetting(); AlmSettingDto notMatchingAlmSettingDto = db.almSettings().insertGitHubAlmSetting(); ProjectAlmSettingDto matchingRepo = createAlmProject(matchingAlmSettingDto, dto -> dto.setAlmRepo("matchingRepo")); - ProjectAlmSettingDto notMatchingRepo = createAlmProject(matchingAlmSettingDto, dto -> dto.setAlmRepo("whatever")); ProjectAlmSettingDto matchingAlmSetting = createAlmProject(matchingAlmSettingDto, dto -> dto.setAlmRepo("matchingRepo")); - ProjectAlmSettingDto notMatchingAlmSetting = createAlmProject(notMatchingAlmSettingDto, dto -> dto.setAlmRepo("matchingRepo")); + createAlmProject(matchingAlmSettingDto, dto -> dto.setAlmRepo("whatever")); // not matching repo + createAlmProject(notMatchingAlmSettingDto, dto -> dto.setAlmRepo("matchingRepo")); // not matching alm setting - List<ProjectAlmSettingDto> dtos = underTest.selectProjectAlmSettings(dbSession, new ProjectAlmSettingQuery("matchingRepo", matchingAlmSettingDto.getUuid()), 1, 100); - assertThat(dtos) + ProjectAlmSettingQuery query = new ProjectAlmSettingQuery("matchingRepo", matchingAlmSettingDto.getUuid()); + List<ProjectAlmSettingDto> results = underTest.selectProjectAlmSettings(dbSession, query, 1, 100); + + assertThat(results) .usingRecursiveFieldByFieldElementComparator() .containsExactlyInAnyOrder(matchingRepo, matchingAlmSetting); } private static Object[][] paginationTestCases() { - return new Object[][]{ + return new Object[][] { {100, 1, 5}, {100, 3, 18}, {2075, 41, 50}, @@ -265,7 +248,7 @@ class ProjectAlmSettingDaoIT { @ParameterizedTest @MethodSource("paginationTestCases") void selectProjectAlmSettings_whenUsingPagination_findsTheRightResults(int numberToGenerate, int offset, int limit) { - when(uuidFactory.create()).thenAnswer(answer -> UUID.randomUUID().toString()); + when(uuidFactory.create()).thenAnswer(answer -> UUID.randomUUID().toString()); Map<String, ProjectAlmSettingDto> allProjectAlmSettingsDtos = generateProjectAlmSettingsDtos(numberToGenerate); @@ -284,10 +267,10 @@ class ProjectAlmSettingDaoIT { } Map<String, ProjectAlmSettingDto> result = IntStream.range(1000, 1000 + numberToGenerate) .mapToObj(i -> underTest.insertOrUpdate(dbSession, new ProjectAlmSettingDto() - .setAlmRepo("repo_" + i) - .setAlmSettingUuid("almSettingUuid_" + i) - .setProjectUuid("projectUuid_" + i) - .setMonorepo(false), + .setAlmRepo("repo_" + i) + .setAlmSettingUuid("almSettingUuid_" + i) + .setProjectUuid("projectUuid_" + i) + .setMonorepo(false), "key_" + i, "projectName_" + i, "projectKey_" + i)) .collect(toMap(ProjectAlmSettingDto::getAlmRepo, Function.identity())); db.commit(); @@ -384,4 +367,83 @@ class ProjectAlmSettingDaoIT { assertThat(underTest.countByAlmSetting(dbSession, githubAlmSetting1)).isOne(); } + @Test + void selectProjectAlmSettings_whenSearchingByAlmRepo_returnsMatchingResults() { + AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting(); + ProjectAlmSettingDto matchingProject = createAlmProject(almSetting, dto -> dto.setAlmRepo("target-repo")); + createAlmProject(almSetting, dto -> dto.setAlmRepo("other-repo")); + createAlmProject(almSetting, dto -> dto.setAlmSlug("target-repo")); // slug should not match + + ProjectAlmSettingQuery query = ProjectAlmSettingQuery.forAlmRepo("target-repo"); + List<ProjectAlmSettingDto> results = underTest.selectProjectAlmSettings(dbSession, query, 1, 100); + + assertThat(results) + .usingRecursiveFieldByFieldElementComparator() + .containsExactly(matchingProject); + } + + @Test + void selectProjectAlmSettings_whenSearchingByAlmRepoAndSlug_returnsMatchingResults() { + AlmSettingDto almSetting = db.almSettings().insertAzureAlmSetting(); + ProjectAlmSettingDto matchingProject = createAzureProject(almSetting, "target-repo", "target-project"); + createAzureProject(almSetting, "target-repo", "other-project"); // different slug + createAzureProject(almSetting, "other-repo", "target-project"); // different repo + createAlmProject(almSetting, dto -> dto.setAlmRepo("target-repo")); // missing slug + + ProjectAlmSettingQuery query = ProjectAlmSettingQuery.forAlmRepoAndSlug("target-repo", "target-project"); + List<ProjectAlmSettingDto> results = underTest.selectProjectAlmSettings(dbSession, query, 1, 100); + + assertThat(results) + .usingRecursiveFieldByFieldElementComparator() + .containsExactly(matchingProject); + } + + @Test + void selectProjectAlmSettings_whenSearchingByCaseInsensitiveAlmRepo_returnsMatchingResults() { + AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting(); + ProjectAlmSettingDto upperCaseProject = createAlmProject(almSetting, dto -> dto.setAlmRepo("TARGET-REPO")); + ProjectAlmSettingDto lowerCaseProject = createAlmProject(almSetting, dto -> dto.setAlmRepo("target-repo")); + createAlmProject(almSetting, dto -> dto.setAlmRepo("other-repo")); + + ProjectAlmSettingQuery query = ProjectAlmSettingQuery.forAlmRepo("Target-Repo"); + List<ProjectAlmSettingDto> results = underTest.selectProjectAlmSettings(dbSession, query, 1, 100); + + assertThat(results) + .usingRecursiveFieldByFieldElementComparator() + .containsExactlyInAnyOrder(upperCaseProject, lowerCaseProject); + } + + @Test + void countProjectAlmSettings_whenSearchingByAlmRepo_returnsCorrectCount() { + AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting(); + createAlmProject(almSetting, dto -> dto.setAlmRepo("target-repo")); + createAlmProject(almSetting, dto -> dto.setAlmRepo("target-repo")); + createAlmProject(almSetting, dto -> dto.setAlmRepo("other-repo")); + + ProjectAlmSettingQuery query = ProjectAlmSettingQuery.forAlmRepo("target-repo"); + int count = underTest.countProjectAlmSettings(dbSession, query); + + assertThat(count).isEqualTo(2); + } + + private ProjectAlmSettingDto createAzureProject(AlmSettingDto almSettingsDto, String almRepo, String almSlug) { + return createAlmProject(almSettingsDto, dto -> { + dto.setAlmRepo(almRepo); + dto.setAlmSlug(almSlug); + }, project -> newAzureProjectAlmSettingDto(almSettingsDto, project)); + } + + private ProjectAlmSettingDto createBitbucketProject(AlmSettingDto almSettingsDto, Consumer<ProjectAlmSettingDto> customizer) { + return createAlmProject(almSettingsDto, customizer, project -> newBitbucketProjectAlmSettingDto(almSettingsDto, project)); + } + + private ProjectAlmSettingDto createAlmProject(AlmSettingDto almSettingsDto, Consumer<ProjectAlmSettingDto> customizer, Function<ProjectDto, ProjectAlmSettingDto> dtoFactory) { + ProjectDto project = db.components().insertPrivateProject().getProjectDto(); + when(uuidFactory.create()).thenReturn(project.getUuid() + "_set"); + ProjectAlmSettingDto projectAlmSettingDto = dtoFactory.apply(project); + customizer.accept(projectAlmSettingDto); + underTest.insertOrUpdate(dbSession, projectAlmSettingDto, almSettingsDto.getKey(), project.getName(), project.getKey()); + return projectAlmSettingDto; + } + } diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/component/BranchDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/component/BranchDaoIT.java index 2b1cb099fca..feae0d3f20c 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/component/BranchDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/component/BranchDaoIT.java @@ -906,6 +906,41 @@ class BranchDaoIT { tuple(branch1.getUuid(), projectData1.projectUuid(), true)); } + @Test + void selectPullRequestsTargetingBranch() { + BranchDto mainBranch = new BranchDto(); + mainBranch.setProjectUuid("U1"); + mainBranch.setUuid("U1"); + mainBranch.setIsMain(true); + mainBranch.setBranchType(BranchType.BRANCH); + mainBranch.setKey("master"); + underTest.insert(dbSession, mainBranch); + + BranchDto prBranch = new BranchDto(); + prBranch.setProjectUuid("U1"); + prBranch.setUuid("U2"); + prBranch.setIsMain(false); + prBranch.setBranchType(PULL_REQUEST); + prBranch.setKey("1234"); + prBranch.setMergeBranchUuid("U1"); + underTest.insert(dbSession, prBranch); + + // make a second PR also targeting main branch + prBranch.setUuid("U3"); + prBranch.setKey("4321"); + prBranch.setMergeBranchUuid("U1"); + underTest.insert(dbSession, prBranch); + + // make a third PR NOT targeting main branch to be sure we filter it out + prBranch.setUuid("U4"); + prBranch.setKey("5678"); + prBranch.setMergeBranchUuid("U42"); + underTest.insert(dbSession, prBranch); + + var result = underTest.selectPullRequestsTargetingBranch(dbSession, "U1", "U1"); + assertThat(result.stream().map(BranchDto::getUuid).toList()).containsExactlyInAnyOrder("U2", "U3"); + } + private void insertBranchesForProjectUuids(boolean mainBranch, String... uuids) { for (String uuid : uuids) { BranchDto dto = new BranchDto(); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java index df3414b2cfc..a7b9260ba8a 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueDaoIT.java @@ -42,7 +42,7 @@ import org.sonar.api.issue.Issue; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.db.DbSession; import org.sonar.db.DbTester; diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueMapperIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueMapperIT.java index 31bdb45c3af..2d85056e0c2 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueMapperIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/issue/IssueMapperIT.java @@ -38,7 +38,7 @@ import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.issue.Issue; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; import org.sonar.core.issue.FieldDiffs; diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/AuthorizationDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/AuthorizationDaoIT.java index e7816a9c29f..1e322841762 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/AuthorizationDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/AuthorizationDaoIT.java @@ -31,7 +31,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.Uuids; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -218,13 +217,13 @@ class AuthorizationDaoIT { @Test void keepAuthorizedEntityUuids_returns_empty_for_group_AnyOne_if_project_set_is_empty_on__project() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), null, ProjectPermission.USER)) .isEmpty(); } @Test void keepAuthorizedEntityUuids_returns_empty_for_user_if_project_set_is_empty_on__project() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), ProjectPermission.USER)) .isEmpty(); } @@ -234,7 +233,7 @@ class AuthorizationDaoIT { .mapToObj(i -> Integer.toString(3_562 + i)) .collect(Collectors.toSet()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomNonProjectsSet, null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomNonProjectsSet, null, ProjectPermission.USER)) .isEmpty(); } @@ -244,31 +243,31 @@ class AuthorizationDaoIT { .mapToObj(i -> Integer.toString(9_666 + i)) .collect(Collectors.toSet()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomNonProjectsSet, user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomNonProjectsSet, user.getUuid(), ProjectPermission.USER)) .isEmpty(); } @Test void keepAuthorizedEntityUuids_returns_any__project_for_group_AnyOne_without_any_permission_in_DB_and_permission_USER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, null, ProjectPermission.USER)) .containsAll(randomPublicEntityUuids); } @Test void keepAuthorizedEntityUuids_returns_any__project_for_user_without_any_permission_in_DB_and_permission_USER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, user.getUuid(), ProjectPermission.USER)) .containsAll(randomPublicEntityUuids); } @Test void keepAuthorizedEntityUuids_returns_any__project_for_group_AnyOne_without_any_permission_in_DB_and_permission_CODEVIEWER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, null, UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, null, ProjectPermission.CODEVIEWER)) .containsAll(randomPublicEntityUuids); } @Test void keepAuthorizedEntityUuids_returns_any__project_for_user_without_any_permission_in_DB_and_permission_CODEVIEWER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, user.getUuid(), UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPublicEntityUuids, user.getUuid(), ProjectPermission.CODEVIEWER)) .containsAll(randomPublicEntityUuids); } @@ -335,25 +334,25 @@ class AuthorizationDaoIT { @Test void keepAuthorizedEntityUuids_returns_empty_for_user_on_private_project_without_any_permission_in_DB_and_permission_USER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, user.getUuid(), ProjectPermission.USER)) .isEmpty(); } @Test void keepAuthorizedEntityUuids_returns_empty_for_group_AnyOne_on_private_project_without_any_permission_in_DB_and_permission_USER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, null, ProjectPermission.USER)) .isEmpty(); } @Test void keepAuthorizedEntityUuids_returns_empty_for_user_on_private_project_without_any_permission_in_DB_and_permission_CODEVIEWER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, user.getUuid(), UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, user.getUuid(), ProjectPermission.CODEVIEWER)) .isEmpty(); } @Test void keepAuthorizedEntityUuids_returns_empty_for_group_AnyOne_on_private_project_without_any_permission_in_DB_and_permission_CODEVIEWER() { - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, null, UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, randomPrivateEntityUuids, null, ProjectPermission.CODEVIEWER)) .isEmpty(); } @@ -421,20 +420,20 @@ class AuthorizationDaoIT { ProjectDto project3 = db.components().insertPrivateProject().getProjectDto(); UserDto user = db.users().insertUser("u1"); GroupDto group = db.users().insertGroup(); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project2); - db.users().insertProjectPermissionOnUser(user, UserRole.USER, project3); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project2); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.USER, project3); db.users().insertMember(group, user); - db.users().insertEntityPermissionOnGroup(group, UserRole.USER, project1); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.USER, project1); assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project2.getUuid(), project3.getUuid()), user.getUuid(), - UserRole.USER)) + ProjectPermission.USER)) .containsOnly(project2.getUuid(), project3.getUuid()); // user does not have the role "admin" - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project2.getUuid()), user.getUuid(), UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project2.getUuid()), user.getUuid(), ProjectPermission.ADMIN)) .isEmpty(); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), ProjectPermission.ADMIN)) .isEmpty(); } @@ -446,17 +445,17 @@ class AuthorizationDaoIT { UserDto user1 = db.users().insertUser("u1"); GroupDto group = db.users().insertGroup(); db.users().insertMembers(group, user1); - db.users().insertProjectPermissionOnUser(user1, UserRole.USER, project1); - db.users().insertEntityPermissionOnGroup(group, UserRole.USER, project2); - db.users().insertEntityPermissionOnGroup(group, UserRole.USER, project3); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.USER, project1); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.USER, project2); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.USER, project3); assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project2.getUuid(), project3.getUuid()), user1.getUuid(), - UserRole.USER)) + ProjectPermission.USER)) .containsOnly(project2.getUuid(), project3.getUuid()); // group does not have the role "admin" assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project2.getUuid(), project3.getUuid()), user1.getUuid(), - UserRole.ADMIN)) + ProjectPermission.ADMIN)) .isEmpty(); } @@ -468,7 +467,7 @@ class AuthorizationDaoIT { GroupDto group = db.users().insertGroup(); db.users().insertMembers(group, user1); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project1.getUuid(), project2.getUuid()), null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(project1.getUuid(), project2.getUuid()), null, ProjectPermission.USER)) .containsOnly(project1.getUuid(), project2.getUuid()); // group does not have the role "admin" @@ -481,7 +480,7 @@ class AuthorizationDaoIT { List<ProjectDto> projects = IntStream.range(0, 2000).mapToObj(i -> db.components().insertPublicProject().getProjectDto()).toList(); Collection<String> uuids = projects.stream().map(ProjectDto::getUuid).collect(Collectors.toSet()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, uuids, null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, uuids, null, ProjectPermission.USER)) .containsOnly(uuids.toArray(new String[0])); } @@ -489,7 +488,7 @@ class AuthorizationDaoIT { void keepAuthorizedUsersForRoleAndEntity_returns_empty_if_user_set_is_empty_on__project() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, Collections.emptySet(), UserRole.USER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, Collections.emptySet(), ProjectPermission.USER, project.getUuid())) .isEmpty(); } @@ -501,7 +500,7 @@ class AuthorizationDaoIT { .mapToObj(i -> Uuids.createFast()) .collect(Collectors.toSet()); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomNonExistingUserUuidsSet, UserRole.USER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomNonExistingUserUuidsSet, ProjectPermission.USER, project.getUuid())) .isEmpty(); } @@ -509,7 +508,7 @@ class AuthorizationDaoIT { void keepAuthorizedUsersForRoleAndEntity_returns_any_users_for__project_without_any_permission_in_DB_and_permission_USER() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, UserRole.USER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, ProjectPermission.USER, project.getUuid())) .containsAll(randomExistingUserUuids); } @@ -517,7 +516,7 @@ class AuthorizationDaoIT { void keepAuthorizedUsersForRoleAndEntity_returns_any_users_for__project_without_any_permission_in_DB_and_permission_CODEVIEWER() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, UserRole.CODEVIEWER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, ProjectPermission.CODEVIEWER, project.getUuid())) .containsAll(randomExistingUserUuids); } @@ -591,7 +590,7 @@ class AuthorizationDaoIT { void keepAuthorizedUsersForRoleAndEntity_returns_empty_for_any_user_on_private_project_without_any_permission_in_DB_and_permission_USER() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, UserRole.USER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, ProjectPermission.USER, project.getUuid())) .isEmpty(); } @@ -599,7 +598,7 @@ class AuthorizationDaoIT { void keepAuthorizedUsersForRoleAndEntity_returns_empty_for_any_user_on_private_project_without_any_permission_in_DB_and_permission_CODEVIEWER() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, UserRole.CODEVIEWER, project.getUuid())) + assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, randomExistingUserUuids, ProjectPermission.CODEVIEWER, project.getUuid())) .isEmpty(); } @@ -667,10 +666,10 @@ class AuthorizationDaoIT { GroupDto group2 = db.users().insertGroup(); db.users().insertMembers(group1, user1, user2); db.users().insertMembers(group2, user3); - db.users().insertProjectPermissionOnUser(user1, UserRole.USER, project1); - db.users().insertProjectPermissionOnUser(user2, UserRole.USER, project1); - db.users().insertProjectPermissionOnUser(user3, UserRole.USER, project1); - db.users().insertEntityPermissionOnGroup(group2, UserRole.USER, project3); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.USER, project1); + db.users().insertProjectPermissionOnUser(user2, ProjectPermission.USER, project1); + db.users().insertProjectPermissionOnUser(user3, ProjectPermission.USER, project1); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.USER, project3); assertThat(underTest.keepAuthorizedUsersForRoleAndEntity(dbSession, // Only 100 and 101 has 'user' role on project @@ -769,31 +768,31 @@ class AuthorizationDaoIT { @Test void selectEntityPermissions_returns_permissions_of_logged_in_user_on_specified_project() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, project); - db.users().insertProjectPermissionOnUser(db.users().insertUser(), UserRole.ISSUE_ADMIN, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, project); + db.users().insertProjectPermissionOnUser(db.users().insertUser(), ProjectPermission.ISSUE_ADMIN, project); - assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(UserRole.CODEVIEWER); + assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(ProjectPermission.CODEVIEWER.getKey()); } @Test void selectEntityPermissions_returns_permissions_of_logged_in_user_on_specified_project_through_group_membership() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertEntityPermissionOnGroup(group1, UserRole.CODEVIEWER, project); - db.users().insertEntityPermissionOnGroup(group2, UserRole.ISSUE_ADMIN, project); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.CODEVIEWER, project); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.ISSUE_ADMIN, project); db.users().insertMember(group1, user); - assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(UserRole.CODEVIEWER); + assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(ProjectPermission.CODEVIEWER.getKey()); } @Test void selectEntityPermissions_returns_permissions_of_logged_in_user_on_specified_private_project_through_all_possible_configurations() { ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, project); - db.users().insertEntityPermissionOnGroup(group1, UserRole.USER, project); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.CODEVIEWER, project); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.USER, project); db.users().insertMember(group1, user); - assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(UserRole.CODEVIEWER, - UserRole.USER); + assertThat(underTest.selectEntityPermissions(dbSession, project.getUuid(), user.getUuid())).containsOnly(ProjectPermission.CODEVIEWER.getKey(), + ProjectPermission.USER.getKey()); } @Test @@ -918,14 +917,14 @@ class AuthorizationDaoIT { ProjectDto privateProject = db.components().insertPrivateProject().getProjectDto(); ProjectDto Project = db.components().insertPublicProject().getProjectDto(); UserDto user = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, privateProject); + db.users().insertProjectPermissionOnUser(user, ProjectPermission.ADMIN, privateProject); assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(privateProject.getUuid(), Project.getUuid()), user.getUuid(), - UserRole.ADMIN)) + ProjectPermission.ADMIN)) .containsOnly(privateProject.getUuid()); // user does not have the permission "issueadmin" assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(privateProject.getUuid(), Project.getUuid()), user.getUuid(), - UserRole.ISSUE_ADMIN)) + ProjectPermission.ISSUE_ADMIN)) .isEmpty(); } @@ -936,14 +935,14 @@ class AuthorizationDaoIT { UserDto user = db.users().insertUser(); GroupDto group = db.users().insertGroup(); db.users().insertMember(group, user); - db.users().insertEntityPermissionOnGroup(group, UserRole.ADMIN, privateProject); + db.users().insertEntityPermissionOnGroup(group, ProjectPermission.ADMIN, privateProject); assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(privateProject.getUuid(), Project.getUuid()), user.getUuid(), - UserRole.ADMIN)) + ProjectPermission.ADMIN)) .containsOnly(privateProject.getUuid()); // user does not have the permission "issueadmin" assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(privateProject.getUuid(), Project.getUuid()), user.getUuid(), - UserRole.ISSUE_ADMIN)) + ProjectPermission.ISSUE_ADMIN)) .isEmpty(); } @@ -952,11 +951,11 @@ class AuthorizationDaoIT { ProjectDto Project = db.components().insertPublicProject().getProjectDto(); UserDto user = db.users().insertUser(); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, Collections.emptySet(), user.getUuid(), ProjectPermission.USER)) .isEmpty(); // projects do not exist - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet("does_not_exist"), user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet("does_not_exist"), user.getUuid(), ProjectPermission.USER)) .isEmpty(); } @@ -965,7 +964,7 @@ class AuthorizationDaoIT { ProjectDto Project = db.components().insertPublicProject().getProjectDto(); UserDto user = db.users().insertUser(); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet("does_not_exist"), user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet("does_not_exist"), user.getUuid(), ProjectPermission.USER)) .isEmpty(); } @@ -975,19 +974,19 @@ class AuthorizationDaoIT { UserDto user = db.users().insertUser(); // logged-in user - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), ProjectPermission.CODEVIEWER)) .containsOnly(Project.getUuid()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), ProjectPermission.USER)) .containsOnly(Project.getUuid()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), user.getUuid(), ProjectPermission.ADMIN)) .isEmpty(); // anonymous - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, UserRole.CODEVIEWER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, ProjectPermission.CODEVIEWER)) .containsOnly(Project.getUuid()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, UserRole.USER)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, ProjectPermission.USER)) .containsOnly(Project.getUuid()); - assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedEntityUuids(dbSession, newHashSet(Project.getUuid()), null, ProjectPermission.ADMIN)) .isEmpty(); } @@ -1148,21 +1147,21 @@ class AuthorizationDaoIT { // admin with "direct" ADMIN role UserDto admin1 = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(admin1, UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(admin1, ProjectPermission.ADMIN, project); // admin2 with ADMIN role through group UserDto admin2 = db.users().insertUser(); GroupDto adminGroup = db.users().insertGroup("ADMIN"); db.users().insertMember(adminGroup, admin2); - db.users().insertEntityPermissionOnGroup(adminGroup, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(adminGroup, ProjectPermission.ADMIN, project); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin()); assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin(), admin1.getLogin(), admin2.getLogin()), - project.getKey(), UserRole.USER)) + project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin(), admin1.getLogin(), admin2.getLogin()); assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin(), admin1.getLogin(), admin2.getLogin()), - project.getKey(), UserRole.ADMIN)) + project.getKey(), ProjectPermission.ADMIN)) .containsOnly(admin1.getLogin(), admin2.getLogin()); } @@ -1172,12 +1171,12 @@ class AuthorizationDaoIT { GroupDto userGroup = db.users().insertGroup("USERS"); GroupDto adminGroup = db.users().insertGroup("ADMIN"); - db.users().insertEntityPermissionOnGroup(userGroup, UserRole.USER, project); - db.users().insertEntityPermissionOnGroup(adminGroup, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(userGroup, ProjectPermission.USER, project); + db.users().insertEntityPermissionOnGroup(adminGroup, ProjectPermission.ADMIN, project); // admin with "direct" ADMIN role UserDto admin1 = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(admin1, UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(admin1, ProjectPermission.ADMIN, project); // admin2 with ADMIN role through group UserDto admin2 = db.users().insertUser(); @@ -1185,7 +1184,7 @@ class AuthorizationDaoIT { // user1 with "direct" USER role UserDto user1 = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(user1, UserRole.USER, project); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.USER, project); // user2 with USER role through group UserDto user2 = db.users().insertUser(); @@ -1194,17 +1193,17 @@ class AuthorizationDaoIT { // user without role UserDto userWithNoRole = db.users().insertUser(); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(userWithNoRole.getLogin()), project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(userWithNoRole.getLogin()), project.getKey(), ProjectPermission.USER)) .isEmpty(); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin()); Set<String> allLogins = newHashSet(admin1.getLogin(), admin2.getLogin(), user1.getLogin(), user2.getLogin(), userWithNoRole.getLogin()); // Admin does not have the USER permission set - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin(), user2.getLogin()); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), ProjectPermission.ADMIN)) .containsOnly(admin1.getLogin(), admin2.getLogin()); } @@ -1215,12 +1214,12 @@ class AuthorizationDaoIT { GroupDto userGroup = db.users().insertGroup("USERS"); GroupDto adminGroup = db.users().insertGroup("ADMIN"); - db.users().insertEntityPermissionOnGroup(userGroup, UserRole.USER, project); - db.users().insertEntityPermissionOnGroup(adminGroup, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(userGroup, ProjectPermission.USER, project); + db.users().insertEntityPermissionOnGroup(adminGroup, ProjectPermission.ADMIN, project); // admin with "direct" ADMIN role UserDto admin1 = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(admin1, UserRole.ADMIN, project); + db.users().insertProjectPermissionOnUser(admin1, ProjectPermission.ADMIN, project); // admin2 with ADMIN role through group UserDto admin2 = db.users().insertUser(); @@ -1228,7 +1227,7 @@ class AuthorizationDaoIT { // user1 with "direct" USER role UserDto user1 = db.users().insertUser(); - db.users().insertProjectPermissionOnUser(user1, UserRole.USER, project); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.USER, project); // user2 with USER role through group UserDto user2 = db.users().insertUser(); @@ -1237,17 +1236,17 @@ class AuthorizationDaoIT { // user without role UserDto userWithNoRole = db.users().insertUser(); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(userWithNoRole.getLogin()), project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(userWithNoRole.getLogin()), project.getKey(), ProjectPermission.USER)) .isEmpty(); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, newHashSet(user1.getLogin()), project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin()); Set<String> allLogins = newHashSet(admin1.getLogin(), admin2.getLogin(), user1.getLogin(), user2.getLogin(), userWithNoRole.getLogin()); // Admin does not have the USER permission set - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), UserRole.USER)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), ProjectPermission.USER)) .containsOnly(user1.getLogin(), user2.getLogin()); - assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), UserRole.ADMIN)) + assertThat(underTest.keepAuthorizedLoginsOnEntity(dbSession, allLogins, project.getKey(), ProjectPermission.ADMIN)) .containsOnly(admin1.getLogin(), admin2.getLogin()); } diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoIT.java index 9f640b326a0..04563dc062a 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoIT.java @@ -31,7 +31,6 @@ import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.audit.NoOpAuditPersister; @@ -70,19 +69,19 @@ class GroupPermissionDaoIT { ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project3 = db.components().insertPrivateProject().getProjectDto(); - db.users().insertEntityPermissionOnGroup(group1, UserRole.ISSUE_ADMIN, project1); - db.users().insertEntityPermissionOnGroup(group1, UserRole.ADMIN, project2); - db.users().insertEntityPermissionOnGroup(group2, UserRole.ADMIN, project2); - db.users().insertEntityPermissionOnGroup(group3, UserRole.ADMIN, project2); - db.users().insertEntityPermissionOnGroup(group1, UserRole.USER, project2); - db.users().insertEntityPermissionOnGroup(group1, UserRole.USER, project3); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ISSUE_ADMIN, project1); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ADMIN, project2); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.ADMIN, project2); + db.users().insertEntityPermissionOnGroup(group3, ProjectPermission.ADMIN, project2); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.USER, project2); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.USER, project3); final List<CountPerEntityPermission> result = new ArrayList<>(); underTest.groupsCountByComponentUuidAndPermission(dbSession, asList(project2.getUuid(), project3.getUuid(), "789"), context -> result.add(context.getResultObject())); assertThat(result).hasSize(3); - assertThat(result).extracting("permission").containsOnly(UserRole.ADMIN, UserRole.USER); + assertThat(result).extracting("permission").containsOnly(ProjectPermission.ADMIN.getKey(), ProjectPermission.USER.getKey()); assertThat(result).extracting("entityUuid").containsOnly(project2.getUuid(), project3.getUuid()); assertThat(result).extracting("count").containsOnly(3, 1); } @@ -195,7 +194,7 @@ class GroupPermissionDaoIT { db.users().insertPermissionOnAnyone(GlobalPermission.PROVISION_PROJECTS); db.users().insertPermissionOnGroup(group1, GlobalPermission.SCAN); db.users().insertPermissionOnGroup(group3, GlobalPermission.ADMINISTER); - db.users().insertEntityPermissionOnGroup(group2, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.ADMIN, project); assertThat(underTest.selectGroupNamesByQuery(dbSession, newQuery().setPermission(GlobalPermission.SCAN.getKey()).build())).containsExactly(ANYONE, group1.getName()); @@ -247,8 +246,8 @@ class GroupPermissionDaoIT { db.users().insertEntityPermissionOnGroup(group1, GlobalPermission.SCAN.getKey(), project); db.users().insertEntityPermissionOnGroup(group1, GlobalPermission.PROVISION_PROJECTS.getKey(), project); - db.users().insertEntityPermissionOnGroup(group1, UserRole.ADMIN, anotherProject); - db.users().insertEntityPermissionOnGroup(group3, UserRole.SCAN, anotherProject); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ADMIN, anotherProject); + db.users().insertEntityPermissionOnGroup(group3, ProjectPermission.SCAN, anotherProject); db.users().insertPermissionOnGroup(group2, GlobalPermission.SCAN); PermissionQuery.Builder builderOnComponent = newQuery() @@ -258,7 +257,7 @@ class GroupPermissionDaoIT { assertThat(underTest.selectGroupNamesByQuery(dbSession, builderOnComponent.setPermission(GlobalPermission.SCAN.getKey()).build())).containsOnlyOnce(group1.getName()); assertThat(underTest.selectGroupNamesByQuery(dbSession, - builderOnComponent.setPermission(UserRole.USER).build())).isEmpty(); + builderOnComponent.setPermission(ProjectPermission.USER).build())).isEmpty(); } @Test @@ -297,7 +296,7 @@ class GroupPermissionDaoIT { GroupDto group2 = db.users().insertGroup("Group-2"); ProjectDto project = db.components().insertPrivateProject().getProjectDto(); - db.users().insertEntityPermissionOnGroup(group2, UserRole.ADMIN, project); + db.users().insertEntityPermissionOnGroup(group2, ProjectPermission.ADMIN, project); GroupDto group3 = db.users().insertGroup("Group-3"); db.users().insertPermissionOnGroup(group3, GlobalPermission.ADMINISTER); @@ -370,10 +369,10 @@ class GroupPermissionDaoIT { GroupDto group2 = db.users().insertGroup("Group-2"); ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent(); - db.users().insertProjectPermissionOnGroup(group2, UserRole.USER, project); + db.users().insertProjectPermissionOnGroup(group2, ProjectPermission.USER, project); GroupDto group3 = db.users().insertGroup("Group-3"); - db.users().insertProjectPermissionOnGroup(group3, UserRole.USER, project); + db.users().insertProjectPermissionOnGroup(group3, ProjectPermission.USER, project); // Anyone group db.users().insertPermissionOnAnyone(GlobalPermission.SCAN); @@ -382,11 +381,11 @@ class GroupPermissionDaoIT { assertThat(underTest.selectByGroupUuids(dbSession, singletonList(group2.getUuid()), project.uuid())) .extracting(GroupPermissionDto::getGroupUuid, GroupPermissionDto::getRole, GroupPermissionDto::getEntityUuid) - .containsOnly(tuple(group2.getUuid(), UserRole.USER, project.uuid())); + .containsOnly(tuple(group2.getUuid(), ProjectPermission.USER.getKey(), project.uuid())); assertThat(underTest.selectByGroupUuids(dbSession, singletonList(group3.getUuid()), project.uuid())) .extracting(GroupPermissionDto::getGroupUuid, GroupPermissionDto::getRole, GroupPermissionDto::getEntityUuid) - .containsOnly(tuple(group3.getUuid(), UserRole.USER, project.uuid())); + .containsOnly(tuple(group3.getUuid(), ProjectPermission.USER.getKey(), project.uuid())); assertThat(underTest.selectByGroupUuids(dbSession, singletonList(ANYONE_UUID), project.uuid())) .isEmpty(); @@ -527,7 +526,7 @@ class GroupPermissionDaoIT { GroupDto group = db.users().insertGroup(); db.users().insertProjectPermissionOnGroup(group, "foo", project.getMainBranchComponent()); - assertThat(underTest.selectGroupUuidsWithPermissionOnEntityBut(dbSession, "1234", UserRole.USER)) + assertThat(underTest.selectGroupUuidsWithPermissionOnEntityBut(dbSession, "1234", ProjectPermission.USER)) .isEmpty(); } diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoWithPersisterIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoWithPersisterIT.java index e81f33a54de..51c7d24aa3d 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoWithPersisterIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/GroupPermissionDaoWithPersisterIT.java @@ -38,8 +38,8 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; -import static org.sonar.api.web.UserRole.ADMIN; import static org.sonar.core.util.SequenceUuidFactory.UUID_1; +import static org.sonar.db.permission.ProjectPermission.ADMIN; class GroupPermissionDaoWithPersisterIT { private final AuditPersister auditPersister = mock(AuditPersister.class); @@ -100,7 +100,7 @@ class GroupPermissionDaoWithPersisterIT { verify(auditPersister).deleteGroupPermission(eq(dbSession), newValueCaptor.capture()); newValue = newValueCaptor.getValue(); - assertNewValue(newValue, null, null, null, project.projectUuid(), null, project.projectKey(), project.getProjectDto().getName(), "TRK"); + assertNewValue(newValue, null, null, null, project.projectUuid(), (String) null, project.projectKey(), project.getProjectDto().getName(), "TRK"); assertThat(newValue).hasToString("{\"componentUuid\": \"projectUuid\", \"componentKey\": \"cKey\", \"componentName\": \"cname\", " + "\"qualifier\": \"project\" }"); } @@ -132,7 +132,7 @@ class GroupPermissionDaoWithPersisterIT { verify(auditPersister).deleteGroupPermission(eq(dbSession), newValueCaptor.capture()); newValue = newValueCaptor.getValue(); - assertNewValue(newValue, null, null, null, project.projectUuid(), null, project.projectKey(), project.getProjectDto().getName(), "TRK"); + assertNewValue(newValue, null, null, null, project.projectUuid(), (String) null, project.projectKey(), project.getProjectDto().getName(), "TRK"); assertThat(newValue).hasToString("{\"componentUuid\": \"projectUuid\", \"componentKey\": \"cKey\", " + "\"componentName\": \"cname\", \"qualifier\": \"project\" }"); } @@ -181,6 +181,12 @@ class GroupPermissionDaoWithPersisterIT { } private void assertNewValue(GroupPermissionNewValue newValue, String uuid, String groupUuid, String groupName, String cUuid, + ProjectPermission permission, + String componentKey, String cName, String qualifier) { + assertNewValue(newValue, uuid, groupUuid, groupName, cUuid, permission.getKey(), componentKey, cName, qualifier); + } + + private void assertNewValue(GroupPermissionNewValue newValue, String uuid, String groupUuid, String groupName, String cUuid, String permission, String componentKey, String cName, String qualifier) { assertThat(newValue) diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/UserPermissionDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/UserPermissionDaoIT.java index 1162a9e3778..34a7122ab06 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/UserPermissionDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/UserPermissionDaoIT.java @@ -30,7 +30,6 @@ import org.assertj.core.groups.Tuple; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.Uuids; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -68,7 +67,7 @@ class UserPermissionDaoIT { UserPermissionDto global1 = addGlobalPermission(GlobalPermission.ADMINISTER.getKey(), user1); UserPermissionDto global2 = addGlobalPermission(GlobalPermission.ADMINISTER.getKey(), user2); UserPermissionDto global3 = addGlobalPermission(GlobalPermission.PROVISION_PROJECTS.getKey(), user2); - UserPermissionDto project1Perm = addProjectPermission(UserRole.USER, user3, project); + UserPermissionDto project1Perm = addProjectPermission(ProjectPermission.USER, user3, project); // global permissions of users who has at least one global permission, ordered by user name then permission PermissionQuery query = PermissionQuery.builder().withAtLeastOnePermission().build(); @@ -117,10 +116,10 @@ class UserPermissionDaoIT { addGlobalPermission(GlobalPermission.ADMINISTER.getKey(), user1); ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); - UserPermissionDto perm1 = addProjectPermission(UserRole.USER, user1, project1); - UserPermissionDto perm2 = addProjectPermission(UserRole.ISSUE_ADMIN, user1, project1); - UserPermissionDto perm3 = addProjectPermission(UserRole.ISSUE_ADMIN, user2, project1); - addProjectPermission(UserRole.ISSUE_ADMIN, user3, project2); + UserPermissionDto perm1 = addProjectPermission(ProjectPermission.USER, user1, project1); + UserPermissionDto perm2 = addProjectPermission(ProjectPermission.ISSUE_ADMIN, user1, project1); + UserPermissionDto perm3 = addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project1); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user3, project2); // project permissions of users who has at least one permission on this project PermissionQuery query = PermissionQuery.builder().withAtLeastOnePermission().setEntity(project1).build(); @@ -135,7 +134,7 @@ class UserPermissionDaoIT { expectPermissions(query, asList(user2.getUuid(), user1.getUuid()), perm3, perm2, perm1); // search by user name (matches 2 users) and project permission - query = PermissionQuery.builder().setSearchQuery("Mari").setPermission(UserRole.ISSUE_ADMIN).setEntity(project1).build(); + query = PermissionQuery.builder().setSearchQuery("Mari").setPermission(ProjectPermission.ISSUE_ADMIN).setEntity(project1).build(); expectPermissions(query, asList(user2.getUuid(), user1.getUuid()), perm3, perm2); // search by user name (no match) @@ -208,9 +207,9 @@ class UserPermissionDaoIT { UserDto user2 = insertUser(u -> u.setLogin("login2").setName("A").setEmail("email2@email.com")); addGlobalPermission(GlobalPermission.ADMINISTER.getKey(), user1); ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); - addProjectPermission(UserRole.USER, user2, project1); - addProjectPermission(UserRole.USER, user1, project1); - addProjectPermission(UserRole.ADMIN, user1, project1); + addProjectPermission(ProjectPermission.USER, user2, project1); + addProjectPermission(ProjectPermission.USER, user1, project1); + addProjectPermission(ProjectPermission.ADMIN, user1, project1); PermissionQuery query = PermissionQuery.builder().build(); @@ -226,24 +225,24 @@ class UserPermissionDaoIT { ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); addGlobalPermission(GlobalPermission.ADMINISTER.getKey(), user1); - addProjectPermission(UserRole.USER, user1, project1); - addProjectPermission(UserRole.ISSUE_ADMIN, user1, project1); - addProjectPermission(UserRole.ISSUE_ADMIN, user2, project1); - addProjectPermission(UserRole.ISSUE_ADMIN, user2, project2); + addProjectPermission(ProjectPermission.USER, user1, project1); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user1, project1); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project1); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project2); // no projects -> return empty list assertThat(underTest.countUsersByEntityPermission(dbSession, emptyList())).isEmpty(); // one project expectCount(singletonList(project1.getUuid()), - new CountPerEntityPermission(project1.getUuid(), UserRole.USER, 1), - new CountPerEntityPermission(project1.getUuid(), UserRole.ISSUE_ADMIN, 2)); + new CountPerEntityPermission(project1.getUuid(), ProjectPermission.USER, 1), + new CountPerEntityPermission(project1.getUuid(), ProjectPermission.ISSUE_ADMIN, 2)); // multiple projects expectCount(asList(project1.getUuid(), project2.getUuid(), "invalid"), - new CountPerEntityPermission(project1.getUuid(), UserRole.USER, 1), - new CountPerEntityPermission(project1.getUuid(), UserRole.ISSUE_ADMIN, 2), - new CountPerEntityPermission(project2.getUuid(), UserRole.ISSUE_ADMIN, 1)); + new CountPerEntityPermission(project1.getUuid(), ProjectPermission.USER, 1), + new CountPerEntityPermission(project1.getUuid(), ProjectPermission.ISSUE_ADMIN, 2), + new CountPerEntityPermission(project2.getUuid(), ProjectPermission.ISSUE_ADMIN, 1)); } @Test @@ -252,9 +251,9 @@ class UserPermissionDaoIT { UserDto user2 = insertUser(u -> u.setLogin("login2").setName("Marie").setEmail("email2@email.com")); ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); - addProjectPermission(UserRole.USER, user1, project1); - addProjectPermission(UserRole.USER, user2, project1); - addProjectPermission(UserRole.ISSUE_ADMIN, user2, project1); + addProjectPermission(ProjectPermission.USER, user1, project1); + addProjectPermission(ProjectPermission.USER, user2, project1); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project1); // logins are ordered by user name: user2 ("Marie") then user1 ("Marius") PermissionQuery query = PermissionQuery.builder().setEntity(project1).withAtLeastOnePermission().build(); @@ -285,9 +284,9 @@ class UserPermissionDaoIT { UserDto user2 = insertUser(u -> u.setLogin("login2").setName("Marie").setEmail("email2@email.com")); ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); - addProjectPermission(UserRole.USER, user1, project1); + addProjectPermission(ProjectPermission.USER, user1, project1); addGlobalPermission(GlobalPermission.PROVISION_PROJECTS.getKey(), user1); - addProjectPermission(UserRole.ISSUE_ADMIN, user2, project2); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project2); PermissionQuery query = PermissionQuery.builder().build(); List<String> result = underTest.selectUserUuidsByQueryAndScope(dbSession, query); @@ -302,9 +301,9 @@ class UserPermissionDaoIT { UserDto user2 = insertUser(u -> u.setLogin("login2").setName("Marie").setEmail("email2@email.com")); ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); ProjectDto project2 = db.components().insertPrivateProject().getProjectDto(); - addProjectPermission(UserRole.USER, user1, project1); + addProjectPermission(ProjectPermission.USER, user1, project1); addGlobalPermission(GlobalPermission.PROVISION_PROJECTS.getKey(), user1); - addProjectPermission(UserRole.ISSUE_ADMIN, user2, project2); + addProjectPermission(ProjectPermission.ISSUE_ADMIN, user2, project2); PermissionQuery query = PermissionQuery.builder() .setEntity(project1) .build(); @@ -459,7 +458,7 @@ class UserPermissionDaoIT { UserDto user = insertUser(); db.users().insertProjectPermissionOnUser(user, "foo", project.getMainBranchComponent()); - assertThat(underTest.selectUserIdsWithPermissionOnEntityBut(dbSession, "1234", UserRole.USER)) + assertThat(underTest.selectUserIdsWithPermissionOnEntityBut(dbSession, "1234", ProjectPermission.USER.getKey())) .isEmpty(); } @@ -579,7 +578,8 @@ class UserPermissionDaoIT { assertThat(underTest.selectEntityPermissionsOfUser(dbSession, user1.getUuid(), project1.projectUuid())).isEmpty(); assertThat(underTest.selectEntityPermissionsOfUser(dbSession, user2.getUuid(), project1.projectUuid())).isEmpty(); assertThat(underTest.selectEntityPermissionsOfUser(dbSession, user1.getUuid(), project2.projectUuid())).containsOnly(GlobalPermission.SCAN.getKey()); - assertThat(underTest.selectEntityPermissionsOfUser(dbSession, user2.getUuid(), project2.projectUuid())).containsOnly(GlobalPermission.SCAN.getKey(), GlobalPermission.PROVISION_PROJECTS.getKey()); + assertThat(underTest.selectEntityPermissionsOfUser(dbSession, user2.getUuid(), project2.projectUuid())).containsOnly(GlobalPermission.SCAN.getKey(), + GlobalPermission.PROVISION_PROJECTS.getKey()); deletedCount = underTest.deleteEntityPermissionOfAnyUser(dbSession, GlobalPermission.SCAN.getKey(), project2.getProjectDto()); @@ -639,6 +639,10 @@ class UserPermissionDaoIT { return dto; } + private UserPermissionDto addProjectPermission(ProjectPermission permission, UserDto user, EntityDto project) { + return addProjectPermission(permission.getKey(), user, project); + } + private UserPermissionDto addProjectPermission(String permission, UserDto user, EntityDto project) { UserPermissionDto dto = new UserPermissionDto(Uuids.create(), permission, user.getUuid(), project.getUuid()); underTest.insert(dbSession, dto, project, user, null); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/GroupWithPermissionTemplateDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/GroupWithPermissionTemplateDaoIT.java index 382fbc885b6..4367f147b0c 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/GroupWithPermissionTemplateDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/GroupWithPermissionTemplateDaoIT.java @@ -25,7 +25,7 @@ import java.util.stream.IntStream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.permission.PermissionQuery; @@ -34,8 +34,8 @@ import org.sonar.db.user.GroupDto; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS; import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE; import static org.sonar.db.permission.PermissionQuery.builder; @@ -95,7 +95,7 @@ class GroupWithPermissionTemplateDaoIT { GroupDto group2 = db.users().insertGroup("B"); GroupDto group3 = db.users().insertGroup("C"); - permissionTemplateDbTester.addGroupToTemplate(template, group3, UserRole.USER); + permissionTemplateDbTester.addGroupToTemplate(template, group3, ProjectPermission.USER); PermissionQuery query = PermissionQuery.builder().build(); assertThat(underTest.selectGroupNamesByQueryAndTemplate(db.getSession(), query, template.getUuid())) @@ -108,7 +108,7 @@ class GroupWithPermissionTemplateDaoIT { IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> db.users().insertGroup("Group-" + i)); String lastGroupName = "Group-" + (DEFAULT_PAGE_SIZE + 1); - permissionTemplateDbTester.addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), UserRole.USER); + permissionTemplateDbTester.addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), ProjectPermission.USER); PermissionQuery query = PermissionQuery.builder().build(); assertThat(underTest.selectGroupNamesByQueryAndTemplate(db.getSession(), query, template.getUuid())) @@ -122,11 +122,11 @@ class GroupWithPermissionTemplateDaoIT { PermissionTemplateDto otherTemplate = permissionTemplateDbTester.insertTemplate(); IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> { GroupDto group = db.users().insertGroup("Group-" + i); - permissionTemplateDbTester.addGroupToTemplate(otherTemplate, group, UserRole.USER); + permissionTemplateDbTester.addGroupToTemplate(otherTemplate, group, ProjectPermission.USER); }); String lastGroupName = "Group-" + (DEFAULT_PAGE_SIZE + 1); - permissionTemplateDbTester.addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), UserRole.USER); + permissionTemplateDbTester.addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), ProjectPermission.USER); PermissionQuery query = PermissionQuery.builder().build(); assertThat(underTest.selectGroupNamesByQueryAndTemplate(db.getSession(), query, template.getUuid())) @@ -216,8 +216,8 @@ class GroupWithPermissionTemplateDaoIT { .extracting(PermissionTemplateGroupDto::getGroupUuid, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission) .containsOnly( - tuple(group1.getUuid(), "Group-1", USER), - tuple(group1.getUuid(), "Group-1", ADMIN)); + tuple(group1.getUuid(), "Group-1", USER.getKey()), + tuple(group1.getUuid(), "Group-1", ADMIN.getKey())); assertThat(underTest.selectGroupPermissionsByTemplateIdAndGroupNames(session, anotherTemplate.getUuid(), asList("Group-1"))) .extracting(PermissionTemplateGroupDto::getGroupUuid, PermissionTemplateGroupDto::getGroupName, @@ -229,7 +229,7 @@ class GroupWithPermissionTemplateDaoIT { .extracting(PermissionTemplateGroupDto::getGroupUuid, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission) .containsOnly( - tuple("Anyone", "Anyone", USER)); + tuple("Anyone", "Anyone", USER.getKey())); assertThat(underTest.selectGroupPermissionsByTemplateIdAndGroupNames(session, template.getUuid(), asList("Group-1", "Group-2", "Anyone"))).hasSize(3); @@ -258,15 +258,15 @@ class GroupWithPermissionTemplateDaoIT { .extracting(PermissionTemplateGroupDto::getGroupUuid, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission) .containsOnly( - tuple(group1.getUuid(), "Group-1", USER), - tuple(group1.getUuid(), "Group-1", ADMIN), + tuple(group1.getUuid(), "Group-1", USER.getKey()), + tuple(group1.getUuid(), "Group-1", ADMIN.getKey()), tuple(group2.getUuid(), "Group-2", PROVISION_PROJECTS.getKey())); assertThat(underTest.selectGroupPermissionsByTemplateUuid(session, anotherTemplate.getUuid())) .extracting(PermissionTemplateGroupDto::getGroupUuid, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission) .containsOnly( tuple(group1.getUuid(), "Group-1", PROVISION_PROJECTS.getKey()), - tuple("Anyone", "Anyone", USER)); + tuple("Anyone", "Anyone", USER.getKey())); assertThat(underTest.selectGroupPermissionsByTemplateUuid(session, "321")).isEmpty(); } diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoIT.java index ed49ce3fd1c..d275eb56563 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoIT.java @@ -24,7 +24,7 @@ import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.audit.NoOpAuditPersister; @@ -46,7 +46,7 @@ class PermissionTemplateCharacteristicDaoIT { void selectByTemplateId_filter_by_template_uuid() { PermissionTemplateCharacteristicDto templatePermission1 = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid1") - .setPermission(UserRole.ADMIN) + .setPermission(ProjectPermission.ADMIN) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(1_000_000_000L) @@ -54,7 +54,7 @@ class PermissionTemplateCharacteristicDaoIT { "template"); PermissionTemplateCharacteristicDto templatePermission2 = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid2") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("2") .setWithProjectCreator(false) .setCreatedAt(1_000_000_000L) @@ -62,7 +62,7 @@ class PermissionTemplateCharacteristicDaoIT { "template"); PermissionTemplateCharacteristicDto templatePermission3 = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid3") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("3") .setWithProjectCreator(false) .setCreatedAt(1_000_000_001L) @@ -71,7 +71,7 @@ class PermissionTemplateCharacteristicDaoIT { PermissionTemplateCharacteristicDto templatePermissionForAnotherTemplate = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid4") - .setPermission(UserRole.ADMIN) + .setPermission(ProjectPermission.ADMIN) .setTemplateUuid("42") .setWithProjectCreator(true) .setCreatedAt(1_000_000_000L) @@ -99,7 +99,7 @@ class PermissionTemplateCharacteristicDaoIT { void selectByPermissionAndTemplateId() { PermissionTemplateCharacteristicDto templatePermission1 = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid1") - .setPermission(UserRole.ADMIN) + .setPermission(ProjectPermission.ADMIN) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(1_000_000_000L) @@ -107,7 +107,7 @@ class PermissionTemplateCharacteristicDaoIT { "template"); underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid2") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(false) .setCreatedAt(1_000_000_000L) @@ -115,14 +115,14 @@ class PermissionTemplateCharacteristicDaoIT { "template"); underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid3") - .setPermission(UserRole.ADMIN) + .setPermission(ProjectPermission.ADMIN) .setTemplateUuid("42") .setWithProjectCreator(true) .setCreatedAt(1_000_000_000L) .setUpdatedAt(2_000_000_000L), "template"); - Optional<PermissionTemplateCharacteristicDto> result = underTest.selectByPermissionAndTemplateId(dbSession, UserRole.ADMIN, "1"); + Optional<PermissionTemplateCharacteristicDto> result = underTest.selectByPermissionAndTemplateId(dbSession, ProjectPermission.ADMIN, "1"); assertThat(result).isPresent(); assertThat(result.get()).isEqualToComparingFieldByField(templatePermission1); @@ -132,7 +132,7 @@ class PermissionTemplateCharacteristicDaoIT { void insert() { PermissionTemplateCharacteristicDto expectedResult = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) @@ -149,7 +149,7 @@ class PermissionTemplateCharacteristicDaoIT { void update_only_change_with_project_creator_and_updated_at() { PermissionTemplateCharacteristicDto insertedDto = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) @@ -177,7 +177,7 @@ class PermissionTemplateCharacteristicDaoIT { void fail_insert_if_created_at_is_equal_to_0() { PermissionTemplateCharacteristicDto characteristicDto = new PermissionTemplateCharacteristicDto() .setUuid("uuid") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setUpdatedAt(2_000_000_000L); @@ -189,7 +189,7 @@ class PermissionTemplateCharacteristicDaoIT { void fail_insert_if_updated_at_is_equal_to_0() { PermissionTemplateCharacteristicDto characteristicDto = new PermissionTemplateCharacteristicDto() .setUuid("uuid") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(2_000_000_000L); @@ -201,7 +201,7 @@ class PermissionTemplateCharacteristicDaoIT { @Test void fail_update_if_uuid_is_null() { PermissionTemplateCharacteristicDto characteristicDto = new PermissionTemplateCharacteristicDto() - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) @@ -214,7 +214,7 @@ class PermissionTemplateCharacteristicDaoIT { void delete_by_permission_template_uuid() { underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid1") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) @@ -222,7 +222,7 @@ class PermissionTemplateCharacteristicDaoIT { "template"); underTest.insert(dbSession, new PermissionTemplateCharacteristicDto() .setUuid("uuid2") - .setPermission(UserRole.USER) + .setPermission(ProjectPermission.USER) .setTemplateUuid("2") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoWithPersisterIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoWithPersisterIT.java index 0d35817630b..e7890b25e6c 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoWithPersisterIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoWithPersisterIT.java @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.ArgumentCaptor; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.audit.AuditPersister; @@ -45,7 +45,7 @@ class PermissionTemplateCharacteristicDaoWithPersisterIT { @Test void insertPermissionTemplateCharacteristicIsPersisted() { - PermissionTemplateCharacteristicDto dto = getPermissionTemplateCharacteristic(UserRole.USER); + PermissionTemplateCharacteristicDto dto = getPermissionTemplateCharacteristic(ProjectPermission.USER); underTest.insert(session, dto, "template"); verify(auditPersister).addCharacteristicToPermissionTemplate(eq(session), newValueCaptor.capture()); @@ -59,9 +59,9 @@ class PermissionTemplateCharacteristicDaoWithPersisterIT { @Test void updatePermissionTemplateCharacteristicIsPersisted() { - underTest.insert(session, getPermissionTemplateCharacteristic(UserRole.USER), + underTest.insert(session, getPermissionTemplateCharacteristic(ProjectPermission.USER), "template"); - PermissionTemplateCharacteristicDto updated = getPermissionTemplateCharacteristic(UserRole.ADMIN); + PermissionTemplateCharacteristicDto updated = getPermissionTemplateCharacteristic(ProjectPermission.ADMIN); underTest.update(session, updated, "template"); verify(auditPersister).updateCharacteristicInPermissionTemplate(eq(session), newValueCaptor.capture()); @@ -73,10 +73,10 @@ class PermissionTemplateCharacteristicDaoWithPersisterIT { assertThat(newValue.toString()).contains("withProjectCreator"); } - private PermissionTemplateCharacteristicDto getPermissionTemplateCharacteristic(String role) { + private PermissionTemplateCharacteristicDto getPermissionTemplateCharacteristic(ProjectPermission role) { return new PermissionTemplateCharacteristicDto() .setUuid("uuid") - .setPermission(role) + .setPermission(role.getKey()) .setTemplateUuid("1") .setWithProjectCreator(true) .setCreatedAt(123_456_789L) diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoIT.java index 4e5edc3d579..24dcf253be2 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoIT.java @@ -26,13 +26,13 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.core.util.UuidFactory; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.audit.NoOpAuditPersister; import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; @@ -284,22 +284,22 @@ class PermissionTemplateDaoIT { GroupDto group1 = db.users().insertGroup(newGroupDto()); GroupDto group2 = db.users().insertGroup(newGroupDto()); GroupDto group3 = db.users().insertGroup(newGroupDto()); - templateDb.addGroupToTemplate(template1.getUuid(), group1.getUuid(), UserRole.CODEVIEWER, template1.getName(), group1.getName()); - templateDb.addGroupToTemplate(template1.getUuid(), group2.getUuid(), UserRole.CODEVIEWER, template1.getName(), group2.getName()); - templateDb.addGroupToTemplate(template1.getUuid(), group3.getUuid(), UserRole.CODEVIEWER, template1.getName(), group3.getName()); - templateDb.addGroupToTemplate(template1.getUuid(), null, UserRole.CODEVIEWER, template1.getName(), null); - templateDb.addGroupToTemplate(template1.getUuid(), group1.getUuid(), UserRole.ADMIN, template1.getName(), group1.getName()); - templateDb.addGroupToTemplate(template2.getUuid(), group1.getUuid(), UserRole.ADMIN, template2.getName(), group1.getName()); - templateDb.addGroupToTemplate(template4.getUuid(), group1.getUuid(), UserRole.ISSUE_ADMIN, template4.getName(), group1.getName()); + templateDb.addGroupToTemplate(template1.getUuid(), group1.getUuid(), ProjectPermission.CODEVIEWER, template1.getName(), group1.getName()); + templateDb.addGroupToTemplate(template1.getUuid(), group2.getUuid(), ProjectPermission.CODEVIEWER, template1.getName(), group2.getName()); + templateDb.addGroupToTemplate(template1.getUuid(), group3.getUuid(), ProjectPermission.CODEVIEWER, template1.getName(), group3.getName()); + templateDb.addGroupToTemplate(template1.getUuid(), null, ProjectPermission.CODEVIEWER, template1.getName(), null); + templateDb.addGroupToTemplate(template1.getUuid(), group1.getUuid(), ProjectPermission.ADMIN, template1.getName(), group1.getName()); + templateDb.addGroupToTemplate(template2.getUuid(), group1.getUuid(), ProjectPermission.ADMIN, template2.getName(), group1.getName()); + templateDb.addGroupToTemplate(template4.getUuid(), group1.getUuid(), ProjectPermission.ISSUE_ADMIN, template4.getName(), group1.getName()); final List<CountByTemplateAndPermissionDto> result = new ArrayList<>(); underTest.groupsCountByTemplateUuidAndPermission(dbSession, asList(template1.getUuid(), template2.getUuid(), template3.getUuid()), context -> result.add(context.getResultObject())); assertThat(result).extracting(CountByTemplateAndPermissionDto::getPermission, CountByTemplateAndPermissionDto::getTemplateUuid, - CountByTemplateAndPermissionDto::getCount) - .containsOnly(tuple(UserRole.ADMIN, template1.getUuid(), 1), tuple(UserRole.CODEVIEWER, template1.getUuid(), 4), - tuple(UserRole.ADMIN, template2.getUuid(), 1)); + CountByTemplateAndPermissionDto::getCount) + .containsOnly(tuple(ProjectPermission.ADMIN.getKey(), template1.getUuid(), 1), tuple(ProjectPermission.CODEVIEWER.getKey(), template1.getUuid(), 4), + tuple(ProjectPermission.ADMIN.getKey(), template2.getUuid(), 1)); } @Test @@ -313,12 +313,12 @@ class PermissionTemplateDaoIT { UserDto user2 = db.users().insertUser(); UserDto user3 = db.users().insertUser(); - templateDb.addUserToTemplate(template1.getUuid(), user1.getUuid(), UserRole.ADMIN, template1.getName(), user1.getLogin()); - templateDb.addUserToTemplate(template1.getUuid(), user2.getUuid(), UserRole.ADMIN, template1.getName(), user2.getLogin()); - templateDb.addUserToTemplate(template1.getUuid(), user3.getUuid(), UserRole.ADMIN, template1.getName(), user3.getLogin()); - templateDb.addUserToTemplate(template1.getUuid(), user1.getUuid(), UserRole.USER, template1.getName(), user1.getLogin()); - templateDb.addUserToTemplate(template2.getUuid(), user1.getUuid(), UserRole.USER, template2.getName(), user1.getLogin()); - templateDb.addUserToTemplate(anotherTemplate.getUuid(), user1.getUuid(), UserRole.ISSUE_ADMIN, anotherTemplate.getName(), + templateDb.addUserToTemplate(template1.getUuid(), user1.getUuid(), ProjectPermission.ADMIN, template1.getName(), user1.getLogin()); + templateDb.addUserToTemplate(template1.getUuid(), user2.getUuid(), ProjectPermission.ADMIN, template1.getName(), user2.getLogin()); + templateDb.addUserToTemplate(template1.getUuid(), user3.getUuid(), ProjectPermission.ADMIN, template1.getName(), user3.getLogin()); + templateDb.addUserToTemplate(template1.getUuid(), user1.getUuid(), ProjectPermission.USER, template1.getName(), user1.getLogin()); + templateDb.addUserToTemplate(template2.getUuid(), user1.getUuid(), ProjectPermission.USER, template2.getName(), user1.getLogin()); + templateDb.addUserToTemplate(anotherTemplate.getUuid(), user1.getUuid(), ProjectPermission.ISSUE_ADMIN, anotherTemplate.getName(), user1.getLogin()); final List<CountByTemplateAndPermissionDto> result = new ArrayList<>(); @@ -328,9 +328,9 @@ class PermissionTemplateDaoIT { .extracting(CountByTemplateAndPermissionDto::getPermission, CountByTemplateAndPermissionDto::getTemplateUuid, CountByTemplateAndPermissionDto::getCount) .containsExactlyInAnyOrder( - tuple(UserRole.ADMIN, template1.getUuid(), 3), - tuple(UserRole.USER, template1.getUuid(), 1), - tuple(UserRole.USER, template2.getUuid(), 1)); + tuple(ProjectPermission.ADMIN.getKey(), template1.getUuid(), 3), + tuple(ProjectPermission.USER.getKey(), template1.getUuid(), 1), + tuple(ProjectPermission.USER.getKey(), template2.getUuid(), 1)); } @Test @@ -357,21 +357,22 @@ class PermissionTemplateDaoIT { db.users().insertMember(group, user); PermissionTemplateDto template = templateDb.insertTemplate(); templateDb.addProjectCreatorToTemplate(template.getUuid(), GlobalPermission.SCAN.getKey(), template.getName()); - templateDb.addProjectCreatorToTemplate(template.getUuid(), UserRole.ADMIN, template.getName()); - templateDb.addUserToTemplate(template.getUuid(), user.getUuid(), UserRole.USER, template.getName(), user.getLogin()); - templateDb.addUserToTemplate(template.getUuid(), user.getUuid(), UserRole.ADMIN, template.getName(), user.getLogin()); - templateDb.addGroupToTemplate(template.getUuid(), group.getUuid(), UserRole.CODEVIEWER, template.getName(), group.getName()); - templateDb.addGroupToTemplate(template.getUuid(), group.getUuid(), UserRole.ADMIN, template.getName(), group.getName()); - templateDb.addGroupToTemplate(template.getUuid(), null, UserRole.ISSUE_ADMIN, template.getName(), null); + templateDb.addProjectCreatorToTemplate(template.getUuid(), ProjectPermission.ADMIN, template.getName()); + templateDb.addUserToTemplate(template.getUuid(), user.getUuid(), ProjectPermission.USER, template.getName(), user.getLogin()); + templateDb.addUserToTemplate(template.getUuid(), user.getUuid(), ProjectPermission.ADMIN, template.getName(), user.getLogin()); + templateDb.addGroupToTemplate(template.getUuid(), group.getUuid(), ProjectPermission.CODEVIEWER, template.getName(), group.getName()); + templateDb.addGroupToTemplate(template.getUuid(), group.getUuid(), ProjectPermission.ADMIN, template.getName(), group.getName()); + templateDb.addGroupToTemplate(template.getUuid(), null, ProjectPermission.ISSUE_ADMIN, template.getName(), null); List<String> resultWithUser = underTest.selectPotentialPermissionsByUserUuidAndTemplateUuid(dbSession, user.getUuid(), template.getUuid()); List<String> resultWithoutUser = underTest.selectPotentialPermissionsByUserUuidAndTemplateUuid(dbSession, null, template.getUuid()); - assertThat(resultWithUser).containsOnlyOnce(GlobalPermission.SCAN.getKey(), UserRole.ADMIN, UserRole.USER, UserRole.CODEVIEWER, - UserRole.ISSUE_ADMIN); + assertThat(resultWithUser).containsOnlyOnce(ProjectPermission.SCAN.getKey(), ProjectPermission.ADMIN.getKey(), ProjectPermission.USER.getKey(), + ProjectPermission.CODEVIEWER.getKey(), + ProjectPermission.ISSUE_ADMIN.getKey()); // only permission from anyone group - assertThat(resultWithoutUser).containsOnly(UserRole.ISSUE_ADMIN); + assertThat(resultWithoutUser).containsOnly(ProjectPermission.ISSUE_ADMIN.getKey()); } @Test diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoWithPersisterIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoWithPersisterIT.java index b9126a5953f..6a12c5222b9 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoWithPersisterIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/PermissionTemplateDaoWithPersisterIT.java @@ -36,7 +36,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; -import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.db.permission.ProjectPermission.ADMIN; import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto; import static org.sonar.db.user.GroupTesting.newGroupDto; @@ -110,7 +110,7 @@ class PermissionTemplateDaoWithPersisterIT { assertThat(newValue) .extracting(PermissionTemplateNewValue::getTemplateUuid, PermissionTemplateNewValue::getName, PermissionTemplateNewValue::getPermission, PermissionTemplateNewValue::getUserUuid, PermissionTemplateNewValue::getUserLogin) - .containsExactly(dto.getUuid(), dto.getName(), ADMIN, user.getUuid(), user.getLogin()); + .containsExactly(dto.getUuid(), dto.getName(), ADMIN.getKey(), user.getUuid(), user.getLogin()); assertThat(newValue.toString()).doesNotContain("groupUuid"); underTest.deleteUserPermission(session, dto.getUuid(), user.getUuid(), ADMIN, dto.getName(), user.getLogin()); @@ -120,7 +120,7 @@ class PermissionTemplateDaoWithPersisterIT { assertThat(newValue) .extracting(PermissionTemplateNewValue::getTemplateUuid, PermissionTemplateNewValue::getName, PermissionTemplateNewValue::getPermission, PermissionTemplateNewValue::getUserUuid, PermissionTemplateNewValue::getUserLogin) - .containsExactly(dto.getUuid(), dto.getName(), ADMIN, user.getUuid(), user.getLogin()); + .containsExactly(dto.getUuid(), dto.getName(), ADMIN.getKey(), user.getUuid(), user.getLogin()); assertThat(newValue.toString()).doesNotContain("groupUuid"); } @@ -166,7 +166,7 @@ class PermissionTemplateDaoWithPersisterIT { assertThat(newValue) .extracting(PermissionTemplateNewValue::getTemplateUuid, PermissionTemplateNewValue::getName, PermissionTemplateNewValue::getPermission, PermissionTemplateNewValue::getGroupUuid, PermissionTemplateNewValue::getGroupName) - .containsExactly(dto.getUuid(), dto.getName(), ADMIN, group.getUuid(), group.getName()); + .containsExactly(dto.getUuid(), dto.getName(), ADMIN.getKey(), group.getUuid(), group.getName()); assertThat(newValue.toString()).contains("groupUuid"); underTest.deleteGroupPermission(session, dto.getUuid(), group.getUuid(), ADMIN, dto.getName(), group.getName()); @@ -176,7 +176,7 @@ class PermissionTemplateDaoWithPersisterIT { assertThat(newValue) .extracting(PermissionTemplateNewValue::getTemplateUuid, PermissionTemplateNewValue::getName, PermissionTemplateNewValue::getPermission, PermissionTemplateNewValue::getGroupUuid, PermissionTemplateNewValue::getGroupName) - .containsExactly(dto.getUuid(), dto.getName(), ADMIN, group.getUuid(), group.getName()); + .containsExactly(dto.getUuid(), dto.getName(), ADMIN.getKey(), group.getUuid(), group.getName()); assertThat(newValue.toString()).contains("groupUuid"); } @@ -206,7 +206,7 @@ class PermissionTemplateDaoWithPersisterIT { assertThat(newValue) .extracting(PermissionTemplateNewValue::getTemplateUuid, PermissionTemplateNewValue::getName, PermissionTemplateNewValue::getPermission, PermissionTemplateNewValue::getGroupUuid, PermissionTemplateNewValue::getGroupName) - .containsExactly(templateDto.getUuid(), templateDto.getName(), ADMIN, templateGroupDto.getGroupUuid(), + .containsExactly(templateDto.getUuid(), templateDto.getName(), ADMIN.getKey(), templateGroupDto.getGroupUuid(), templateGroupDto.getGroupName()); assertThat(newValue.toString()).doesNotContain("userUuid"); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/UserWithPermissionTemplateDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/UserWithPermissionTemplateDaoIT.java index 3916abc3e51..e85669305e0 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/UserWithPermissionTemplateDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/permission/template/UserWithPermissionTemplateDaoIT.java @@ -24,7 +24,7 @@ import java.util.stream.IntStream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.permission.PermissionQuery; @@ -34,9 +34,9 @@ import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.ADMIN; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE; import static org.sonar.db.permission.PermissionQuery.builder; @@ -140,7 +140,7 @@ class UserWithPermissionTemplateDaoIT { UserDto user1 = db.users().insertUser(u -> u.setName("A")); UserDto user2 = db.users().insertUser(u -> u.setName("B")); UserDto user3 = db.users().insertUser(u -> u.setName("C")); - db.permissionTemplates().addUserToTemplate(template.getUuid(), user3.getUuid(), UserRole.USER, template.getName(), user3.getLogin()); + db.permissionTemplates().addUserToTemplate(template.getUuid(), user3.getUuid(), ProjectPermission.USER, template.getName(), user3.getLogin()); PermissionQuery query = PermissionQuery.builder().build(); assertThat(underTest.selectUserLoginsByQueryAndTemplate(db.getSession(), query, template.getUuid())) @@ -154,10 +154,10 @@ class UserWithPermissionTemplateDaoIT { PermissionTemplateDto otherTemplate = db.permissionTemplates().insertTemplate(); IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> { UserDto user = db.users().insertUser("User-" + i); - db.permissionTemplates().addUserToTemplate(otherTemplate, user, UserRole.USER); + db.permissionTemplates().addUserToTemplate(otherTemplate, user, ProjectPermission.USER); }); String lastLogin = "User-" + (DEFAULT_PAGE_SIZE + 1); - db.permissionTemplates().addUserToTemplate(template, db.users().selectUserByLogin(lastLogin).get(), UserRole.USER); + db.permissionTemplates().addUserToTemplate(template, db.users().selectUserByLogin(lastLogin).get(), ProjectPermission.USER); PermissionQuery query = PermissionQuery.builder().build(); assertThat(underTest.selectUserLoginsByQueryAndTemplate(db.getSession(), query, template.getUuid())) @@ -219,18 +219,18 @@ class UserWithPermissionTemplateDaoIT { singletonList(user1.getLogin()))) .extracting(PermissionTemplateUserDto::getUserLogin, PermissionTemplateUserDto::getPermission) .containsExactlyInAnyOrder( - tuple(user1.getLogin(), USER), - tuple(user1.getLogin(), ADMIN), - tuple(user1.getLogin(), CODEVIEWER)); + tuple(user1.getLogin(), USER.getKey()), + tuple(user1.getLogin(), ADMIN.getKey()), + tuple(user1.getLogin(), CODEVIEWER.getKey())); assertThat(underTest.selectUserPermissionsByTemplateIdAndUserLogins(dbSession, permissionTemplate.getUuid(), asList(user1.getLogin(), user2.getLogin(), user2.getLogin()))) .extracting(PermissionTemplateUserDto::getUserLogin, PermissionTemplateUserDto::getPermission) .containsExactlyInAnyOrder( - tuple(user1.getLogin(), USER), - tuple(user1.getLogin(), ADMIN), - tuple(user1.getLogin(), CODEVIEWER), - tuple(user2.getLogin(), USER)); + tuple(user1.getLogin(), USER.getKey()), + tuple(user1.getLogin(), ADMIN.getKey()), + tuple(user1.getLogin(), CODEVIEWER.getKey()), + tuple(user2.getLogin(), USER.getKey())); assertThat(underTest.selectUserPermissionsByTemplateIdAndUserLogins(dbSession, permissionTemplate.getUuid(), singletonList("unknown"))).isEmpty(); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectExportDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectExportDaoIT.java index f6b00f3c515..4bf4c263fef 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectExportDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectExportDaoIT.java @@ -34,7 +34,7 @@ import org.sonar.api.issue.Issue; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java index 7f3905764e1..f468306e8f8 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/purge/PurgeDaoIT.java @@ -29,7 +29,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Random; import java.util.Set; @@ -44,7 +46,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.slf4j.event.Level; import org.sonar.api.issue.Issue; -import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.testfixtures.log.LogAndArguments; import org.sonar.api.testfixtures.log.LogTesterJUnit5; import org.sonar.api.utils.System2; @@ -67,6 +68,7 @@ import org.sonar.db.component.BranchDto; import org.sonar.db.component.BranchType; import org.sonar.db.component.ComponentDbTester; import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.component.ComponentTesting; import org.sonar.db.component.ProjectData; import org.sonar.db.component.SnapshotDto; @@ -89,10 +91,6 @@ import org.sonar.db.property.PropertyDto; import org.sonar.db.report.ReportScheduleDto; import org.sonar.db.report.ReportSubscriptionDto; import org.sonar.db.rule.RuleDto; -import org.sonar.db.sca.ScaDependenciesDbTester; -import org.sonar.db.sca.ScaIssueReleaseDto; -import org.sonar.db.sca.ScaReleasesDbTester; -import org.sonar.db.sca.ScaSeverity; import org.sonar.db.source.FileSourceDto; import org.sonar.db.user.UserDismissedMessageDto; import org.sonar.db.user.UserDto; @@ -140,6 +138,7 @@ class PurgeDaoIT { private final LogTesterJUnit5 logTester = new LogTesterJUnit5(); private final DbClient dbClient = db.getDbClient(); private final DbSession dbSession = db.getSession(); + private final PurgeDao underTest = db.getDbClient().purgeDao(); @Test @@ -1964,38 +1963,126 @@ oldCreationDate)); } + private <K, V> Map<K, V> merge(Map<? extends K, ? extends V> map1, Map<? extends K, ? extends V> map2) { + Map<K, V> result = new HashMap<>(map1); + result.putAll(map2); + return result; + } + + // the SCA mappers are in an extension, so we have to use direct sql here. + // A cleaner approach would be to allow extensions to add purge logic on branch + // deletion and remove SCA knowledge from the core PurgeMapper. + private void insertScaData(String branch1Uuid, String branch2Uuid) { + var releaseBase = Map.of("package_url", "purl1", + "package_manager", "MAVEN", + "package_name", "whatever", + "version", "1.0", + "license_expression", "MIT", + "known", true, + "known_package", true, + "is_new", false, + "created_at", 0L, "updated_at", 0L); + db.executeInsert("sca_releases", merge(releaseBase, Map.of("uuid", "release-uuid1", "component_uuid", branch1Uuid))); + db.executeInsert("sca_releases", merge(releaseBase, Map.of("uuid", "release-uuid2", "component_uuid", branch2Uuid))); + assertThat(db.countRowsOfTable(dbSession, "sca_releases")).isEqualTo(2); + + var dependencyBase = Map.of("created_at", 0L, "updated_at", 0L, + "direct", true, "scope", "compile", "is_new", true); + db.executeInsert("sca_dependencies", merge(dependencyBase, Map.of("uuid", "dependency-uuid1", "sca_release_uuid", "release-uuid1"))); + db.executeInsert("sca_dependencies", merge(dependencyBase, Map.of("uuid", "dependency-uuid2", "sca_release_uuid", "release-uuid2"))); + assertThat(db.countRowsOfTable(dbSession, "sca_dependencies")).isEqualTo(2); + + // the issue uuids here don't even exist but doesn't matter, we don't delete issues so not testing that + var issueReleaseBase = Map.of("created_at", 0L, "updated_at", 0L, + "severity", "INFO", "original_severity", "INFO", "manual_severity", false, + "severity_sort_key", 42, "status", "TO_REVIEW"); + db.executeInsert("sca_issues_releases", merge(issueReleaseBase, Map.of("uuid", "issue-release-uuid1", + "sca_issue_uuid", "issue-uuid1", "sca_release_uuid", "release-uuid1"))); + db.executeInsert("sca_issues_releases", merge(issueReleaseBase, Map.of("uuid", "issue-release-uuid2", + "sca_issue_uuid", "issue-uuid2", "sca_release_uuid", "release-uuid2"))); + + assertThat(db.countRowsOfTable(dbSession, "sca_issues_releases")).isEqualTo(2); + + var issueReleaseChangeBase = Map.of("created_at", 0L, "updated_at", 0L); + db.executeInsert("sca_issue_rels_changes", merge(issueReleaseChangeBase, Map.of("uuid", "issue-release-change-uuid1", + "sca_issues_releases_uuid", "issue-release-uuid1"))); + db.executeInsert("sca_issue_rels_changes", merge(issueReleaseChangeBase, Map.of("uuid", "issue-release-change-uuid2", + "sca_issues_releases_uuid", "issue-release-uuid2"))); + + assertThat(db.countRowsOfTable(dbSession, "sca_issue_rels_changes")).isEqualTo(2); + + var analysisBase = Map.of( + "created_at", 0L, + "updated_at", 0L, + "status", "COMPLETED", + "errors", "[]", + "parsed_files", "[]", + "failed_reason", "something"); + db.executeInsert("sca_analyses", merge(analysisBase, Map.of( + "uuid", "analysis-uuid1", + "component_uuid", branch1Uuid))); + db.executeInsert("sca_analyses", merge(analysisBase, Map.of( + "uuid", "analysis-uuid2", + "component_uuid", branch2Uuid))); + assertThat(db.countRowsOfTable(dbSession, "sca_analyses")).isEqualTo(2); + } + @Test void deleteBranch_purgesScaActivity() { ProjectDto project = db.components().insertPublicProject().getProjectDto(); BranchDto branch1 = db.components().insertProjectBranch(project); BranchDto branch2 = db.components().insertProjectBranch(project); - ScaReleasesDbTester scaReleasesDbTester = new ScaReleasesDbTester(db); - var release1 = scaReleasesDbTester.insertScaRelease(branch1.getUuid(), "1"); - var release2 = scaReleasesDbTester.insertScaRelease(branch2.getUuid(), "2"); + insertScaData(branch1.getUuid(), branch2.getUuid()); + + underTest.deleteBranch(dbSession, branch1.getUuid()); + + assertThat(db.countRowsOfTable(dbSession, "sca_releases")).isEqualTo(1); + assertThat(db.countRowsOfTable(dbSession, "sca_dependencies")).isEqualTo(1); + assertThat(db.countRowsOfTable(dbSession, "sca_issues_releases")).isEqualTo(1); + assertThat(db.countRowsOfTable(dbSession, "sca_issue_rels_changes")).isEqualTo(1); + assertThat(db.countRowsOfTable(dbSession, "sca_analyses")).isEqualTo(1); + } - ScaDependenciesDbTester scaDependenciesDbTester = new ScaDependenciesDbTester(db); - scaDependenciesDbTester.insertScaDependency(release1.uuid(), "1"); - scaDependenciesDbTester.insertScaDependency(release2.uuid(), "2"); + @Test + void deleteProject_purgesScaLicenseProfiles() { + ProjectDto project = db.components().insertPublicProject().getProjectDto(); - ScaIssueReleaseDto issueRelease1 = new ScaIssueReleaseDto.Builder().setUuid("foo1").setScaIssueUuid("baz").setSeverity(ScaSeverity.LOW).setScaReleaseUuid(release1.uuid()).build(); - ScaIssueReleaseDto issueRelease2 = new ScaIssueReleaseDto.Builder().setUuid("foo2").setScaIssueUuid("baz").setSeverity(ScaSeverity.LOW).setScaReleaseUuid(release2.uuid()).build(); - dbClient.scaIssuesReleasesDao().insert(dbSession, issueRelease1); - dbClient.scaIssuesReleasesDao().insert(dbSession, issueRelease2); + var scaLicenseProfileProjectBase = Map.of( + "sca_license_profile_uuid", "sca-license-profile-uuid1", + "created_at", 0L, + "updated_at", 0L); - assertThat(dbClient.scaReleasesDao().selectByBranchUuid(dbSession, branch1.getUuid())).isNotEmpty(); - assertThat(dbClient.scaDependenciesDao().selectByBranchUuid(dbSession, branch1.getUuid())).isNotEmpty(); - assertThat(dbClient.scaIssuesReleasesDao().selectByBranchUuid(dbSession, branch1.getUuid())).isNotEmpty(); + db.executeInsert("sca_lic_prof_projects", merge(scaLicenseProfileProjectBase, Map.of( + "uuid", "sca-lic-prof-project-uuid1", + "project_uuid", project.getUuid()))); - underTest.deleteBranch(dbSession, branch1.getUuid()); + db.executeInsert("sca_lic_prof_projects", merge(scaLicenseProfileProjectBase, Map.of( + "uuid", "sca-lic-prof-project-uuid2", + "project_uuid", "other-project-uuid"))); - assertThat(dbClient.scaReleasesDao().selectByBranchUuid(dbSession, branch1.getUuid())).isEmpty(); - assertThat(dbClient.scaDependenciesDao().selectByBranchUuid(dbSession, branch1.getUuid())).isEmpty(); - assertThat(dbClient.scaIssuesReleasesDao().selectByBranchUuid(dbSession, branch1.getUuid())).isEmpty(); + assertThat(db.countRowsOfTable(dbSession, "sca_lic_prof_projects")).isEqualTo(2); - assertThat(dbClient.scaReleasesDao().selectByBranchUuid(dbSession, branch2.getUuid())).isNotEmpty(); - assertThat(dbClient.scaDependenciesDao().selectByBranchUuid(dbSession, branch2.getUuid())).isNotEmpty(); - assertThat(dbClient.scaIssuesReleasesDao().selectByBranchUuid(dbSession, branch2.getUuid())).isNotEmpty(); + underTest.deleteProject(dbSession, project.getUuid(), project.getQualifier(), project.getName(), project.getKey()); + + assertThat(db.countRowsOfTable(dbSession, "sca_lic_prof_projects")).isEqualTo(1); + } + + @Test + void whenDeleteBranch_thenPurgeArchitectureGraphs() { + ProjectDto project = db.components().insertPublicProject().getProjectDto(); + BranchDto branch1 = db.components().insertProjectBranch(project); + BranchDto branch2 = db.components().insertProjectBranch(project); + + db.executeInsert("architecture_graphs", Map.of("uuid", "12345", "branch_uuid", branch1.getUuid(), "ecosystem", "xoo", "type", "file_graph", "graph_data", "{}")); + db.executeInsert("architecture_graphs", Map.of("uuid", "123456", "branch_uuid", branch1.getUuid(), "ecosystem", "xoo", "type", "class_graph", "graph_data", "{}")); + db.executeInsert("architecture_graphs", Map.of("uuid", "1234567", "branch_uuid", branch2.getUuid(), "ecosystem", "xoo", "type", "file_graph", "graph_data", "{}")); + + assertThat(db.countRowsOfTable(dbSession, "architecture_graphs")).isEqualTo(3); + underTest.deleteBranch(dbSession, branch1.getUuid()); + assertThat(db.countRowsOfTable(dbSession, "architecture_graphs")).isEqualTo(1); + underTest.deleteBranch(dbSession, branch2.getUuid()); + assertThat(db.countRowsOfTable(dbSession, "architecture_graphs")).isZero(); } private AnticipatedTransitionDto getAnticipatedTransitionsDto(String uuid, String projectUuid, Date creationDate) { diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/ActiveRuleDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/ActiveRuleDaoIT.java index 033ba5daa9f..f15bbf5cc1c 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/ActiveRuleDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/ActiveRuleDaoIT.java @@ -33,7 +33,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.impl.utils.TestSystem2; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.Severity; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RuleParamType; import org.sonar.api.utils.System2; import org.sonar.db.DbSession; diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/QualityProfileExportDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/QualityProfileExportDaoIT.java index 3b7f50942fa..be6d177fb98 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/QualityProfileExportDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/qualityprofile/QualityProfileExportDaoIT.java @@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.rule.RuleDto; @@ -97,7 +97,7 @@ class QualityProfileExportDaoIT { assertThat(exportCustomRuleDto.getExtendedDescription()).isEqualTo(customRule.getNoteData()); assertThat(exportCustomRuleDto.getName()).isEqualTo(customRule.getName()); assertThat(exportCustomRuleDto.getRuleKey()).isEqualTo(customRule.getKey()); - assertThat(exportCustomRuleDto.getRuleType()).isEqualTo(RuleType.valueOf(customRule.getType())); + assertThat(exportCustomRuleDto.getRuleType()).isEqualTo(RuleType.fromDbConstant(customRule.getType())); assertThat(exportCustomRuleDto.getTags()).isEqualTo(customRule.getTags()); assertThat(exportCustomRuleDto.getTemplateRuleKey()).isEqualTo(ruleTemplate.getKey()); @@ -115,7 +115,7 @@ class QualityProfileExportDaoIT { assertThat(exportRuleDto.getExtendedDescription()).isEqualTo(rule.getNoteData()); assertThat(exportRuleDto.getName()).isEqualTo(rule.getName()); assertThat(exportRuleDto.getRuleKey()).isEqualTo(rule.getKey()); - assertThat(exportRuleDto.getRuleType()).isEqualTo(RuleType.valueOf(rule.getType())); + assertThat(exportRuleDto.getRuleType()).isEqualTo(RuleType.fromDbConstant(rule.getType())); ActiveRuleDto activeRule = activeRules.stream().filter(activeRuleDto -> activeRuleDto.getRuleKey().equals(rule.getKey())).findFirst().get(); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/report/RegulatoryReportDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/report/RegulatoryReportDaoIT.java index 7eb2bc34250..88440d187a1 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/report/RegulatoryReportDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/report/RegulatoryReportDaoIT.java @@ -26,7 +26,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; @@ -90,7 +90,7 @@ class RegulatoryReportDaoIT { List<IssueFindingDto> issues = new ArrayList<>(); underTest.scrollIssues(db.getSession(), PROJECT_UUID, result -> issues.add(result.getResultObject())); - assertThat(issues).extracting(IssueFindingDto::getKey).containsOnly(issue1.getKey(), issue2.getKey(), issue3.getKey()); + assertThat(issues).extracting(IssueFindingDto::getKey).containsOnly(issue1.getKey(), issue2.getKey(), issue3.getKey(), issueCodeSmell.getKey()); // check fields IssueFindingDto issue = issues.stream().filter(i -> i.getKey().equals(issue1.getKey())).findFirst().get(); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java index 26f799fa610..cb66d99fc6b 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java @@ -41,7 +41,7 @@ import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttribute; import org.sonar.api.rules.RuleQuery; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; @@ -1157,7 +1157,7 @@ class RuleDaoIT { assertThat(ruleForIndexing.getInternalKey()).isEqualTo(r1.getConfigKey()); assertThat(ruleForIndexing.getLanguage()).isEqualTo(r1.getLanguage()); assertThat(ruleForIndexing.getType()).isEqualTo(r1.getType()); - assertThat(ruleForIndexing.getTypeAsRuleType()).isEqualTo(RuleType.valueOf(r1.getType())); + assertThat(ruleForIndexing.getTypeAsRuleType()).isEqualTo(RuleType.fromDbConstant(r1.getType())); assertThat(ruleForIndexing.getCreatedAt()).isEqualTo(r1.getCreatedAt()); assertThat(ruleForIndexing.getUpdatedAt()).isEqualTo(r1.getUpdatedAt()); } diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaDependenciesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaDependenciesDaoIT.java deleted file mode 100644 index 99c028718ef..00000000000 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaDependenciesDaoIT.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.Pagination; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ProjectData; - -import static org.assertj.core.api.Assertions.assertThat; - -class ScaDependenciesDaoIT { - - @RegisterExtension - private final DbTester db = DbTester.create(System2.INSTANCE); - - private final ScaDependenciesDao scaDependenciesDao = db.getDbClient().scaDependenciesDao(); - - @Test - void insert_shouldPersistScaDependencies() { - ScaDependencyDto scaDependencyDto = db.getScaDependenciesDbTester().insertScaDependency("scaReleaseUuid", "1"); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_dependencies"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - assertThat(stringObjectMap).containsExactlyInAnyOrderEntriesOf( - Map.ofEntries( - Map.entry("uuid", scaDependencyDto.uuid()), - Map.entry("sca_release_uuid", scaDependencyDto.scaReleaseUuid()), - Map.entry("direct", scaDependencyDto.direct()), - Map.entry("scope", scaDependencyDto.scope()), - Map.entry("user_dependency_file_path", scaDependencyDto.userDependencyFilePath()), - Map.entry("lockfile_dependency_file_path", scaDependencyDto.lockfileDependencyFilePath()), - Map.entry("chains", scaDependencyDto.getChainsJson()), - Map.entry("new_in_pull_request", scaDependencyDto.newInPullRequest()), - Map.entry("production_scope", scaDependencyDto.productionScope()), - Map.entry("created_at", scaDependencyDto.createdAt()), - Map.entry("updated_at", scaDependencyDto.updatedAt()))); - } - - @Test - void deleteByUuid_shouldDeleteScaDependencies() { - ScaDependencyDto scaDependencyDto = db.getScaDependenciesDbTester().insertScaDependency("scaReleaseUuid", "1"); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_dependencies"); - assertThat(select).isNotEmpty(); - - scaDependenciesDao.deleteByUuid(db.getSession(), scaDependencyDto.uuid()); - - select = db.select(db.getSession(), "select * from sca_dependencies"); - assertThat(select).isEmpty(); - } - - @Test - void selectByUuid_shouldLoadScaDependency() { - ScaDependencyDto scaDependencyDto = db.getScaDependenciesDbTester().insertScaDependency("scaReleaseUuid", "1"); - - var loadedOptional = scaDependenciesDao.selectByUuid(db.getSession(), scaDependencyDto.uuid()); - - assertThat(loadedOptional).contains(scaDependencyDto); - } - - @Test - void selectByReleaseUuids_shouldReturnScaDependencies() { - ComponentDto componentDto = prepareComponentDto(); - ScaDependencyDto scaDependencyDto1a = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1a", true, PackageManager.MAVEN, "foo.bar1"); - // same release, different dependency - ScaDependencyDto scaDependencyDto1b = db.getScaDependenciesDbTester().insertScaDependency(scaDependencyDto1a.scaReleaseUuid(), "1b", false); - ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "2", true, PackageManager.MAVEN, "foo.bar2"); - ScaDependencyDto scaDependencyDto3 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "3", true, PackageManager.MAVEN, "foo.bar3"); - - List<ScaDependencyDto> results = scaDependenciesDao.selectByReleaseUuids(db.getSession(), List.of(scaDependencyDto1a.scaReleaseUuid(), scaDependencyDto2.scaReleaseUuid())); - - assertThat(results) - .containsExactlyInAnyOrder(scaDependencyDto1a, scaDependencyDto1b, scaDependencyDto2) - .doesNotContain(scaDependencyDto3); - } - - @Test - void selectByQuery_shouldReturnScaDependencies_whenQueryByBranchUuid() { - ComponentDto componentDto = prepareComponentDto(); - ScaDependencyDto scaDependencyDto1 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); - // same release, different dependency - ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependency(scaDependencyDto1.scaReleaseUuid(), "2", false); - - ScaDependenciesQuery scaDependenciesQuery = new ScaDependenciesQuery(componentDto.branchUuid(), null, null, null); - List<ScaDependencyDto> results = scaDependenciesDao.selectByQuery(db.getSession(), scaDependenciesQuery, Pagination.all()); - - assertThat(results).containsExactlyInAnyOrder(scaDependencyDto1, scaDependencyDto2); - } - - @Test - void selectByQuery_shouldReturnPaginatedScaDependencies() { - ComponentDto componentDto = prepareComponentDto(); - ScaDependencyDto scaDependencyDto1 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); - ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "2", true, PackageManager.MAVEN, "foo.bar"); - ScaDependencyDto scaDependencyDto3 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "3", true, PackageManager.MAVEN, "something"); - ScaDependencyDto scaDependencyDto4 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "4", true, PackageManager.MAVEN, "something-else"); - - ScaDependenciesQuery scaDependenciesQuery = new ScaDependenciesQuery(componentDto.branchUuid(), null, null, null); - List<ScaDependencyDto> page1Results = scaDependenciesDao.selectByQuery(db.getSession(), scaDependenciesQuery, Pagination.forPage(1).andSize(2)); - List<ScaDependencyDto> page2Results = scaDependenciesDao.selectByQuery(db.getSession(), scaDependenciesQuery, Pagination.forPage(2).andSize(2)); - - // we order by uuid, so order is not meaningful here - var allResults = new ArrayList<>(page1Results); - allResults.addAll(page2Results); - assertThat(allResults).containsExactlyInAnyOrder(scaDependencyDto1, scaDependencyDto2, scaDependencyDto3, scaDependencyDto4); - assertThat(List.of(page1Results.size(), page2Results.size())).containsExactly(2, 2); - } - - @Test - void selectByQuery_shouldPartiallyMatchPackageName_whenQueriedByText() { - ComponentDto componentDto = prepareComponentDto(); - ScaDependencyDto scaDependencyDto1 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); - @SuppressWarnings("unused") - ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "2", true, PackageManager.MAVEN, "bar.mee"); - ScaDependencyDto scaDependencyDto3 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "3", true, PackageManager.MAVEN, "foo.bar.me"); - @SuppressWarnings("unused") - ScaDependencyDto scaDependencyDto4 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "4", true, PackageManager.MAVEN, "some.foo.bar"); - - ScaDependenciesQuery scaDependenciesQuery = new ScaDependenciesQuery(componentDto.branchUuid(), null, null, "foo.bar"); - List<ScaDependencyDto> results = scaDependenciesDao.selectByQuery(db.getSession(), scaDependenciesQuery, Pagination.all()); - - assertThat(results).hasSize(2); - assertThat(results.get(0)).usingRecursiveComparison().isEqualTo(scaDependencyDto1); - assertThat(results.get(1)).usingRecursiveComparison().isEqualTo(scaDependencyDto3); - - ScaDependenciesQuery scaDependenciesCaseInsensitiveQuery = new ScaDependenciesQuery(componentDto.branchUuid(), null, null, "Foo.Bar"); - List<ScaDependencyDto> resultsCaseInsensitive = scaDependenciesDao.selectByQuery(db.getSession(), scaDependenciesCaseInsensitiveQuery, Pagination.all()); - - assertThat(resultsCaseInsensitive).hasSize(2); - assertThat(resultsCaseInsensitive.get(0)).usingRecursiveComparison().isEqualTo(scaDependencyDto1); - assertThat(resultsCaseInsensitive.get(1)).usingRecursiveComparison().isEqualTo(scaDependencyDto3); - } - - @Test - void selectByQuery_shouldReturnScaDependencies_whenQueryByDirect() { - ComponentDto componentDto = prepareComponentDto(); - ScaDependencyDto scaDependencyDto1 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); - ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "2", false, PackageManager.MAVEN, "foo.bar"); - - ScaDependenciesQuery scaDependenciesDirectQuery = new ScaDependenciesQuery(componentDto.branchUuid(), true, null, null); - List<ScaDependencyDto> resultsDirect = scaDependenciesDao.selectByQuery(db.getSession(), scaDependenciesDirectQuery, Pagination.all()); - - assertThat(resultsDirect).hasSize(1); - assertThat(resultsDirect.get(0)).usingRecursiveComparison().isEqualTo(scaDependencyDto1); - - ScaDependenciesQuery scaDependenciesNoDirectQuery = new ScaDependenciesQuery(componentDto.branchUuid(), false, null, null); - List<ScaDependencyDto> resultsNoDirect = scaDependenciesDao.selectByQuery(db.getSession(), scaDependenciesNoDirectQuery, Pagination.all()); - - assertThat(resultsNoDirect).hasSize(1); - assertThat(resultsNoDirect.get(0)).usingRecursiveComparison().isEqualTo(scaDependencyDto2); - } - - @Test - void selectByQuery_shouldReturnScaDependencies_whenQueryByPackageManager() { - ComponentDto componentDto = prepareComponentDto(); - ScaDependencyDto scaDependencyDto1 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); - ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "2", true, PackageManager.NPM, "foo.bar"); - ScaDependencyDto scaDependencyDto3 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "3", true, PackageManager.CARGO, "foo.bar"); - - ScaDependenciesQuery scaDependenciesMavenQuery = new ScaDependenciesQuery(componentDto.branchUuid(), null, List.of(PackageManager.MAVEN.name()), null); - List<ScaDependencyDto> resultsMaven = scaDependenciesDao.selectByQuery(db.getSession(), scaDependenciesMavenQuery, Pagination.all()); - - assertThat(resultsMaven).hasSize(1); - assertThat(resultsMaven.get(0)).usingRecursiveComparison().isEqualTo(scaDependencyDto1); - - ScaDependenciesQuery scaDependenciesNpmAndCargoQuery = new ScaDependenciesQuery(componentDto.branchUuid(), null, - List.of(PackageManager.NPM.name(), PackageManager.CARGO.name()), null); - List<ScaDependencyDto> resultsNpm = scaDependenciesDao.selectByQuery(db.getSession(), scaDependenciesNpmAndCargoQuery, Pagination.all()); - - assertThat(resultsNpm).hasSize(2); - assertThat(resultsNpm.get(0)).usingRecursiveComparison().isEqualTo(scaDependencyDto2); - assertThat(resultsNpm.get(1)).usingRecursiveComparison().isEqualTo(scaDependencyDto3); - } - - @Test - void update_shouldUpdateScaDependency() { - ScaDependencyDto scaDependencyDto = db.getScaDependenciesDbTester().insertScaDependency("scaReleaseUuid", "1", true); - ScaDependencyDto updatedScaDependency = scaDependencyDto.toBuilder() - .setUpdatedAt(scaDependencyDto.updatedAt() + 1) - .setDirect(!scaDependencyDto.direct()) - .setLockfileDependencyFilePath("lockfile2") - .setProductionScope(!scaDependencyDto.productionScope()) - .build(); - - scaDependenciesDao.update(db.getSession(), updatedScaDependency); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_dependencies"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - assertThat(stringObjectMap).containsExactlyInAnyOrderEntriesOf( - Map.ofEntries( - Map.entry("uuid", updatedScaDependency.uuid()), - Map.entry("sca_release_uuid", updatedScaDependency.scaReleaseUuid()), - Map.entry("direct", updatedScaDependency.direct()), - Map.entry("scope", updatedScaDependency.scope()), - Map.entry("user_dependency_file_path", updatedScaDependency.userDependencyFilePath()), - Map.entry("lockfile_dependency_file_path", updatedScaDependency.lockfileDependencyFilePath()), - Map.entry("chains", updatedScaDependency.getChainsJson()), - Map.entry("new_in_pull_request", updatedScaDependency.newInPullRequest()), - Map.entry("production_scope", updatedScaDependency.productionScope()), - Map.entry("created_at", updatedScaDependency.createdAt()), - Map.entry("updated_at", updatedScaDependency.updatedAt()))); - } - - @Test - void countByQuery_shouldReturnTheTotalOfDependencies() { - ComponentDto componentDto1 = prepareComponentDto(); - db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto1.uuid(), "1", true, PackageManager.MAVEN, "foo.bar"); - db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto1.uuid(), "2", true, PackageManager.MAVEN, "foo.bar.mee"); - db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto1.uuid(), "3", true, PackageManager.MAVEN, "bar.foo"); - - ScaDependenciesQuery scaDependenciesQuery = new ScaDependenciesQuery(componentDto1.branchUuid(), null, null, "foo"); - - assertThat(scaDependenciesDao.countByQuery(db.getSession(), scaDependenciesQuery)).isEqualTo(2); - assertThat(scaDependenciesDao.countByQuery(db.getSession(), new ScaDependenciesQuery(componentDto1.branchUuid(), null, null, null))).isEqualTo(3); - assertThat(scaDependenciesDao.countByQuery(db.getSession(), new ScaDependenciesQuery("another_branch_uuid", null, null, null))).isZero(); - } - - private ComponentDto prepareComponentDto() { - ProjectData projectData = db.components().insertPublicProject(); - return projectData.getMainBranchComponent(); - } -} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesDaoIT.java deleted file mode 100644 index a13fa082603..00000000000 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesDaoIT.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import java.util.Map; -import org.apache.ibatis.exceptions.PersistenceException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class ScaIssuesDaoIT { - - @RegisterExtension - private final DbTester db = DbTester.create(System2.INSTANCE); - - private final ScaIssuesDao scaIssuesDao = db.getDbClient().scaIssuesDao(); - - private static final ScaIssueDto newScaIssueDto(String suffix) { - return new ScaIssueDto("uuid" + suffix, ScaIssueType.PROHIBITED_LICENSE, "fakePackageUrl" + suffix, "fakeVulnerabilityId" + suffix, "fakeSpdxId" + suffix, 1L, 2L); - } - - @Test - void insert_shouldPersistScaIssues() { - ScaIssueDto issueDto = newScaIssueDto("1"); - scaIssuesDao.insert(db.getSession(), issueDto); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_issues"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - assertThat(stringObjectMap).containsExactlyInAnyOrderEntriesOf( - Map.ofEntries( - Map.entry("uuid", issueDto.uuid()), - Map.entry("sca_issue_type", issueDto.scaIssueType().name()), - Map.entry("package_url", issueDto.packageUrl()), - Map.entry("vulnerability_id", issueDto.vulnerabilityId()), - Map.entry("spdx_license_id", issueDto.spdxLicenseId()), - Map.entry("created_at", issueDto.createdAt()), - Map.entry("updated_at", issueDto.updatedAt()))); - } - - // Postgresql apparently doesn't support doing anything else in the session - // after a statement with an error (constraint violation), while other - // databases do. So we use a dedicated session here. - private void insertAndCommit(ScaIssueDto issueDto) { - try (var dbSession = db.getDbClient().openSession(false)) { - scaIssuesDao.insert(dbSession, issueDto); - dbSession.commit(true); - } - } - - @Test - void insert_shouldFailOnDuplicateInsert() { - // we are avoiding db.getSession() in here because the constraint violation - // can invalidate the session and there's some chance of deadlock problems - // with multiple sessions so let's just juggle dedicated sessions manually - // for each query and not use the global session from DbTester - - ScaIssueDto issueDto = newScaIssueDto("1"); - try (var dbSession = db.getDbClient().openSession(false)) { - scaIssuesDao.insert(dbSession, issueDto); - dbSession.commit(); - } - - ScaIssueDto issueDtoDifferentUuid = new ScaIssueDto("uuid-different", issueDto.scaIssueType(), issueDto.packageUrl(), - issueDto.vulnerabilityId(), issueDto.spdxLicenseId(), 10L, 11L); - - assertThrows(PersistenceException.class, () -> insertAndCommit(issueDtoDifferentUuid)); - - try (var dbSession = db.getDbClient().openSession(false)) { - List<Map<String, Object>> select = db.select(dbSession, "select * from sca_issues"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - assertThat(stringObjectMap).containsEntry("uuid", issueDto.uuid()); - } - } - - @Test - void selectByUuid_shouldLoadScaIssue() { - ScaIssueDto issueDto = newScaIssueDto("1"); - scaIssuesDao.insert(db.getSession(), issueDto); - - var loadedOptional = scaIssuesDao.selectByUuid(db.getSession(), issueDto.uuid()); - - assertThat(loadedOptional).contains(issueDto); - } - - @Test - void selectByUuids_shouldLoadScaIssues() { - List<ScaIssueDto> issueDtos = List.of(newScaIssueDto("1"), newScaIssueDto("2"), newScaIssueDto("3")); - for (var issueDto : issueDtos) { - scaIssuesDao.insert(db.getSession(), issueDto); - } - - List<String> uuidsToLoad = List.of(issueDtos.get(0).uuid(), issueDtos.get(2).uuid()); - var loaded = scaIssuesDao.selectByUuids(db.getSession(), uuidsToLoad); - - assertThat(loaded).containsExactlyInAnyOrder(issueDtos.get(0), issueDtos.get(2)); - } - - @Test - void selectUuidByValue_shouldLoadScaIssue() { - List<ScaIssueDto> issueDtos = List.of(newScaIssueDto("1"), newScaIssueDto("2"), newScaIssueDto("3")); - for (var issueDto : issueDtos) { - scaIssuesDao.insert(db.getSession(), issueDto); - } - - ScaIssueDto toLoad = issueDtos.get(1); - var loadedOptionalUuid = scaIssuesDao.selectUuidByValue(db.getSession(), toLoad); - - assertThat(loadedOptionalUuid).contains(toLoad.uuid()); - } -} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesReleasesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesReleasesDaoIT.java deleted file mode 100644 index 8a4f5d4bec7..00000000000 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesReleasesDaoIT.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import java.util.Map; -import org.apache.ibatis.exceptions.PersistenceException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class ScaIssuesReleasesDaoIT { - - @RegisterExtension - private final DbTester db = DbTester.create(System2.INSTANCE); - - private final ScaIssuesReleasesDao scaIssuesReleasesDao = db.getDbClient().scaIssuesReleasesDao(); - - private static ScaIssueReleaseDto newScaIssueReleaseDto(String suffix) { - return new ScaIssueReleaseDto("uuid" + suffix, "sca-issue-uuid" + suffix, "sca-release-uuid" + suffix, ScaSeverity.INFO, 1L, 2L); - } - - @Test - void insert_shouldPersistScaIssuesReleases() { - ScaIssueReleaseDto issueReleaseDto = newScaIssueReleaseDto("1"); - - scaIssuesReleasesDao.insert(db.getSession(), issueReleaseDto); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_issues_releases"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - assertThat(stringObjectMap).usingRecursiveComparison().isEqualTo( - Map.ofEntries( - Map.entry("uuid", issueReleaseDto.uuid()), - Map.entry("sca_issue_uuid", issueReleaseDto.scaIssueUuid()), - Map.entry("sca_release_uuid", issueReleaseDto.scaReleaseUuid()), - Map.entry("severity", issueReleaseDto.severity().name()), - Map.entry("severity_sort_key", (long) issueReleaseDto.severitySortKey()), - Map.entry("created_at", issueReleaseDto.createdAt()), - Map.entry("updated_at", issueReleaseDto.updatedAt()))); - } - - // Postgresql apparently doesn't support doing anything else in the session - // after a statement with an error (constraint violation), while other - // databases do. So we use a dedicated session here. - private void insertAndCommit(ScaIssueReleaseDto issueReleaseDto) { - try (var dbSession = db.getDbClient().openSession(false)) { - scaIssuesReleasesDao.insert(dbSession, issueReleaseDto); - dbSession.commit(true); - } - } - - @Test - void insert_shouldFailOnDuplicateInsert() { - ScaIssueReleaseDto issueReleaseDto = newScaIssueReleaseDto("1"); - try (var dbSession = db.getDbClient().openSession(false)) { - scaIssuesReleasesDao.insert(dbSession, issueReleaseDto); - dbSession.commit(); - } - - ScaIssueReleaseDto issueReleaseDtoDifferentUuid = new ScaIssueReleaseDto("uuid-different", - issueReleaseDto.scaIssueUuid(), issueReleaseDto.scaReleaseUuid(), ScaSeverity.INFO, - 10L, 11L); - - assertThrows(PersistenceException.class, () -> insertAndCommit(issueReleaseDtoDifferentUuid)); - - try (var dbSession = db.getDbClient().openSession(false)) { - List<Map<String, Object>> select = db.select(dbSession, "select * from sca_issues_releases"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - assertThat(stringObjectMap).containsEntry("uuid", issueReleaseDto.uuid()); - } - } - - @Test - void deleteByUuid_shouldDelete() { - var dbSession = db.getSession(); - ScaIssueReleaseDto issueReleaseDto = newScaIssueReleaseDto("1"); - scaIssuesReleasesDao.insert(dbSession, issueReleaseDto); - dbSession.commit(); - - assertThat(db.countRowsOfTable(dbSession, "sca_issues_releases")).isOne(); - - scaIssuesReleasesDao.deleteByUuid(dbSession, issueReleaseDto.uuid()); - - assertThat(db.countRowsOfTable(dbSession, "sca_issues_releases")).isZero(); - } -} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDaoIT.java deleted file mode 100644 index 4db2590aed3..00000000000 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDaoIT.java +++ /dev/null @@ -1,618 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import com.google.common.collect.Lists; -import java.math.BigDecimal; -import java.util.Collections; -import java.util.Comparator; -import java.util.EnumMap; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Stream; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.Pagination; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ProjectData; - -import static org.assertj.core.api.Assertions.assertThat; - -class ScaIssuesReleasesDetailsDaoIT { - - @RegisterExtension - private final DbTester db = DbTester.create(System2.INSTANCE); - - private final ScaIssuesReleasesDetailsDao scaIssuesReleasesDetailsDao = db.getDbClient().scaIssuesReleasesDetailsDao(); - - private static Comparator<ScaIssueReleaseDetailsDto> identityComparator() { - Function<ScaIssueReleaseDetailsDto, String> typeString = dto -> dto.scaIssueType().name(); - return Comparator.comparing(typeString) - .thenComparing(ScaIssueReleaseDetailsDto::vulnerabilityId) - .thenComparing(ScaIssueReleaseDetailsDto::issuePackageUrl) - .thenComparing(ScaIssueReleaseDetailsDto::spdxLicenseId) - .thenComparing(ScaIssueReleaseDetailsDto::issueReleaseUuid); - } - - private static Comparator<ScaIssueReleaseDetailsDto> severityComparator() { - return Comparator.comparing(dto -> dto.severity().databaseSortKey()); - } - - private static Comparator<ScaIssueReleaseDetailsDto> cvssScoreComparator() { - return Comparator.comparing(ScaIssueReleaseDetailsDto::cvssScore, - // we treat null cvss as a score of 0.0 - Comparator.nullsFirst(Comparator.naturalOrder())); - } - - private static Comparator<ScaIssueReleaseDetailsDto> comparator(ScaIssuesReleasesDetailsQuery.Sort sort) { - return switch (sort) { - case IDENTITY_ASC -> identityComparator(); - case IDENTITY_DESC -> identityComparator().reversed(); - case SEVERITY_ASC -> severityComparator() - .thenComparing(cvssScoreComparator()) - .thenComparing(identityComparator()); - case SEVERITY_DESC -> severityComparator().reversed() - .thenComparing(cvssScoreComparator().reversed()) - .thenComparing(identityComparator()); - case CVSS_SCORE_ASC -> cvssScoreComparator() - .thenComparing(ScaIssueReleaseDetailsDto::severity) - .thenComparing(identityComparator()); - case CVSS_SCORE_DESC -> cvssScoreComparator().reversed() - .thenComparing(Comparator.comparing(ScaIssueReleaseDetailsDto::severity).reversed()) - .thenComparing(identityComparator()); - }; - } - - @Test - void selectByBranchUuid_shouldReturnIssues() { - var projectData = db.components().insertPrivateProject(); - var componentDto = projectData.getMainBranchComponent(); - var issue1 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "1", componentDto.uuid()); - var issue2 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "2", componentDto.uuid()); - - var foundPage = scaIssuesReleasesDetailsDao.selectByBranchUuid(db.getSession(), componentDto.branchUuid(), Pagination.forPage(1).andSize(1)); - - assertThat(foundPage).hasSize(1).isSubsetOf(issue1, issue2); - var foundAllIssues = scaIssuesReleasesDetailsDao.selectByBranchUuid(db.getSession(), componentDto.branchUuid(), Pagination.forPage(1).andSize(10)); - assertThat(foundAllIssues).hasSize(2).containsExactlyElementsOf(Stream.of(issue1, issue2).sorted(comparator(ScaIssuesReleasesDetailsQuery.Sort.SEVERITY_DESC)).toList()); - } - - @Test - void countByBranchUuid_shouldCountIssues() { - var componentDto = db.components().insertPrivateProject().getMainBranchComponent(); - db.getScaIssuesReleasesDetailsDbTester().insertVulnerabilityIssue("1", componentDto.uuid()); - db.getScaIssuesReleasesDetailsDbTester().insertVulnerabilityIssue("2", componentDto.uuid()); - db.getScaIssuesReleasesDetailsDbTester().insertVulnerabilityIssue("3", componentDto.uuid()); - - var count1 = scaIssuesReleasesDetailsDao.countByBranchUuid(db.getSession(), componentDto.branchUuid()); - assertThat(count1).isEqualTo(3); - - assertThat(scaIssuesReleasesDetailsDao.countByBranchUuid(db.getSession(), "bogus-branch-uuid")).isZero(); - } - - @Test - void selectByReleaseUuid_shouldReturnIssues() { - var projectData = db.components().insertPrivateProject(); - var componentDto = projectData.getMainBranchComponent(); - var issue1 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "1", componentDto.uuid()); - var release1 = issue1.releaseDto(); - // make these other issues use the same release and have a variety of CVSS - var issue2 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "2", componentDto.uuid(), - null, vi -> vi.toBuilder().setCvssScore(new BigDecimal("1.1")).build(), - releaseDto -> release1, - issueReleaseDto -> issueReleaseDto.toBuilder().setScaReleaseUuid(release1.uuid()).build()); - var issue3 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "3", componentDto.uuid(), - null, vi -> vi.toBuilder().setCvssScore(new BigDecimal("9.9")).build(), - releaseDto -> release1, - issueReleaseDto -> issueReleaseDto.toBuilder().setScaReleaseUuid(release1.uuid()).build()); - var issue4 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "4", componentDto.uuid(), - null, null, - releaseDto -> release1, - issueReleaseDto -> issueReleaseDto.toBuilder().setScaReleaseUuid(release1.uuid()).build()); - - var foundPage = scaIssuesReleasesDetailsDao.selectByBranchUuid(db.getSession(), componentDto.branchUuid(), Pagination.forPage(1).andSize(1)); - - assertThat(foundPage).hasSize(1).isSubsetOf(issue1, issue2, issue3, issue4); - var foundAllIssues = scaIssuesReleasesDetailsDao.selectByBranchUuid(db.getSession(), componentDto.branchUuid(), Pagination.forPage(1).andSize(10)); - assertThat(foundAllIssues).hasSize(4) - .containsExactlyElementsOf(Stream.of(issue1, issue2, issue3, issue4).sorted(comparator(ScaIssuesReleasesDetailsQuery.Sort.SEVERITY_DESC)).toList()); - } - - @Test - void withNoQueryFilters_shouldReturnAllIssues() { - setupAndExecuteQueryTest(Function.identity(), QueryTestData::expectedIssuesSortedByIdentityAsc, "All issues should be returned"); - } - - @Test - void withNoQueryFilters_shouldCountAllIssues() { - setupAndExecuteQueryCountTest(Function.identity(), 6); - } - - @Test - void withNoQueryFilters_shouldSort() { - QueryTestData testData = createQueryTestData(); - var expectedLists = new EnumMap<ScaIssuesReleasesDetailsQuery.Sort, List<ScaIssueReleaseDetailsDto>>(ScaIssuesReleasesDetailsQuery.Sort.class); - for (var sort : ScaIssuesReleasesDetailsQuery.Sort.values()) { - var expectedIssues = testData.expectedIssuesSorted(sort); - executeQueryTest(testData, queryBuilder -> queryBuilder.setSort(sort), expectedIssues, - "Sort %s should return expected issues".formatted(sort)); - expectedLists.put(sort, expectedIssues); - } - - // The assertions below here are actually about the expectations, but above - // we've just established that the actual matches the expectations. - - // The point of this is to assert that the test data contains a distinct ordering for each - // ordering in ScaIssuesReleasesDetailsQuery.Sort, because if it doesn't we could get - // false negatives in our tests. - assertThat(expectedLists.values().stream().distinct().toList()) - .as("Expected issues should have distinct orderings for each sort") - .containsExactlyInAnyOrderElementsOf(expectedLists.values()); - - // for identity, assert that our ASC and DESC actually invert each other. - // for severity and cvss score, this isn't supposed to be true because the - // secondary sort is IDENTITY_ASC even when we sort by DESC severity; but the - // severity and score values ignoring the other attributes should still be - // reversed. - assertThat(Lists.reverse(expectedLists.get(ScaIssuesReleasesDetailsQuery.Sort.IDENTITY_ASC))) - .as("IDENTITY sort should be reversed when sorted by DESC") - .containsExactlyElementsOf(expectedLists.get(ScaIssuesReleasesDetailsQuery.Sort.IDENTITY_DESC)); - assertThat( - Lists.reverse(expectedLists.get(ScaIssuesReleasesDetailsQuery.Sort.SEVERITY_ASC)).stream() - .map(ScaIssueReleaseDetailsDto::severity) - .toList()) - .as("SEVERITY sort should be reversed when sorted by DESC") - .containsExactlyElementsOf(expectedLists.get(ScaIssuesReleasesDetailsQuery.Sort.SEVERITY_DESC).stream() - .map(ScaIssueReleaseDetailsDto::severity) - .toList()); - assertThat(Lists.reverse(expectedLists.get(ScaIssuesReleasesDetailsQuery.Sort.CVSS_SCORE_ASC).stream() - .map(ScaIssueReleaseDetailsDto::cvssScore) - .toList())) - .as("CVSS_SCORE sort should be reversed when sorted by DESC") - .containsExactlyElementsOf(expectedLists.get(ScaIssuesReleasesDetailsQuery.Sort.CVSS_SCORE_DESC).stream() - .map(ScaIssueReleaseDetailsDto::cvssScore) - .toList()); - } - - @Test - void withQueryFilteredByIssueType_shouldReturnExpectedTypes() { - QueryTestData testData = createQueryTestData(); - executeQueryTest(testData, - queryBuilder -> queryBuilder.setTypes(List.of(ScaIssueType.VULNERABILITY)), - testData.expectedIssuesSortedByIdentityAsc().stream() - .filter(expected -> expected.scaIssueType() == ScaIssueType.VULNERABILITY) - .toList(), - "Only vulnerability issues should be returned"); - executeQueryTest(testData, - queryBuilder -> queryBuilder.setTypes(List.of(ScaIssueType.PROHIBITED_LICENSE)), - testData.expectedIssuesSortedByIdentityAsc().stream() - .filter(expected -> expected.scaIssueType() == ScaIssueType.PROHIBITED_LICENSE) - .toList(), - "Only vulnerability issues should be returned"); - executeQueryTest(testData, - queryBuilder -> queryBuilder.setTypes(List.of(ScaIssueType.values())), - testData.expectedIssuesSortedByIdentityAsc(), - "All issues should be returned"); - executeQueryTest(testData, - queryBuilder -> queryBuilder.setTypes(Collections.emptyList()), - Collections.emptyList(), - "No issues should be returned when searching for zero types"); - } - - @Test - void withQueryFilteredByIssueType_shouldCountSelectedIssues() { - QueryTestData testData = createQueryTestData(); - executeQueryCountTest(testData, - queryBuilder -> queryBuilder.setTypes(List.of(ScaIssueType.VULNERABILITY)), - 4); - executeQueryCountTest(testData, - queryBuilder -> queryBuilder.setTypes(List.of(ScaIssueType.PROHIBITED_LICENSE)), - 2); - executeQueryCountTest(testData, - queryBuilder -> queryBuilder.setTypes(List.of(ScaIssueType.values())), - 6); - executeQueryCountTest(testData, - queryBuilder -> queryBuilder.setTypes(Collections.emptyList()), - 0); - } - - @Test - void withQueryFilteredByVulnerabilityId_shouldReturnExpectedItems() { - QueryTestData testData = createQueryTestData(); - var expectedEndsInId1 = testData.expectedIssues().stream() - .filter(issue -> issue.vulnerabilityId() != null && issue.vulnerabilityId().endsWith("Id1")) - .toList(); - assertThat(expectedEndsInId1).hasSize(1); - executeQueryTest(testData, - queryBuilder -> queryBuilder.setVulnerabilityIdSubstring("Id1"), - expectedEndsInId1, - "Only the vulnerability ending in Id1 should be returned"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setVulnerabilityIdSubstring("NotInThere"), - Collections.emptyList(), - "No issues should be returned when searching for the substring 'NotInThere'"); - executeQueryTest(testData, - queryBuilder -> queryBuilder.setVulnerabilityIdSubstring("Escape% NULL AS!%"), - Collections.emptyList(), - "No issues should be returned when searching for a string that needs escaping"); - executeQueryTest(testData, - queryBuilder -> queryBuilder.setVulnerabilityIdSubstring(ScaIssueDto.NULL_VALUE), - Collections.emptyList(), - "No vulnerabilities should be returned when searching for ScaIssueDto.NULL_VALUE"); - - var allVulnerabilityIssues = testData.expectedIssuesSortedByIdentityAsc().stream() - .filter(issue -> issue.scaIssueType() == ScaIssueType.VULNERABILITY) - .toList(); - assertThat(allVulnerabilityIssues).hasSize(4); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setVulnerabilityIdSubstring("Vulnerability"), - allVulnerabilityIssues, - "All vulnerabilities should be returned when searching for the substring 'Vulnerability'"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setVulnerabilityIdSubstring(""), - allVulnerabilityIssues, - "All vulnerabilities should be returned when searching for empty vulnerabilityId"); - } - - @Test - void withQueryFilteredByPackageName_shouldReturnExpectedItems() { - QueryTestData testData = createQueryTestData(); - var expectedEndsInName1 = testData.expectedIssues().subList(0, 1); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setPackageNameSubstring("Name1"), - expectedEndsInName1, - "Only the packages containing Name1 should be returned"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setPackageNameSubstring("NotInThere"), - Collections.emptyList(), - "No issues should be returned when searching for the substring 'NotInThere'"); - executeQueryTest(testData, - queryBuilder -> queryBuilder.setPackageNameSubstring("Escape% NULL AS!%"), - Collections.emptyList(), - "No issues should be returned when searching for a string that needs escaping"); - executeQueryTest(testData, - queryBuilder -> queryBuilder.setPackageNameSubstring(ScaIssueDto.NULL_VALUE), - Collections.emptyList(), - "No vulnerabilities should be returned when searching for ScaIssueDto.NULL_VALUE"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setPackageNameSubstring("Package"), - testData.expectedIssuesSortedByIdentityAsc(), - "All issues should be returned when searching for the substring 'Package'"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setPackageNameSubstring(""), - testData.expectedIssuesSortedByIdentityAsc(), - "All issues should be returned when searching for empty package name"); - } - - @Test - void withQueryFilteredByNewInPullRequest_shouldReturnExpectedItems() { - QueryTestData testData = createQueryTestData(); - - var expectedNew = testData.expectedIssuesSortedByIdentityAsc().stream() - .filter(issue -> issue.newInPullRequest()) - .toList(); - var expectedNotNew = testData.expectedIssuesSortedByIdentityAsc().stream() - .filter(issue -> !issue.newInPullRequest()) - .toList(); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setNewInPullRequest(true), - expectedNew, - "Only the releases marked newInPullRequest should be returned"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setNewInPullRequest(false), - expectedNotNew, - "Only the releases marked not newInPullRequest should be returned"); - } - - @Test - void withQueryFilteredBySeverity_shouldReturnExpectedItems() { - QueryTestData testData = createQueryTestData(); - var expectedSeverityInfo = testData.expectedIssuesSortedByIdentityAsc().stream() - .filter(issue -> issue.severity() == ScaSeverity.INFO) - .toList(); - var expectedSeverityBlocker = testData.expectedIssuesSortedByIdentityAsc().stream() - .filter(issue -> issue.severity() == ScaSeverity.BLOCKER) - .toList(); - assertThat(expectedSeverityInfo).hasSize(5); - assertThat(expectedSeverityBlocker).hasSize(1); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setSeverities(List.of(ScaSeverity.INFO)), - expectedSeverityInfo, - "Only the issues of severity INFO should be returned"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setSeverities(List.of(ScaSeverity.BLOCKER)), - expectedSeverityBlocker, - "Only the issues of severity BLOCKER should be returned"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setSeverities(List.of(ScaSeverity.LOW, ScaSeverity.HIGH)), - Collections.emptyList(), - "Should not match any severities of LOW or HIGH"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setSeverities(List.of(ScaSeverity.BLOCKER, ScaSeverity.INFO, ScaSeverity.LOW)), - testData.expectedIssuesSortedByIdentityAsc(), - "All issues should be returned when searching for a list that contains them all"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setSeverities(Collections.emptyList()), - Collections.emptyList(), - "No issues should be returned when searching for zero severities"); - } - - @Test - void withQueryFilteredByPackageManager_shouldReturnExpectedItems() { - QueryTestData testData = createQueryTestData(); - var expectedPackageManagerNpm = testData.expectedIssuesWithPackageManager(PackageManager.NPM).stream() - .sorted(identityComparator()).toList(); - var expectedPackageManagerMaven = testData.expectedIssuesWithPackageManager(PackageManager.MAVEN).stream() - .sorted(identityComparator()).toList(); - - assertThat(expectedPackageManagerNpm).hasSize(2); - assertThat(expectedPackageManagerMaven).hasSize(4); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setPackageManagers(List.of(PackageManager.NPM)), - expectedPackageManagerNpm, - "Only the npm issues should be returned"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setPackageManagers(List.of(PackageManager.MAVEN)), - expectedPackageManagerMaven, - "Only the Maven issues should be returned"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setPackageManagers(List.of(PackageManager.NPM, PackageManager.MAVEN)), - testData.expectedIssuesSortedByIdentityAsc(), - "All issues should be returned when searching for two package managers"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setPackageManagers(Collections.emptyList()), - Collections.emptyList(), - "No issues should be returned when searching for zero package managers"); - } - - @Test - void withQueryFilteredByDirect_shouldReturnExpectedItems() { - QueryTestData testData = createQueryTestData(); - var expectedDirect = testData.directIssues(); - var expectedTransitive = testData.transitiveIssues(); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setDirect(true), - expectedDirect, - "Only direct issues should be returned"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setDirect(false), - expectedTransitive, - "Only the transitive issues should be returned"); - } - - @Test - void withQueryFilteredByProductionScope_shouldReturnExpectedItems() { - QueryTestData testData = createQueryTestData(); - var expectedProduction = testData.productionIssues(); - var expectedNotProduction = testData.notProductionIssues(); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setProductionScope(true), - expectedProduction, - "Only production issues should be returned"); - - executeQueryTest(testData, - queryBuilder -> queryBuilder.setProductionScope(false), - expectedNotProduction, - "Only the non-production issues should be returned"); - } - - @Test - void withQueryMultipleFiltersNonDefaultSort_shouldReturnExpectedItems() { - QueryTestData testData = createQueryTestData(); - var expectedPackageManagerMaven = testData.expectedIssuesWithPackageManager(PackageManager.MAVEN); - var expectedTypeVulnerability = testData.expectedIssuesSortedByIdentityAsc().stream() - .filter(issue -> issue.scaIssueType() == ScaIssueType.VULNERABILITY) - .toList(); - var sortedByCvssDesc = testData.expectedIssuesSortedByCvssDesc(); - var expectedResults = sortedByCvssDesc.stream() - .filter(expectedPackageManagerMaven::contains) - .filter(expectedTypeVulnerability::contains) - .toList(); - assertThat(expectedResults).hasSize(3); - - executeQueryTest(testData, - queryBuilder -> queryBuilder - .setSort(ScaIssuesReleasesDetailsQuery.Sort.CVSS_SCORE_DESC) - .setPackageManagers(List.of(PackageManager.MAVEN)) - .setTypes(List.of(ScaIssueType.VULNERABILITY)), - expectedResults, - "Maven vulnerabilities returned in cvss score desc order"); - } - - private void setupAndExecuteQueryTest(Function<ScaIssuesReleasesDetailsQuery.Builder, ScaIssuesReleasesDetailsQuery.Builder> builderFunction, - Function<QueryTestData, List<ScaIssueReleaseDetailsDto>> expectedIssuesFunction, String assertAs) { - QueryTestData testData = createQueryTestData(); - executeQueryTest(testData, builderFunction, expectedIssuesFunction.apply(testData), assertAs); - } - - private void executeQueryTest(QueryTestData testData, - Function<ScaIssuesReleasesDetailsQuery.Builder, ScaIssuesReleasesDetailsQuery.Builder> builderFunction, - List<ScaIssueReleaseDetailsDto> expectedIssues, - String assertAs) { - var query = builderFunction.apply( - new ScaIssuesReleasesDetailsQuery.Builder() - .setBranchUuid(testData.branchUuid()) - .setSort(ScaIssuesReleasesDetailsQuery.Sort.IDENTITY_ASC)) - .build(); - var foundPage = scaIssuesReleasesDetailsDao.selectByQuery(db.getSession(), query, Pagination.forPage(1).andSize(10)); - - assertThat(foundPage).as(assertAs).containsExactlyElementsOf(expectedIssues); - } - - private void setupAndExecuteQueryCountTest(Function<ScaIssuesReleasesDetailsQuery.Builder, ScaIssuesReleasesDetailsQuery.Builder> builderFunction, - int expectedCount) { - QueryTestData testData = createQueryTestData(); - executeQueryCountTest(testData, builderFunction, expectedCount); - } - - private void executeQueryCountTest(QueryTestData testData, - Function<ScaIssuesReleasesDetailsQuery.Builder, ScaIssuesReleasesDetailsQuery.Builder> builderFunction, - int expectedCount) { - var query = builderFunction.apply( - new ScaIssuesReleasesDetailsQuery.Builder() - .setBranchUuid(testData.branchUuid()) - .setSort(ScaIssuesReleasesDetailsQuery.Sort.IDENTITY_ASC)) - .build(); - var count = scaIssuesReleasesDetailsDao.countByQuery(db.getSession(), query); - - assertThat(count).isEqualTo(expectedCount); - } - - private QueryTestData createQueryTestData() { - var projectData = db.components().insertPrivateProject(); - var componentDto = projectData.getMainBranchComponent(); - // the first two are set to NPM, the others default to MAVEN - var issue1 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "1", componentDto.uuid(), - scaIssueDto -> scaIssueDto, - scaVulnerabilityIssueDto -> scaVulnerabilityIssueDto, - scaReleaseDto -> scaReleaseDto.toBuilder().setPackageManager(PackageManager.NPM).build(), - scaIssueReleaseDto -> scaIssueReleaseDto); - var issue2 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "2", componentDto.uuid(), - scaIssueDto -> scaIssueDto, - scaVulnerabilityIssueDto -> scaVulnerabilityIssueDto, - scaReleaseDto -> scaReleaseDto.toBuilder().setPackageManager(PackageManager.NPM).build(), - scaIssueReleaseDto -> scaIssueReleaseDto); - var issue3 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "3", componentDto.uuid()); - var issue4 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "4", componentDto.uuid()); - // low cvss but high severity - var issue5 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "5", componentDto.uuid(), - scaIssueDto -> scaIssueDto, - scaVulnerabilityIssueDto -> scaVulnerabilityIssueDto.toBuilder() - .setCvssScore(new BigDecimal("2.1")) - .setBaseSeverity(ScaSeverity.BLOCKER) - .build(), - scaReleaseDto -> scaReleaseDto.toBuilder().setNewInPullRequest(true).build(), - scaIssueReleaseDto -> scaIssueReleaseDto.toBuilder().setSeverity(ScaSeverity.BLOCKER).build()); - // high cvss but low severity - var issue6 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "6", componentDto.uuid(), - scaIssueDto -> scaIssueDto, - scaVulnerabilityIssueDto -> scaVulnerabilityIssueDto.toBuilder() - .setCvssScore(new BigDecimal("9.1")) - .setBaseSeverity(ScaSeverity.INFO) - .build(), - scaReleaseDto -> scaReleaseDto.toBuilder().setNewInPullRequest(true).build(), - scaIssueReleaseDto -> scaIssueReleaseDto.toBuilder().setSeverity(ScaSeverity.INFO).build()); - - // issue 1 weirdly has no dependency, issues 2-3 are direct, issues 4-6 are transitive - // issues 2 and 4 are production, 3,5,6 are not production - db.getScaDependenciesDbTester().insertScaDependency(issue2.releaseUuid(), "2", - builder -> builder.setDirect(true).setProductionScope(true)); - var dep3 = db.getScaDependenciesDbTester().insertScaDependency(issue3.releaseUuid(), "3", - builder -> builder.setDirect(true).setProductionScope(false)); - var dep4 = db.getScaDependenciesDbTester().insertScaDependency(issue4.releaseUuid(), "4", - builder -> builder.setDirect(false).setProductionScope(true)); - var dep5 = db.getScaDependenciesDbTester().insertScaDependency(issue5.releaseUuid(), "5", - builder -> builder.setDirect(false).setProductionScope(false)); - db.getScaDependenciesDbTester().insertScaDependency(issue6.releaseUuid(), "6", - builder -> builder.setDirect(false).setProductionScope(false)); - - // make issue3 and issue4 BOTH direct and transitive, - // issue4 and issue5 are BOTH production and not - db.getScaDependenciesDbTester().insertScaDependency(issue3.releaseUuid(), "7", - builder -> builder.setDirect(!dep3.direct()).setProductionScope(dep3.productionScope())); - db.getScaDependenciesDbTester().insertScaDependency(issue4.releaseUuid(), "8", - builder -> builder.setDirect(!dep4.direct()).setProductionScope(!dep4.productionScope())); - db.getScaDependenciesDbTester().insertScaDependency(issue5.releaseUuid(), "9", - builder -> builder.setDirect(dep5.direct()).setProductionScope(!dep5.productionScope())); - - var directIssues = List.of(issue2, issue3, issue4).stream().sorted(identityComparator()).toList(); - var transitiveIssues = List.of(issue3, issue4, issue5, issue6).stream().sorted(identityComparator()).toList(); - var productionIssues = List.of(issue2, issue4, issue5).stream().sorted(identityComparator()).toList(); - var notProductionIssues = List.of(issue3, issue4, issue5, issue6).stream().sorted(identityComparator()).toList(); - - return new QueryTestData(projectData, componentDto, - List.of(issue1, issue2, issue3, issue4, issue5, issue6), - directIssues, transitiveIssues, productionIssues, notProductionIssues); - } - - @Test - void selectByScaIssueReleaseUuid_shouldReturnAnIssue() { - var projectData = db.components().insertPrivateProject(); - var componentDto = projectData.getMainBranchComponent(); - var issue1 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "1", componentDto.uuid()); - - // insert another issue to assert that it's not selected - db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "2", componentDto.uuid()); - - var foundIssue = scaIssuesReleasesDetailsDao.selectByScaIssueReleaseUuid(db.getSession(), issue1.issueReleaseUuid()); - assertThat(foundIssue).isEqualTo(issue1); - - var notFoundIssue = scaIssuesReleasesDetailsDao.selectByScaIssueReleaseUuid(db.getSession(), "00000"); - assertThat(notFoundIssue).isNull(); - } - - private record QueryTestData(ProjectData projectData, - ComponentDto componentDto, - List<ScaIssueReleaseDetailsDto> expectedIssues, - List<ScaIssueReleaseDetailsDto> directIssues, - List<ScaIssueReleaseDetailsDto> transitiveIssues, - List<ScaIssueReleaseDetailsDto> productionIssues, - List<ScaIssueReleaseDetailsDto> notProductionIssues) { - - public String branchUuid() { - return componentDto.branchUuid(); - } - - public List<ScaIssueReleaseDetailsDto> expectedIssuesSorted(ScaIssuesReleasesDetailsQuery.Sort sort) { - return expectedIssues.stream().sorted(comparator(sort)).toList(); - } - - public List<ScaIssueReleaseDetailsDto> expectedIssuesSortedByIdentityAsc() { - return expectedIssuesSorted(ScaIssuesReleasesDetailsQuery.Sort.IDENTITY_ASC); - } - - public List<ScaIssueReleaseDetailsDto> expectedIssuesSortedByCvssDesc() { - return expectedIssuesSorted(ScaIssuesReleasesDetailsQuery.Sort.CVSS_SCORE_DESC); - } - - public List<ScaIssueReleaseDetailsDto> expectedIssuesWithPackageManager(PackageManager packageManager) { - // we just have hardcoded knowledge of how we set them up, because ScaIssueReleaseDetailsDto doesn't - // contain the ScaReleaseDto to look at this - return switch (packageManager) { - case NPM -> expectedIssues.subList(0, 2); - case MAVEN -> expectedIssues.subList(2, expectedIssues.size()); - default -> Collections.emptyList(); - }; - } - } -} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java deleted file mode 100644 index f59f2fbf39c..00000000000 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.assertj.core.groups.Tuple; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.slf4j.LoggerFactory; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.Pagination; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ProjectData; - -import static org.assertj.core.api.Assertions.assertThat; - -class ScaReleasesDaoIT { - - @RegisterExtension - private final DbTester db = DbTester.create(System2.INSTANCE); - - private final ScaReleasesDao scaReleasesDao = db.getDbClient().scaReleasesDao(); - - @Test - void insert_shouldPersistScaReleases() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_releases"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - assertThat(stringObjectMap).containsExactlyInAnyOrderEntriesOf( - Map.ofEntries( - Map.entry("uuid", scaReleaseDto.uuid()), - Map.entry("component_uuid", scaReleaseDto.componentUuid()), - Map.entry("package_url", scaReleaseDto.packageUrl()), - Map.entry("package_manager", scaReleaseDto.packageManager().name()), - Map.entry("package_name", scaReleaseDto.packageName()), - Map.entry("version", scaReleaseDto.version()), - Map.entry("license_expression", scaReleaseDto.licenseExpression()), - Map.entry("declared_license_expression", scaReleaseDto.declaredLicenseExpression()), - Map.entry("known", scaReleaseDto.known()), - Map.entry("new_in_pull_request", scaReleaseDto.newInPullRequest()), - Map.entry("created_at", scaReleaseDto.createdAt()), - Map.entry("updated_at", scaReleaseDto.updatedAt()))); - } - - @Test - void deleteByUuid_shouldDeleteScaReleases() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_releases"); - assertThat(select).isNotEmpty(); - - scaReleasesDao.deleteByUuid(db.getSession(), scaReleaseDto.uuid()); - - select = db.select(db.getSession(), "select * from sca_releases"); - assertThat(select).isEmpty(); - } - - @Test - void selectByUuid_shouldLoadScaRelease() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); - - var loadedOptional = scaReleasesDao.selectByUuid(db.getSession(), scaReleaseDto.uuid()); - - assertThat(loadedOptional).contains(scaReleaseDto); - } - - @Test - void selectByUuid_shouldLoadScaReleases() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); - db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2"); - ScaReleaseDto scaReleaseDto3 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3"); - - // we don't ask for the second one, so this tests we only get what we asked for. - var loaded = scaReleasesDao.selectByUuids(db.getSession(), Set.of(scaReleaseDto1.uuid(), scaReleaseDto3.uuid())); - - assertThat(loaded).containsExactlyInAnyOrder(scaReleaseDto1, scaReleaseDto3); - } - - @Test - void selectByUuid_shouldLoadEmptyScaReleases() { - ComponentDto componentDto = prepareComponentDto(); - db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); - db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2"); - db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3"); - - var loaded = scaReleasesDao.selectByUuids(db.getSession(), Collections.emptyList()); - - assertThat(loaded).isEmpty(); - } - - @Test - void selectByQuery_shouldReturnScaReleases_whenQueryByBranchUuid() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); - System.out.println("componentDto = " + componentDto); - - ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null, null, null); - List<ScaReleaseDto> results = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesQuery, Pagination.all()); - - assertThat(results).hasSize(1); - assertThat(results.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto); - } - - @Test - void selectByQuery_shouldReturnPaginatedScaReleases() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); - ScaReleaseDto scaReleaseDto2 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2"); - ScaReleaseDto scaReleaseDto3 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3"); - ScaReleaseDto scaReleaseDto4 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "4"); - - ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null, null, null); - List<ScaReleaseDto> page1Results = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesQuery, Pagination.forPage(1).andSize(2)); - List<ScaReleaseDto> page2Results = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesQuery, Pagination.forPage(2).andSize(2)); - - // we order by created_at so it would seem we can assert the order here... except that created_at has finite resolution, so it can be nondeterministic. - var allResults = new ArrayList<>(page1Results); - allResults.addAll(page2Results); - assertThat(allResults).containsExactlyInAnyOrder(scaReleaseDto1, scaReleaseDto2, scaReleaseDto3, scaReleaseDto4); - assertThat(List.of(page1Results.size(), page2Results.size())).containsExactly(2, 2); - } - - @Test - void selectByQuery_shouldPartiallyMatchPackageName_whenQueriedByText() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1", PackageManager.MAVEN, "foo.bar"); - db.getScaDependenciesDbTester().insertScaDependency(scaReleaseDto1, "1", true); - db.getScaDependenciesDbTester().insertScaDependency(scaReleaseDto1, "2", false); - var log = LoggerFactory.getLogger(""); - List<Map<String, Object>> temp = db.select(db.getSession(), "select * from sca_releases"); - log.warn("sca_releases: {}", temp.stream().count()); - for (Map<String, Object> map : temp) { - log.warn(map.toString()); - } - temp = db.select(db.getSession(), "select * from sca_dependencies"); - log.warn("sca_dependencies: {}", temp.stream().count()); - for (Map<String, Object> map : temp) { - log.warn(map.toString()); - } - - @SuppressWarnings("unused") - ScaReleaseDto scaReleaseDto2 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2", PackageManager.MAVEN, "bar.mee"); - ScaReleaseDto scaReleaseDto3 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3", PackageManager.MAVEN, "foo.bar.me"); - @SuppressWarnings("unused") - ScaReleaseDto scaReleaseDto4 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "4", PackageManager.MAVEN, "some.foo.bar"); - - ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null, null, "foo"); - List<ScaReleaseDto> results = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesQuery, Pagination.all()); - - assertThat(results).hasSize(3); - assertThat(results.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto1); - assertThat(results.get(1)).usingRecursiveComparison().isEqualTo(scaReleaseDto3); - - ScaReleasesQuery scaReleasesCaseInsensitiveQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null, null, "Foo.Bar"); - List<ScaReleaseDto> resultsCaseInsensitive = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesCaseInsensitiveQuery, Pagination.all()); - - assertThat(resultsCaseInsensitive).hasSize(3); - assertThat(resultsCaseInsensitive.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto1); - assertThat(resultsCaseInsensitive.get(1)).usingRecursiveComparison().isEqualTo(scaReleaseDto3); - } - - @Test - void selectByQuery_shouldReturnScaReleases_whenQueryByDirect() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto.uuid(), "1", 2, true, PackageManager.MAVEN, "foo.bar"); - ScaReleaseDto scaReleaseDto2 = db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto.uuid(), "2", 3, false, PackageManager.MAVEN, "foo.bar"); - - ScaReleasesQuery scaReleasesDirectQuery = new ScaReleasesQuery(componentDto.branchUuid(), true, null, null, null, null); - List<ScaReleaseDto> resultsDirect = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesDirectQuery, Pagination.all()); - - assertThat(resultsDirect).hasSize(1); - assertThat(resultsDirect.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto1); - - ScaReleasesQuery scaReleasesNoDirectQuery = new ScaReleasesQuery(componentDto.branchUuid(), false, null, null, null, null); - List<ScaReleaseDto> resultsNoDirect = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesNoDirectQuery, Pagination.all()); - - assertThat(resultsNoDirect).hasSize(1); - assertThat(resultsNoDirect.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto2); - } - - @Test - void selectByQuery_shouldReturnScaReleases_whenQueryByProductionScope() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); - ScaReleaseDto scaReleaseDto2 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2"); - db.getScaDependenciesDbTester().insertScaDependency(scaReleaseDto1, "1", builder -> builder.setProductionScope(true)); - db.getScaDependenciesDbTester().insertScaDependency(scaReleaseDto2, "2", builder -> builder.setProductionScope(false)); - - ScaReleasesQuery scaReleasesProductionScopeQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, true, null, null, null); - List<ScaReleaseDto> resultsProductionScope = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesProductionScopeQuery, Pagination.all()); - - assertThat(resultsProductionScope).hasSize(1); - assertThat(resultsProductionScope.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto1); - - ScaReleasesQuery scaReleasesNoProductionScopeQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, false, null, null, null); - List<ScaReleaseDto> resultsNoProductionScope = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesNoProductionScopeQuery, Pagination.all()); - - assertThat(resultsNoProductionScope).hasSize(1); - assertThat(resultsNoProductionScope.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto2); - } - - @Test - void selectByQuery_shouldReturnScaReleases_whenQueryByPackageManager() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1", PackageManager.MAVEN, "foo.bar"); - ScaReleaseDto scaReleaseDto2 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2", PackageManager.NPM, "foo.bar"); - ScaReleaseDto scaReleaseDto3 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3", PackageManager.CARGO, "foo.bar"); - - ScaReleasesQuery scaReleasesMavenQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, List.of(PackageManager.MAVEN.name()), null, null); - List<ScaReleaseDto> resultsMaven = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesMavenQuery, Pagination.all()); - - assertThat(resultsMaven).hasSize(1); - assertThat(resultsMaven.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto1); - - ScaReleasesQuery scaReleasesNpmAndCargoQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, - List.of(PackageManager.NPM.name(), PackageManager.CARGO.name()), null, null); - List<ScaReleaseDto> resultsNpm = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesNpmAndCargoQuery, Pagination.all()); - - assertThat(resultsNpm).hasSize(2); - assertThat(resultsNpm.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto2); - assertThat(resultsNpm.get(1)).usingRecursiveComparison().isEqualTo(scaReleaseDto3); - } - - @Test - void update_shouldUpdateScaRelease() { - ComponentDto componentDto = prepareComponentDto(); - ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1", PackageManager.MAVEN, "foo.bar"); - ScaReleaseDto updatedScaRelease = scaReleaseDto.toBuilder().setUpdatedAt(scaReleaseDto.updatedAt() + 1).setVersion("newVersion").build(); - - scaReleasesDao.update(db.getSession(), updatedScaRelease); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_releases"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - assertThat(stringObjectMap).containsExactlyInAnyOrderEntriesOf( - Map.ofEntries( - Map.entry("uuid", updatedScaRelease.uuid()), - Map.entry("component_uuid", updatedScaRelease.componentUuid()), - Map.entry("package_url", updatedScaRelease.packageUrl()), - Map.entry("package_manager", updatedScaRelease.packageManager().name()), - Map.entry("package_name", updatedScaRelease.packageName()), - Map.entry("version", updatedScaRelease.version()), - Map.entry("license_expression", updatedScaRelease.licenseExpression()), - Map.entry("declared_license_expression", updatedScaRelease.declaredLicenseExpression()), - Map.entry("known", updatedScaRelease.known()), - Map.entry("new_in_pull_request", updatedScaRelease.newInPullRequest()), - Map.entry("created_at", updatedScaRelease.createdAt()), - Map.entry("updated_at", updatedScaRelease.updatedAt()))); - } - - @Test - void countByQuery_shouldReturnTheTotalOfReleases() { - ComponentDto componentDto1 = prepareComponentDto(); - db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "1", 1, true, PackageManager.MAVEN, "foo.bar"); - db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "2", 2, true, PackageManager.MAVEN, "foo.bar.mee"); - db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "3", 3, true, PackageManager.MAVEN, "bar.fo"); - - ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto1.branchUuid(), null, null, null, null, "foo"); - - assertThat(scaReleasesDao.countByQuery(db.getSession(), scaReleasesQuery)).isEqualTo(2); - assertThat(scaReleasesDao.countByQuery(db.getSession(), new ScaReleasesQuery(componentDto1.branchUuid(), null, null, null, null, null))).isEqualTo(3); - assertThat(scaReleasesDao.countByQuery(db.getSession(), new ScaReleasesQuery("another_branch_uuid", null, null, null, null, null))).isZero(); - } - - private ComponentDto prepareComponentDto() { - ProjectData projectData = db.components().insertPublicProject(); - return projectData.getMainBranchComponent(); - } - - @Test - void countByPlatformQuery_shouldReturnPlatforms() { - ComponentDto componentDto1 = prepareComponentDto(); - db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "1", 1, true, PackageManager.MAVEN, "foo.bar"); - db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "2", 2, true, PackageManager.NPM, "foo.bar.mee"); - db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "3", 3, true, PackageManager.MAVEN, "bar.foo"); - db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "4", 4, true, PackageManager.PYPI, "bar.foo"); - - ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto1.branchUuid(), null, null, null, null, null); - - List<ScaReleaseByPackageManagerCountDto> releaseCounts = scaReleasesDao.countReleasesByPackageManager(db.getSession(), scaReleasesQuery); - assertThat(releaseCounts).hasSize(3); - assertThat(releaseCounts).extracting("packageManager", "releaseCount") - .containsExactlyInAnyOrder(Tuple.tuple(PackageManager.MAVEN.name(), 2), - Tuple.tuple(PackageManager.NPM.name(), 1), - Tuple.tuple(PackageManager.PYPI.name(), 1)); - } -} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDependenciesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDependenciesDaoIT.java deleted file mode 100644 index e8384f05a0c..00000000000 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDependenciesDaoIT.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; - -import static org.assertj.core.api.Assertions.assertThat; - -class ScaReleasesDependenciesDaoIT { - @RegisterExtension - private final DbTester db = DbTester.create(System2.INSTANCE); - - private final ScaReleasesDependenciesDao scaReleasesDependenciesDao = db.getDbClient().scaReleasesDependenciesDao(); - - @Test - void test_whenEmptyDatabaseAndQuery_selectByReleaseUuids() { - assertThat(scaReleasesDependenciesDao.selectByReleaseUuids(db.getSession(), List.of())).isEmpty(); - } - - @Test - void test_whenSomeDependencies_selectByReleaseUuids() { - ComponentDto componentDto = db.components().insertPublicProject().getMainBranchComponent(); - - ScaDependencyDto scaDependencyDto1a = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "1a", true, PackageManager.MAVEN, "foo.bar1"); - // same release, different dependency - ScaDependencyDto scaDependencyDto1b = db.getScaDependenciesDbTester().insertScaDependency(scaDependencyDto1a.scaReleaseUuid(), "1b", false); - ScaDependencyDto scaDependencyDto2 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "2", true, PackageManager.MAVEN, "foo.bar2"); - ScaDependencyDto scaDependencyDto3 = db.getScaDependenciesDbTester().insertScaDependencyWithRelease(componentDto.uuid(), "3", true, PackageManager.MAVEN, "foo.bar3"); - - List<ScaReleaseDependenciesDto> results = scaReleasesDependenciesDao.selectByReleaseUuids(db.getSession(), - List.of(scaDependencyDto1a.scaReleaseUuid(), scaDependencyDto2.scaReleaseUuid())); - - assertThat(results.stream().map(ScaReleaseDependenciesDto::dependencies).flatMap(List::stream).toList()) - .containsExactlyInAnyOrder(scaDependencyDto1a, scaDependencyDto1b, scaDependencyDto2) - .doesNotContain(scaDependencyDto3); - var twoDeps = results.stream().filter(rd -> rd.releaseUuid().equals(scaDependencyDto1a.scaReleaseUuid())) - .findFirst().map(ScaReleaseDependenciesDto::dependencies).orElseThrow(); - assertThat(twoDeps).containsExactlyInAnyOrder(scaDependencyDto1a, scaDependencyDto1b); - - var resultsWithEmptyQuery = scaReleasesDependenciesDao.selectByReleaseUuids(db.getSession(), List.of()); - assertThat(resultsWithEmptyQuery).isEmpty(); - } -} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaVulnerabilityIssuesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaVulnerabilityIssuesDaoIT.java deleted file mode 100644 index dbfbaf3d6d2..00000000000 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaVulnerabilityIssuesDaoIT.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.List; -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; - -import static org.assertj.core.api.Assertions.assertThat; - -class ScaVulnerabilityIssuesDaoIT { - - @RegisterExtension - private final DbTester db = DbTester.create(System2.INSTANCE); - - private final ScaVulnerabilityIssuesDao scaVulnerabilityIssuesDao = db.getDbClient().scaVulnerabilityIssuesDao(); - - private static final ScaVulnerabilityIssueDto newScaVulnerabilityIssueDto(String suffix) { - return new ScaVulnerabilityIssueDto("uuid" + suffix, ScaSeverity.INFO, List.of("cwe-" + suffix), new BigDecimal("7.1"), 1L, 2L); - } - - @Test - void insert_shouldPersistScaVulnerabilityIssues() { - ScaVulnerabilityIssueDto issueDto = newScaVulnerabilityIssueDto("1"); - scaVulnerabilityIssuesDao.insert(db.getSession(), issueDto); - - List<Map<String, Object>> select = db.select(db.getSession(), "select * from sca_vulnerability_issues"); - assertThat(select).hasSize(1); - Map<String, Object> stringObjectMap = select.get(0); - // we can't compare doubles, so it's hackin' time - var possibleDouble = stringObjectMap.get("cvss_score"); - if (possibleDouble instanceof Double d) { - stringObjectMap.put("cvss_score", BigDecimal.valueOf(d)); - } - assertThat(stringObjectMap).containsExactlyInAnyOrderEntriesOf( - Map.ofEntries( - Map.entry("uuid", issueDto.uuid()), - Map.entry("base_severity", issueDto.baseSeverity().name()), - Map.entry("cwe_ids", "[" + String.join(", ", issueDto.cweIds().stream().map(s -> "\"" + s + "\"").toList()) + "]"), - Map.entry("cvss_score", issueDto.cvssScore()), - Map.entry("created_at", issueDto.createdAt()), - Map.entry("updated_at", issueDto.updatedAt()))); - } - - @Test - void insert_canSaveNullCvssScore() { - ScaVulnerabilityIssueDto issueDtoNotNull = newScaVulnerabilityIssueDto("1"); - ScaVulnerabilityIssueDto issueDto = new ScaVulnerabilityIssueDto(issueDtoNotNull.uuid(), ScaSeverity.INFO, issueDtoNotNull.cweIds(), - null, issueDtoNotNull.createdAt(), issueDtoNotNull.updatedAt()); - - scaVulnerabilityIssuesDao.insert(db.getSession(), issueDto); - - var loadedOptional = scaVulnerabilityIssuesDao.selectByUuid(db.getSession(), issueDto.uuid()); - - assertThat(loadedOptional).contains(issueDto); - assertThat(loadedOptional.get().cvssScore()).isNull(); - } - - @Test - void insert_canSaveTenCvssScore() { - ScaVulnerabilityIssueDto issueDtoBase = newScaVulnerabilityIssueDto("1"); - ScaVulnerabilityIssueDto issueDto = new ScaVulnerabilityIssueDto(issueDtoBase.uuid(), ScaSeverity.INFO, - issueDtoBase.cweIds(), new BigDecimal("10.0"), issueDtoBase.createdAt(), issueDtoBase.updatedAt()); - assertThat(issueDto.cvssScore().scale()).isEqualTo(1); - - scaVulnerabilityIssuesDao.insert(db.getSession(), issueDto); - - // the different db backends are not consistent about actually keeping the scale - // so we have to fix it to be what we expect - var loadedOptionalScore = scaVulnerabilityIssuesDao.selectByUuid(db.getSession(), issueDto.uuid()) - .map(ScaVulnerabilityIssueDto::cvssScore) - .map(score -> score.setScale(1, RoundingMode.HALF_UP)); - - assertThat(loadedOptionalScore).contains(issueDto.cvssScore()); - } - - @Test - void selectByUuid_shouldLoadScaVulnerabilityIssue() { - ScaVulnerabilityIssueDto issueDto = newScaVulnerabilityIssueDto("1"); - scaVulnerabilityIssuesDao.insert(db.getSession(), issueDto); - - var loadedOptional = scaVulnerabilityIssuesDao.selectByUuid(db.getSession(), issueDto.uuid()); - - assertThat(loadedOptional).contains(issueDto); - } - - @Test - void selectByUuids_shouldLoadScaVulnerabilityIssues() { - List<ScaVulnerabilityIssueDto> issueDtos = List.of(newScaVulnerabilityIssueDto("1"), - newScaVulnerabilityIssueDto("2"), newScaVulnerabilityIssueDto("3")); - for (var issueDto : issueDtos) { - scaVulnerabilityIssuesDao.insert(db.getSession(), issueDto); - } - - List<String> uuidsToLoad = List.of(issueDtos.get(0).uuid(), issueDtos.get(2).uuid()); - var loaded = scaVulnerabilityIssuesDao.selectByUuids(db.getSession(), uuidsToLoad); - - assertThat(loaded).containsExactlyInAnyOrder(issueDtos.get(0), issueDtos.get(2)); - } - - @Test - void update_shouldModifyScaVulnerabilityIssue() { - ScaVulnerabilityIssueDto issueDto = newScaVulnerabilityIssueDto("1"); - scaVulnerabilityIssuesDao.insert(db.getSession(), issueDto); - ScaVulnerabilityIssueDto issueDtoUpdated = new ScaVulnerabilityIssueDto(issueDto.uuid(), - ScaSeverity.BLOCKER, - issueDto.cweIds().stream().map(s -> s + "-updated").toList(), - issueDto.cvssScore().add(new BigDecimal("1.3")), - issueDto.createdAt(), 5L); - - assertThat(issueDtoUpdated.baseSeverity()).isNotEqualTo(issueDto.baseSeverity()); - - scaVulnerabilityIssuesDao.update(db.getSession(), issueDtoUpdated); - - var loadedOptional = scaVulnerabilityIssuesDao.selectByUuid(db.getSession(), issueDto.uuid()); - - assertThat(loadedOptional).contains(issueDtoUpdated); - } -} diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/user/GroupDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/user/GroupDaoIT.java index 9b52c0d7264..16e86bcd2e5 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/user/GroupDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/user/GroupDaoIT.java @@ -223,6 +223,47 @@ class GroupDaoIT { } @Test + void findByQuery_withUserId_countAndFindExpectedUsers() { + GroupDto group1 = db.users().insertGroup("sonar-users"); + GroupDto group2 = db.users().insertGroup("SONAR-ADMINS"); + GroupDto group3 = db.users().insertGroup("customers-group1"); + + UserDto user = db.users().insertUser(); + UserDto user2 = db.users().insertUser(); + db.users().insertMember(group1, user); + db.users().insertMember(group2, user); + db.users().insertMember(group2, user2); + db.users().insertMember(group3, user2); + + GroupQuery groupQueryIncludingUser = GroupQuery.builder().userId(user.getUuid()).build(); + + assertThat(underTest.countByQuery(dbSession, groupQueryIncludingUser)).isEqualTo(2); + assertThat(underTest.selectByQuery(dbSession, groupQueryIncludingUser, 1, 100)) + .extracting(GroupDto::getUuid) + .containsExactlyInAnyOrder(group1.getUuid(), group2.getUuid()); + } + + @Test + void findByQuery_withExcludedUserId_countAndFindExpectedUsers() { + GroupDto group1 = db.users().insertGroup("sonar-users"); + GroupDto group2 = db.users().insertGroup("SONAR-ADMINS"); + GroupDto group3 = db.users().insertGroup("customers-group1"); + + UserDto user = db.users().insertUser(); + UserDto user2 = db.users().insertUser(); + db.users().insertMember(group1, user); + db.users().insertMember(group2, user); + db.users().insertMember(group2, user2); + db.users().insertMember(group3, user2); + + GroupQuery groupQueryExcludingUser = GroupQuery.builder().excludedUserId(user.getUuid()).build(); + assertThat(underTest.countByQuery(dbSession, groupQueryExcludingUser)).isEqualTo(1); + assertThat(underTest.selectByQuery(dbSession, groupQueryExcludingUser, 1, 100)) + .extracting(GroupDto::getUuid) + .containsExactlyInAnyOrder(group3.getUuid()); + } + + @Test void deleteByUuid() { db.getDbClient().groupDao().insert(dbSession, aGroup); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/user/RoleDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/user/RoleDaoIT.java index 51740d120f0..a2ad19232a7 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/user/RoleDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/user/RoleDaoIT.java @@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; +import org.sonar.db.permission.ProjectPermission; import org.sonar.core.util.Uuids; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -64,13 +64,13 @@ class RoleDaoIT { @Test void selectComponentUuidsByPermissionAndUserId_throws_IAR_if_permission_USER_is_specified() { expectUnsupportedUserAndCodeViewerPermission(() -> underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, - UserRole.USER, Uuids.createFast(), PROJECT_QUALIFIER)); + ProjectPermission.USER, Uuids.createFast(), PROJECT_QUALIFIER)); } @Test void selectComponentUuidsByPermissionAndUserId_throws_IAR_if_permission_CODEVIEWER_is_specified() { expectUnsupportedUserAndCodeViewerPermission(() -> underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, - UserRole.CODEVIEWER, Uuids.createFast(), PROJECT_QUALIFIER)); + ProjectPermission.CODEVIEWER, Uuids.createFast(), PROJECT_QUALIFIER)); } private void expectUnsupportedUserAndCodeViewerPermission(ThrowingCallable callback) { @@ -81,16 +81,16 @@ class RoleDaoIT { @Test void selectEntityIdsByPermissionAndUserUuid() { - db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, project1); - db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, project2); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ADMIN, project1); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ADMIN, project2); // global permission - not returned db.users().insertGlobalPermissionOnUser(user1, ADMINISTER); // project permission on another user id - not returned - db.users().insertProjectPermissionOnUser(user2, UserRole.ADMIN, project1); + db.users().insertProjectPermissionOnUser(user2, ProjectPermission.ADMIN, project1); // project permission on another permission - not returned - db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, project1); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ISSUE_ADMIN, project1); - List<String> entityUuids = underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, UserRole.ADMIN, user1.getUuid(), + List<String> entityUuids = underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, ProjectPermission.ADMIN, user1.getUuid(), PROJECT_QUALIFIER); assertThat(entityUuids).containsExactly(project1.getUuid(), project2.getUuid()); @@ -100,9 +100,9 @@ class RoleDaoIT { void selectComponentIdsByPermissionAndUserUuid_group_permissions() { GroupDto group1 = db.users().insertGroup(); GroupDto group2 = db.users().insertGroup(); - db.users().insertEntityPermissionOnGroup(group1, UserRole.ADMIN, project1); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ADMIN, project1); db.users().insertMember(group1, user1); - db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, project2); + db.users().insertProjectPermissionOnUser(user1, ProjectPermission.ADMIN, project2); // global permission - not returned db.users().insertGlobalPermissionOnUser(user1, ADMINISTER); db.users().insertPermissionOnGroup(group1, ADMINISTER); @@ -110,9 +110,9 @@ class RoleDaoIT { db.users().insertPermissionOnGroup(group2, ADMINISTER); db.users().insertMember(group2, user2); // project permission on another permission - not returned - db.users().insertEntityPermissionOnGroup(group1, UserRole.ISSUE_ADMIN, project1); + db.users().insertEntityPermissionOnGroup(group1, ProjectPermission.ISSUE_ADMIN, project1); - List<String> result = underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, UserRole.ADMIN, user1.getUuid(), + List<String> result = underTest.selectEntityUuidsByPermissionAndUserUuidAndQualifier(dbSession, ProjectPermission.ADMIN, user1.getUuid(), PROJECT_QUALIFIER); assertThat(result).containsExactlyInAnyOrder(project1.getUuid(), project2.getUuid()); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java index 23ee064c592..02986d9c4c6 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java @@ -88,13 +88,6 @@ import org.sonar.db.report.ReportSubscriptionDao; import org.sonar.db.rule.RuleChangeDao; import org.sonar.db.rule.RuleDao; import org.sonar.db.rule.RuleRepositoryDao; -import org.sonar.db.sca.ScaDependenciesDao; -import org.sonar.db.sca.ScaIssuesDao; -import org.sonar.db.sca.ScaIssuesReleasesDao; -import org.sonar.db.sca.ScaIssuesReleasesDetailsDao; -import org.sonar.db.sca.ScaReleasesDao; -import org.sonar.db.sca.ScaReleasesDependenciesDao; -import org.sonar.db.sca.ScaVulnerabilityIssuesDao; import org.sonar.db.scannercache.ScannerAnalysisCacheDao; import org.sonar.db.schemamigration.SchemaMigrationDao; import org.sonar.db.scim.ScimGroupDao; @@ -156,7 +149,6 @@ public class DaoModule extends Module { IssueChangeDao.class, IssueDao.class, IssueFixedDao.class, - ScaIssuesReleasesDetailsDao.class, MeasureDao.class, ProjectMeasureDao.class, MetricDao.class, @@ -192,12 +184,6 @@ public class DaoModule extends Module { RuleChangeDao.class, RuleRepositoryDao.class, SamlMessageIdDao.class, - ScaDependenciesDao.class, - ScaIssuesDao.class, - ScaIssuesReleasesDao.class, - ScaReleasesDao.class, - ScaReleasesDependenciesDao.class, - ScaVulnerabilityIssuesDao.class, ScannerAnalysisCacheDao.class, SchemaMigrationDao.class, ScimGroupDao.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java index ed5319a5ec9..ec1fc6884b1 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java @@ -88,13 +88,6 @@ import org.sonar.db.report.ReportSubscriptionDao; import org.sonar.db.rule.RuleChangeDao; import org.sonar.db.rule.RuleDao; import org.sonar.db.rule.RuleRepositoryDao; -import org.sonar.db.sca.ScaDependenciesDao; -import org.sonar.db.sca.ScaIssuesDao; -import org.sonar.db.sca.ScaIssuesReleasesDao; -import org.sonar.db.sca.ScaIssuesReleasesDetailsDao; -import org.sonar.db.sca.ScaReleasesDao; -import org.sonar.db.sca.ScaReleasesDependenciesDao; -import org.sonar.db.sca.ScaVulnerabilityIssuesDao; import org.sonar.db.scannercache.ScannerAnalysisCacheDao; import org.sonar.db.schemamigration.SchemaMigrationDao; import org.sonar.db.scim.ScimGroupDao; @@ -207,13 +200,6 @@ public class DbClient { private final ProjectExportDao projectExportDao; private final IssueFixedDao issueFixedDao; private final TelemetryMetricsSentDao telemetryMetricsSentDao; - private final ScaReleasesDao scaReleasesDao; - private final ScaDependenciesDao scaDependenciesDao; - private final ScaReleasesDependenciesDao scaReleasesDependenciesDao; - private final ScaIssuesDao scaIssuesDao; - private final ScaIssuesReleasesDao scaIssuesReleasesDao; - private final ScaVulnerabilityIssuesDao scaVulnerabilityIssuesDao; - private final ScaIssuesReleasesDetailsDao scaIssuesReleasesDetailsDao; public DbClient(Database database, MyBatis myBatis, DBSessions dbSessions, Dao... daos) { this.database = database; @@ -310,13 +296,6 @@ public class DbClient { projectExportDao = getDao(map, ProjectExportDao.class); issueFixedDao = getDao(map, IssueFixedDao.class); telemetryMetricsSentDao = getDao(map, TelemetryMetricsSentDao.class); - scaReleasesDao = getDao(map, ScaReleasesDao.class); - scaDependenciesDao = getDao(map, ScaDependenciesDao.class); - scaReleasesDependenciesDao = getDao(map, ScaReleasesDependenciesDao.class); - scaIssuesDao = getDao(map, ScaIssuesDao.class); - scaIssuesReleasesDao = getDao(map, ScaIssuesReleasesDao.class); - scaVulnerabilityIssuesDao = getDao(map, ScaVulnerabilityIssuesDao.class); - scaIssuesReleasesDetailsDao = getDao(map, ScaIssuesReleasesDetailsDao.class); } public DbSession openSession(boolean batch) { @@ -680,32 +659,4 @@ public class DbClient { public ProjectExportDao projectExportDao() { return projectExportDao; } - - public ScaReleasesDao scaReleasesDao() { - return scaReleasesDao; - } - - public ScaDependenciesDao scaDependenciesDao() { - return scaDependenciesDao; - } - - public ScaReleasesDependenciesDao scaReleasesDependenciesDao() { - return scaReleasesDependenciesDao; - } - - public ScaIssuesDao scaIssuesDao() { - return scaIssuesDao; - } - - public ScaIssuesReleasesDao scaIssuesReleasesDao() { - return scaIssuesReleasesDao; - } - - public ScaVulnerabilityIssuesDao scaVulnerabilityIssuesDao() { - return scaVulnerabilityIssuesDao; - } - - public ScaIssuesReleasesDetailsDao scaIssuesReleasesDetailsDao() { - return scaIssuesReleasesDetailsDao; - } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java index cb67f4a4b65..334ad5a5cdf 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java @@ -151,13 +151,6 @@ import org.sonar.db.rule.RuleChangeMapper; import org.sonar.db.rule.RuleMapper; import org.sonar.db.rule.RuleParamDto; import org.sonar.db.rule.RuleRepositoryMapper; -import org.sonar.db.sca.ScaDependenciesMapper; -import org.sonar.db.sca.ScaDependencyDto; -import org.sonar.db.sca.ScaIssuesMapper; -import org.sonar.db.sca.ScaIssuesReleasesDetailsMapper; -import org.sonar.db.sca.ScaIssuesReleasesMapper; -import org.sonar.db.sca.ScaReleasesMapper; -import org.sonar.db.sca.ScaVulnerabilityIssuesMapper; import org.sonar.db.scannercache.ScannerAnalysisCacheMapper; import org.sonar.db.schemamigration.SchemaMigrationDto; import org.sonar.db.schemamigration.SchemaMigrationMapper; @@ -258,7 +251,6 @@ public class MyBatis { confBuilder.loadAlias("QualityGate", QualityGateDto.class); confBuilder.loadAlias("Resource", ResourceDto.class); confBuilder.loadAlias("RuleParam", RuleParamDto.class); - confBuilder.loadAlias("ScaDependency", ScaDependencyDto.class); confBuilder.loadAlias("SchemaMigration", SchemaMigrationDto.class); confBuilder.loadAlias("ScrapProperty", ScrapPropertyDto.class); confBuilder.loadAlias("ScrapAnalysisProperty", ScrapAnalysisPropertyDto.class); @@ -347,12 +339,6 @@ public class MyBatis { RuleChangeMapper.class, RuleRepositoryMapper.class, SamlMessageIdMapper.class, - ScaDependenciesMapper.class, - ScaIssuesMapper.class, - ScaIssuesReleasesMapper.class, - ScaIssuesReleasesDetailsMapper.class, - ScaReleasesMapper.class, - ScaVulnerabilityIssuesMapper.class, ScannerAnalysisCacheMapper.class, SchemaMigrationMapper.class, ScimGroupMapper.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingDto.java index 95f83df37d7..2d0e5766eb9 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingDto.java @@ -19,6 +19,7 @@ */ package org.sonar.db.alm.setting; +import java.util.Objects; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -165,5 +166,21 @@ public class ProjectAlmSettingDto { this.createdAt = createdAt; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ProjectAlmSettingDto that = (ProjectAlmSettingDto) o; + return Objects.equals(uuid, that.uuid); + } + + @Override + public int hashCode() { + return Objects.hash(uuid); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingQuery.java index ea3d8fd1b47..54c7f6621f5 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingQuery.java @@ -21,6 +21,73 @@ package org.sonar.db.alm.setting; import javax.annotation.Nullable; -public record ProjectAlmSettingQuery(@Nullable String repository, @Nullable String almSettingUuid -) { +public record ProjectAlmSettingQuery( + @Nullable String repository, + @Nullable String almSettingUuid, + @Nullable String almRepo, + @Nullable String almSlug) { + + // Existing constructor for backward compatibility (repository search in both alm_repo and alm_slug) + public ProjectAlmSettingQuery(String repository, String almSettingUuid) { + this(repository, almSettingUuid, null, null); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String repository; + private String almSettingUuid; + private String almRepo; + private String almSlug; + + private Builder() { + } + + public Builder repository(String repository) { + if (almRepo != null || almSlug != null) { + throw new IllegalStateException("Cannot use repository with almRepo or almSlug"); + } + this.repository = repository; + return this; + } + + public Builder almSettingUuid(String almSettingUuid) { + if (almRepo != null || almSlug != null) { + throw new IllegalStateException("Cannot use almSettingUuid with almRepo or almSlug"); + } + this.almSettingUuid = almSettingUuid; + return this; + } + + public Builder almRepo(String almRepo) { + if (repository != null || almSettingUuid != null) { + throw new IllegalStateException("Cannot use almRepo with repository or almSettingUuid"); + } + this.almRepo = almRepo; + return this; + } + + public Builder almSlug(String almSlug) { + if (repository != null || almSettingUuid != null) { + throw new IllegalStateException("Cannot use almSlug with repository or almSettingUuid"); + } + this.almSlug = almSlug; + return this; + } + + public ProjectAlmSettingQuery build() { + return new ProjectAlmSettingQuery(repository, almSettingUuid, almRepo, almSlug); + } + } + + public static ProjectAlmSettingQuery forAlmRepo(String almRepo) { + return builder().almRepo(almRepo).build(); + } + + public static ProjectAlmSettingQuery forAlmRepoAndSlug(String almRepo, String almSlug) { + return builder().almRepo(almRepo).almSlug(almSlug).build(); + } + } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java index 1f72e4a4002..faa712d555d 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java @@ -214,4 +214,8 @@ public class BranchDao implements Dao { public List<BranchDto> selectMainBranchesAssociatedToDefaultQualityProfile(DbSession dbSession) { return mapper(dbSession).selectMainBranchesAssociatedToDefaultQualityProfile(); } + + public List<BranchDto> selectPullRequestsTargetingBranch(DbSession dbSession, String projectUuid, String branchUuid) { + return mapper(dbSession).selectPullRequestsTargetingBranch(projectUuid, branchUuid); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java index 04c4642834f..dbd11313580 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java @@ -81,4 +81,6 @@ public interface BranchMapper { List<BranchDto> selectMainBranches(); List<BranchDto> selectMainBranchesAssociatedToDefaultQualityProfile(); + + List<BranchDto> selectPullRequestsTargetingBranch(@Param("projectUuid") String projectUuid, @Param("branchUuid") String branchUuid); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java index 61f2b6d96c6..1e58c75dc36 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDto.java @@ -42,7 +42,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.core.issue.DefaultIssue; import org.sonar.db.component.ComponentDto; @@ -877,7 +877,7 @@ public final class IssueDto implements Serializable { public DefaultIssue toDefaultIssue() { DefaultIssue issue = new DefaultIssue(); issue.setKey(kee); - issue.setType(RuleType.valueOf(type)); + issue.setType(RuleType.fromDbConstant(type)); issue.setStatus(status); issue.setResolution(resolution); issue.setMessage(message); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java index 1402b8cadd0..85dd8c651e9 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java @@ -126,6 +126,10 @@ public class AuthorizationDao implements Dao { return mapper(dbSession).countUsersWithGlobalPermissionExcludingUserPermission(permission, userUuid); } + public Set<String> keepAuthorizedEntityUuids(DbSession dbSession, Collection<String> entityUuids, @Nullable String userUuid, ProjectPermission permission) { + return keepAuthorizedEntityUuids(dbSession, entityUuids, userUuid, permission.getKey()); + } + public Set<String> keepAuthorizedEntityUuids(DbSession dbSession, Collection<String> entityUuids, @Nullable String userUuid, String permission) { return executeLargeInputsIntoSet( entityUuids, @@ -142,10 +146,15 @@ public class AuthorizationDao implements Dao { * Keep only authorized user that have the given permission on a given entity. * Please Note that if the permission is 'Anyone' is NOT taking into account by this method. */ - public Collection<String> keepAuthorizedUsersForRoleAndEntity(DbSession dbSession, Collection<String> userUuids, String role, String entityUuid) { + public Collection<String> keepAuthorizedUsersForRoleAndEntity(DbSession dbSession, Collection<String> userUuids, ProjectPermission permission, String entityUuid) { + return keepAuthorizedUsersForRoleAndEntity(dbSession, userUuids, permission.getKey(), entityUuid); + } + + + public Collection<String> keepAuthorizedUsersForRoleAndEntity(DbSession dbSession, Collection<String> userUuids, String permission, String entityUuid) { return executeLargeInputs( userUuids, - partitionOfIds -> mapper(dbSession).keepAuthorizedUsersForRoleAndEntity(role, entityUuid, partitionOfIds), + partitionOfIds -> mapper(dbSession).keepAuthorizedUsersForRoleAndEntity(permission, entityUuid, partitionOfIds), partitionSize -> partitionSize / 3); } @@ -161,6 +170,10 @@ public class AuthorizationDao implements Dao { return mapper(dbSession).selectEmailSubscribersWithGlobalPermission(ADMINISTER.getKey()); } + public Set<String> keepAuthorizedLoginsOnEntity(DbSession dbSession, Set<String> logins, String entityKey, ProjectPermission permission) { + return keepAuthorizedLoginsOnEntity(dbSession, logins, entityKey, permission.getKey()); + } + public Set<String> keepAuthorizedLoginsOnEntity(DbSession dbSession, Set<String> logins, String entityKey, String permission) { return executeLargeInputsIntoSet( logins, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/CountPerEntityPermission.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/CountPerEntityPermission.java index 9d6c2c207ac..e3870a20127 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/CountPerEntityPermission.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/CountPerEntityPermission.java @@ -34,9 +34,9 @@ public class CountPerEntityPermission { } @VisibleForTesting - CountPerEntityPermission(String entityUuid, String permission, int count) { + CountPerEntityPermission(String entityUuid, ProjectPermission permission, int count) { this.entityUuid = entityUuid; - this.permission = permission; + this.permission = permission.getKey(); this.count = count; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GlobalPermission.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GlobalPermission.java index 395d31a7ff9..f7998a70808 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GlobalPermission.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GlobalPermission.java @@ -59,7 +59,7 @@ public enum GlobalPermission { return p; } } - throw new IllegalArgumentException("Unsupported permission: " + key); + throw new IllegalArgumentException("Unsupported global permission: " + key); } public static boolean contains(String key) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDao.java index 3306033e1d3..bcdfaee08db 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDao.java @@ -117,6 +117,10 @@ public class GroupPermissionDao implements Dao { * permission, <strong>excluding group "AnyOne"</strong> (which implies the returned {@code Sett} can't contain * {@code null}). */ + public Set<String> selectGroupUuidsWithPermissionOnEntityBut(DbSession session, String entityUuid, ProjectPermission permission) { + return selectGroupUuidsWithPermissionOnEntityBut(session, entityUuid, permission.getKey()); + } + public Set<String> selectGroupUuidsWithPermissionOnEntityBut(DbSession session, String entityUuid, String permission) { return mapper(session).selectGroupUuidsWithPermissionOnEntityBut(entityUuid, permission); } @@ -205,6 +209,11 @@ public class GroupPermissionDao implements Dao { * @param groupUuid if null, then anyone, else uuid of group * @param entityDto if null, then global permission, otherwise the uuid of entity */ + public void delete(DbSession dbSession, ProjectPermission permission, @Nullable String groupUuid, + @Nullable String groupName, @Nullable EntityDto entityDto) { + delete(dbSession, permission.getKey(), groupUuid, groupName, entityDto); + } + public void delete(DbSession dbSession, String permission, @Nullable String groupUuid, @Nullable String groupName, @Nullable EntityDto entityDto) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDto.java index e0507f7bb26..d6fcd6a3646 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/GroupPermissionDto.java @@ -64,6 +64,10 @@ public class GroupPermissionDto { return role; } + public GroupPermissionDto setRole(ProjectPermission permission) { + return setRole(permission.getKey()); + } + public GroupPermissionDto setRole(String role) { this.role = role; return this; diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/PermissionQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/PermissionQuery.java index 95dd6226eea..5bb0acd62f1 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/PermissionQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/PermissionQuery.java @@ -137,6 +137,10 @@ public class PermissionQuery { return this; } + public Builder setPermission(@Nullable ProjectPermission permission) { + return setPermission(permission == null ? null : permission.getKey()); + } + public Builder setEntity(ComponentDto component) { return setEntityUuid(component.uuid()); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/ProjectPermission.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/ProjectPermission.java new file mode 100644 index 00000000000..230594b58b5 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/ProjectPermission.java @@ -0,0 +1,77 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.permission; + +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; + +public enum ProjectPermission { + + USER("user"), + ADMIN("admin"), + CODEVIEWER("codeviewer"), + ISSUE_ADMIN("issueadmin"), + SECURITYHOTSPOT_ADMIN("securityhotspotadmin"), + SCAN("scan"); + + /** + * Permissions which are implicitly available for any user, any group on public projects. + */ + public static final Set<ProjectPermission> PUBLIC_PERMISSIONS = Collections.unmodifiableSet(EnumSet.of(ProjectPermission.USER, ProjectPermission.CODEVIEWER)); + + private final String key; + + ProjectPermission(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + + @Override + public String toString() { + return key; + } + + public static ProjectPermission fromKey(String key) { + for (ProjectPermission p : values()) { + if (p.getKey().equals(key)) { + return p; + } + } + throw new IllegalArgumentException("Unsupported project permission: " + key); + } + + public static boolean contains(String key) { + return Arrays.stream(values()).anyMatch(v -> v.getKey().equals(key)); + } + + public static boolean isPublic(ProjectPermission permission) { + return PUBLIC_PERMISSIONS.contains(permission); + } + + public static boolean isPublic(String permissionKey) { + return PUBLIC_PERMISSIONS.stream().anyMatch(p -> p.getKey().equals(permissionKey)); + } + +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java index 7014a0aed29..b6cc79c9f85 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java @@ -25,6 +25,7 @@ import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.audit.AuditPersister; import org.sonar.db.audit.model.PermissionTemplateNewValue; +import org.sonar.db.permission.ProjectPermission; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; @@ -41,6 +42,10 @@ public class PermissionTemplateCharacteristicDao implements Dao { return executeLargeInputs(templateUuids, partitionOfTemplateUuids -> mapper(dbSession).selectByTemplateUuids(partitionOfTemplateUuids)); } + public Optional<PermissionTemplateCharacteristicDto> selectByPermissionAndTemplateId(DbSession dbSession, ProjectPermission permission, String templateUuid) { + return selectByPermissionAndTemplateId(dbSession, permission.getKey(), templateUuid); + } + public Optional<PermissionTemplateCharacteristicDto> selectByPermissionAndTemplateId(DbSession dbSession, String permission, String templateUuid) { PermissionTemplateCharacteristicDto dto = mapper(dbSession).selectByPermissionAndTemplateUuid(permission, templateUuid); return Optional.ofNullable(dto); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDto.java index 89aebabc55d..fc3224c9ec6 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDto.java @@ -19,6 +19,8 @@ */ package org.sonar.db.permission.template; +import org.sonar.db.permission.ProjectPermission; + import static com.google.common.base.Preconditions.checkArgument; public class PermissionTemplateCharacteristicDto { @@ -54,6 +56,10 @@ public class PermissionTemplateCharacteristicDto { return permission; } + public PermissionTemplateCharacteristicDto setPermission(ProjectPermission permission) { + return setPermission(permission.getKey()); + } + public PermissionTemplateCharacteristicDto setPermission(String permission) { checkArgument(permission.length() <= MAX_PERMISSION_KEY_LENGTH, "Permission key length (%s) is longer than the maximum authorized (%s). '%s' was provided.", permission.length(), MAX_PERMISSION_KEY_LENGTH, permission); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java index 5ef2e73adef..46a6633133e 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java @@ -37,6 +37,7 @@ import org.sonar.db.audit.AuditPersister; import org.sonar.db.audit.model.PermissionTemplateNewValue; import org.sonar.db.permission.CountPerEntityPermission; import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.ProjectPermission; import static java.lang.String.format; import static org.sonar.api.security.DefaultGroups.ANYONE; @@ -175,6 +176,11 @@ public class PermissionTemplateDao implements Dao { return permissionTemplate; } + public void insertUserPermission(DbSession session, String templateUuid, String userUuid, ProjectPermission permission, + String templateName, String userLogin) { + insertUserPermission(session, templateUuid, userUuid, permission.getKey(), templateName, userLogin); + } + public void insertUserPermission(DbSession session, String templateUuid, String userUuid, String permission, String templateName, String userLogin) { PermissionTemplateUserDto permissionTemplateUser = new PermissionTemplateUserDto() @@ -192,6 +198,11 @@ public class PermissionTemplateDao implements Dao { session.commit(); } + public void deleteUserPermission(DbSession session, String templateUuid, String userUuid, ProjectPermission permission, + String templateName, String userLogin) { + deleteUserPermission(session, templateUuid, userUuid, permission.getKey(), templateName, userLogin); + } + public void deleteUserPermission(DbSession session, String templateUuid, String userUuid, String permission, String templateName, String userLogin) { PermissionTemplateUserDto permissionTemplateUser = new PermissionTemplateUserDto() @@ -215,6 +226,11 @@ public class PermissionTemplateDao implements Dao { } } + public void insertGroupPermission(DbSession session, String templateUuid, @Nullable String groupUuid, ProjectPermission permission, + String templateName, @Nullable String groupName) { + insertGroupPermission(session, templateUuid, groupUuid, permission.getKey(), templateName, groupName); + } + public void insertGroupPermission(DbSession session, String templateUuid, @Nullable String groupUuid, String permission, String templateName, @Nullable String groupName) { PermissionTemplateGroupDto permissionTemplateGroup = new PermissionTemplateGroupDto() @@ -236,6 +252,11 @@ public class PermissionTemplateDao implements Dao { permissionTemplateGroup.getPermission(), null, null, permissionTemplateGroup.getGroupUuid(), permissionTemplateGroup.getGroupName())); } + public void deleteGroupPermission(DbSession session, String templateUuid, @Nullable String groupUuid, ProjectPermission permission, String templateName, + @Nullable String groupName) { + deleteGroupPermission(session, templateUuid, groupUuid, permission.getKey(), templateName, groupName); + } + public void deleteGroupPermission(DbSession session, String templateUuid, @Nullable String groupUuid, String permission, String templateName, @Nullable String groupName) { PermissionTemplateGroupDto permissionTemplateGroup = new PermissionTemplateGroupDto() diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateGroupDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateGroupDto.java index 1bd6fc26ef1..94155be3d5c 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateGroupDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/permission/template/PermissionTemplateGroupDto.java @@ -21,6 +21,7 @@ package org.sonar.db.permission.template; import java.util.Date; import javax.annotation.Nullable; +import org.sonar.db.permission.ProjectPermission; public class PermissionTemplateGroupDto { private String uuid; @@ -67,6 +68,10 @@ public class PermissionTemplateGroupDto { return this; } + public PermissionTemplateGroupDto setPermission(ProjectPermission permission) { + return setPermission(permission.getKey()); + } + public String getGroupName() { return groupName; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java index a031d8d69db..fcf9e17e0bb 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java @@ -74,7 +74,7 @@ public class ProjectDao implements Dao { if (keys.isEmpty()) { return emptyList(); } - return mapper(session).selectProjectsByKeys(keys); + return executeLargeInputs(keys, partition -> mapper(session).selectProjectsByKeys(partition)); } public List<ProjectDto> selectApplicationsByKeys(DbSession session, Set<String> keys) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/provisioning/DevOpsPermissionsMappingDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/provisioning/DevOpsPermissionsMappingDto.java index d1e8a396407..d1e6085d072 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/provisioning/DevOpsPermissionsMappingDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/provisioning/DevOpsPermissionsMappingDto.java @@ -19,5 +19,20 @@ */ package org.sonar.db.provisioning; +import org.apache.ibatis.annotations.AutomapConstructor; +import org.sonar.db.permission.ProjectPermission; + public record DevOpsPermissionsMappingDto(String uuid, String devOpsPlatform, String role, String sonarqubePermission) { + + @AutomapConstructor + public DevOpsPermissionsMappingDto { + } + + public DevOpsPermissionsMappingDto(String uuid, String devOpsPlatform, String role, ProjectPermission sonarqubePermission) { + this(uuid, devOpsPlatform, role, sonarqubePermission.getKey()); + } + + public ProjectPermission projectPermission() { + return ProjectPermission.fromKey(sonarqubePermission); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java index 230d9aff010..fca991f9f28 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java @@ -510,6 +510,13 @@ class PurgeCommands { profiler.stop(); } + public void deleteArchitectureGraphs(String branchUuid) { + profiler.start("deleteArchitectureGraphs (architecture_graphs)"); + purgeMapper.deleteArchitectureGraphsByBranchUuid(branchUuid); + session.commit(); + profiler.stop(); + } + public void deleteAnticipatedTransitions(String projectUuid, long createdAt) { profiler.start("deleteAnticipatedTransitions (anticipated_transitions)"); purgeMapper.deleteAnticipatedTransitionsByProjectUuidAndCreationDate(projectUuid, createdAt); @@ -525,11 +532,24 @@ class PurgeCommands { } public void deleteScaActivity(String componentUuid) { + // delete sca_analyses first since it sort of marks the analysis as valid/existing + profiler.start("deleteScaAnalyses (sca_analyses)"); + purgeMapper.deleteScaAnalysesByComponentUuid(componentUuid); + session.commit(); + profiler.stop(); + profiler.start("deleteScaDependencies (sca_dependencies)"); purgeMapper.deleteScaDependenciesByComponentUuid(componentUuid); session.commit(); profiler.stop(); + // this must be done before deleting sca_issues_releases or we won't + // be able to find the rows + profiler.start("deleteScaIssuesReleasesChanges (sca_issue_rels_changes)"); + purgeMapper.deleteScaIssuesReleasesChangesByComponentUuid(componentUuid); + session.commit(); + profiler.stop(); + profiler.start("deleteScaIssuesReleases (sca_issues_releases)"); purgeMapper.deleteScaIssuesReleasesByComponentUuid(componentUuid); session.commit(); @@ -542,4 +562,10 @@ class PurgeCommands { session.commit(); profiler.stop(); } + + public void deleteScaLicenseProfiles(String projectUuid) { + profiler.start("deleteScaLicenseProfileProjects (sca_lic_prof_projects)"); + purgeMapper.deleteScaLicenseProfileProjectsByProjectUuid(projectUuid); + profiler.stop(); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java index ce5e0cf5e70..ff34ce5783d 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java @@ -281,6 +281,7 @@ public class PurgeDao implements Dao { commands.deleteReportSubscriptions(branchUuid); commands.deleteIssuesFixed(branchUuid); commands.deleteScaActivity(branchUuid); + commands.deleteArchitectureGraphs(branchUuid); } private static void deleteProject(String projectUuid, PurgeMapper mapper, PurgeCommands commands) { @@ -313,6 +314,7 @@ public class PurgeDao implements Dao { commands.deleteOutdatedProperties(projectUuid); commands.deleteReportSchedules(projectUuid); commands.deleteReportSubscriptions(projectUuid); + commands.deleteScaLicenseProfiles(projectUuid); } /** diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java index 5ca08a12d7a..ab4b369aef6 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java @@ -195,9 +195,17 @@ public interface PurgeMapper { void deleteIssuesFixedByBranchUuid(@Param("branchUuid") String branchUuid); + void deleteScaAnalysesByComponentUuid(@Param("componentUuid") String componentUuid); + void deleteScaDependenciesByComponentUuid(@Param("componentUuid") String componentUuid); void deleteScaIssuesReleasesByComponentUuid(@Param("componentUuid") String componentUuid); + void deleteScaIssuesReleasesChangesByComponentUuid(@Param("componentUuid") String componentUuid); + void deleteScaReleasesByComponentUuid(@Param("componentUuid") String componentUuid); + + void deleteScaLicenseProfileProjectsByProjectUuid(@Param("projectUuid") String projectUuid); + + void deleteArchitectureGraphsByBranchUuid(@Param("branchUuid") String branchUuid); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateFindingDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateFindingDto.java index ebefc919835..17e310f3887 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateFindingDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateFindingDto.java @@ -27,6 +27,7 @@ public class QualityGateFindingDto { private String operator = null; private String valueType = null; private String errorThreshold = null; + private String qualityGateName = null; public String getDescription() { return description; @@ -52,6 +53,10 @@ public class QualityGateFindingDto { return errorThreshold; } + public String getQualityGateName() { + return qualityGateName; + } + private String getOperator() { return operator; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ExportRuleDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ExportRuleDto.java index 8b847759942..ec68a1f28cb 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ExportRuleDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ExportRuleDto.java @@ -26,7 +26,7 @@ import java.util.Objects; import java.util.Set; import javax.annotation.CheckForNull; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.rule.SeverityUtil; public class ExportRuleDto { @@ -71,7 +71,7 @@ public class ExportRuleDto { } public RuleType getRuleType() { - return RuleType.valueOf(type); + return RuleType.fromDbConstant(type); } @CheckForNull diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/report/IssueFindingDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/report/IssueFindingDto.java index 43eeda81427..b3e75db1658 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/report/IssueFindingDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/report/IssueFindingDto.java @@ -22,7 +22,7 @@ package org.sonar.db.report; import java.util.List; import java.util.Set; import javax.annotation.CheckForNull; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.issue.ImpactDto; import org.sonar.db.rule.RuleDto; @@ -77,7 +77,7 @@ public class IssueFindingDto { } public RuleType getType() { - return RuleType.valueOf(type); + return RuleType.fromDbConstant(type); } public String getSeverity() { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java index 684cf6eca4a..c9dd18df7ba 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java @@ -36,7 +36,7 @@ import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.issue.ImpactDto; import static com.google.common.base.Preconditions.checkArgument; @@ -421,7 +421,7 @@ public class RuleDto { } public RuleType getEnumType() { - return RuleType.valueOf(type); + return RuleType.fromDbConstant(type); } public RuleDto setType(int type) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java index f1041e97702..c03eb7c04f0 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java @@ -28,7 +28,7 @@ import javax.annotation.CheckForNull; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.issue.ImpactDto; public class RuleForIndexingDto { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/DefaultScaIssueIdentity.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/DefaultScaIssueIdentity.java deleted file mode 100644 index 7eec1512e71..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/DefaultScaIssueIdentity.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import static com.google.common.base.Preconditions.checkArgument; - -/** - * <p> - * Default implementation of {@link ScaIssueIdentity}. - * </p> - * <p> - * Caution: missing fields are empty string, not null, so db unique constraint works. - * </p> - * @param scaIssueType the issue type - * @param packageUrl the package url (may or may not have a version) - * @param vulnerabilityId the vulnerability id such as CVE-12345 - * @param spdxLicenseId the SPDX license identifier (not license expression) - */ -public record DefaultScaIssueIdentity(ScaIssueType scaIssueType, - String packageUrl, - String vulnerabilityId, - String spdxLicenseId) implements ScaIssueIdentity { - public DefaultScaIssueIdentity { - checkIdentityColumn(packageUrl, "packageUrl"); - checkIdentityColumn(vulnerabilityId, "vulnerabilityId"); - checkIdentityColumn(spdxLicenseId, "spdxLicenseId"); - } - - private static void checkIdentityColumn(String value, String name) { - checkArgument(value != null, "DefaultScaIssueIdentity.%s cannot be null", name); - checkArgument(!value.isBlank(), "DefaultScaIssueIdentity.%s cannot be blank, use ScaIssueDto.NULL_VALUE", name); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ListOfListOfStringsTypeHandler.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ListOfListOfStringsTypeHandler.java deleted file mode 100644 index e90ddafba5d..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ListOfListOfStringsTypeHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import java.lang.reflect.Type; -import java.sql.CallableStatement; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; -import org.apache.ibatis.type.BaseTypeHandler; -import org.apache.ibatis.type.JdbcType; - -public class ListOfListOfStringsTypeHandler extends BaseTypeHandler<List<List<String>>> { - private static final Gson GSON = new Gson(); - private static final Type type = new TypeToken<List<List<String>>>() { - }.getType(); - - @Override - public void setNonNullParameter(PreparedStatement ps, int i, List<List<String>> parameter, JdbcType jdbcType) throws SQLException { - ps.setString(i, GSON.toJson(parameter)); - } - - @Override - public List<List<String>> getNullableResult(ResultSet rs, String columnName) throws SQLException { - return GSON.fromJson(rs.getString(columnName), type); - } - - @Override - public List<List<String>> getNullableResult(ResultSet rs, int columnIndex) throws SQLException { - return GSON.fromJson(rs.getString(columnIndex), type); - } - - @Override - public List<List<String>> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { - return GSON.fromJson(cs.getString(columnIndex), type); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ListOfStringsTypeHandler.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ListOfStringsTypeHandler.java deleted file mode 100644 index 6d573e282d8..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ListOfStringsTypeHandler.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import java.lang.reflect.Type; -import java.sql.CallableStatement; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; -import org.apache.ibatis.type.BaseTypeHandler; -import org.apache.ibatis.type.JdbcType; - -public class ListOfStringsTypeHandler extends BaseTypeHandler<List<String>> { - public static final int MAXIMUM_LENGTH = 255; - private static final Gson GSON = new Gson(); - private static final Type type = new TypeToken<List<String>>() { - }.getType(); - - @Override - public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException { - var s = GSON.toJson(parameter); - if (s.length() > MAXIMUM_LENGTH) { - throw new SQLException("List of strings is too long to store in database"); - } - ps.setString(i, s); - } - - @Override - public List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException { - return GSON.fromJson(rs.getString(columnName), type); - } - - @Override - public List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException { - return GSON.fromJson(rs.getString(columnIndex), type); - } - - @Override - public List<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { - return GSON.fromJson(cs.getString(columnIndex), type); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/PackageManager.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/PackageManager.java deleted file mode 100644 index 50b49bcd185..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/PackageManager.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -/** - * These values come from https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst and correspond - * to the package manager string used in PURLs. - */ -public enum PackageManager { - CARGO, COCOAPODS, COMPOSER, CONAN, CONDA, GEM, GOLANG, MAVEN, NPM, NUGET, PYPI -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependenciesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependenciesDao.java deleted file mode 100644 index 166a8e0f2aa..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependenciesDao.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import org.sonar.db.Dao; -import org.sonar.db.DbSession; -import org.sonar.db.Pagination; - -public class ScaDependenciesDao implements Dao { - - private static ScaDependenciesMapper mapper(DbSession session) { - return session.getMapper(ScaDependenciesMapper.class); - } - - public void insert(DbSession session, ScaDependencyDto scaDependencyDto) { - mapper(session).insert(scaDependencyDto); - } - - public void deleteByUuid(DbSession session, String uuid) { - mapper(session).deleteByUuid(uuid); - } - - public Optional<ScaDependencyDto> selectByUuid(DbSession dbSession, String uuid) { - return Optional.ofNullable(mapper(dbSession).selectByUuid(uuid)); - } - - /** - * Retrieves all dependencies with a specific branch UUID, no other filtering is done by this method. - */ - public List<ScaDependencyDto> selectByBranchUuid(DbSession dbSession, String branchUuid) { - return mapper(dbSession).selectByBranchUuid(branchUuid); - } - - public List<ScaDependencyDto> selectByQuery(DbSession session, ScaDependenciesQuery scaDependenciesQuery, Pagination pagination) { - return mapper(session).selectByQuery(scaDependenciesQuery, pagination); - } - - public int countByQuery(DbSession session, ScaDependenciesQuery scaDependenciesQuery) { - return mapper(session).countByQuery(scaDependenciesQuery); - } - - public void update(DbSession session, ScaDependencyDto scaDependencyDto) { - mapper(session).update(scaDependencyDto); - } - - public List<ScaDependencyDto> selectByReleaseUuids(DbSession dbSession, Collection<String> releaseUuids) { - return mapper(dbSession).selectByReleaseUuids(releaseUuids); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependenciesMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependenciesMapper.java deleted file mode 100644 index 9113c76a906..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependenciesMapper.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.Collection; -import java.util.List; -import org.apache.ibatis.annotations.Param; -import org.sonar.db.Pagination; - -public interface ScaDependenciesMapper { - void insert(ScaDependencyDto dto); - - void deleteByUuid(String uuid); - - ScaDependencyDto selectByUuid(String uuid); - - List<ScaDependencyDto> selectByBranchUuid(String branchUuid); - - List<ScaDependencyDto> selectByQuery(@Param("query") ScaDependenciesQuery query, @Param("pagination") Pagination pagination); - - List<ScaDependencyDto> selectByReleaseUuids(Collection<String> releaseUuids); - - void update(ScaDependencyDto dto); - - int countByQuery(@Param("query") ScaDependenciesQuery query); -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependenciesQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependenciesQuery.java deleted file mode 100644 index 459fcf7a50e..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependenciesQuery.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import java.util.Locale; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; - -import static org.sonar.db.DaoUtils.buildLikeValue; -import static org.sonar.db.WildcardPosition.AFTER; - -public record ScaDependenciesQuery( - String branchUuid, - @Nullable Boolean direct, - @Nullable List<String> packageManagers, - @Nullable String query) { - - /** - * Used by MyBatis mapper - */ - @CheckForNull - public String likeQuery() { - return query == null ? null : buildLikeValue(query.toLowerCase(Locale.ENGLISH), AFTER); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependencyDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependencyDto.java deleted file mode 100644 index 2b5f59800bc..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependencyDto.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import com.google.gson.Gson; -import java.util.List; -import javax.annotation.Nullable; - -import static com.google.common.base.Preconditions.checkArgument; - -/** - * Represents a Software Composition Analysis (SCA) dependency, associated with a component. - * The component will be a package component nested inside a project branch component. - * <p> - * One of userDependencyFilePath or lockfileDependencyFilePath should not be null. - *</p> - * <p> - * A dependency is a "mention" of a release in a project, with a scope and a specific - * dependency file that it was mentioned in. - *</p> - * @param uuid primary key - * @param scaReleaseUuid the UUID of the SCA release that this dependency refers to - * @param direct is this a direct dependency of the project - * @param scope the scope of the dependency e.g. "development" - * @param productionScope whether the scope appears to be a production scope or test scope - * @param userDependencyFilePath path to the user-editable file where the dependency was found ("manifest") e.g. package.json - * @param lockfileDependencyFilePath path to the machine-maintained lockfile where the dependency was found e.g. package-lock.json - * @param chains a list of the purl chains that require the dependency, stored as JSON string, e.g. [["pkg:npm/foo@1.0.0", ...], ...] - * @param newInPullRequest is it newly-added vs. target branch in this PR - * @param createdAt timestamp of creation - * @param updatedAt timestamp of most recent update - */ -public record ScaDependencyDto( - String uuid, - String scaReleaseUuid, - boolean direct, - String scope, - boolean productionScope, - @Nullable String userDependencyFilePath, - @Nullable String lockfileDependencyFilePath, - @Nullable List<List<String>> chains, - boolean newInPullRequest, - long createdAt, - long updatedAt) { - - // These need to be in sync with the database but because the db migration module and this module don't - // depend on each other, we can't make one just refer to the other. - public static final int SCOPE_MAX_LENGTH = 100; - public static final int DEPENDENCY_FILE_PATH_MAX_LENGTH = 1000; - - private static final Gson GSON = new Gson(); - - public ScaDependencyDto { - // We want these to raise errors and not silently put junk values in the db - checkLength(scope, SCOPE_MAX_LENGTH, "scope"); - checkLength(userDependencyFilePath, DEPENDENCY_FILE_PATH_MAX_LENGTH, "userDependencyFilePath"); - checkLength(lockfileDependencyFilePath, DEPENDENCY_FILE_PATH_MAX_LENGTH, "lockfileDependencyFilePath"); - if (userDependencyFilePath == null && lockfileDependencyFilePath == null) { - throw new IllegalArgumentException("One of userDependencyFilePath or lockfileDependencyFilePath should not be null"); - } - } - - private static void checkLength(@Nullable String value, int maxLength, String name) { - if (value != null) { - checkArgument(value.length() <= maxLength, "Maximum length of %s is %s: %s", name, maxLength, value); - } - } - - public String getChainsJson() { - return chains == null ? null : GSON.toJson(chains); - } - - /** - * Returns the userDependencyFilePath if it is not null, otherwise returns the lockfileDependencyFilePath. - * - * @return a non-null file path - */ - public String primaryDependencyFilePath() { - return userDependencyFilePath != null ? userDependencyFilePath : lockfileDependencyFilePath; - } - - /** - * Returns an object whose .equals and .hashCode would match that of another ScaDependencyDto's - * identity() if the two ScaDependencyDto would count as duplicates within the sca_dependencies table. - * This is different from the DTOs themselves being equal because some fields do not count in - * the identity of the row, and can be updated while preserving the identity. The method just - * returns Object and not a type, because it exists just to call .equals and .hashCode on. - * - * @return an object to be used for hashing and comparing ScaDependencyDto instances for identity - */ - public Identity identity() { - return new IdentityImpl(this); - } - - public Builder toBuilder() { - return new Builder() - .setUuid(this.uuid) - .setScaReleaseUuid(this.scaReleaseUuid) - .setDirect(this.direct) - .setScope(this.scope) - .setProductionScope(this.productionScope) - .setUserDependencyFilePath(this.userDependencyFilePath) - .setLockfileDependencyFilePath(this.lockfileDependencyFilePath) - .setChains(this.chains) - .setNewInPullRequest(this.newInPullRequest) - .setCreatedAt(this.createdAt) - .setUpdatedAt(this.updatedAt); - } - - public interface Identity { - /** - * Return a new identity with a different scaReleaseUuid - * @param scaReleaseUuid to swap in to the identity - * @return an object to be used for hashing and comparing ScaDependencyDto instances for identity - */ - Identity withScaReleaseUuid(String scaReleaseUuid); - } - - /** This object has the subset of fields that have to be unique in a ScaDependencyDto, - * so if this is the same for two ScaDependencyDto, we can update rather than insert - * those ScaDependencyDto. Conceptually, sca_dependencies table could have a unique - * constraint on these fields, though in practice it does not. - *<p> - * This class is private because it is exclusively used for .equals and .hashCode - * so nobody cares about it otherwise. - *</p> - */ - private record IdentityImpl(String scaReleaseUuid, - boolean direct, - String scope, - @Nullable String userDependencyFilePath, - @Nullable String lockfileDependencyFilePath) implements Identity { - - IdentityImpl(ScaDependencyDto dto) { - this(dto.scaReleaseUuid(), dto.direct(), dto.scope(), dto.userDependencyFilePath(), dto.lockfileDependencyFilePath()); - } - - @Override - public IdentityImpl withScaReleaseUuid(String scaReleaseUuid) { - return new IdentityImpl(scaReleaseUuid, direct, scope, userDependencyFilePath, lockfileDependencyFilePath); - } - } - - public static class Builder { - private String uuid; - private String scaReleaseUuid; - private boolean direct; - private String scope; - private boolean productionScope; - private String userDependencyFilePath; - private String lockfileDependencyFilePath; - private List<List<String>> chains; - private boolean newInPullRequest; - private long createdAt; - private long updatedAt; - - public Builder setUuid(String uuid) { - this.uuid = uuid; - return this; - } - - public Builder setScaReleaseUuid(String scaReleaseUuid) { - this.scaReleaseUuid = scaReleaseUuid; - return this; - } - - public Builder setDirect(boolean direct) { - this.direct = direct; - return this; - } - - public Builder setScope(String scope) { - this.scope = scope; - return this; - } - - public Builder setProductionScope(boolean productionScope) { - this.productionScope = productionScope; - return this; - } - - public Builder setUserDependencyFilePath(@Nullable String dependencyFilePath) { - this.userDependencyFilePath = dependencyFilePath; - return this; - } - - public Builder setLockfileDependencyFilePath(@Nullable String dependencyFilePath) { - this.lockfileDependencyFilePath = dependencyFilePath; - return this; - } - - public Builder setChains(@Nullable List<List<String>> chains) { - this.chains = chains; - return this; - } - - public Builder setNewInPullRequest(boolean newInPullRequest) { - this.newInPullRequest = newInPullRequest; - return this; - } - - public Builder setCreatedAt(long createdAt) { - this.createdAt = createdAt; - return this; - } - - public Builder setUpdatedAt(long updatedAt) { - this.updatedAt = updatedAt; - return this; - } - - public ScaDependencyDto build() { - return new ScaDependencyDto( - uuid, scaReleaseUuid, direct, scope, productionScope, userDependencyFilePath, lockfileDependencyFilePath, chains, newInPullRequest, createdAt, updatedAt); - } - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependencyReleaseDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependencyReleaseDto.java deleted file mode 100644 index 131a84bf1c0..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaDependencyReleaseDto.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import javax.annotation.Nullable; - -/** - * This DTO represents the join of sca_dependencies and sca_releases, and is "read only" - * (it cannot be inserted, it would only be a query result). - * - * @param dependencyUuid uuid of the sca_dependencies row - * @param releaseUuid uuid of the sca_releases row - * @param componentUuid uuid of the component both rows were associated with - * @param direct is it a direct dep - * @param scope scope/type of the dep like "compile" - * @param userDependencyFilePath which manifest file (e.g. package.json) - * @param lockfileDependencyFilePath which lockfile (e.g. package-lock.json) - * @param chains chains that brought the dependency in, e.g. [["pkg:npm/foo@1.0.0", ...], ...] - * @param packageUrl PURL specification URL - * @param packageManager package manager - * @param packageName name of package - * @param version version - * @param licenseExpression SPDX license expression - * @param known was the package known to Sonar - */ -public record ScaDependencyReleaseDto(String dependencyUuid, - String releaseUuid, - String componentUuid, - boolean direct, - String scope, - @Nullable String userDependencyFilePath, - @Nullable String lockfileDependencyFilePath, - @Nullable List<List<String>> chains, - String packageUrl, - PackageManager packageManager, - String packageName, - String version, - String licenseExpression, - boolean known) { - - public ScaDependencyReleaseDto(ScaDependencyDto dependency, ScaReleaseDto release) { - this( - dependency.uuid(), - release.uuid(), - release.componentUuid(), - dependency.direct(), - dependency.scope(), - dependency.userDependencyFilePath(), - dependency.lockfileDependencyFilePath(), - dependency.chains(), - release.packageUrl(), - release.packageManager(), - release.packageName(), - release.version(), - release.licenseExpression(), - release.known()); - if (!dependency.scaReleaseUuid().equals(release.uuid())) { - throw new IllegalArgumentException("Dependency and release UUIDs should match"); - } - } - - public String primaryDependencyFilePath() { - return userDependencyFilePath != null ? userDependencyFilePath : lockfileDependencyFilePath; - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueDto.java deleted file mode 100644 index c1d28a4916b..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueDto.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import static com.google.common.base.Preconditions.checkArgument; - -/** - * This table has GLOBAL rows spanning all analysis runs. For a given notional - * problem there will be ONE row. A notional problem could be a particular - * vulnerability "CVE-12345" or a particular license rule like "GPL-3.0 is prohibited". - * The purpose of this table is to assign a uuid to that notional problem. - * Because the uuid must be globally unique for the same problem, there is a - * unique constraint across all the columns. - * <p> - * NULL columns cannot participate in unique constraints on all database backends, - * so irrelevant columns for a particular issue type are set to empty string instead of NULL. - * </p> - * <p> - * The columns in this table should be those that establish the identity of the issue - * and no more. See {@link ScaIssueType} which has a method returning the proper - * ScaIssueDto for each issue type. Those same columns without uuid and timestamps - * are also in the {@link DefaultScaIssueIdentity} type. - * </p> - * <p> - * The packageUrl may or may not include a version number, depending on whether - * the issue type is per-package or per-release. - * </p> - */ -public record ScaIssueDto( - String uuid, - ScaIssueType scaIssueType, - String packageUrl, - String vulnerabilityId, - String spdxLicenseId, - long createdAt, - long updatedAt) implements ScaIssueIdentity { - - /** - * Value that represents "does not apply" in one of the identity columns. - * <p> - * You know you are going to ask, so the reason we can't use empty string - * is that Oracle thinks empty strings are NULL. And the reason we can't - * use NULL is that not all databases have a way to consider NULL as a - * value in a unique constraint. So anyway, just go with it. - * </p> - * <p> - * This string should be invalid as an actual value for all of the - * columns, so it's not a package url, not a vulnerability ID, - * and not a SPDX license ID. - * </p> - */ - public static final String NULL_VALUE = "-"; - - // these need to match what's in the db - public static final int SCA_ISSUE_TYPE_MAX_LENGTH = 40; - public static final int PACKAGE_URL_MAX_LENGTH = 400; - public static final int VULNERABILITY_ID_MAX_LENGTH = 63; - public static final int SPDX_LICENSE_ID_MAX_LENGTH = 127; - - public ScaIssueDto { - // We want these to raise errors and not silently put junk values in the db - checkIdentityColumn(packageUrl, PACKAGE_URL_MAX_LENGTH, "packageUrl"); - checkIdentityColumn(vulnerabilityId, VULNERABILITY_ID_MAX_LENGTH, "vulnerabilityId"); - checkIdentityColumn(spdxLicenseId, SPDX_LICENSE_ID_MAX_LENGTH, "spdxLicenseId"); - } - - public ScaIssueDto(String uuid, ScaIssueIdentity identity, long createdAt, long updatedAt) { - this(uuid, identity.scaIssueType(), identity.packageUrl(), identity.vulnerabilityId(), identity.spdxLicenseId(), createdAt, updatedAt); - } - - private static void checkIdentityColumn(String value, int maxLength, String name) { - checkArgument(value != null, "Column %s cannot be null", name); - checkArgument(!value.isBlank(), "Column %s cannot be blank, use ScaIssueDto.NULL_VALUE", name); - checkArgument(value.length() <= maxLength, "Maximum length of %s is %s: %s", name, maxLength, value); - } - - public Builder toBuilder() { - return new Builder() - .setUuid(uuid) - .setScaIssueType(scaIssueType) - .setPackageUrl(packageUrl) - .setVulnerabilityId(vulnerabilityId) - .setSpdxLicenseId(spdxLicenseId) - .setCreatedAt(createdAt) - .setUpdatedAt(updatedAt); - } - - public static class Builder { - private String uuid; - private ScaIssueType scaIssueType; - private String packageUrl; - private String vulnerabilityId; - private String spdxLicenseId; - private long createdAt; - private long updatedAt; - - public Builder setUuid(String uuid) { - this.uuid = uuid; - return this; - } - - public Builder setScaIssueType(ScaIssueType scaIssueType) { - this.scaIssueType = scaIssueType; - return this; - } - - public Builder setPackageUrl(String packageUrl) { - this.packageUrl = packageUrl; - return this; - } - - public Builder setVulnerabilityId(String vulnerabilityId) { - this.vulnerabilityId = vulnerabilityId; - return this; - } - - public Builder setSpdxLicenseId(String spdxLicenseId) { - this.spdxLicenseId = spdxLicenseId; - return this; - } - - public Builder setCreatedAt(long createdAt) { - this.createdAt = createdAt; - return this; - } - - public Builder setUpdatedAt(long updatedAt) { - this.updatedAt = updatedAt; - return this; - } - - public ScaIssueDto build() { - return new ScaIssueDto(uuid, scaIssueType, packageUrl, vulnerabilityId, spdxLicenseId, createdAt, updatedAt); - } - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueIdentity.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueIdentity.java deleted file mode 100644 index fc101ea46f6..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueIdentity.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -/** - * <p> - * Contains those fields which are in the unique index of the sca_issues table. - * This will be a subset of fields in the {@link ScaIssueDto} class. - * These fields are used to assign a global uuid to each issue, such as - * each vulnerability or each prohibited license. - * </p> - * <p> - * None of the fields are nullable; if not relevant to the issue's identity - * they must be empty string instead. Nulls are not usable in a unique index - * in standard sql. - * </p> - * <p> - * Implementations of this interface are allowed to include fields other than - * the identity fields in their equals and hashCode, so it is probably not - * appropriate to use instances of this interface as a hash key. You can likely - * use a concrete implementation of this interface as a hash key, though. - * </p> - */ -public interface ScaIssueIdentity { - ScaIssueType scaIssueType(); - - String packageUrl(); - - String vulnerabilityId(); - - String spdxLicenseId(); -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueReleaseDetailsDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueReleaseDetailsDto.java deleted file mode 100644 index 5ea5e9f49a1..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueReleaseDetailsDto.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.math.BigDecimal; -import java.util.List; -import javax.annotation.Nullable; -import org.sonar.api.utils.DateUtils; - -/** - * <p>A "read-only" DTO used to query the join of sca_issues_releases, sca_issues, and sca_*_issues. - * This is used to return all the details shown in a list of issues in the UX. - * This DTO and its mapper are an optimization, to do more work in SQL and - * avoid "joining in Java." - * </p> - * <p> - * The uuids in the DTOs must all correspond, or some kind of bug is happening. - * </p> - * <p> - * issueReleaseUuid is passed in separately because it allows mybatis to have an ID for the DTO, - * which it then uses for caching and lookup instead of hashing the whole object. - * </p> - */ -public record ScaIssueReleaseDetailsDto( - String issueReleaseUuid, - ScaIssueReleaseDto issueReleaseDto, - ScaIssueDto issueDto, - ScaReleaseDto releaseDto, - @Nullable ScaVulnerabilityIssueDto vulnerabilityIssueDto) { - - public ScaIssueReleaseDetailsDto { - // the issueReleaseUuid is separate so mybatis can use it for instance - // identity, but it must match the UUID in the issueReleaseDto - // and is straight-up redundant. - if (!issueReleaseUuid.equals(issueReleaseDto.uuid())) { - throw new IllegalArgumentException("issueReleaseUuid must match issueReleaseDto.uuid()"); - } - if (!issueDto.uuid().equals(issueReleaseDto.scaIssueUuid())) { - throw new IllegalArgumentException("issueDto.uuid() must match issueReleaseDto.scaIssueUuid()"); - } - if (!releaseDto.uuid().equals(issueReleaseDto.scaReleaseUuid())) { - throw new IllegalArgumentException("releaseDto.uuid() must match issueReleaseDto.scaReleaseUuid()"); - } - if (vulnerabilityIssueDto != null && !vulnerabilityIssueDto.uuid().equals(issueDto.uuid())) { - throw new IllegalArgumentException("vulnerabilityIssueDto.uuid() must match issueDto.uuid()"); - } - } - - // DateUtils says that this returns an RFC 822 timestamp - // but it is really a ISO 8601 timestamp. - public String createdAtIso8601() { - return DateUtils.formatDateTime(issueReleaseDto.createdAt()); - } - - public ScaSeverity severity() { - return issueReleaseDto.severity(); - } - - public String issueUuid() { - return issueDto.uuid(); - } - - public String releaseUuid() { - return releaseDto.uuid(); - } - - public ScaIssueType scaIssueType() { - return issueDto.scaIssueType(); - } - - public boolean newInPullRequest() { - return releaseDto.newInPullRequest(); - } - - public String version() { - return releaseDto.version(); - } - - /** - * Returns the versioned package URL of the release - */ - public String releasePackageUrl() { - return releaseDto.packageUrl(); - } - - /** Returns the unversioned package URL of the security vulnerability, - * or ScaIssueDto::NULL_VALUE if the issue is not a vulnerability. - */ - public String issuePackageUrl() { - return issueDto.packageUrl(); - } - - /** - * Returns the vulnerability ID of the issue, or ScaIssueDto::NULL_VALUE if the issue is not a vulnerability. - */ - public String vulnerabilityId() { - return issueDto.vulnerabilityId(); - } - - /** Returns the SPDX license ID of the issue, or ScaIssueDto::NULL_VALUE if the issue is not a license issue. */ - public String spdxLicenseId() { - return issueDto.spdxLicenseId(); - } - - /** Returns the base severity of the vulnerability, or null if the issue is not a vulnerability. */ - public @Nullable ScaSeverity vulnerabilityBaseSeverity() { - return vulnerabilityIssueDto == null ? null : vulnerabilityIssueDto.baseSeverity(); - } - - /** Returns the CWE IDs of the vulnerability, or null if the issue is not a vulnerability. */ - public @Nullable List<String> cweIds() { - return vulnerabilityIssueDto == null ? null : vulnerabilityIssueDto.cweIds(); - } - - /** Returns the CVSS score of the vulnerability, or null if the issue is not a vulnerability or does not have a CVSS score. */ - public @Nullable BigDecimal cvssScore() { - return vulnerabilityIssueDto == null ? null : vulnerabilityIssueDto.cvssScore(); - } - - public Builder toBuilder() { - return new Builder() - .setIssueReleaseDto(issueReleaseDto) - .setIssueDto(issueDto) - .setReleaseDto(releaseDto) - .setVulnerabilityIssueDto(vulnerabilityIssueDto); - } - - public static class Builder { - private ScaIssueReleaseDto issueReleaseDto; - private ScaIssueDto issueDto; - private ScaReleaseDto releaseDto; - @Nullable - private ScaVulnerabilityIssueDto vulnerabilityIssueDto; - - public Builder setIssueReleaseDto(ScaIssueReleaseDto issueReleaseDto) { - this.issueReleaseDto = issueReleaseDto; - return this; - } - - public Builder setIssueDto(ScaIssueDto issueDto) { - this.issueDto = issueDto; - return this; - } - - public Builder setReleaseDto(ScaReleaseDto releaseDto) { - this.releaseDto = releaseDto; - return this; - } - - public Builder setVulnerabilityIssueDto(@Nullable ScaVulnerabilityIssueDto vulnerabilityIssueDto) { - this.vulnerabilityIssueDto = vulnerabilityIssueDto; - return this; - } - - public ScaIssueReleaseDetailsDto build() { - return new ScaIssueReleaseDetailsDto(issueReleaseDto.uuid(), issueReleaseDto, issueDto, releaseDto, vulnerabilityIssueDto); - } - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueReleaseDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueReleaseDto.java deleted file mode 100644 index 74f4979b0fa..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueReleaseDto.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -/** - * Represents a many-to-many join between Software Composition Analysis (SCA) issue and a SCA release. - * - * @param uuid primary key - * @param scaIssueUuid the UUID of the SCA issue - * @param scaReleaseUuid the UUID of the SCA release - * @param severity the severity of the issue - * @param createdAt timestamp of creation - * @param updatedAt timestamp of most recent update - */ -public record ScaIssueReleaseDto( - String uuid, - String scaIssueUuid, - String scaReleaseUuid, - ScaSeverity severity, - long createdAt, - long updatedAt) { - - /** - * This constructor makes it a little harder to get the issue and release uuids backward, - * if you have the DTOs around to use it. - */ - public ScaIssueReleaseDto(String uuid, ScaIssueDto scaIssueDto, ScaReleaseDto scaReleaseDto, ScaSeverity severity, long createdAt, long updatedAt) { - this(uuid, scaIssueDto.uuid(), scaReleaseDto.uuid(), severity, createdAt, updatedAt); - } - - public int severitySortKey() { - return severity.databaseSortKey(); - } - - public Builder toBuilder() { - return new Builder() - .setUuid(this.uuid) - .setScaIssueUuid(this.scaIssueUuid) - .setScaReleaseUuid(this.scaReleaseUuid) - .setSeverity(this.severity) - .setCreatedAt(this.createdAt) - .setUpdatedAt(this.updatedAt); - } - - /** - * Returns an object whose .equals and .hashCode would match that of another ScaIssueReleaseDto's - * identity() if the two ScaIssueReleaseDto would count as duplicates within the sca_issues_releases - * table. - * This is different from the DTOs themselves being equal because some fields do not count in - * the identity of the row, and can be updated while preserving the identity. The method just - * returns Object and not a type, because it exists just to call .equals and .hashCode on. - * - * @return an object to be used for hashing and comparing ScaReleaseDto instances for identity - */ - public Identity identity() { - return new IdentityImpl(this); - } - - public interface Identity { - } - - private record IdentityImpl(String scaIssueUuid, String scaReleaseUuid) implements Identity { - IdentityImpl(ScaIssueReleaseDto dto) { - this(dto.scaIssueUuid(), dto.scaReleaseUuid()); - } - } - - public static class Builder { - private String uuid; - private String scaIssueUuid; - private String scaReleaseUuid; - private ScaSeverity severity; - private long createdAt; - private long updatedAt; - - public Builder setUuid(String uuid) { - this.uuid = uuid; - return this; - } - - public Builder setScaIssueUuid(String scaIssueUuid) { - this.scaIssueUuid = scaIssueUuid; - return this; - } - - public Builder setScaReleaseUuid(String scaReleaseUuid) { - this.scaReleaseUuid = scaReleaseUuid; - return this; - } - - public Builder setSeverity(ScaSeverity severity) { - this.severity = severity; - return this; - } - - public Builder setCreatedAt(long createdAt) { - this.createdAt = createdAt; - return this; - } - - public Builder setUpdatedAt(long updatedAt) { - this.updatedAt = updatedAt; - return this; - } - - public ScaIssueReleaseDto build() { - return new ScaIssueReleaseDto( - uuid, scaIssueUuid, scaReleaseUuid, severity, createdAt, updatedAt); - } - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueType.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueType.java deleted file mode 100644 index 0dcd8825622..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueType.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -/** - * The type of ScaIssue (not the type of generic Sonar issue). - */ -public enum ScaIssueType { - VULNERABILITY, - PROHIBITED_LICENSE; -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesDao.java deleted file mode 100644 index 93c527cff7a..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesDao.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import org.sonar.db.Dao; -import org.sonar.db.DbSession; - -public class ScaIssuesDao implements Dao { - - private static ScaIssuesMapper mapper(DbSession session) { - return session.getMapper(ScaIssuesMapper.class); - } - - public void insert(DbSession session, ScaIssueDto scaIssueDto) { - mapper(session).insert(scaIssueDto); - } - - public Optional<ScaIssueDto> selectByUuid(DbSession dbSession, String uuid) { - return Optional.ofNullable(mapper(dbSession).selectByUuid(uuid)); - } - - public List<ScaIssueDto> selectByUuids(DbSession dbSession, Collection<String> uuids) { - return mapper(dbSession).selectByUuids(uuids); - } - - public Optional<String> selectUuidByValue(DbSession dbSession, ScaIssueIdentity scaIssueIdentity) { - return mapper(dbSession).selectUuidByValue(scaIssueIdentity); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesMapper.java deleted file mode 100644 index 0ebe2c02056..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesMapper.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -public interface ScaIssuesMapper { - void insert(ScaIssueDto dto); - - ScaIssueDto selectByUuid(String uuid); - - List<ScaIssueDto> selectByUuids(Collection<String> uuids); - - Optional<String> selectUuidByValue(ScaIssueIdentity scaIssueIdentity); -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDao.java deleted file mode 100644 index 710deb12d2c..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDao.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import org.sonar.db.Dao; -import org.sonar.db.DbSession; - -public class ScaIssuesReleasesDao implements Dao { - - private static ScaIssuesReleasesMapper mapper(DbSession session) { - return session.getMapper(ScaIssuesReleasesMapper.class); - } - - public void insert(DbSession session, ScaIssueReleaseDto scaIssueReleaseDto) { - mapper(session).insert(scaIssueReleaseDto); - } - - public void update(DbSession session, ScaIssueReleaseDto scaIssueReleaseDto) { - mapper(session).update(scaIssueReleaseDto); - } - - public void deleteByUuid(DbSession session, String uuid) { - mapper(session).deleteByUuid(uuid); - } - - public List<ScaIssueReleaseDto> selectByBranchUuid(DbSession dbSession, String branchUuid) { - return mapper(dbSession).selectByBranchUuid(branchUuid); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDao.java deleted file mode 100644 index 31a0d5dd611..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDao.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import org.sonar.db.Dao; -import org.sonar.db.DbSession; -import org.sonar.db.Pagination; - -public class ScaIssuesReleasesDetailsDao implements Dao { - - private static ScaIssuesReleasesDetailsMapper mapper(DbSession session) { - return session.getMapper(ScaIssuesReleasesDetailsMapper.class); - } - - /** - * Retrieves all issues with a specific branch UUID, no other filtering is done by this method. - */ - public List<ScaIssueReleaseDetailsDto> selectByBranchUuid(DbSession dbSession, String branchUuid, Pagination pagination) { - return mapper(dbSession).selectByBranchUuid(branchUuid, pagination); - } - - /** - * Retrieves all issues with a specific release UUID, no other filtering is done by this method. - */ - public List<ScaIssueReleaseDetailsDto> selectByReleaseUuid(DbSession dbSession, String releaseUuid) { - return mapper(dbSession).selectByReleaseUuid(releaseUuid); - } - - /** - * Counts all issues with a specific branch UUID, no other filtering is done by this method. - */ - public int countByBranchUuid(DbSession dbSession, String branchUuid) { - return mapper(dbSession).countByBranchUuid(branchUuid); - } - - public List<ScaIssueReleaseDetailsDto> selectByQuery(DbSession dbSession, ScaIssuesReleasesDetailsQuery query, Pagination pagination) { - return mapper(dbSession).selectByQuery(query, pagination); - } - - public int countByQuery(DbSession dbSession, ScaIssuesReleasesDetailsQuery query) { - return mapper(dbSession).countByQuery(query); - } - - /** - * Retrieves a single issue with a specific release. - */ - public ScaIssueReleaseDetailsDto selectByScaIssueReleaseUuid(DbSession dbSession, String scaIssueReleaseUuid) { - return mapper(dbSession).selectByScaIssueReleaseUuid(scaIssueReleaseUuid); - } - -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.java deleted file mode 100644 index 35d6608322d..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import org.apache.ibatis.annotations.Param; -import org.sonar.db.Pagination; - -public interface ScaIssuesReleasesDetailsMapper { - List<ScaIssueReleaseDetailsDto> selectByBranchUuid(@Param("branchUuid") String branchUuid, @Param("pagination") Pagination pagination); - - ScaIssueReleaseDetailsDto selectByScaIssueReleaseUuid(String scaIssueReleaseUuid); - - List<ScaIssueReleaseDetailsDto> selectByReleaseUuid(String releaseUuid); - - int countByBranchUuid(String branchUuid); - - List<ScaIssueReleaseDetailsDto> selectByQuery(@Param("query") ScaIssuesReleasesDetailsQuery query, @Param("pagination") Pagination pagination); - - int countByQuery(@Param("query") ScaIssuesReleasesDetailsQuery query); -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQuery.java deleted file mode 100644 index 17397e97c34..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQuery.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.sonar.db.WildcardPosition; - -import static org.sonar.db.DaoUtils.buildLikeValue; -import static org.sonar.db.WildcardPosition.BEFORE_AND_AFTER; - -public record ScaIssuesReleasesDetailsQuery( - String branchUuid, - Sort sort, - @Nullable Boolean direct, - @Nullable Boolean productionScope, - @Nullable String vulnerabilityIdSubstring, - @Nullable String packageNameSubstring, - @Nullable Boolean newInPullRequest, - @Nullable List<ScaIssueType> types, - @Nullable List<ScaSeverity> severities, - @Nullable List<PackageManager> packageManagers) { - - public ScaIssuesReleasesDetailsQuery { - Objects.requireNonNull(branchUuid); - Objects.requireNonNull(sort); - } - - /** For use in the mapper after <code>upper(vulnerabilityId) LIKE</code>, - * and per the {@link org.sonar.db.DaoUtils#buildLikeValue(String, WildcardPosition)}} - * docs, we have to say <code>ESCAPE '/'</code>. We are using uppercase because - * most ids will be uppercase already. - */ - @CheckForNull - public String vulnerabilityIdUppercaseEscapedAsLikeValue() { - return vulnerabilityIdSubstring == null ? null : buildLikeValue(vulnerabilityIdSubstring.toUpperCase(Locale.ROOT), BEFORE_AND_AFTER); - } - - /** For use in the mapper after <code>lower(packageName) LIKE</code>, - * and per the {@link org.sonar.db.DaoUtils#buildLikeValue(String, WildcardPosition)}} - * docs, we have to say <code>ESCAPE '/'</code>. We are using lowercase because most - * package names will be all or mostly lowercase already. - */ - @CheckForNull - public String packageNameLowercaseEscapedAsLikeValue() { - return packageNameSubstring == null ? null : buildLikeValue(packageNameSubstring.toLowerCase(Locale.ROOT), BEFORE_AND_AFTER); - } - - public Builder toBuilder() { - return new Builder() - .setBranchUuid(branchUuid) - .setSort(sort) - .setDirect(direct) - .setProductionScope(productionScope) - .setVulnerabilityIdSubstring(vulnerabilityIdSubstring) - .setPackageNameSubstring(packageNameSubstring) - .setNewInPullRequest(newInPullRequest) - .setTypes(types) - .setSeverities(severities) - .setPackageManagers(packageManagers); - } - - public enum Sort { - IDENTITY_ASC("+identity"), - IDENTITY_DESC("-identity"), - SEVERITY_ASC("+severity"), - SEVERITY_DESC("-severity"), - CVSS_SCORE_ASC("+cvssScore"), - CVSS_SCORE_DESC("-cvssScore"); - - private final String queryParameterValue; - - Sort(String queryParameterValue) { - this.queryParameterValue = queryParameterValue; - } - - /** - * Convert a query parameter value to the corresponding {@link Sort} enum value. - * The passed-in string must not be null. - */ - public static Optional<Sort> fromQueryParameterValue(String queryParameterValue) { - for (Sort sort : values()) { - if (sort.queryParameterValue.equals(queryParameterValue)) { - return Optional.of(sort); - } - } - return Optional.empty(); - } - - public String queryParameterValue() { - return queryParameterValue; - } - } - - public static class Builder { - private String branchUuid; - private Sort sort; - private Boolean direct; - private Boolean productionScope; - private String vulnerabilityIdSubstring; - private String packageNameSubstring; - private Boolean newInPullRequest; - private List<ScaIssueType> types; - private List<ScaSeverity> severities; - private List<PackageManager> packageManagers; - - public Builder setBranchUuid(String branchUuid) { - this.branchUuid = branchUuid; - return this; - } - - public Builder setSort(Sort sort) { - this.sort = sort; - return this; - } - - public Builder setDirect(@Nullable Boolean direct) { - this.direct = direct; - return this; - } - - public Builder setProductionScope(@Nullable Boolean productionScope) { - this.productionScope = productionScope; - return this; - } - - public Builder setVulnerabilityIdSubstring(@Nullable String vulnerabilityIdSubstring) { - this.vulnerabilityIdSubstring = vulnerabilityIdSubstring; - return this; - } - - public Builder setPackageNameSubstring(@Nullable String packageNameSubstring) { - this.packageNameSubstring = packageNameSubstring; - return this; - } - - public Builder setNewInPullRequest(@Nullable Boolean newInPullRequest) { - this.newInPullRequest = newInPullRequest; - return this; - } - - public Builder setTypes(@Nullable List<ScaIssueType> types) { - this.types = types; - return this; - } - - public Builder setSeverities(@Nullable List<ScaSeverity> severities) { - this.severities = severities; - return this; - } - - public Builder setPackageManagers(@Nullable List<PackageManager> packageManagers) { - this.packageManagers = packageManagers; - return this; - } - - public ScaIssuesReleasesDetailsQuery build() { - return new ScaIssuesReleasesDetailsQuery(branchUuid, sort, direct, productionScope, vulnerabilityIdSubstring, - packageNameSubstring, newInPullRequest, types, severities, packageManagers); - } - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesMapper.java deleted file mode 100644 index 58c40fd1435..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; - -public interface ScaIssuesReleasesMapper { - void insert(ScaIssueReleaseDto dto); - - void update(ScaIssueReleaseDto dto); - - void deleteByUuid(String uuid); - - List<ScaIssueReleaseDto> selectByBranchUuid(String branchUuid); -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseByPackageManagerCountDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseByPackageManagerCountDto.java deleted file mode 100644 index 35f2625f7c2..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseByPackageManagerCountDto.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -public record ScaReleaseByPackageManagerCountDto(String packageManager, int releaseCount) { -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDependenciesDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDependenciesDto.java deleted file mode 100644 index 82204443c5a..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDependenciesDto.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import java.util.Objects; - -/** - * This DTO represents the join of sca_releases and sca_dependencies, and is "read only" - * (it cannot be inserted, it would only be a query result). - * <p> - * The releaseUuid must match the uuid in the release DTO, it is duplicated to help out mybatis - * in caching and lookup (allow the mapper for this DTO have an idArg). - * </p> - * @param releaseUuid uuid of the releaseDto - * @param release release - * @param dependencies dependency DTOs - */ -public record ScaReleaseDependenciesDto( - String releaseUuid, - ScaReleaseDto release, - List<ScaDependencyDto> dependencies) { - - public ScaReleaseDependenciesDto { - Objects.requireNonNull(release); - Objects.requireNonNull(dependencies); - if (!releaseUuid.equals(release.uuid())) { - throw new IllegalArgumentException("releaseUuid must match release.uuid()"); - } - } - - public ScaReleaseDependenciesDto(ScaReleaseDto release, List<ScaDependencyDto> dependencies) { - this(release.uuid(), release, dependencies); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDto.java deleted file mode 100644 index 0a7916383db..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDto.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import static com.google.common.base.Preconditions.checkArgument; - -/** - * Represents a single release of a package, such as an npm or maven package, - * as found in a single dependency analysis run (so it's attached to a branch component, - * and there's a separate copy of each release per branch it appears in). - * - * @param uuid Primary key - * @param componentUuid the component the release is associated with - * @param packageUrl package URL following the PURL specification - * @param packageManager package manager e.g. PYPI - * @param packageName package name e.g. "urllib3" - * @param version package version e.g. "1.25.6" - * @param licenseExpression an SPDX license expression (NOT a single license, can have parens/AND/OR) - * @param declaredLicenseExpression the valid SPDX license expression declared by the package itself - * @param known is this package and version known to Sonar (if not it be internal, could be malicious, could be from a weird repo) - * @param newInPullRequest is it newly added in a PR (always false when not on a PR) - * @param createdAt timestamp it was created - * @param updatedAt timestamp it was last updated - */ -public record ScaReleaseDto( - String uuid, - String componentUuid, - String packageUrl, - PackageManager packageManager, - String packageName, - String version, - String licenseExpression, - String declaredLicenseExpression, - boolean known, - boolean newInPullRequest, - long createdAt, - long updatedAt) { - - // these need to match what's in the db - public static final int PACKAGE_URL_MAX_LENGTH = 400; - public static final int PACKAGE_MANAGER_MAX_LENGTH = 20; - public static final int PACKAGE_NAME_MAX_LENGTH = 400; - public static final int VERSION_MAX_LENGTH = 400; - public static final int LICENSE_EXPRESSION_MAX_LENGTH = 400; - - public ScaReleaseDto { - // We want these to raise errors and not silently put junk values in the db - checkLength(packageUrl, PACKAGE_URL_MAX_LENGTH, "packageUrl"); - checkLength(packageName, PACKAGE_NAME_MAX_LENGTH, "packageName"); - checkLength(version, VERSION_MAX_LENGTH, "version"); - checkLength(licenseExpression, LICENSE_EXPRESSION_MAX_LENGTH, "licenseExpression"); - } - - private static void checkLength(String value, int maxLength, String name) { - checkArgument(value.length() <= maxLength, "Maximum length of %s is %s: %s", name, maxLength, value); - } - - public Builder toBuilder() { - return new Builder() - .setUuid(this.uuid) - .setComponentUuid(this.componentUuid) - .setPackageUrl(this.packageUrl) - .setPackageManager(this.packageManager) - .setPackageName(this.packageName) - .setVersion(this.version) - .setLicenseExpression(this.licenseExpression) - .setDeclaredLicenseExpression(this.declaredLicenseExpression) - .setKnown(this.known) - .setNewInPullRequest(this.newInPullRequest) - .setCreatedAt(this.createdAt) - .setUpdatedAt(this.updatedAt); - } - - /** - * Returns an object whose .equals and .hashCode would match that of another ScaReleaseDto's - * identity() if the two ScaReleaseDto would count as duplicates within the sca_releases table - * (within a single analysis, so ignoring the componentUuid). - * This is different from the DTOs themselves being equal because some fields do not count in - * the identity of the row, and can be updated while preserving the identity. The method just - * returns Object and not a type, because it exists just to call .equals and .hashCode on. - * - * @return an object to be used for hashing and comparing ScaReleaseDto instances for identity - */ - public Identity identity() { - return new IdentityImpl(this); - } - - public interface Identity { - } - - private record IdentityImpl(String packageUrl) implements Identity { - IdentityImpl(ScaReleaseDto dto) { - this(dto.packageUrl()); - } - } - - public static class Builder { - private String uuid; - private String componentUuid; - private String packageUrl; - private PackageManager packageManager; - private String packageName; - private String version; - private String licenseExpression; - private String declaredLicenseExpression; - private boolean known; - private boolean newInPullRequest; - private long createdAt; - private long updatedAt; - - public Builder setUuid(String uuid) { - this.uuid = uuid; - return this; - } - - public Builder setComponentUuid(String componentUuid) { - this.componentUuid = componentUuid; - return this; - } - - public Builder setPackageUrl(String packageUrl) { - this.packageUrl = packageUrl; - return this; - } - - public Builder setPackageManager(PackageManager packageManager) { - this.packageManager = packageManager; - return this; - } - - public Builder setPackageName(String packageName) { - this.packageName = packageName; - return this; - } - - public Builder setVersion(String version) { - this.version = version; - return this; - } - - public Builder setLicenseExpression(String licenseExpression) { - this.licenseExpression = licenseExpression; - return this; - } - - public Builder setDeclaredLicenseExpression(String declaredLicenseExpression) { - this.declaredLicenseExpression = declaredLicenseExpression; - return this; - } - - public Builder setKnown(boolean known) { - this.known = known; - return this; - } - - public Builder setNewInPullRequest(boolean newInPullRequest) { - this.newInPullRequest = newInPullRequest; - return this; - } - - public Builder setCreatedAt(long createdAt) { - this.createdAt = createdAt; - return this; - } - - public Builder setUpdatedAt(long updatedAt) { - this.updatedAt = updatedAt; - return this; - } - - public ScaReleaseDto build() { - return new ScaReleaseDto( - uuid, componentUuid, packageUrl, packageManager, packageName, version, licenseExpression, declaredLicenseExpression, known, newInPullRequest, createdAt, updatedAt); - } - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesDao.java deleted file mode 100644 index 878276874de..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesDao.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import org.sonar.db.Dao; -import org.sonar.db.DbSession; -import org.sonar.db.Pagination; - -public class ScaReleasesDao implements Dao { - - private static ScaReleasesMapper mapper(DbSession session) { - return session.getMapper(ScaReleasesMapper.class); - } - - public void insert(DbSession session, ScaReleaseDto scaReleaseDto) { - mapper(session).insert(scaReleaseDto); - } - - public void deleteByUuid(DbSession session, String uuid) { - mapper(session).deleteByUuid(uuid); - } - - public Optional<ScaReleaseDto> selectByUuid(DbSession dbSession, String uuid) { - return Optional.ofNullable(mapper(dbSession).selectByUuid(uuid)); - } - - public List<ScaReleaseDto> selectByUuids(DbSession dbSession, Collection<String> uuids) { - return mapper(dbSession).selectByUuids(uuids); - } - - /** - * Retrieves all releases with a specific branch UUID, no other filtering is done by this method. - */ - public List<ScaReleaseDto> selectByBranchUuid(DbSession dbSession, String branchUuid) { - return mapper(dbSession).selectByBranchUuid(branchUuid); - } - - public List<ScaReleaseDto> selectByQuery(DbSession session, ScaReleasesQuery scaReleasesQuery, Pagination pagination) { - return mapper(session).selectByQuery(scaReleasesQuery, pagination); - } - - public int countByQuery(DbSession session, ScaReleasesQuery scaReleasesQuery) { - return mapper(session).countByQuery(scaReleasesQuery); - } - - public List<ScaReleaseByPackageManagerCountDto> countReleasesByPackageManager(DbSession session, ScaReleasesQuery scaReleasesQuery) { - return mapper(session).countReleasesByPackageManager(scaReleasesQuery); - } - - public void update(DbSession session, ScaReleaseDto scaReleaseDto) { - mapper(session).update(scaReleaseDto); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesDependenciesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesDependenciesDao.java deleted file mode 100644 index b4b1d2c1564..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesDependenciesDao.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; -import org.sonar.db.Dao; -import org.sonar.db.DbSession; - -public class ScaReleasesDependenciesDao implements Dao { - - private static ScaReleasesMapper releasesMapper(DbSession session) { - return session.getMapper(ScaReleasesMapper.class); - } - - private static ScaDependenciesMapper dependenciesMapper(DbSession session) { - return session.getMapper(ScaDependenciesMapper.class); - } - - /** - * Obtain ScaReleaseDependenciesDto for each of the release uuids. - * - * @param dbSession db session - * @param uuids uuids for sca_releases - * @return the list of ScaReleaseDependenciesDto - */ - public List<ScaReleaseDependenciesDto> selectByReleaseUuids(DbSession dbSession, Collection<String> uuids) { - List<ScaReleaseDto> releases = releasesMapper(dbSession).selectByUuids(uuids); - return selectByReleaseDtos(dbSession, releases); - } - - /** - * Obtain ScaReleaseDependenciesDto wrapping each of the passed-in ScaReleaseDto and adding - * the dependencies list. - * - * @param dbSession db session - * @param releases ScaReleaseDto to be wrapped in ScaReleaseDependenciesDto after selecting dependencies - * @return the list of ScaReleaseDependenciesDto - */ - public List<ScaReleaseDependenciesDto> selectByReleaseDtos(DbSession dbSession, Collection<ScaReleaseDto> releases) { - // This has a somewhat abnormal implementation (not in the mapper xml) due to - // https://github.com/mybatis/mybatis-3/issues/101 , - // essentially a mapper cannot mix "creating immutable objects via constructor" (the <constructor> tag) - // "filling in child objects from another query" (the <collection> tag), because mybatis would have to - // be refactored to postpone creating the parent objects until it had loaded the child objects. - // Some options considered: - // 1. use mutable DTOs or temporary mutable DTOs that we then convert (lots of cruft) - // 2. use a single join query instead of two queries (result set duplicates the parent's columns for each child) - // 3. custom result handler doing something-or-other (not really worked out) - // 4. just don't use a mapper and have a Dao that delegates to other mappers (this solution) - List<ScaDependencyDto> dependencies = dependenciesMapper(dbSession).selectByReleaseUuids(releases.stream().map(ScaReleaseDto::uuid).toList()); - Map<String, List<ScaDependencyDto>> dependenciesGroupedByReleaseId = dependencies.stream().collect(Collectors.groupingBy(ScaDependencyDto::scaReleaseUuid)); - - return releases.stream().map(releaseDto -> { - // by returning empty list instead of omitting the release if there are no deps, we simulate a left join. - // We may never actually save dependency-less sca_releases in real life though, which means we may - // only be doing this so our tests don't always have to create dependencies in order to load releases - // through here. - var dependenciesDtos = Optional.ofNullable(dependenciesGroupedByReleaseId.get(releaseDto.uuid())).orElse(Collections.emptyList()); - return new ScaReleaseDependenciesDto(releaseDto, dependenciesDtos); - }).toList(); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesMapper.java deleted file mode 100644 index 0694271ee3f..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesMapper.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.Collection; -import java.util.List; -import org.apache.ibatis.annotations.Param; -import org.sonar.db.Pagination; - -public interface ScaReleasesMapper { - void insert(ScaReleaseDto dto); - - void deleteByUuid(String uuid); - - ScaReleaseDto selectByUuid(String uuid); - - List<ScaReleaseDto> selectByUuids(Collection<String> uuids); - - List<ScaReleaseDto> selectByBranchUuid(String branchUuid); - - List<ScaReleaseDto> selectByQuery(@Param("query") ScaReleasesQuery query, @Param("pagination") Pagination pagination); - - void update(ScaReleaseDto dto); - - int countByQuery(@Param("query") ScaReleasesQuery query); - - List<ScaReleaseByPackageManagerCountDto> countReleasesByPackageManager(@Param("query") ScaReleasesQuery query); -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesQuery.java deleted file mode 100644 index 1e24eaf8c6a..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesQuery.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import java.util.Locale; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; - -import static org.sonar.db.DaoUtils.buildLikeValue; -import static org.sonar.db.WildcardPosition.BEFORE_AND_AFTER; - -public record ScaReleasesQuery( - String branchUuid, - @Nullable Boolean direct, - @Nullable Boolean productionScope, - @Nullable List<String> packageManagers, - @Nullable Boolean newInPullRequest, - @Nullable String query) { - - /** - * Used by MyBatis mapper - */ - @CheckForNull - public String likeQuery() { - return query == null ? null : buildLikeValue(query.toLowerCase(Locale.ENGLISH), BEFORE_AND_AFTER); - } - - public Builder toBuilder() { - return new Builder() - .setBranchUuid(branchUuid) - .setDirect(direct) - .setProductionScope(productionScope) - .setPackageManagers(packageManagers) - .setNewInPullRequest(newInPullRequest) - .setQuery(query); - } - - public static class Builder { - private String branchUuid; - private Boolean direct; - private Boolean productionScope; - private List<String> packageManagers; - private Boolean newInPullRequest; - private String query; - - public Builder setBranchUuid(String branchUuid) { - this.branchUuid = branchUuid; - return this; - } - - public Builder setDirect(Boolean direct) { - this.direct = direct; - return this; - } - - public Builder setProductionScope(Boolean productionScope) { - this.productionScope = productionScope; - return this; - } - - public Builder setPackageManagers(List<String> packageManagers) { - this.packageManagers = packageManagers; - return this; - } - - public Builder setNewInPullRequest(Boolean newInPullRequest) { - this.newInPullRequest = newInPullRequest; - return this; - } - - public Builder setQuery(String query) { - this.query = query; - return this; - } - - public ScaReleasesQuery build() { - return new ScaReleasesQuery(branchUuid, direct, productionScope, packageManagers, newInPullRequest, query); - } - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaSeverity.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaSeverity.java deleted file mode 100644 index d7d0e63eafd..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaSeverity.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -/** - * The severity of a dependency issue found by SCA. - * This is calculated as a base severity (which may be based on a vulnerability's CVSS score - * or just based on the type of issue), and then analysis-specific factors such as reachability - * can be considered to get the final severity. - */ -public enum ScaSeverity { - INFO(5), - LOW(10), - MEDIUM(15), - HIGH(20), - BLOCKER(25); - - // this needs to match the DB varchar length - public static final int MAX_NAME_LENGTH = 15; - private final int databaseSortKey; - - ScaSeverity(int databaseSortKey) { - this.databaseSortKey = databaseSortKey; - } - - /** - * Returns the sort key for the severity in the database. - * We store the severity as a string for debuggability - * and so on, but to sort by severity we need an integer - * that gets higher as the severity gets more severe. - * The sort keys have gaps so we could add new - * in-between values to the enum without a big data migration. - * @return integer to sort by severity - */ - public final int databaseSortKey() { - return databaseSortKey; - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaVulnerabilityIssueDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaVulnerabilityIssueDto.java deleted file mode 100644 index 7746571d087..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaVulnerabilityIssueDto.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.math.BigDecimal; -import java.util.List; -import javax.annotation.Nullable; - -/** - * This table has GLOBAL rows spanning all analysis runs. It represents - * extra fields on all rows of sca_issues that are of {@link ScaIssueType#VULNERABILITY}, - * in other words it's a polymorphic child class of sca_issues. - * <p> - * The uuid primary key will match the primary key of the corresponding row in the sca_issues table. - * </p> - * <p> - * The base severity does not consider project-specific considerations such as reachability. - * </p> - * <p> - * At least in the current take, this table does not contain all attributes of a given - * vulnerability; it only contains those that we show in a list of issues, but not those - * that appear when we show full details of a vulnerability. The columns in this table - * need to be returned by the cloud endpoint that analyzes dependency files. - * </p> - */ -public record ScaVulnerabilityIssueDto( - String uuid, - ScaSeverity baseSeverity, - List<String> cweIds, - @Nullable BigDecimal cvssScore, - long createdAt, - long updatedAt) { - - // these need to match what's in the db - public static final int CWE_IDS_MAX_LENGTH = 255; - - public Builder toBuilder() { - return new Builder() - .setUuid(uuid) - .setBaseSeverity(baseSeverity) - .setCweIds(cweIds) - .setCvssScore(cvssScore) - .setCreatedAt(createdAt) - .setUpdatedAt(updatedAt); - } - - public static class Builder { - private String uuid; - private ScaSeverity baseSeverity; - private List<String> cweIds; - private BigDecimal cvssScore; - private long createdAt; - private long updatedAt; - - public Builder setUuid(String uuid) { - this.uuid = uuid; - return this; - } - - public Builder setBaseSeverity(ScaSeverity baseSeverity) { - this.baseSeverity = baseSeverity; - return this; - } - - public Builder setCweIds(List<String> cweIds) { - this.cweIds = cweIds; - return this; - } - - public Builder setCvssScore(BigDecimal cvssScore) { - this.cvssScore = cvssScore; - return this; - } - - public Builder setCreatedAt(long createdAt) { - this.createdAt = createdAt; - return this; - } - - public Builder setUpdatedAt(long updatedAt) { - this.updatedAt = updatedAt; - return this; - } - - public ScaVulnerabilityIssueDto build() { - return new ScaVulnerabilityIssueDto(uuid, baseSeverity, cweIds, cvssScore, createdAt, updatedAt); - } - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaVulnerabilityIssuesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaVulnerabilityIssuesDao.java deleted file mode 100644 index d06bfb872da..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaVulnerabilityIssuesDao.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import org.sonar.db.Dao; -import org.sonar.db.DbSession; - -public class ScaVulnerabilityIssuesDao implements Dao { - - private static ScaVulnerabilityIssuesMapper mapper(DbSession session) { - return session.getMapper(ScaVulnerabilityIssuesMapper.class); - } - - public void insert(DbSession session, ScaVulnerabilityIssueDto scaVulnerabilityIssueDto) { - mapper(session).insert(scaVulnerabilityIssueDto); - } - - public Optional<ScaVulnerabilityIssueDto> selectByUuid(DbSession dbSession, String uuid) { - return Optional.ofNullable(mapper(dbSession).selectByUuid(uuid)); - } - - public List<ScaVulnerabilityIssueDto> selectByUuids(DbSession dbSession, Collection<String> uuids) { - return mapper(dbSession).selectByUuids(uuids); - } - - public void update(DbSession session, ScaVulnerabilityIssueDto scaVulnerabilityIssueDto) { - mapper(session).update(scaVulnerabilityIssueDto); - } -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaVulnerabilityIssuesMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaVulnerabilityIssuesMapper.java deleted file mode 100644 index 487039a1e06..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaVulnerabilityIssuesMapper.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.Collection; -import java.util.List; - -public interface ScaVulnerabilityIssuesMapper { - void insert(ScaVulnerabilityIssueDto dto); - - ScaVulnerabilityIssueDto selectByUuid(String uuid); - - List<ScaVulnerabilityIssueDto> selectByUuids(Collection<String> uuids); - - void update(ScaVulnerabilityIssueDto dto); -} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/package-info.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/package-info.java deleted file mode 100644 index 91273c3d426..00000000000 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -@ParametersAreNonnullByDefault -package org.sonar.db.sca; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/GroupQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/GroupQuery.java index a2185648d6b..b54c25da22d 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/user/GroupQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/GroupQuery.java @@ -29,10 +29,14 @@ import org.sonar.db.WildcardPosition; public class GroupQuery { private final String searchText; private final String isManagedSqlClause; + private final String userId; + private final String excludedUserId; - GroupQuery(@Nullable String searchText, @Nullable String isManagedSqlClause) { + GroupQuery(@Nullable String searchText, @Nullable String isManagedSqlClause, String userId, String excludedUserId) { this.searchText = searchTextToSearchTextSql(searchText); this.isManagedSqlClause = isManagedSqlClause; + this.userId = userId; + this.excludedUserId = excludedUserId; } private static String searchTextToSearchTextSql(@Nullable String text) { @@ -54,6 +58,16 @@ public class GroupQuery { return isManagedSqlClause; } + @CheckForNull + public String getUserId() { + return userId; + } + + @CheckForNull + public String getExcludedUserId() { + return excludedUserId; + } + public static GroupQueryBuilder builder() { return new GroupQueryBuilder(); } @@ -61,6 +75,8 @@ public class GroupQuery { public static final class GroupQueryBuilder { private String searchText = null; private String isManagedSqlClause = null; + private String userId = null; + private String excludedUserId = null; private GroupQueryBuilder() { } @@ -70,14 +86,23 @@ public class GroupQuery { return this; } - public GroupQuery.GroupQueryBuilder isManagedClause(@Nullable String isManagedSqlClause) { this.isManagedSqlClause = isManagedSqlClause; return this; } + public GroupQuery.GroupQueryBuilder userId(@Nullable String userId) { + this.userId = userId; + return this; + } + + public GroupQuery.GroupQueryBuilder excludedUserId(@Nullable String excludedUserId) { + this.excludedUserId = excludedUserId; + return this; + } + public GroupQuery build() { - return new GroupQuery(searchText, isManagedSqlClause); + return new GroupQuery(searchText, isManagedSqlClause, userId, excludedUserId); } } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/RoleDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/RoleDao.java index 6c725d60262..bc823cc79a6 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/user/RoleDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/RoleDao.java @@ -19,33 +19,33 @@ */ package org.sonar.db.user; -import com.google.common.collect.ImmutableSet; import java.util.Collection; +import java.util.EnumSet; import java.util.List; import java.util.Set; -import org.sonar.api.web.UserRole; import org.sonar.db.Dao; import org.sonar.db.DbSession; +import org.sonar.db.permission.ProjectPermission; import static com.google.common.base.Preconditions.checkArgument; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.USER; +import static org.sonar.db.permission.ProjectPermission.CODEVIEWER; +import static org.sonar.db.permission.ProjectPermission.USER; public class RoleDao implements Dao { - private static final Set<String> UNSUPPORTED_PROJECT_PERMISSIONS = ImmutableSet.of(USER, CODEVIEWER); + private static final Set<ProjectPermission> UNSUPPORTED_PROJECT_PERMISSIONS = EnumSet.of(USER, CODEVIEWER); /** * All the entities on which the user has {@code permission}, directly or through * groups. * - * @throws IllegalArgumentException this method does not support permissions {@link UserRole#USER user} nor - * {@link UserRole#CODEVIEWER codeviewer} because it does not support public root components. + * @throws IllegalArgumentException this method does not support permissions {@link ProjectPermission#USER user} nor + * {@link ProjectPermission#CODEVIEWER codeviewer} because it does not support public root components. */ - public List<String> selectEntityUuidsByPermissionAndUserUuidAndQualifier(DbSession dbSession, String permission, String userUuid, Collection<String> qualifiers) { + public List<String> selectEntityUuidsByPermissionAndUserUuidAndQualifier(DbSession dbSession, ProjectPermission permission, String userUuid, Collection<String> qualifiers) { checkArgument( !UNSUPPORTED_PROJECT_PERMISSIONS.contains(permission), "Permissions %s are not supported by selectEntityUuidsByPermissionAndUserUuidAndQualifier", UNSUPPORTED_PROJECT_PERMISSIONS); - return mapper(dbSession).selectEntityUuidsByPermissionAndUserUuidAndQualifier(permission, userUuid, qualifiers); + return mapper(dbSession).selectEntityUuidsByPermissionAndUserUuidAndQualifier(permission.getKey(), userUuid, qualifiers); } public void deleteGroupRolesByGroupUuid(DbSession session, String groupUuid) { diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/setting/ProjectAlmSettingMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/setting/ProjectAlmSettingMapper.xml index 9f015b2d22e..e5de9d5a3e1 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/setting/ProjectAlmSettingMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/setting/ProjectAlmSettingMapper.xml @@ -215,6 +215,12 @@ <if test="query.almSettingUuid != null"> AND p.alm_setting_uuid = #{query.almSettingUuid, jdbcType=VARCHAR} </if> + <if test="query.almRepo != null"> + AND lower(p.alm_repo) = lower(#{query.almRepo, jdbcType=VARCHAR}) + </if> + <if test="query.almSlug != null"> + AND lower(p.alm_slug) = lower(#{query.almSlug, jdbcType=VARCHAR}) + </if> </where> </sql> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml index f96a116d7c1..acf970ba7ac 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml @@ -322,4 +322,13 @@ and p.uuid not in (select project_uuid from project_qprofiles) </select> + <select id="selectPullRequestsTargetingBranch" resultType="org.sonar.db.component.BranchDto"> + select <include refid="columns"/> + from project_branches pb + where + pb.project_uuid = #{projectUuid, jdbcType=VARCHAR} + and pb.merge_branch_uuid = #{branchUuid, jdbcType=VARCHAR} + and pb.branch_type = 'PULL_REQUEST' + </select> + </mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml index 4a64f3cdeab..bc5c066d6b4 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml @@ -670,14 +670,28 @@ delete from issues_fixed where pull_request_uuid = #{branchUuid,jdbcType=VARCHAR} </delete> + <delete id="deleteArchitectureGraphsByBranchUuid"> + delete from architecture_graphs where branch_uuid = #{branchUuid,jdbcType=VARCHAR} + </delete> + <delete id="deleteScaAnalysesByComponentUuid"> + delete from sca_analyses where component_uuid = #{componentUuid,jdbcType=VARCHAR} + </delete> <delete id="deleteScaDependenciesByComponentUuid"> delete from sca_dependencies where sca_release_uuid in (select uuid from sca_releases where component_uuid = #{componentUuid,jdbcType=VARCHAR}) </delete> <delete id="deleteScaIssuesReleasesByComponentUuid"> delete from sca_issues_releases where sca_release_uuid in (select uuid from sca_releases where component_uuid = #{componentUuid,jdbcType=VARCHAR}) </delete> + <delete id="deleteScaIssuesReleasesChangesByComponentUuid"> + delete from sca_issue_rels_changes where sca_issues_releases_uuid in + (select sca_issues_releases.uuid from sca_issues_releases join sca_releases on sca_releases.uuid = sca_issues_releases.sca_release_uuid + where sca_releases.component_uuid = #{componentUuid,jdbcType=VARCHAR}) + </delete> <delete id="deleteScaReleasesByComponentUuid"> delete from sca_releases where component_uuid = #{componentUuid,jdbcType=VARCHAR} </delete> + <delete id="deleteScaLicenseProfileProjectsByProjectUuid"> + delete from sca_lic_prof_projects where project_uuid = #{projectUuid,jdbcType=VARCHAR} + </delete> </mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateMapper.xml index d4dd06bf35d..16df5308d01 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateMapper.xml @@ -7,6 +7,12 @@ </sql> <sql id="qualityGateFindingColumns"> + <!-- + If a row's columns are all `null`, MyBatis, by default, will return `null` + instead of an instantiated object with all its properties set to `null`. + This case expression, for the QG name, is designed to preserve that behavior. + --> + CASE WHEN qgc.operator IS NULL THEN NULL ELSE qg.name END AS qualityGateName, m.short_name as description, qgc.operator as operator, m.val_type as valueType, diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/report/RegulatoryReportMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/report/RegulatoryReportMapper.xml index 7506b52f060..6281acad179 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/report/RegulatoryReportMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/report/RegulatoryReportMapper.xml @@ -69,8 +69,8 @@ left outer join issues_impacts ii on i.kee = ii.issue_key where i.project_uuid=#{branchUuid,jdbcType=VARCHAR} and i.status !='CLOSED' - <!--BUG, VULNERABILITY, SECURITY_HOTSPOT --> - and i.issue_type in (2, 3, 4) + <!--CODE_SMELL, BUG, VULNERABILITY, SECURITY_HOTSPOT --> + and i.issue_type in (1, 2, 3, 4) order by i.kee, ic.issue_change_creation_date </select> </mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaDependenciesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaDependenciesMapper.xml deleted file mode 100644 index c3aabf332f2..00000000000 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaDependenciesMapper.xml +++ /dev/null @@ -1,145 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> -<mapper namespace="org.sonar.db.sca.ScaDependenciesMapper"> - <!-- we're using a resultMap instead of the usual resultType approach in order to provide - a typeHandler for the chains column --> - <resultMap id="scaDependencyResultMap" type="org.sonar.db.sca.ScaDependencyDto"> - <constructor> - <idArg column="uuid" javaType="String"/> - <arg column="sca_release_uuid" javaType="String"/> - <!-- the underscore prefix means to use the primitive type instead of boxed type --> - <arg column="direct" javaType="_boolean"/> - <arg column="scope" javaType="String"/> - <arg column="production_scope" javaType="_boolean"/> - <arg column="user_dependency_file_path" javaType="String"/> - <arg column="lockfile_dependency_file_path" javaType="String"/> - <arg column="chains" typeHandler="org.sonar.db.sca.ListOfListOfStringsTypeHandler" jdbcType="CLOB" - javaType="java.util.List"/> - <arg column="new_in_pull_request" javaType="_boolean"/> - <arg column="created_at" javaType="_long"/> - <arg column="updated_at" javaType="_long"/> - </constructor> - </resultMap> - - <sql id="scaDependenciesColumns"> - sd.uuid, - sd.sca_release_uuid, - sd.direct, - sd.scope, - sd.production_scope, - sd.user_dependency_file_path, - sd.lockfile_dependency_file_path, - sd.chains, - sd.new_in_pull_request, - sd.created_at, - sd.updated_at - </sql> - - <insert id="insert" parameterType="org.sonar.db.sca.ScaDependencyDto" useGeneratedKeys="false"> - insert into sca_dependencies ( - uuid, - sca_release_uuid, - direct, - scope, - production_scope, - user_dependency_file_path, - lockfile_dependency_file_path, - chains, - new_in_pull_request, - created_at, - updated_at - ) values ( - #{uuid,jdbcType=VARCHAR}, - #{scaReleaseUuid,jdbcType=VARCHAR}, - #{direct,jdbcType=BOOLEAN}, - #{scope,jdbcType=VARCHAR}, - #{productionScope,jdbcType=BOOLEAN}, - #{userDependencyFilePath,jdbcType=VARCHAR}, - #{lockfileDependencyFilePath,jdbcType=VARCHAR}, - #{chains,jdbcType=CLOB,typeHandler=org.sonar.db.sca.ListOfListOfStringsTypeHandler}, - #{newInPullRequest,jdbcType=BOOLEAN}, - #{createdAt,jdbcType=BIGINT}, - #{updatedAt,jdbcType=BIGINT} - ) - </insert> - - <delete id="deleteByUuid" parameterType="string"> - delete from sca_dependencies - where uuid = #{uuid,jdbcType=VARCHAR} - </delete> - - <select id="selectByUuid" parameterType="string" resultMap="scaDependencyResultMap"> - select <include refid="scaDependenciesColumns"/> - from sca_dependencies sd - where sd.uuid = #{uuid,jdbcType=VARCHAR} - </select> - - <select id="selectByReleaseUuids" parameterType="string" resultMap="scaDependencyResultMap"> - select <include refid="scaDependenciesColumns"/> - from sca_dependencies sd - <if test="arg0.isEmpty()"> - where 1=0 - </if> - <if test="!arg0.isEmpty()"> - where sd.sca_release_uuid in - <foreach collection="collection" item="sca_release_uuid" open="(" close=")" separator=","> - #{sca_release_uuid, jdbcType=VARCHAR} - </foreach> - </if> - </select> - - <select id="selectByBranchUuid" parameterType="string" resultMap="scaDependencyResultMap"> - select <include refid="scaDependenciesColumns"/> - from sca_dependencies sd - inner join sca_releases sr on sd.sca_release_uuid = sr.uuid - where sr.component_uuid = #{branchUuid,jdbcType=VARCHAR} - </select> - - <select id="selectByQuery" parameterType="map" resultMap="scaDependencyResultMap"> - select <include refid="scaDependenciesColumns"/> - <include refid="sqlSelectByQuery"/> - ORDER BY sd.uuid ASC - <include refid="org.sonar.db.common.Common.pagination"/> - </select> - - <select id="countByQuery" resultType="int"> - select count(sd.uuid) - <include refid="sqlSelectByQuery"/> - </select> - - <sql id="sqlSelectByQuery"> - from sca_dependencies sd - inner join sca_releases sr on sd.sca_release_uuid = sr.uuid - where sr.component_uuid = #{query.branchUuid,jdbcType=VARCHAR} - <if test="query.direct != null"> - AND sd.direct = #{query.direct,jdbcType=BOOLEAN} - </if> - <if test="query.packageManagers != null and !query.packageManagers.isEmpty()"> - AND sr.package_manager IN - <foreach collection="query.packageManagers" open="(" close=")" item="packageManager" separator=","> - #{packageManager,jdbcType=VARCHAR} - </foreach> - </if> - <if test="query.query() != null"> - AND lower(sr.package_name) LIKE #{query.likeQuery} ESCAPE '/' - </if> - </sql> - - <update id="update" parameterType="org.sonar.db.sca.ScaDependencyDto" useGeneratedKeys="false"> - update sca_dependencies - set - uuid = #{uuid, jdbcType=VARCHAR}, - sca_release_uuid = #{scaReleaseUuid, jdbcType=VARCHAR}, - direct = #{direct, jdbcType=BOOLEAN}, - scope = #{scope, jdbcType=VARCHAR}, - production_scope = #{productionScope, jdbcType=BOOLEAN}, - user_dependency_file_path = #{userDependencyFilePath, jdbcType=VARCHAR}, - lockfile_dependency_file_path = #{lockfileDependencyFilePath, jdbcType=VARCHAR}, - chains = #{chains, jdbcType=CLOB, typeHandler=org.sonar.db.sca.ListOfListOfStringsTypeHandler}, - new_in_pull_request = #{newInPullRequest, jdbcType=BOOLEAN}, - updated_at = #{updatedAt, jdbcType=BIGINT} - where - uuid = #{uuid, jdbcType=VARCHAR} - </update> - -</mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesMapper.xml deleted file mode 100644 index 39e8b4eade8..00000000000 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesMapper.xml +++ /dev/null @@ -1,80 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> -<mapper namespace="org.sonar.db.sca.ScaIssuesMapper"> - <resultMap id="scaIssueResultMap" type="org.sonar.db.sca.ScaIssueDto"> - <constructor> - <idArg column="uuid" javaType="String"/> - <arg column="sca_issue_type" javaType="org.sonar.db.sca.ScaIssueType"/> - <arg column="package_url" javaType="String"/> - <arg column="vulnerability_id" javaType="String"/> - <arg column="spdx_license_id" javaType="String"/> - <arg column="created_at" javaType="_long"/> - <arg column="updated_at" javaType="_long"/> - </constructor> - </resultMap> - - <sql id="scaIssuesColumns"> - si.uuid, - si.sca_issue_type, - si.package_url, - si.vulnerability_id, - si.spdx_license_id, - si.created_at, - si.updated_at - </sql> - - <insert id="insert" parameterType="org.sonar.db.sca.ScaIssueDto" useGeneratedKeys="false"> - insert into sca_issues ( - uuid, - sca_issue_type, - package_url, - vulnerability_id, - spdx_license_id, - created_at, - updated_at - ) values ( - #{uuid,jdbcType=VARCHAR}, - #{scaIssueType,jdbcType=VARCHAR}, - #{packageUrl,jdbcType=VARCHAR}, - #{vulnerabilityId,jdbcType=VARCHAR}, - #{spdxLicenseId,jdbcType=VARCHAR}, - #{createdAt,jdbcType=BIGINT}, - #{updatedAt,jdbcType=BIGINT} - ) - </insert> - - <!-- delete is left out for now, because it is very dangerous without foreign key constraints and ON DELETE behavior, - and it hasn't yet been necessary to try to "garbage collect" this table. --> - - <select id="selectByUuid" parameterType="string" resultMap="scaIssueResultMap"> - select <include refid="scaIssuesColumns"/> - from sca_issues si - where si.uuid = #{uuid,jdbcType=VARCHAR} - </select> - - <select id="selectByUuids" parameterType="string" resultMap="scaIssueResultMap"> - select <include refid="scaIssuesColumns"/> - from sca_issues si - <if test="arg0.isEmpty()"> - where 1=0 - </if> - <if test="!arg0.isEmpty()"> - where si.uuid in - <foreach collection="collection" item="uuid" open="(" close=")" separator=","> - #{uuid, jdbcType=VARCHAR} - </foreach> - </if> - </select> - - <!-- selectByValue is used to upsert (get or create) the issues found in an analysis. --> - <select id="selectUuidByValue" parameterType="org.sonar.db.sca.ScaIssueIdentity" resultType="String"> - select si.uuid - from sca_issues si - where (si.sca_issue_type = #{scaIssueType,jdbcType=VARCHAR} - and si.package_url = #{packageUrl,jdbcType=VARCHAR} - and si.vulnerability_id = #{vulnerabilityId,jdbcType=VARCHAR} - and si.spdx_license_id = #{spdxLicenseId,jdbcType=VARCHAR}) - </select> - - <!-- there is no update operation; sca_issues table is append-only --> -</mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml deleted file mode 100644 index fc5b3468983..00000000000 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml +++ /dev/null @@ -1,237 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> -<mapper namespace="org.sonar.db.sca.ScaIssuesReleasesDetailsMapper"> - <resultMap id="scaIssueReleaseDetailsResultMap" type="org.sonar.db.sca.ScaIssueReleaseDetailsDto"> - <constructor> - <idArg column="issue_release_uuid" javaType="String"/> - <arg resultMap="org.sonar.db.sca.ScaIssuesReleasesMapper.scaIssueReleaseResultMap" - columnPrefix="sir_" - javaType="org.sonar.db.sca.ScaIssueReleaseDto"/> - <arg resultMap="org.sonar.db.sca.ScaIssuesMapper.scaIssueResultMap" - columnPrefix="si_" - javaType="org.sonar.db.sca.ScaIssueDto"/> - <arg resultMap="org.sonar.db.sca.ScaReleasesMapper.scaReleaseResultMap" - columnPrefix="sr_" - javaType="org.sonar.db.sca.ScaReleaseDto"/> - <arg resultMap="org.sonar.db.sca.ScaVulnerabilityIssuesMapper.scaVulnerabilityIssueResultMap" - columnPrefix="svi_" - javaType="org.sonar.db.sca.ScaVulnerabilityIssueDto"/> - </constructor> - </resultMap> - - <sql id="columns"> - <!-- These have to match all of the properties in the other tables' mappers, - adding the columnPrefix given in our resultMap above --> - sir.uuid as issue_release_uuid, - sir.uuid as sir_uuid, - sir.sca_issue_uuid as sir_sca_issue_uuid, - sir.sca_release_uuid as sir_sca_release_uuid, - sir.severity as sir_severity, - sir.severity_sort_key as sir_severity_sort_key, - sir.created_at as sir_created_at, - sir.updated_at as sir_updated_at, - si.uuid as si_uuid, - si.sca_issue_type as si_sca_issue_type, - si.package_url as si_package_url, - si.vulnerability_id as si_vulnerability_id, - si.spdx_license_id as si_spdx_license_id, - si.created_at as si_created_at, - si.updated_at as si_updated_at, - sr.uuid as sr_uuid, - sr.component_uuid as sr_component_uuid, - sr.package_url as sr_package_url, - sr.package_manager as sr_package_manager, - sr.package_name as sr_package_name, - sr.version as sr_version, - sr.license_expression as sr_license_expression, - sr.declared_license_expression as sr_declared_license_expression, - sr.known as sr_known, - sr.new_in_pull_request as sr_new_in_pull_request, - sr.created_at as sr_created_at, - sr.updated_at as sr_updated_at, - svi.uuid as svi_uuid, - svi.base_severity as svi_base_severity, - svi.cwe_ids as svi_cwe_ids, - svi.cvss_score as svi_cvss_score, - svi.created_at as svi_created_at, - svi.updated_at as svi_updated_at - </sql> - - <sql id="columnsWithCvssSortKey"> - <include refid="columns"/>, - <!-- It seems that the behavior of NULL in ORDER BY varies by database backend, with different - defaults and a lack of universal support for NULLS FIRST / NULLS LAST. - This poses an issue for nullable columns we want to sort by such as cvss_score. - On databases that support it, NULLS FIRST could probably use the index while this COALESCE - hack does not, so maybe someday we want to conditionalize on db backend somehow. --> - <!-- NULL score is treated as least severe --> - COALESCE(svi.cvss_score, 0.0) as cvss_sort_key - </sql> - - <sql id="sqlBaseJoins"> - from sca_issues_releases sir - inner join sca_issues si on sir.sca_issue_uuid = si.uuid - inner join sca_releases sr on sir.sca_release_uuid = sr.uuid - left join sca_vulnerability_issues svi on sir.sca_issue_uuid = svi.uuid - </sql> - - <sql id="sqlSelectByScaIssueReleaseUuid"> - <include refid="sqlBaseJoins"/> - where sir.uuid = #{scaIssueReleaseUuid,jdbcType=VARCHAR} - </sql> - - <sql id="sqlSelectByReleaseUuid"> - <include refid="sqlBaseJoins"/> - where sr.uuid = #{releaseUuid,jdbcType=VARCHAR} - </sql> - - <sql id="sqlSelectByBranchUuid"> - <include refid="sqlBaseJoins"/> - where sr.component_uuid = #{branchUuid,jdbcType=VARCHAR} - </sql> - - <select id="selectByReleaseUuid" parameterType="map" resultMap="scaIssueReleaseDetailsResultMap"> - select <include refid="columnsWithCvssSortKey"/> - <include refid="sqlSelectByReleaseUuid"/> - <include refid="sqlOrderBySeverityDesc"/> - </select> - - <select id="selectByBranchUuid" parameterType="map" resultMap="scaIssueReleaseDetailsResultMap"> - select <include refid="columnsWithCvssSortKey"/> - <include refid="sqlSelectByBranchUuid"/> - <include refid="sqlOrderBySeverityDesc"/> - <include refid="org.sonar.db.common.Common.pagination"/> - </select> - - <select id="selectByScaIssueReleaseUuid" parameterType="map" resultMap="scaIssueReleaseDetailsResultMap"> - select <include refid="columns"/> - <include refid="sqlSelectByScaIssueReleaseUuid"/> - <!-- no ORDER BY here because it's always one result --> - </select> - - <select id="countByBranchUuid" parameterType="string" resultType="int"> - select count(sir.uuid) - <include refid="sqlSelectByBranchUuid"/> - </select> - - <sql id="sqlSelectByQueryWhereClause"> - <where> - sr.component_uuid = #{query.branchUuid,jdbcType=VARCHAR} - <if test="query.direct != null"> - <!-- we only want each sca_releases row once, so this isn't a join. Note that each release - can be BOTH direct and !direct if it has multiple dependencies. --> - AND exists (select 1 from sca_dependencies sd where sd.sca_release_uuid = sr.uuid and sd.direct = #{query.direct,jdbcType=BOOLEAN}) - </if> - <if test="query.productionScope != null"> - <!-- we only want each sca_releases row once, so this isn't a join. --> - AND exists (select 1 from sca_dependencies sd where sd.sca_release_uuid = sr.uuid and sd.production_scope = #{query.productionScope,jdbcType=BOOLEAN}) - </if> - <if test="query.vulnerabilityIdSubstring != null"> - <!-- this screens out non-vulnerability-having issue types even if the search is for empty string --> - AND si.vulnerability_id != '${@org.sonar.db.sca.ScaIssueDto@NULL_VALUE}' - <if test="query.vulnerabilityIdSubstring.length > 0"> - AND upper(si.vulnerability_id) LIKE #{query.vulnerabilityIdUppercaseEscapedAsLikeValue, jdbcType=VARCHAR} ESCAPE '/' - </if> - </if> - <if test="query.packageNameSubstring != null and query.packageNameSubstring.length > 0"> - AND lower(sr.package_name) LIKE #{query.packageNameLowercaseEscapedAsLikeValue, jdbcType=VARCHAR} ESCAPE '/' - </if> - <if test="query.newInPullRequest != null"> - AND sr.new_in_pull_request = #{query.newInPullRequest, jdbcType=BOOLEAN} - </if> - <if test="query.types != null"> - <if test="query.types.isEmpty()"> - AND 1=0 - </if> - <if test="!query.types.isEmpty()"> - AND si.sca_issue_type in - <foreach collection="query.types" open="(" close=")" item="type" separator=","> - #{type, jdbcType=VARCHAR} - </foreach> - </if> - </if> - <if test="query.severities != null"> - <if test="query.severities.isEmpty()"> - AND 1=0 - </if> - <if test="!query.severities.isEmpty()"> - AND sir.severity in - <foreach collection="query.severities" open="(" close=")" item="severity" separator=","> - #{severity, jdbcType=VARCHAR} - </foreach> - </if> - </if> - <if test="query.packageManagers != null"> - <if test="query.packageManagers.isEmpty()"> - AND 1=0 - </if> - <if test="!query.packageManagers.isEmpty()"> - AND sr.package_manager in - <foreach collection="query.packageManagers" open="(" close=")" item="packageManager" separator=","> - #{packageManager, jdbcType=VARCHAR} - </foreach> - </if> - </if> - </where> - </sql> - - <sql id="sqlIdentityOrderColumns"> - <!-- the unique index is ordered as: scaIssueType, vulnerabilityId, packageUrl, spdxLicenseId - so we're guessing (or hoping?) that is the most efficient sort order, and it should sort of make - more sense to users than random. This sort is alphabetical first by issue type then - by CVE ID or license name. --> - si.sca_issue_type ASC, si.vulnerability_id ASC, si.package_url ASC, si.spdx_license_id ASC, sir.uuid ASC - </sql> - - <!-- this is the default sort for the selects that don't have a sort parameter (i.e. not the query) - but is probably slower than the identity sort until/unless we create a matching index --> - <sql id="sqlOrderBySeverityDesc"> - ORDER BY sir.severity_sort_key DESC, cvss_sort_key DESC, <include refid="sqlIdentityOrderColumns"/> - </sql> - - <sql id="sqlOrderByQuery"> - <choose> - <when test="query.sort == @org.sonar.db.sca.ScaIssuesReleasesDetailsQuery$Sort@IDENTITY_ASC"> - ORDER BY <include refid="sqlIdentityOrderColumns"/> - </when> - <when test="query.sort == @org.sonar.db.sca.ScaIssuesReleasesDetailsQuery$Sort@IDENTITY_DESC"> - <!-- This is a bizarre and useless sort order and we really only have it for symmetry in the REST API --> - ORDER BY si.sca_issue_type DESC, si.vulnerability_id DESC, si.package_url DESC, si.spdx_license_id DESC, sir.uuid DESC - </when> - <when test="query.sort == @org.sonar.db.sca.ScaIssuesReleasesDetailsQuery$Sort@SEVERITY_ASC"> - <!-- because many severities are the same, we try to keep the user intent by ordering by cvss score secondarily --> - ORDER BY sir.severity_sort_key ASC, cvss_sort_key ASC, <include refid="sqlIdentityOrderColumns"/> - </when> - <when test="query.sort == @org.sonar.db.sca.ScaIssuesReleasesDetailsQuery$Sort@SEVERITY_DESC"> - <!-- because many severities are the same, we try to keep the user intent by ordering by cvss score secondarily --> - <include refid="sqlOrderBySeverityDesc"/> - </when> - <when test="query.sort == @org.sonar.db.sca.ScaIssuesReleasesDetailsQuery$Sort@CVSS_SCORE_ASC"> - <!-- because cvss score can be null, we try to keep the user intent by ordering by severity secondarily --> - ORDER BY cvss_sort_key ASC, sir.severity_sort_key ASC, <include refid="sqlIdentityOrderColumns"/> - </when> - <when test="query.sort == @org.sonar.db.sca.ScaIssuesReleasesDetailsQuery$Sort@CVSS_SCORE_DESC"> - <!-- because cvss score can be null, we try to keep the user intent by ordering by severity secondarily --> - ORDER BY cvss_sort_key DESC, sir.severity_sort_key DESC, <include refid="sqlIdentityOrderColumns"/> - </when> - <otherwise> - <!-- generate a noisy failure --> - ORDER BY SYNTAX ERROR SHOULD NOT BE REACHED - </otherwise> - </choose> - </sql> - - <select id="selectByQuery" parameterType="map" resultMap="scaIssueReleaseDetailsResultMap"> - select <include refid="columnsWithCvssSortKey"/> - <include refid="sqlBaseJoins"/> - <include refid="sqlSelectByQueryWhereClause"/> - <include refid="sqlOrderByQuery"/> - <include refid="org.sonar.db.common.Common.pagination"/> - </select> - - <select id="countByQuery" parameterType="string" resultType="int"> - select count(sir.uuid) - <include refid="sqlBaseJoins"/> - <include refid="sqlSelectByQueryWhereClause"/> - </select> -</mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesMapper.xml deleted file mode 100644 index 27895f8b276..00000000000 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesMapper.xml +++ /dev/null @@ -1,69 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> -<mapper namespace="org.sonar.db.sca.ScaIssuesReleasesMapper"> - <resultMap id="scaIssueReleaseResultMap" type="org.sonar.db.sca.ScaIssueReleaseDto"> - <constructor> - <idArg name="uuid" column="uuid" javaType="String"/> - <arg name="scaIssueUuid" column="sca_issue_uuid" javaType="String"/> - <arg name="scaReleaseUuid" column="sca_release_uuid" javaType="String"/> - <arg name="severity" column="severity" javaType="org.sonar.db.sca.ScaSeverity" jdbcType="VARCHAR"/> - <arg name="createdAt" column="created_at" javaType="_long"/> - <arg name="updatedAt" column="updated_at" javaType="_long"/> - </constructor> - </resultMap> - - <sql id="scaIssuesReleasesColumns"> - sir.uuid, - sir.sca_issue_uuid, - sir.sca_release_uuid, - sir.severity, - sir.created_at, - sir.updated_at - </sql> - - <insert id="insert" parameterType="org.sonar.db.sca.ScaIssueReleaseDto" useGeneratedKeys="false"> - insert into sca_issues_releases ( - uuid, - sca_issue_uuid, - sca_release_uuid, - severity, - severity_sort_key, - created_at, - updated_at - ) values ( - #{uuid,jdbcType=VARCHAR}, - #{scaIssueUuid,jdbcType=VARCHAR}, - #{scaReleaseUuid,jdbcType=VARCHAR}, - #{severity,jdbcType=VARCHAR}, - #{severitySortKey,jdbcType=INTEGER}, - #{createdAt,jdbcType=BIGINT}, - #{updatedAt,jdbcType=BIGINT} - ) - </insert> - - <delete id="deleteByUuid" parameterType="string"> - delete from sca_issues_releases - where uuid = #{uuid,jdbcType=VARCHAR} - </delete> - - <update id="update" parameterType="org.sonar.db.sca.ScaIssueReleaseDto" useGeneratedKeys="false"> - update sca_issues_releases - set - sca_issue_uuid = #{scaIssueUuid, jdbcType=VARCHAR}, - sca_release_uuid = #{scaReleaseUuid, jdbcType=VARCHAR}, - severity = #{severity, jdbcType=VARCHAR}, - severity_sort_key = #{severitySortKey, jdbcType=VARCHAR}, - updated_at = #{updatedAt, jdbcType=BIGINT} - where - uuid = #{uuid, jdbcType=VARCHAR} -</update> - - - <select id="selectByBranchUuid" parameterType="string" resultMap="scaIssueReleaseResultMap"> - select <include refid="scaIssuesReleasesColumns"/> - from sca_issues_releases sir - inner join sca_releases sr on sir.sca_release_uuid = sr.uuid - where sr.component_uuid = #{branchUuid,jdbcType=VARCHAR} - order by sir.uuid asc - </select> -</mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml deleted file mode 100644 index b394011781f..00000000000 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml +++ /dev/null @@ -1,164 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> -<mapper namespace="org.sonar.db.sca.ScaReleasesMapper"> - <resultMap id="scaReleaseResultMap" type="org.sonar.db.sca.ScaReleaseDto"> - <constructor> - <idArg name="uuid" column="uuid" javaType="String"/> - <arg name="componentUuid" column="component_uuid" javaType="String"/> - <arg name="packageUrl" column="package_url" javaType="String"/> - <arg name="packageManager" column="package_manager" javaType="org.sonar.db.sca.PackageManager" jdbcType="VARCHAR"/> - <arg name="packageName" column="package_name" javaType="String"/> - <arg name="version" column="version" javaType="String"/> - <arg name="licenseExpression" column="license_expression" javaType="String"/> - <arg name="declaredLicenseExpression" column="declared_license_expression" javaType="String"/> - <arg name="known" column="known" javaType="_boolean"/> - <arg name="newInPullRequest" column="new_in_pull_request" javaType="_boolean"/> - <arg name="createdAt" column="created_at" javaType="_long"/> - <arg name="updatedAt" column="updated_at" javaType="_long"/> - </constructor> - </resultMap> - - <sql id="scaReleasesColumns"> - sr.uuid as uuid, - sr.component_uuid, - sr.package_url, - sr.package_manager, - sr.package_name, - sr.version, - sr.license_expression, - sr.declared_license_expression, - sr.known, - sr.new_in_pull_request, - sr.created_at, - sr.updated_at - </sql> - - <insert id="insert" parameterType="org.sonar.db.sca.ScaReleaseDto" useGeneratedKeys="false"> - insert into sca_releases ( - uuid, - component_uuid, - package_url, - package_manager, - package_name, - version, - license_expression, - declared_license_expression, - known, - new_in_pull_request, - created_at, - updated_at - ) values ( - #{uuid,jdbcType=VARCHAR}, - #{componentUuid,jdbcType=VARCHAR}, - #{packageUrl,jdbcType=VARCHAR}, - #{packageManager,jdbcType=VARCHAR}, - #{packageName,jdbcType=VARCHAR}, - #{version,jdbcType=VARCHAR}, - #{licenseExpression,jdbcType=VARCHAR}, - #{declaredLicenseExpression,jdbcType=VARCHAR}, - #{known,jdbcType=BOOLEAN}, - #{newInPullRequest,jdbcType=BOOLEAN}, - #{createdAt,jdbcType=BIGINT}, - #{updatedAt,jdbcType=BIGINT} - ) - </insert> - - <delete id="deleteByUuid" parameterType="string"> - delete from sca_releases - where uuid = #{uuid,jdbcType=VARCHAR} - </delete> - - <select id="selectByUuid" parameterType="string" resultMap="scaReleaseResultMap"> - select <include refid="scaReleasesColumns"/> - from sca_releases sr - where sr.uuid = #{uuid,jdbcType=VARCHAR} - </select> - - <select id="selectByUuids" parameterType="string" resultMap="scaReleaseResultMap"> - select <include refid="scaReleasesColumns"/> - from sca_releases sr - <if test="arg0.isEmpty()"> - where 1=0 - </if> - <if test="!arg0.isEmpty()"> - where sr.uuid in - <foreach collection="collection" item="uuid" open="(" close=")" separator=","> - #{uuid, jdbcType=VARCHAR} - </foreach> - </if> - </select> - - <sql id="scaReleasesOrderBy"> - sr.uuid ASC - </sql> - - <select id="selectByBranchUuid" parameterType="string" resultMap="scaReleaseResultMap"> - select <include refid="scaReleasesColumns"/> - from sca_releases sr - where sr.component_uuid = #{branchUuid,jdbcType=VARCHAR} - order by <include refid="scaReleasesOrderBy"/> - </select> - - <select id="selectByQuery" parameterType="map" resultMap="scaReleaseResultMap"> - select <include refid="scaReleasesColumns"/> - <include refid="sqlSelectByQuery"/> - ORDER BY <include refid="scaReleasesOrderBy"/> - <include refid="org.sonar.db.common.Common.pagination"/> - </select> - - <select id="countByQuery" resultType="int"> - select count(sr.uuid) - <include refid="sqlSelectByQuery"/> - </select> - - <select id="countReleasesByPackageManager" resultType="org.sonar.db.sca.ScaReleaseByPackageManagerCountDto"> - SELECT - package_manager AS packageManager, - count(sr.uuid) AS releaseCount - <include refid="sqlSelectByQuery"/> - GROUP BY package_manager - </select> - - <sql id="sqlSelectByQuery"> - from sca_releases sr - where sr.component_uuid = #{query.branchUuid,jdbcType=VARCHAR} - <if test="query.direct != null"> - <!-- we only want each sca_releases row once, so this isn't a join. --> - AND exists (select 1 from sca_dependencies sd where sd.sca_release_uuid = sr.uuid and sd.direct = #{query.direct,jdbcType=BOOLEAN}) - </if> - <if test="query.productionScope != null"> - <!-- we only want each sca_releases row once, so this isn't a join. --> - AND exists (select 1 from sca_dependencies sd where sd.sca_release_uuid = sr.uuid and sd.production_scope = #{query.productionScope,jdbcType=BOOLEAN}) - </if> - <if test="query.packageManagers != null and !query.packageManagers.isEmpty()"> - AND sr.package_manager IN - <foreach collection="query.packageManagers" open="(" close=")" item="packageManager" separator=","> - #{packageManager,jdbcType=VARCHAR} - </foreach> - </if> - <if test="query.newInPullRequest != null"> - AND sr.new_in_pull_request = #{query.newInPullRequest,jdbcType=BOOLEAN} - </if> - <if test="query.query() != null"> - AND lower(sr.package_name) LIKE #{query.likeQuery} ESCAPE '/' - </if> - </sql> - - <update id="update" parameterType="org.sonar.db.sca.ScaReleaseDto" useGeneratedKeys="false"> - update sca_releases - set - uuid = #{uuid, jdbcType=VARCHAR}, - component_uuid = #{componentUuid, jdbcType=VARCHAR}, - package_url = #{packageUrl, jdbcType=VARCHAR}, - package_manager = #{packageManager, jdbcType=VARCHAR}, - package_name = #{packageName, jdbcType=VARCHAR}, - version = #{version, jdbcType=VARCHAR}, - license_expression = #{licenseExpression, jdbcType=VARCHAR}, - declared_license_expression = #{declaredLicenseExpression, jdbcType=VARCHAR}, - known = #{known, jdbcType=BOOLEAN}, - new_in_pull_request = #{newInPullRequest, jdbcType=BOOLEAN}, - updated_at = #{updatedAt, jdbcType=BIGINT} - where - uuid = #{uuid, jdbcType=VARCHAR} - </update> -</mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaVulnerabilityIssuesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaVulnerabilityIssuesMapper.xml deleted file mode 100644 index 1f9a7e07600..00000000000 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaVulnerabilityIssuesMapper.xml +++ /dev/null @@ -1,80 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> -<mapper namespace="org.sonar.db.sca.ScaVulnerabilityIssuesMapper"> - <!-- we're using a resultMap instead of the usual resultType approach in order to provide - a typeHandler for the cwe_ids column --> - <resultMap id="scaVulnerabilityIssueResultMap" type="org.sonar.db.sca.ScaVulnerabilityIssueDto"> - <constructor> - <idArg column="uuid" javaType="String"/> - <arg column="base_severity" javaType="org.sonar.db.sca.ScaSeverity" jdbcType="VARCHAR"/> - <arg column="cwe_ids" typeHandler="org.sonar.db.sca.ListOfStringsTypeHandler" jdbcType="VARCHAR" - javaType="java.util.List"/> - <arg column="cvss_score" javaType="java.math.BigDecimal"/> - <!-- the underscore prefix means to use the primitive type instead of boxed type --> - <arg column="created_at" javaType="_long"/> - <arg column="updated_at" javaType="_long"/> - </constructor> - </resultMap> - - <sql id="scaVulnerabilityIssuesColumns"> - svi.uuid, - svi.base_severity, - svi.cwe_ids, - svi.cvss_score, - svi.created_at, - svi.updated_at - </sql> - - <insert id="insert" parameterType="org.sonar.db.sca.ScaVulnerabilityIssueDto" useGeneratedKeys="false"> - insert into sca_vulnerability_issues ( - uuid, - base_severity, - cwe_ids, - cvss_score, - created_at, - updated_at - ) values ( - #{uuid,jdbcType=VARCHAR}, - #{baseSeverity,jdbcType=VARCHAR}, - #{cweIds,jdbcType=VARCHAR,typeHandler=org.sonar.db.sca.ListOfStringsTypeHandler}, - #{cvssScore,jdbcType=DECIMAL}, - #{createdAt,jdbcType=BIGINT}, - #{updatedAt,jdbcType=BIGINT} - ) - </insert> - - <!-- delete is left out for now, because it is very dangerous without foreign key constraints and ON DELETE behavior, - and it hasn't yet been necessary to try to "garbage collect" this table. --> - - <select id="selectByUuid" parameterType="string" resultMap="scaVulnerabilityIssueResultMap"> - select <include refid="scaVulnerabilityIssuesColumns"/> - from sca_vulnerability_issues svi - where svi.uuid = #{uuid,jdbcType=VARCHAR} - </select> - - <select id="selectByUuids" parameterType="string" resultMap="scaVulnerabilityIssueResultMap"> - select <include refid="scaVulnerabilityIssuesColumns"/> - from sca_vulnerability_issues svi - <if test="arg0.isEmpty()"> - where 1=0 - </if> - <if test="!arg0.isEmpty()"> - where svi.uuid in - <foreach collection="collection" item="uuid" open="(" close=")" separator=","> - #{uuid, jdbcType=VARCHAR} - </foreach> - </if> - </select> - - <update id="update" parameterType="org.sonar.db.sca.ScaVulnerabilityIssueDto" useGeneratedKeys="false"> - update sca_vulnerability_issues - set - uuid = #{uuid, jdbcType=VARCHAR}, - base_severity = #{baseSeverity, jdbcType=VARCHAR}, - cwe_ids = #{cweIds, jdbcType=VARCHAR, typeHandler=org.sonar.db.sca.ListOfStringsTypeHandler}, - cvss_score = #{cvssScore, jdbcType=DECIMAL}, - updated_at = #{updatedAt, jdbcType=BIGINT} - where - uuid = #{uuid, jdbcType=VARCHAR} - </update> -</mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/user/GroupMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/user/GroupMapper.xml index 7adc671389e..87ed608b98a 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/user/GroupMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/user/GroupMapper.xml @@ -113,6 +113,12 @@ <if test="query.isManagedSqlClause != null"> AND ${query.isManagedSqlClause} </if> + <if test="query.userId != null"> + AND g.uuid in (select group_uuid from groups_users gu where gu.user_uuid = #{query.userId,jdbcType=VARCHAR}) + </if> + <if test="query.excludedUserId != null"> + AND g.uuid not in (select group_uuid from groups_users gu where gu.user_uuid = #{query.excludedUserId,jdbcType=VARCHAR}) + </if> </where> </sql> </mapper> diff --git a/server/sonar-db-dao/src/schema/schema-sq.ddl b/server/sonar-db-dao/src/schema/schema-sq.ddl index 78f221a55e4..3a18fcb87e4 100644 --- a/server/sonar-db-dao/src/schema/schema-sq.ddl +++ b/server/sonar-db-dao/src/schema/schema-sq.ddl @@ -121,11 +121,15 @@ CREATE INDEX "IDX_APP_PROJ_PROJECT_UUID" ON "APP_PROJECTS"("PROJECT_UUID" NULLS CREATE TABLE "ARCHITECTURE_GRAPHS"( "UUID" CHARACTER VARYING(40) NOT NULL, "BRANCH_UUID" CHARACTER VARYING(40) NOT NULL, - "SOURCE" CHARACTER VARYING(255) NOT NULL, + "ECOSYSTEM" CHARACTER VARYING(255) NOT NULL, "TYPE" CHARACTER VARYING(255) NOT NULL, - "GRAPH_DATA" CHARACTER LARGE OBJECT NOT NULL + "GRAPH_DATA" CHARACTER LARGE OBJECT NOT NULL, + "ANALYSIS_UUID" CHARACTER VARYING(40), + "PERSPECTIVE_KEY" CHARACTER VARYING(255), + "GRAPH_VERSION" CHARACTER VARYING(255) DEFAULT '1.0.0' NOT NULL ); ALTER TABLE "ARCHITECTURE_GRAPHS" ADD CONSTRAINT "PK_ARCHITECTURE_GRAPHS" PRIMARY KEY("UUID"); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "UQ_IDX_AG_BRCH_TP_SRC_PSPCTV" ON "ARCHITECTURE_GRAPHS"("BRANCH_UUID" NULLS FIRST, "TYPE" NULLS FIRST, "ECOSYSTEM" NULLS FIRST, "PERSPECTIVE_KEY" NULLS FIRST); CREATE TABLE "AUDITS"( "UUID" CHARACTER VARYING(40) NOT NULL, @@ -398,9 +402,9 @@ ALTER TABLE "GROUPS" ADD CONSTRAINT "PK_GROUPS" PRIMARY KEY("UUID"); CREATE UNIQUE NULLS NOT DISTINCT INDEX "UNIQ_GROUPS_NAME" ON "GROUPS"("NAME" NULLS FIRST); CREATE TABLE "GROUPS_USERS"( + "UUID" CHARACTER VARYING(40) NOT NULL, "GROUP_UUID" CHARACTER VARYING(40) NOT NULL, - "USER_UUID" CHARACTER VARYING(255) NOT NULL, - "UUID" CHARACTER VARYING(40) NOT NULL + "USER_UUID" CHARACTER VARYING(255) NOT NULL ); ALTER TABLE "GROUPS_USERS" ADD CONSTRAINT "PK_GROUPS_USERS" PRIMARY KEY("UUID"); CREATE INDEX "INDEX_GROUPS_USERS_GROUP_UUID" ON "GROUPS_USERS"("GROUP_UUID" NULLS FIRST); @@ -698,6 +702,7 @@ ALTER TABLE "PROJECT_ALM_SETTINGS" ADD CONSTRAINT "PK_PROJECT_ALM_SETTINGS" PRIM CREATE UNIQUE NULLS NOT DISTINCT INDEX "UNIQ_PROJECT_ALM_SETTINGS" ON "PROJECT_ALM_SETTINGS"("PROJECT_UUID" NULLS FIRST); CREATE INDEX "PROJECT_ALM_SETTINGS_ALM" ON "PROJECT_ALM_SETTINGS"("ALM_SETTING_UUID" NULLS FIRST); CREATE INDEX "PROJECT_ALM_SETTINGS_SLUG" ON "PROJECT_ALM_SETTINGS"("ALM_SLUG" NULLS FIRST); +CREATE INDEX "PROJECT_ALM_SETTINGS_ALM_REPO" ON "PROJECT_ALM_SETTINGS"("ALM_REPO" NULLS FIRST); CREATE TABLE "PROJECT_BADGE_TOKEN"( "UUID" CHARACTER VARYING(40) NOT NULL, @@ -962,7 +967,7 @@ CREATE UNIQUE NULLS NOT DISTINCT INDEX "RULE_TAGS_RULE_UUID" ON "RULE_TAGS"("RUL CREATE TABLE "RULES"( "UUID" CHARACTER VARYING(40) NOT NULL, - "NAME" CHARACTER VARYING(200), + "NAME" CHARACTER VARYING(255), "PLUGIN_RULE_KEY" CHARACTER VARYING(200) NOT NULL, "PLUGIN_KEY" CHARACTER VARYING(200), "PLUGIN_CONFIG_KEY" CHARACTER VARYING(200), @@ -1041,6 +1046,20 @@ CREATE TABLE "SAML_MESSAGE_IDS"( ALTER TABLE "SAML_MESSAGE_IDS" ADD CONSTRAINT "PK_SAML_MESSAGE_IDS" PRIMARY KEY("UUID"); CREATE UNIQUE NULLS NOT DISTINCT INDEX "SAML_MESSAGE_IDS_UNIQUE" ON "SAML_MESSAGE_IDS"("MESSAGE_ID" NULLS FIRST); +CREATE TABLE "SCA_ANALYSES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "COMPONENT_UUID" CHARACTER VARYING(40) NOT NULL, + "STATUS" CHARACTER VARYING(40) NOT NULL, + "FAILED_REASON" CHARACTER VARYING(255), + "ERRORS" CHARACTER LARGE OBJECT NOT NULL, + "PARSED_FILES" CHARACTER LARGE OBJECT NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL, + "ANALYSIS_PARAMETERS" CHARACTER LARGE OBJECT +); +ALTER TABLE "SCA_ANALYSES" ADD CONSTRAINT "PK_SCA_ANALYSES" PRIMARY KEY("UUID"); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "SCA_ANALYSES_COMPONENT_UNIQ" ON "SCA_ANALYSES"("COMPONENT_UUID" NULLS FIRST); + CREATE TABLE "SCA_DEPENDENCIES"( "UUID" CHARACTER VARYING(40) NOT NULL, "SCA_RELEASE_UUID" CHARACTER VARYING(40) NOT NULL, @@ -1051,12 +1070,33 @@ CREATE TABLE "SCA_DEPENDENCIES"( "CHAINS" CHARACTER LARGE OBJECT, "CREATED_AT" BIGINT NOT NULL, "UPDATED_AT" BIGINT NOT NULL, - "NEW_IN_PULL_REQUEST" BOOLEAN DEFAULT FALSE NOT NULL, - "PRODUCTION_SCOPE" BOOLEAN DEFAULT TRUE NOT NULL + "PRODUCTION_SCOPE" BOOLEAN DEFAULT TRUE NOT NULL, + "IS_NEW" BOOLEAN DEFAULT FALSE NOT NULL ); ALTER TABLE "SCA_DEPENDENCIES" ADD CONSTRAINT "PK_SCA_DEPENDENCIES" PRIMARY KEY("UUID"); CREATE INDEX "SCA_DEPENDENCIES_RELEASE_UUID" ON "SCA_DEPENDENCIES"("SCA_RELEASE_UUID" NULLS FIRST); +CREATE TABLE "SCA_ENCOUNTERED_LICENSES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "LICENSE_POLICY_ID" CHARACTER VARYING(127) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL +); +ALTER TABLE "SCA_ENCOUNTERED_LICENSES" ADD CONSTRAINT "PK_SCA_ENCOUNTERED_LICENSES" PRIMARY KEY("UUID"); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "SCA_ENCOUNTERED_LIC_UNIQ" ON "SCA_ENCOUNTERED_LICENSES"("LICENSE_POLICY_ID" NULLS FIRST); + +CREATE TABLE "SCA_ISSUE_RELS_CHANGES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "SCA_ISSUES_RELEASES_UUID" CHARACTER VARYING(40) NOT NULL, + "USER_UUID" CHARACTER VARYING(40), + "CHANGE_DATA" CHARACTER LARGE OBJECT, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL, + "CHANGE_COMMENT" CHARACTER VARYING(4000) +); +ALTER TABLE "SCA_ISSUE_RELS_CHANGES" ADD CONSTRAINT "PK_SCA_ISSUE_RELS_CHANGES" PRIMARY KEY("UUID"); +CREATE INDEX "SCA_ISS_RELS_CHANGES_IR_UUID" ON "SCA_ISSUE_RELS_CHANGES"("SCA_ISSUES_RELEASES_UUID" NULLS FIRST); + CREATE TABLE "SCA_ISSUES"( "UUID" CHARACTER VARYING(40) NOT NULL, "SCA_ISSUE_TYPE" CHARACTER VARYING(40) NOT NULL, @@ -1076,13 +1116,62 @@ CREATE TABLE "SCA_ISSUES_RELEASES"( "SEVERITY" CHARACTER VARYING(15) NOT NULL, "SEVERITY_SORT_KEY" INTEGER NOT NULL, "CREATED_AT" BIGINT NOT NULL, - "UPDATED_AT" BIGINT NOT NULL + "UPDATED_AT" BIGINT NOT NULL, + "STATUS" CHARACTER VARYING(40) NOT NULL, + "ASSIGNEE_UUID" CHARACTER VARYING(40), + "PREVIOUS_MANUAL_STATUS" CHARACTER VARYING(40), + "ORIGINAL_SEVERITY" CHARACTER VARYING(15) NOT NULL, + "MANUAL_SEVERITY" CHARACTER VARYING(15), + "SHOW_INCREASED_SEVERITY_WARNING" BOOLEAN DEFAULT FALSE NOT NULL ); ALTER TABLE "SCA_ISSUES_RELEASES" ADD CONSTRAINT "PK_SCA_ISSUES_RELEASES" PRIMARY KEY("UUID"); CREATE INDEX "SCA_ISSUES_RELEASES_SCA_ISSUE" ON "SCA_ISSUES_RELEASES"("SCA_ISSUE_UUID" NULLS FIRST); CREATE INDEX "SCA_ISSUES_RELEASES_SCA_RELEAS" ON "SCA_ISSUES_RELEASES"("SCA_RELEASE_UUID" NULLS FIRST); CREATE UNIQUE NULLS NOT DISTINCT INDEX "SCA_ISSUES_RELEASES_UNIQUE" ON "SCA_ISSUES_RELEASES"("SCA_ISSUE_UUID" NULLS FIRST, "SCA_RELEASE_UUID" NULLS FIRST); +CREATE TABLE "SCA_LIC_PROF_CATEGORIES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "SCA_LICENSE_PROFILE_UUID" CHARACTER VARYING(40) NOT NULL, + "CATEGORY" CHARACTER VARYING(40) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL +); +ALTER TABLE "SCA_LIC_PROF_CATEGORIES" ADD CONSTRAINT "PK_SCA_LIC_PROF_CATEGORIES" PRIMARY KEY("UUID"); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "SCA_LIC_PROF_CATEGORIES_UNIQ" ON "SCA_LIC_PROF_CATEGORIES"("SCA_LICENSE_PROFILE_UUID" NULLS FIRST, "CATEGORY" NULLS FIRST); + +CREATE TABLE "SCA_LIC_PROF_CUSTOMS"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "SCA_LICENSE_PROFILE_UUID" CHARACTER VARYING(40) NOT NULL, + "LICENSE_POLICY_ID" CHARACTER VARYING(127) NOT NULL, + "STATUS" CHARACTER VARYING(40) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL +); +ALTER TABLE "SCA_LIC_PROF_CUSTOMS" ADD CONSTRAINT "PK_SCA_LIC_PROF_CUSTOMS" PRIMARY KEY("UUID"); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "SCA_LIC_PROF_CUSTOMS_UNIQ" ON "SCA_LIC_PROF_CUSTOMS"("SCA_LICENSE_PROFILE_UUID" NULLS FIRST, "LICENSE_POLICY_ID" NULLS FIRST); + +CREATE TABLE "SCA_LIC_PROF_PROJECTS"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "PROJECT_UUID" CHARACTER VARYING(40) NOT NULL, + "SCA_LICENSE_PROFILE_UUID" CHARACTER VARYING(40) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL +); +ALTER TABLE "SCA_LIC_PROF_PROJECTS" ADD CONSTRAINT "PK_SCA_LIC_PROF_PROJECTS" PRIMARY KEY("UUID"); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "SCA_LIC_PROF_PROJECTS_UNIQ" ON "SCA_LIC_PROF_PROJECTS"("PROJECT_UUID" NULLS FIRST); + +CREATE TABLE "SCA_LICENSE_PROFILES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "IS_DEFAULT_PROFILE" BOOLEAN NOT NULL, + "NAME" CHARACTER VARYING(400) NOT NULL, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL, + "POLICY_UPDATED_AT" BIGINT NOT NULL, + "ORGANIZATION_UUID" CHARACTER VARYING(40) DEFAULT '00000000-0000-4000-0000-000000000000' NOT NULL +); +ALTER TABLE "SCA_LICENSE_PROFILES" ADD CONSTRAINT "PK_SCA_LICENSE_PROFILES" PRIMARY KEY("UUID"); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "SCA_LICENSE_PROFILES_UNIQ" ON "SCA_LICENSE_PROFILES"("ORGANIZATION_UUID" NULLS FIRST, "NAME" NULLS FIRST); + CREATE TABLE "SCA_RELEASES"( "UUID" CHARACTER VARYING(40) NOT NULL, "COMPONENT_UUID" CHARACTER VARYING(40) NOT NULL, @@ -1094,11 +1183,13 @@ CREATE TABLE "SCA_RELEASES"( "KNOWN" BOOLEAN NOT NULL, "CREATED_AT" BIGINT NOT NULL, "UPDATED_AT" BIGINT NOT NULL, - "NEW_IN_PULL_REQUEST" BOOLEAN DEFAULT FALSE NOT NULL, - "DECLARED_LICENSE_EXPRESSION" CHARACTER VARYING(400) DEFAULT 'NOASSERTION' NOT NULL + "DECLARED_LICENSE_EXPRESSION" CHARACTER VARYING(400) DEFAULT 'NOASSERTION' NOT NULL, + "KNOWN_PACKAGE" BOOLEAN NOT NULL, + "IS_NEW" BOOLEAN DEFAULT FALSE NOT NULL ); ALTER TABLE "SCA_RELEASES" ADD CONSTRAINT "PK_SCA_RELEASES" PRIMARY KEY("UUID"); CREATE INDEX "SCA_RELEASES_COMP_UUID_UUID" ON "SCA_RELEASES"("COMPONENT_UUID" NULLS FIRST, "UUID" NULLS FIRST); +CREATE UNIQUE NULLS NOT DISTINCT INDEX "SCA_RELEASES_PACKAGE_URL_UNIQ" ON "SCA_RELEASES"("PACKAGE_URL" NULLS FIRST, "COMPONENT_UUID" NULLS FIRST); CREATE TABLE "SCA_VULNERABILITY_ISSUES"( "UUID" CHARACTER VARYING(40) NOT NULL, @@ -1106,7 +1197,8 @@ CREATE TABLE "SCA_VULNERABILITY_ISSUES"( "CWE_IDS" CHARACTER VARYING(255) NOT NULL, "CVSS_SCORE" DOUBLE PRECISION, "CREATED_AT" BIGINT NOT NULL, - "UPDATED_AT" BIGINT NOT NULL + "UPDATED_AT" BIGINT NOT NULL, + "WITHDRAWN" BOOLEAN DEFAULT FALSE NOT NULL ); ALTER TABLE "SCA_VULNERABILITY_ISSUES" ADD CONSTRAINT "PK_SCA_VULNERABILITY_ISSUES" PRIMARY KEY("UUID"); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/createdb/PopulateDb.java b/server/sonar-db-dao/src/test/java/org/sonar/db/createdb/PopulateDb.java index c7821cf24d3..57d80bc8fc1 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/createdb/PopulateDb.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/createdb/PopulateDb.java @@ -39,7 +39,7 @@ import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.System2; import org.sonar.core.metric.SoftwareQualitiesMetrics; import org.sonar.core.util.UuidFactoryImpl; diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDtoTest.java index 790a9dd48b5..00e1d78fb3e 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDtoTest.java @@ -34,7 +34,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.utils.Duration; import org.sonar.core.issue.DefaultIssue; import org.sonar.db.protobuf.DbIssues; diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java index 6ccc07e07d6..e043370f381 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java @@ -28,7 +28,7 @@ import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.util.Uuids; import org.sonar.db.issue.ImpactDto; diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleForIndexingDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleForIndexingDtoTest.java index a9886bd355c..8a72fbe785e 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleForIndexingDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleForIndexingDtoTest.java @@ -25,7 +25,7 @@ import org.sonar.api.issue.impact.Severity; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rules.CleanCodeAttribute; import org.sonar.api.rules.CleanCodeAttributeCategory; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.db.issue.ImpactDto; import static org.assertj.core.api.Assertions.assertThat; diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/DefaultScaIssueIdentityTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/DefaultScaIssueIdentityTest.java deleted file mode 100644 index 122e328a16b..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/DefaultScaIssueIdentityTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class DefaultScaIssueIdentityTest { - - @Test - void test_constructWithValidValues() { - var issueIdentity = new DefaultScaIssueIdentity(ScaIssueType.VULNERABILITY, "packageUrl", "vulnerabilityId", "spdxLicenseId"); - assertEquals(ScaIssueType.VULNERABILITY, issueIdentity.scaIssueType()); - assertEquals("packageUrl", issueIdentity.packageUrl()); - assertEquals("vulnerabilityId", issueIdentity.vulnerabilityId()); - assertEquals("spdxLicenseId", issueIdentity.spdxLicenseId()); - } - - @Test - void test_throwsOnInvalidValues() { - assertThrows(IllegalArgumentException.class, () -> new DefaultScaIssueIdentity(ScaIssueType.VULNERABILITY, "", "vulnerabilityId", "spdxLicenseId")); - assertThrows(IllegalArgumentException.class, () -> new DefaultScaIssueIdentity(ScaIssueType.VULNERABILITY, null, "vulnerabilityId", "spdxLicenseId")); - assertThrows(IllegalArgumentException.class, () -> new DefaultScaIssueIdentity(ScaIssueType.VULNERABILITY, "packageUrl", "", "spdxLicenseId")); - assertThrows(IllegalArgumentException.class, () -> new DefaultScaIssueIdentity(ScaIssueType.VULNERABILITY, "packageUrl", null, "spdxLicenseId")); - assertThrows(IllegalArgumentException.class, () -> new DefaultScaIssueIdentity(ScaIssueType.VULNERABILITY, "packageUrl", "vulnerabilityId", "")); - assertThrows(IllegalArgumentException.class, () -> new DefaultScaIssueIdentity(ScaIssueType.VULNERABILITY, "packageUrl", "vulnerabilityId", null)); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/PackageManagerTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/PackageManagerTest.java deleted file mode 100644 index eed4dcfa2aa..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/PackageManagerTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class PackageManagerTest { - - @Test - void test_namesAreShortEnough() { - for (PackageManager packageManager : PackageManager.values()) { - assertThat(packageManager.name().length()).isLessThanOrEqualTo(ScaReleaseDto.PACKAGE_MANAGER_MAX_LENGTH); - } - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaDependenciesQueryTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaDependenciesQueryTest.java deleted file mode 100644 index 7a88e9ba53a..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaDependenciesQueryTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - -class ScaDependenciesQueryTest { - - @Test - void testLikeQuery() { - ScaDependenciesQuery scaDependenciesQuery = new ScaDependenciesQuery("branchUuid", null, null, "QUERY"); - assertEquals("query%", scaDependenciesQuery.likeQuery()); - } - - @Test - void testLikeQueryWithNullQuery() { - ScaDependenciesQuery scaDependenciesQuery = new ScaDependenciesQuery("branchUuid", null, null, null); - assertNull(scaDependenciesQuery.likeQuery()); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaDependencyDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaDependencyDtoTest.java deleted file mode 100644 index 505a06d6f35..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaDependencyDtoTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -class ScaDependencyDtoTest { - - @Test - void test_toBuilder_build_shouldRoundTrip() { - var scaDependencyDto = new ScaDependencyDto("scaDependencyUuid", - "scaReleaseUuid", - true, - "compile", - false, - "some/path", - "another/path", - List.of(List.of("pkg:npm/fodo@1.0.0")), - true, - 1L, - 2L); - assertThat(scaDependencyDto.toBuilder().build()).isEqualTo(scaDependencyDto); - } - - @Test - void test_identity_shouldIgnoreUuidAndUpdatableFields() { - var scaDependencyDto = new ScaDependencyDto("scaDependencyUuid", - "scaReleaseUuid", - true, - "compile", - false, - "some/path", - "another/path", - List.of(List.of("pkg:npm/IGNORED@1.0.0")), - false, - 1L, - 2L); - var scaDependencyDtoDifferentButSameIdentity = new ScaDependencyDto("differentUuid", - "scaReleaseUuid", - true, - "compile", - true, - "some/path", - "another/path", - List.of(List.of("pkg:npm/DIFFERENT_ALSO_IGNORED@1.0.0")), - true, - 42L, - 57L); - assertThat(scaDependencyDto.identity()).isEqualTo(scaDependencyDtoDifferentButSameIdentity.identity()); - assertThat(scaDependencyDto).isNotEqualTo(scaDependencyDtoDifferentButSameIdentity); - } - - @Test - void test_identity_changingScaReleaseUuid() { - var scaDependencyDto = new ScaDependencyDto("scaDependencyUuid", - "scaReleaseUuid", - true, - "compile", - false, - "some/path", - "another/path", - List.of(List.of("pkg:npm/IGNORED@1.0.0")), - true, - 1L, - 2L); - var scaDependencyDtoChangedReleaseUuid = new ScaDependencyDto("scaDependencyUuid", - "scaReleaseUuidDifferent", - true, - "compile", - false, - "some/path", - "another/path", - List.of(List.of("pkg:npm/IGNORED@1.0.0")), - false, - 1L, - 2L); - assertThat(scaDependencyDto.identity()).isNotEqualTo(scaDependencyDtoChangedReleaseUuid.identity()); - assertThat(scaDependencyDto.identity().withScaReleaseUuid("scaReleaseUuidDifferent")).isEqualTo(scaDependencyDtoChangedReleaseUuid.identity()); - } - - @Test - void test_primaryDependencyFilePath() { - ScaDependencyDto withUserDependencyFilePath = newScaDependencyDto("manifest"); - assertThat(withUserDependencyFilePath.primaryDependencyFilePath()).isEqualTo("manifest"); - ScaDependencyDto withoutUserDependencyFilePath = newScaDependencyDto(null); - assertThat(withoutUserDependencyFilePath.primaryDependencyFilePath()).isEqualTo("lockfileDependencyFilePath"); - } - - private ScaDependencyDto newScaDependencyDto(@Nullable String userDependencyFilePath) { - return new ScaDependencyDto("dependencyUuid", - "scaReleaseUuid", - true, - "compile", - false, - userDependencyFilePath, - "lockfileDependencyFilePath", - List.of(List.of("pkg:npm/foo@1.0.0")), - false, - 1L, - 2L); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaDependencyReleaseDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaDependencyReleaseDtoTest.java deleted file mode 100644 index a0be47c280f..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaDependencyReleaseDtoTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import javax.annotation.Nullable; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class ScaDependencyReleaseDtoTest { - - @Test - void test_primaryDependencyFilePath() { - ScaDependencyReleaseDto withUserDependencyFilePath = newScaDependencyReleaseDto("manifest"); - assertEquals("manifest", withUserDependencyFilePath.primaryDependencyFilePath()); - ScaDependencyReleaseDto withoutUserDependencyFilePath = newScaDependencyReleaseDto(null); - assertEquals("lockfileDependencyFilePath", withoutUserDependencyFilePath.primaryDependencyFilePath()); - } - - private ScaDependencyReleaseDto newScaDependencyReleaseDto(@Nullable String userDependencyFilePath) { - return new ScaDependencyReleaseDto("dependencyUuid", - "releaseUuid", - "componentUuid", - true, - "scope", - userDependencyFilePath, - "lockfileDependencyFilePath", - List.of(List.of("pkg:npm/foo@1.0.0")), - "packageUrl", - PackageManager.MAVEN, - "packageName", - "version", - "licenseExpression", - true); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueDtoTest.java deleted file mode 100644 index da9eb91dddf..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueDtoTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import org.junit.jupiter.api.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class ScaIssueDtoTest { - - @Test - void test_constructWithValidValues() { - var dto = new ScaIssueDto("uuid", ScaIssueType.VULNERABILITY, "packageUrl", "vulnerabilityId", "spdxLicenseId", 1L, 2L); - assertEquals("uuid", dto.uuid()); - assertEquals(ScaIssueType.VULNERABILITY, dto.scaIssueType()); - assertEquals("packageUrl", dto.packageUrl()); - assertEquals("vulnerabilityId", dto.vulnerabilityId()); - assertEquals("spdxLicenseId", dto.spdxLicenseId()); - assertEquals(1L, dto.createdAt()); - assertEquals(2L, dto.updatedAt()); - } - - @Test - void test_throwsOnInvalidValues() { - assertThrows(IllegalArgumentException.class, () -> new ScaIssueDto("uuid", ScaIssueType.VULNERABILITY, "", "vulnerabilityId", "spdxLicenseId", 1L, 2L)); - assertThrows(IllegalArgumentException.class, () -> new ScaIssueDto("uuid", ScaIssueType.VULNERABILITY, null, "vulnerabilityId", "spdxLicenseId", 1L, 2L)); - assertThrows(IllegalArgumentException.class, () -> new ScaIssueDto("uuid", ScaIssueType.VULNERABILITY, "packageUrl", "", "spdxLicenseId", 1L, 2L)); - assertThrows(IllegalArgumentException.class, () -> new ScaIssueDto("uuid", ScaIssueType.VULNERABILITY, "packageUrl", null, "spdxLicenseId", 1L, 2L)); - assertThrows(IllegalArgumentException.class, () -> new ScaIssueDto("uuid", ScaIssueType.VULNERABILITY, "packageUrl", "vulnerabilityId", "", 1L, 2L)); - assertThrows(IllegalArgumentException.class, () -> new ScaIssueDto("uuid", ScaIssueType.VULNERABILITY, "packageUrl", "vulnerabilityId", null, 1L, 2L)); - } - - @Test - void test_constructFromIdentity() { - var identity = new DefaultScaIssueIdentity(ScaIssueType.VULNERABILITY, "packageUrl", "vulnerabilityId", "spdxLicenseId"); - var dto = new ScaIssueDto("uuid", identity, 1L, 2L); - assertEquals("uuid", dto.uuid()); - assertEquals(ScaIssueType.VULNERABILITY, dto.scaIssueType()); - assertEquals("packageUrl", dto.packageUrl()); - assertEquals("vulnerabilityId", dto.vulnerabilityId()); - assertEquals("spdxLicenseId", dto.spdxLicenseId()); - assertEquals(1L, dto.createdAt()); - assertEquals(2L, dto.updatedAt()); - } - - @Test - void test_toBuilder_build_shouldRoundTrip() { - var dto = new ScaIssueDto("uuid", ScaIssueType.VULNERABILITY, "packageUrl", "vulnerabilityId", "spdxLicenseId", 1L, 2L); - assertEquals(dto.toBuilder().build(), dto); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueReleaseDetailsDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueReleaseDetailsDtoTest.java deleted file mode 100644 index a5e62a7d417..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueReleaseDetailsDtoTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.math.BigDecimal; -import java.util.List; -import org.assertj.core.api.ThrowableAssert; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; - -class ScaIssueReleaseDetailsDtoTest { - private static ScaIssueDto newSampleIssueDto() { - return new ScaIssueDto("issueUuid", - ScaIssueType.VULNERABILITY, - "packageUrl", - "vulnerabilityId", - "spdxLicenseId", - 1L, - 2L); - } - - private static ScaReleaseDto newSampleReleaseDto() { - return new ScaReleaseDto("releaseUuid", - "componentUuid", - "packageUrl", - PackageManager.MAVEN, - "foo:bar", - "1.0.0", - "MIT", - "NOASSERTION", - true, - false, - 2L, - 3L); - } - - private static ScaIssueReleaseDto newSampleIssueReleaseDto(ScaIssueDto issueDto, ScaReleaseDto releaseDto) { - return new ScaIssueReleaseDto( - "issueReleaseUuid", - issueDto.uuid(), - releaseDto.uuid(), - ScaSeverity.INFO, - 3L, - 4L); - } - - private static ScaVulnerabilityIssueDto newSampleVulnerabilityIssueDto(ScaIssueDto issueDto) { - return new ScaVulnerabilityIssueDto( - issueDto.uuid(), - ScaSeverity.HIGH, - List.of("cwe1"), - BigDecimal.ONE, - 5L, - 6L); - } - - private static ScaIssueReleaseDetailsDto newSampleIssueReleaseDetailsDto() { - var issueDto = newSampleIssueDto(); - var releaseDto = newSampleReleaseDto(); - var issueReleaseDto = newSampleIssueReleaseDto(issueDto, releaseDto); - var vulnerabilityIssueDto = newSampleVulnerabilityIssueDto(issueDto); - return new ScaIssueReleaseDetailsDto( - issueReleaseDto.uuid(), - issueReleaseDto, - issueDto, - releaseDto, - vulnerabilityIssueDto); - } - - @Test - void test_toBuilder_build_shouldRoundTrip() { - var dto = newSampleIssueReleaseDetailsDto(); - assertThat(dto.toBuilder().build()).isEqualTo(dto); - } - - @Test - void test_withMismatchedReleaseInIssueReleaseDto_throwsIllegalArgumentException() { - var validDto = newSampleIssueReleaseDetailsDto(); - var differentIssueReleaseDto = validDto.issueReleaseDto().toBuilder().setScaReleaseUuid("differentUuid").build(); - var invalidBuilder = validDto.toBuilder().setIssueReleaseDto(differentIssueReleaseDto); - assertThatThrownBy(invalidBuilder::build).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void test_withMismatchedIssueInIssueReleaseDto_throwsIllegalArgumentException() { - var validDto = newSampleIssueReleaseDetailsDto(); - var differentIssueReleaseDto = validDto.issueReleaseDto().toBuilder().setScaIssueUuid("differentUuid").build(); - var invalidBuilder = validDto.toBuilder().setIssueReleaseDto(differentIssueReleaseDto); - assertThatThrownBy(invalidBuilder::build).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void test_withMismatchedIssueReleaseUuid_throwsIllegalArgumentException() { - var validDto = newSampleIssueReleaseDetailsDto(); - ThrowableAssert.ThrowingCallable constructInvalid = () -> new ScaIssueReleaseDetailsDto("differentUuid", - validDto.issueReleaseDto(), validDto.issueDto(), validDto.releaseDto(), validDto.vulnerabilityIssueDto()); - assertThatThrownBy(constructInvalid).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void test_withMismatchedVulnerabilityIssue_throwsIllegalArgumentException() { - var validDto = newSampleIssueReleaseDetailsDto(); - var differentVulnerabiiltyIssue = validDto.vulnerabilityIssueDto().toBuilder().setUuid("differentUuid").build(); - var invalidBuilder = validDto.toBuilder().setVulnerabilityIssueDto(differentVulnerabiiltyIssue); - assertThatThrownBy(invalidBuilder::build).isInstanceOf(IllegalArgumentException.class); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueReleaseDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueReleaseDtoTest.java deleted file mode 100644 index e1df2cfd1c2..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueReleaseDtoTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -class ScaIssueReleaseDtoTest { - - @Test - void test_toBuilder_build_shouldRoundTrip() { - var scaIssueReleaseDto = new ScaIssueReleaseDto("sca-issue-release-uuid", - "sca-issue-uuid", - "sca-release-uuid", - ScaSeverity.INFO, - 1L, - 2L); - assertThat(scaIssueReleaseDto.toBuilder().build()).isEqualTo(scaIssueReleaseDto); - } - - @Test - void test_identity_shouldIgnoreUuidAndUpdatableFields() { - var scaIssueReleaseDto = new ScaIssueReleaseDto("sca-issue-release-uuid", - "sca-issue-uuid", - "sca-release-uuid", - ScaSeverity.INFO, - 1L, - 2L); - var scaIssueReleaseDtoDifferentButSameIdentity = new ScaIssueReleaseDto("differentUuid", - "sca-issue-uuid", - "sca-release-uuid", - ScaSeverity.HIGH, - 10L, - 20L); - assertThat(scaIssueReleaseDto.identity()).isEqualTo(scaIssueReleaseDtoDifferentButSameIdentity.identity()); - assertThat(scaIssueReleaseDto).isNotEqualTo(scaIssueReleaseDtoDifferentButSameIdentity); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueTypeTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueTypeTest.java deleted file mode 100644 index 3027f5e96bd..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueTypeTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class ScaIssueTypeTest { - - @Test - void test_namesAreShortEnough() { - for (ScaIssueType issueType : ScaIssueType.values()) { - assertThat(issueType.name().length()).isLessThanOrEqualTo(ScaIssueDto.SCA_ISSUE_TYPE_MAX_LENGTH); - } - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQueryTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQueryTest.java deleted file mode 100644 index e295fc6b3b4..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQueryTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import org.assertj.core.api.AssertionsForClassTypes; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class ScaIssuesReleasesDetailsQueryTest { - - @Test - void test_toBuilder_build_shouldRoundTrip() { - var query = new ScaIssuesReleasesDetailsQuery("branchUuid", ScaIssuesReleasesDetailsQuery.Sort.IDENTITY_ASC, - true, true, "vulnerabilityIdSubstring", "packageNameSubstring", true, - List.of(ScaIssueType.VULNERABILITY), List.of(ScaSeverity.BLOCKER), List.of(PackageManager.NPM)); - AssertionsForClassTypes.assertThat(query.toBuilder().build()).isEqualTo(query); - } - - @Test - void test_queryParameterValues() { - for (var value : ScaIssuesReleasesDetailsQuery.Sort.values()) { - var queryParameterValue = value.queryParameterValue(); - var fromQueryParameterValue = ScaIssuesReleasesDetailsQuery.Sort.fromQueryParameterValue(queryParameterValue); - assertThat(fromQueryParameterValue).contains(value); - assertThat((queryParameterValue.startsWith("+") && value.name().endsWith("_ASC")) || - (queryParameterValue.startsWith("-") && value.name().endsWith("_DESC"))) - .as("+/- prefix and ASC/DESC suffix line up") - .isTrue(); - } - } - - @Test - void test_whenValueIsInvalid_fromQueryParameterValue() { - assertThat(ScaIssuesReleasesDetailsQuery.Sort.fromQueryParameterValue("invalid")).isEmpty(); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaReleaseDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaReleaseDtoTest.java deleted file mode 100644 index 6c0ac3d9e53..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaReleaseDtoTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -class ScaReleaseDtoTest { - - @Test - void test_toBuilder_build_shouldRoundTrip() { - var scaReleaseDto = new ScaReleaseDto("scaReleaseUuid", - "componentUuid", - "packageUrl", - PackageManager.MAVEN, - "foo:bar", - "1.0.0", - "MIT", - "MIT", - true, - false, - 1L, - 2L); - assertThat(scaReleaseDto.toBuilder().build()).isEqualTo(scaReleaseDto); - } - - @Test - void test_identity_shouldIgnoreUuidAndUpdatableFields() { - var scaReleaseDto = new ScaReleaseDto("scaReleaseUuid", - "componentUuid", - "packageUrl", - PackageManager.MAVEN, - "foo:bar", - "1.0.0", - "MIT", - "MIT", - true, - false, - 1L, - 2L); - var scaReleaseDtoDifferentButSameIdentity = new ScaReleaseDto("differentUuid", - "componentUuidDifferent", - "packageUrl", - PackageManager.NPM, - "foo:bar-different", - "2.0.0", - "GPL-3.0", - "GPL-3.0", - false, - true, - 10L, - 30L); - assertThat(scaReleaseDto.identity()).isEqualTo(scaReleaseDtoDifferentButSameIdentity.identity()); - assertThat(scaReleaseDto).isNotEqualTo(scaReleaseDtoDifferentButSameIdentity); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaReleasesQueryTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaReleasesQueryTest.java deleted file mode 100644 index 23a16876ac9..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaReleasesQueryTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import org.assertj.core.api.AssertionsForClassTypes; -import org.junit.jupiter.api.Test; - -class ScaReleasesQueryTest { - @Test - void test_toBuilder_build_shouldRoundTrip() { - var query = new ScaReleasesQuery("branchUuid", - true, false, List.of("NPM"), true, "query"); - AssertionsForClassTypes.assertThat(query.toBuilder().build()).isEqualTo(query); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaSeverityTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaSeverityTest.java deleted file mode 100644 index 023f2bd9b20..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaSeverityTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.stream.Stream; -import org.junit.jupiter.api.Test; -import org.sonar.api.issue.impact.Severity; - -import static org.assertj.core.api.Assertions.assertThat; - -class ScaSeverityTest { - private static void assertSortOrder(ScaSeverity lower, ScaSeverity higher) { - assertThat(lower.databaseSortKey()) - .as(lower + " sorts below " + higher) - .isLessThan(higher.databaseSortKey()); - } - - @Test - void test_maxLength() { - for (ScaSeverity severity : ScaSeverity.values()) { - assertThat(severity.name().length()).as(severity.name() + " is short enough") - .isLessThanOrEqualTo(ScaSeverity.MAX_NAME_LENGTH); - } - } - - @Test - void test_sortKeysInOrder() { - assertSortOrder(ScaSeverity.INFO, ScaSeverity.LOW); - assertSortOrder(ScaSeverity.LOW, ScaSeverity.MEDIUM); - assertSortOrder(ScaSeverity.MEDIUM, ScaSeverity.HIGH); - assertSortOrder(ScaSeverity.HIGH, ScaSeverity.BLOCKER); - } - - @Test - void test_matchesImpactSeverity() { - assertThat(Stream.of(ScaSeverity.values()).map(Enum::name).toList()) - .as("ScaSeverity has the same values in the same order as impact.Severity") - .isEqualTo(Stream.of(Severity.values()).map(Enum::name).toList()); - } -} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaVulnerabilityIssueDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaVulnerabilityIssueDtoTest.java deleted file mode 100644 index 1019f1e3e5d..00000000000 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaVulnerabilityIssueDtoTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.math.BigDecimal; -import java.util.List; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class ScaVulnerabilityIssueDtoTest { - @Test - void test_cweIdsLength_handledByTypeHandler() { - // this test is here to prevent accidentally messing it up - assertThat(ScaVulnerabilityIssueDto.CWE_IDS_MAX_LENGTH).isLessThanOrEqualTo(ListOfStringsTypeHandler.MAXIMUM_LENGTH); - } - - @Test - void test_toBuilder_build_shouldRoundTrip() { - var scaVulnerabilityIssueDto = new ScaVulnerabilityIssueDto("sca-issue-uuid", - ScaSeverity.INFO, - List.of("cwe"), - new BigDecimal("7.1"), - 1L, - 2L); - assertThat(scaVulnerabilityIssueDto.toBuilder().build()).isEqualTo(scaVulnerabilityIssueDto); - } -} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java index 41975647b49..866b89dfadb 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java @@ -56,11 +56,6 @@ import org.sonar.db.property.PropertyDbTester; import org.sonar.db.qualitygate.QualityGateDbTester; import org.sonar.db.qualityprofile.QualityProfileDbTester; import org.sonar.db.rule.RuleDbTester; -import org.sonar.db.sca.ScaDependenciesDbTester; -import org.sonar.db.sca.ScaIssuesDbTester; -import org.sonar.db.sca.ScaIssuesReleasesDbTester; -import org.sonar.db.sca.ScaIssuesReleasesDetailsDbTester; -import org.sonar.db.sca.ScaReleasesDbTester; import org.sonar.db.source.FileSourceTester; import org.sonar.db.user.UserDbTester; import org.sonar.db.webhook.WebhookDbTester; @@ -101,11 +96,6 @@ public class DbTester extends AbstractDbTester<TestDbImpl> implements BeforeEach private final AlmPatsDbTester almPatsDbtester; private final AuditDbTester auditDbTester; private final AnticipatedTransitionDbTester anticipatedTransitionDbTester; - private final ScaDependenciesDbTester scaDependenciesDbTester; - private final ScaIssuesDbTester scaIssuesDbTester; - private final ScaIssuesReleasesDbTester scaIssuesReleasesDbTester; - private final ScaIssuesReleasesDetailsDbTester scaIssuesReleasesDetailsDbTester; - private final ScaReleasesDbTester scaReleasesDbTester; private DbTester(UuidFactory uuidFactory, System2 system2, @Nullable String schemaPath, AuditPersister auditPersister, MyBatisConfExtension... confExtensions) { super(TestDbImpl.create(schemaPath, confExtensions)); @@ -138,11 +128,6 @@ public class DbTester extends AbstractDbTester<TestDbImpl> implements BeforeEach this.almPatsDbtester = new AlmPatsDbTester(this); this.auditDbTester = new AuditDbTester(this); this.anticipatedTransitionDbTester = new AnticipatedTransitionDbTester(this); - this.scaDependenciesDbTester = new ScaDependenciesDbTester(this); - this.scaIssuesDbTester = new ScaIssuesDbTester(this); - this.scaIssuesReleasesDbTester = new ScaIssuesReleasesDbTester(this); - this.scaIssuesReleasesDetailsDbTester = new ScaIssuesReleasesDetailsDbTester(this); - this.scaReleasesDbTester = new ScaReleasesDbTester(this); } public static DbTester create() { @@ -294,22 +279,6 @@ public class DbTester extends AbstractDbTester<TestDbImpl> implements BeforeEach return anticipatedTransitionDbTester; } - public ScaDependenciesDbTester getScaDependenciesDbTester() { - return scaDependenciesDbTester; - } - - public ScaIssuesDbTester getScaIssuesDbTester() { - return scaIssuesDbTester; - } - - public ScaIssuesReleasesDetailsDbTester getScaIssuesReleasesDetailsDbTester() { - return scaIssuesReleasesDetailsDbTester; - } - - public ScaReleasesDbTester getScaReleasesDbTester() { - return scaReleasesDbTester; - } - @Override public void afterEach(ExtensionContext context) throws Exception { after(); diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java index 82112928b32..171ac2ea2de 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/issue/IssueDbTester.java @@ -24,7 +24,7 @@ import java.util.Random; import java.util.function.Consumer; import javax.annotation.Nullable; import org.sonar.api.issue.Issue; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.issue.DefaultIssueComment; import org.sonar.core.issue.FieldDiffs; import org.sonar.core.util.Uuids; @@ -38,7 +38,7 @@ import org.sonar.db.user.UserDto; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Arrays.stream; import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.issue.IssueTesting.newIssue; diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/PermissionsTestHelper.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/PermissionsTestHelper.java index 740c25e5ccb..4f644ffe6e0 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/PermissionsTestHelper.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/PermissionsTestHelper.java @@ -20,7 +20,6 @@ package org.sonar.db.permission; import java.util.Set; -import org.sonar.api.web.UserRole; import static org.sonar.db.permission.GlobalPermission.APPLICATION_CREATOR; import static org.sonar.db.permission.GlobalPermission.PORTFOLIO_CREATOR; @@ -28,8 +27,9 @@ import static org.sonar.db.permission.GlobalPermission.SCAN; public class PermissionsTestHelper { - public static final Set<String> ALL_PERMISSIONS = Set.of(UserRole.ADMIN, UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN, UserRole.SECURITYHOTSPOT_ADMIN, - SCAN.getKey(), UserRole.USER, APPLICATION_CREATOR.getKey(), PORTFOLIO_CREATOR.getKey()); + public static final Set<String> ALL_PERMISSIONS = Set.of(ProjectPermission.ADMIN.getKey(), ProjectPermission.CODEVIEWER.getKey(), + ProjectPermission.ISSUE_ADMIN.getKey(), ProjectPermission.SECURITYHOTSPOT_ADMIN.getKey(), + SCAN.getKey(), ProjectPermission.USER.getKey(), APPLICATION_CREATOR.getKey(), PORTFOLIO_CREATOR.getKey()); private PermissionsTestHelper() { } diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java index 981ffa9664c..4eb8168524e 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java @@ -23,6 +23,7 @@ import java.util.function.Consumer; import javax.annotation.Nullable; import org.sonar.db.DbClient; import org.sonar.db.DbTester; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; @@ -68,32 +69,60 @@ public class PermissionTemplateDbTester { return templateInDb; } + public void addGroupToTemplate(PermissionTemplateDto permissionTemplate, GroupDto group, ProjectPermission permission) { + addGroupToTemplate(permissionTemplate, group, permission.getKey()); + } + public void addGroupToTemplate(PermissionTemplateDto permissionTemplate, GroupDto group, String permission) { addGroupToTemplate(permissionTemplate.getUuid(), group.getUuid(), permission, permissionTemplate.getName(), group.getName()); } + public void addGroupToTemplate(String templateUuid, @Nullable String groupUuid, ProjectPermission permission, String templateName, @Nullable String groupName) { + addGroupToTemplate(templateUuid, groupUuid, permission.getKey(), templateName, groupName); + } + public void addGroupToTemplate(String templateUuid, @Nullable String groupUuid, String permission, String templateName, @Nullable String groupName) { dbClient.permissionTemplateDao().insertGroupPermission(db.getSession(), templateUuid, groupUuid, permission, templateName, groupName); db.commit(); } + public void addAnyoneToTemplate(PermissionTemplateDto permissionTemplate, ProjectPermission permission) { + addAnyoneToTemplate(permissionTemplate, permission.getKey()); + } + public void addAnyoneToTemplate(PermissionTemplateDto permissionTemplate, String permission) { addGroupToTemplate(permissionTemplate.getUuid(), null, permission, permissionTemplate.getName(), null); } + public void addUserToTemplate(PermissionTemplateDto permissionTemplate, UserDto user, ProjectPermission permission) { + addUserToTemplate(permissionTemplate, user, permission.getKey()); + } + public void addUserToTemplate(PermissionTemplateDto permissionTemplate, UserDto user, String permission) { addUserToTemplate(permissionTemplate.getUuid(), user.getUuid(), permission, permissionTemplate.getName(), user.getName()); } + public void addUserToTemplate(String templateUuid, String userUuid, ProjectPermission permission, String templateName, String userLogin) { + addUserToTemplate(templateUuid, userUuid, permission.getKey(), templateName, userLogin); + } + public void addUserToTemplate(String templateUuid, String userUuid, String permission, String templateName, String userLogin) { dbClient.permissionTemplateDao().insertUserPermission(db.getSession(), templateUuid, userUuid, permission, templateName, userLogin); db.commit(); } + public void addProjectCreatorToTemplate(PermissionTemplateDto permissionTemplate, ProjectPermission permission) { + addProjectCreatorToTemplate(permissionTemplate, permission.getKey()); + } + public void addProjectCreatorToTemplate(PermissionTemplateDto permissionTemplate, String permission) { addProjectCreatorToTemplate(permissionTemplate.getUuid(), permission, permissionTemplate.getName()); } + public void addProjectCreatorToTemplate(String templateUuid, ProjectPermission permission, String templateName) { + addProjectCreatorToTemplate(templateUuid, permission.getKey(), templateName); + } + public void addProjectCreatorToTemplate(String templateUuid, String permission, String templateName) { dbClient.permissionTemplateCharacteristicDao().insert(db.getSession(), newPermissionTemplateCharacteristicDto() .setWithProjectCreator(true) diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleDbTester.java index 18bbfe1e700..a984b01cf27 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleDbTester.java @@ -23,12 +23,12 @@ import java.util.Arrays; import java.util.Random; import java.util.function.Consumer; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.core.util.Uuids; import org.sonar.db.DbTester; import static java.util.Arrays.asList; -import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; +import static org.sonar.core.rule.RuleType.SECURITY_HOTSPOT; import static org.sonar.db.rule.RuleTesting.newDeprecatedRuleKey; import static org.sonar.db.rule.RuleTesting.newRule; diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java index 73a0b5a0993..cdb250e515d 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/rule/RuleTesting.java @@ -31,7 +31,7 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttribute; -import org.sonar.api.rules.RuleType; +import org.sonar.core.rule.RuleType; import org.sonar.api.server.rule.RuleParamType; import org.sonar.core.util.UuidFactory; import org.sonar.core.util.UuidFactoryFast; @@ -44,7 +44,7 @@ import static com.google.common.collect.Sets.newHashSet; import static java.util.Arrays.stream; import static org.apache.commons.lang3.RandomStringUtils.secure; import static org.sonar.api.rule.RuleKey.EXTERNAL_RULE_REPO_PREFIX; -import static org.sonar.api.rules.RuleType.CODE_SMELL; +import static org.sonar.core.rule.RuleType.CODE_SMELL; import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; /** diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaDependenciesDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaDependenciesDbTester.java deleted file mode 100644 index 97d6a718ea5..00000000000 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaDependenciesDbTester.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.List; -import java.util.function.Function; -import javax.annotation.Nullable; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; - -public class ScaDependenciesDbTester { - private final DbTester db; - private final DbClient dbClient; - - public ScaDependenciesDbTester(DbTester db) { - this.db = db; - this.dbClient = db.getDbClient(); - } - - public static ScaDependencyDto newScaDependencyDto(String scaReleaseUuid, String suffix) { - return newScaDependencyDto(scaReleaseUuid, suffix, null); - } - - public static ScaDependencyDto newScaDependencyDto(String scaReleaseUuid, String suffix, boolean direct) { - return newScaDependencyDto(scaReleaseUuid, suffix, builder -> builder.setDirect(direct)); - } - - public static ScaDependencyDto newScaDependencyDto(String scaReleaseUuid, String suffix, @Nullable Function<ScaDependencyDto.Builder, ScaDependencyDto.Builder> customizer) { - long now = 1348L; - var builder = new ScaDependencyDto("scaDependencyUuid" + suffix, - scaReleaseUuid, - true, - "compile", - false, - "pom.xml", - "package-lock.json", - List.of(List.of("pkg:npm/foo@1.0.0")), - false, - now, - now).toBuilder(); - if (customizer != null) { - builder = customizer.apply(builder); - } - return builder.build(); - } - - public ComponentDto newComponentDto(String branchUuid, String suffix) { - return new ComponentDto().setUuid("uuid" + suffix) - .setKey("key" + suffix) - .setUuidPath("uuidPath" + suffix) - .setBranchUuid(branchUuid); - } - - public ComponentDto insertComponent(String branchUuid, String suffix) { - ComponentDto componentDto = newComponentDto(branchUuid, suffix); - db.components().insertComponent(componentDto); - return componentDto; - } - - public ScaDependencyDto insertScaDependency(String scaReleaseUuid, String suffix, Function<ScaDependencyDto.Builder, ScaDependencyDto.Builder> customizer) { - ScaDependencyDto scaDependencyDto = newScaDependencyDto(scaReleaseUuid, suffix, customizer); - dbClient.scaDependenciesDao().insert(db.getSession(), scaDependencyDto); - return scaDependencyDto; - } - - public ScaDependencyDto insertScaDependency(ScaReleaseDto scaReleaseDto, String suffix, Function<ScaDependencyDto.Builder, ScaDependencyDto.Builder> customizer) { - return insertScaDependency(scaReleaseDto.uuid(), suffix, customizer); - } - - public ScaDependencyDto insertScaDependency(String scaReleaseUuid, String suffix) { - ScaDependencyDto scaDependencyDto = newScaDependencyDto(scaReleaseUuid, suffix); - dbClient.scaDependenciesDao().insert(db.getSession(), scaDependencyDto); - return scaDependencyDto; - } - - public ScaDependencyDto insertScaDependency(ScaReleaseDto scaReleaseDto, String suffix) { - return insertScaDependency(scaReleaseDto.uuid(), suffix); - } - - public ScaDependencyDto insertScaDependency(String scaReleaseUuid, String suffix, boolean direct) { - ScaDependencyDto scaDependencyDto = newScaDependencyDto(scaReleaseUuid, suffix, direct); - dbClient.scaDependenciesDao().insert(db.getSession(), scaDependencyDto); - return scaDependencyDto; - } - - public ScaDependencyDto insertScaDependency(ScaReleaseDto scaReleaseDto, String suffix, boolean direct) { - return insertScaDependency(scaReleaseDto.uuid(), suffix, direct); - } - - public ScaDependencyDto insertScaDependencyWithRelease(String componentUuid, String suffix, boolean direct, PackageManager packageManager, String packageName) { - var scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentUuid, suffix, packageManager, packageName); - return insertScaDependency(scaReleaseDto.uuid(), suffix, direct); - } - - public ScaDependencyDto insertScaDependencyWithRelease(String componentUuid, String suffix, Function<ScaDependencyDto.Builder, ScaDependencyDto.Builder> customizer, - PackageManager packageManager, String packageName) { - var scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentUuid, suffix, packageManager, packageName); - return insertScaDependency(scaReleaseDto.uuid(), suffix, customizer); - } -} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesDbTester.java deleted file mode 100644 index c7c26bbd0ae..00000000000 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesDbTester.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Map; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; - -public class ScaIssuesDbTester { - private static final Map<String, String> SAMPLE_LICENSES_BY_SUFFIX = Map.of( - "1", "MIT", - "2", "0BSD", - "3", "GPL-3.0", - "4", "Apache-2.0", - "5", "BSD-3-Clause"); - - private final DbTester db; - private final DbClient dbClient; - - public ScaIssuesDbTester(DbTester db) { - this.db = db; - this.dbClient = db.getDbClient(); - } - - public static ScaVulnerabilityIssueDto newVulnerabilityIssueDto(String suffix) { - return new ScaVulnerabilityIssueDto("sca-issue-uuid" + suffix, ScaSeverity.INFO, List.of("cwe" + suffix), new BigDecimal("7.1"), 1L, 2L); - } - - public static ScaIssueDto newVulnerabilityScaIssueDto(String suffix) { - return new ScaIssueDto("sca-issue-uuid" + suffix, ScaIssueType.VULNERABILITY, "fakePackageUrl" + suffix, "fakeVulnerabilityId" + suffix, ScaIssueDto.NULL_VALUE, 1L, - 2L); - } - - public static ScaIssueDto newProhibitedLicenseScaIssueDto(String suffix) { - return new ScaIssueDto("sca-issue-uuid" + suffix, ScaIssueType.PROHIBITED_LICENSE, ScaIssueDto.NULL_VALUE, ScaIssueDto.NULL_VALUE, - SAMPLE_LICENSES_BY_SUFFIX.getOrDefault(suffix, "GPL-3.0-only"), 1L, 2L); - } - - Map.Entry<ScaIssueDto, ScaVulnerabilityIssueDto> newVulnerabilityIssue(String suffix) { - var scaIssueDto = newVulnerabilityScaIssueDto(suffix); - var vulnerabilityIssueDto = newVulnerabilityIssueDto(suffix); - return Map.entry(scaIssueDto, vulnerabilityIssueDto); - } - - Map.Entry<ScaIssueDto, ScaVulnerabilityIssueDto> insertVulnerabilityIssue(String suffix) { - var scaIssueDto = newVulnerabilityScaIssueDto(suffix); - var vulnerabilityIssueDto = newVulnerabilityIssueDto(suffix); - - dbClient.scaIssuesDao().insert(db.getSession(), scaIssueDto); - dbClient.scaVulnerabilityIssuesDao().insert(db.getSession(), vulnerabilityIssueDto); - return Map.entry(scaIssueDto, vulnerabilityIssueDto); - } - - ScaIssueDto insertProhibitedLicenseIssue(String suffix) { - var scaIssueDto = newProhibitedLicenseScaIssueDto(suffix); - dbClient.scaIssuesDao().insert(db.getSession(), scaIssueDto); - return scaIssueDto; - } -} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesReleasesDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesReleasesDbTester.java deleted file mode 100644 index 7e1b39fd260..00000000000 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesReleasesDbTester.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; - -public class ScaIssuesReleasesDbTester { - private final DbTester db; - private final DbClient dbClient; - - public ScaIssuesReleasesDbTester(DbTester db) { - this.db = db; - this.dbClient = db.getDbClient(); - } - - public static ScaIssueReleaseDto fromDtos(ScaIssueDto issueDto, ScaReleaseDto releaseDto, String suffix) { - return new ScaIssueReleaseDto("issueReleaseUuid" + suffix, issueDto.uuid(), releaseDto.uuid(), ScaSeverity.INFO, 89L, 90L); - } - - public static IssueReleaseData newProhibitedLicenseIssueReleaseDto(String suffix) { - var issueDto = ScaIssuesDbTester.newProhibitedLicenseScaIssueDto(suffix); - var releaseDto = ScaReleasesDbTester.newScaReleaseDto(suffix); - var issueReleaseDto = fromDtos(issueDto, releaseDto, suffix); - return new IssueReleaseData(issueReleaseDto, issueDto, releaseDto, null); - } - - public static IssueReleaseData newVulnerabilityIssueReleaseDto(String suffix) { - var issueDto = ScaIssuesDbTester.newVulnerabilityScaIssueDto(suffix); - var vulnerabiiltyIssueDto = ScaIssuesDbTester.newVulnerabilityIssueDto(suffix); - var releaseDto = ScaReleasesDbTester.newScaReleaseDto(suffix); - var issueReleaseDto = fromDtos(issueDto, releaseDto, suffix); - return new IssueReleaseData(issueReleaseDto, issueDto, releaseDto, vulnerabiiltyIssueDto); - } - - public IssueReleaseData insertProhibitedLicenseIssueReleaseDto(String suffix) { - var data = newProhibitedLicenseIssueReleaseDto(suffix); - dbClient.scaIssuesDao().insert(db.getSession(), data.issueDto); - dbClient.scaReleasesDao().insert(db.getSession(), data.releaseDto); - dbClient.scaIssuesReleasesDao().insert(db.getSession(), data.issueReleaseDto); - return data; - } - - public IssueReleaseData insertVulnerabilityIssueReleaseDto(String suffix) { - var data = newVulnerabilityIssueReleaseDto(suffix); - dbClient.scaIssuesDao().insert(db.getSession(), data.issueDto); - dbClient.scaReleasesDao().insert(db.getSession(), data.releaseDto); - dbClient.scaIssuesReleasesDao().insert(db.getSession(), data.issueReleaseDto); - dbClient.scaVulnerabilityIssuesDao().insert(db.getSession(), data.vulnerabilityIssueDto); - return data; - } - - public record IssueReleaseData( - ScaIssueReleaseDto issueReleaseDto, - ScaIssueDto issueDto, - ScaReleaseDto releaseDto, - ScaVulnerabilityIssueDto vulnerabilityIssueDto) { - } -} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDbTester.java deleted file mode 100644 index 869a62e61a2..00000000000 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDbTester.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import java.util.Optional; -import java.util.function.Function; -import javax.annotation.Nullable; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; - -import static org.assertj.core.api.Assertions.assertThat; - -public class ScaIssuesReleasesDetailsDbTester { - private final DbTester db; - private final DbClient dbClient; - - public ScaIssuesReleasesDetailsDbTester(DbTester db) { - this.db = db; - this.dbClient = db.getDbClient(); - } - - public static ScaIssueReleaseDetailsDto fromIssueReleaseData(ScaIssuesReleasesDbTester.IssueReleaseData issueReleaseData) { - return new ScaIssueReleaseDetailsDto( - issueReleaseData.issueReleaseDto().uuid(), - issueReleaseData.issueReleaseDto(), - issueReleaseData.issueDto(), - issueReleaseData.releaseDto(), - issueReleaseData.vulnerabilityIssueDto()); - } - - public static ScaIssueReleaseDetailsDto fromDtos(ScaIssueReleaseDto issueReleaseDto, ScaIssueDto issueDto, - Optional<ScaVulnerabilityIssueDto> vulnerabilityIssueDtoOptional, ScaReleaseDto releaseDto) { - return new ScaIssueReleaseDetailsDto(issueReleaseDto.uuid(), issueReleaseDto, - issueDto, releaseDto, vulnerabilityIssueDtoOptional.orElse(null)); - } - - private ScaIssueReleaseDetailsDto insertIssue(ScaIssueDto scaIssue, Optional<ScaVulnerabilityIssueDto> scaVulnerabilityIssueDtoOptional, - String suffix, String componentUuid) { - // insertScaRelease has suffix and componentUuid swapped vs. our own method... - var scaRelease = db.getScaReleasesDbTester().insertScaRelease(componentUuid, suffix); - var scaIssueRelease = new ScaIssueReleaseDto("sca-issue-release-uuid-" + suffix, scaIssue, scaRelease, ScaSeverity.INFO, 1L, 2L); - dbClient.scaIssuesReleasesDao().insert(db.getSession(), scaIssueRelease); - return fromDtos(scaIssueRelease, scaIssue, scaVulnerabilityIssueDtoOptional, scaRelease); - } - - public ScaIssueReleaseDetailsDto insertVulnerabilityIssue(String suffix, String componentUuid) { - var entry = db.getScaIssuesDbTester().insertVulnerabilityIssue(suffix); - return insertIssue(entry.getKey(), Optional.of(entry.getValue()), suffix, componentUuid); - } - - public ScaIssueReleaseDetailsDto insertProhibitedLicenseIssue(String suffix, String componentUuid) { - var scaIssue = db.getScaIssuesDbTester().insertProhibitedLicenseIssue(suffix); - return insertIssue(scaIssue, Optional.empty(), suffix, componentUuid); - } - - public ScaIssueReleaseDetailsDto insertIssue(ScaIssueType scaIssueType, String suffix, String componentUuid) { - return insertIssue(scaIssueType, suffix, componentUuid, - null, null, null, null); - } - - public ScaIssueReleaseDetailsDto insertIssue(ScaIssueType scaIssueType, String suffix, String componentUuid, - @Nullable Function<ScaIssueDto, ScaIssueDto> scaIssueModifier, - @Nullable Function<ScaVulnerabilityIssueDto, ScaVulnerabilityIssueDto> scaVulnerabilityIssueModifier, - @Nullable Function<ScaReleaseDto, ScaReleaseDto> scaReleaseModifier, - @Nullable Function<ScaIssueReleaseDto, ScaIssueReleaseDto> scaIssueReleaseModifier) { - var scaRelease = ScaReleasesDbTester.newScaReleaseDto(componentUuid, suffix, PackageManager.MAVEN, "packageName" + suffix); - if (scaReleaseModifier != null) { - scaRelease = scaReleaseModifier.apply(scaRelease); - } - // little hack here because it's useful to allow providing a release that already exists - var existing = dbClient.scaReleasesDao().selectByUuid(db.getSession(), scaRelease.uuid()); - if (existing.isEmpty()) { - dbClient.scaReleasesDao().insert(db.getSession(), scaRelease); - } else { - assertThat(existing).contains(scaRelease); - } - var scaIssue = switch (scaIssueType) { - case PROHIBITED_LICENSE -> ScaIssuesDbTester.newProhibitedLicenseScaIssueDto(suffix); - case VULNERABILITY -> ScaIssuesDbTester.newVulnerabilityScaIssueDto(suffix); - }; - if (scaIssueModifier != null) { - scaIssue = scaIssueModifier.apply(scaIssue); - } - dbClient.scaIssuesDao().insert(db.getSession(), scaIssue); - ScaVulnerabilityIssueDto scaVulnerabilityIssue = null; - if (scaIssue.scaIssueType() == ScaIssueType.VULNERABILITY) { - scaVulnerabilityIssue = ScaIssuesDbTester.newVulnerabilityIssueDto(suffix); - if (!scaVulnerabilityIssue.uuid().equals(scaIssue.uuid())) { - throw new IllegalStateException("ScaVulnerabilityIssueDto.uuid must match ScaIssueDto.uuid or we won't find the ScaVueberabilityIssueDto"); - } - if (scaVulnerabilityIssueModifier != null) { - scaVulnerabilityIssue = scaVulnerabilityIssueModifier.apply(scaVulnerabilityIssue); - } - dbClient.scaVulnerabilityIssuesDao().insert(db.getSession(), scaVulnerabilityIssue); - } - var scaIssueRelease = new ScaIssueReleaseDto("sca-issue-release-uuid-" + suffix, scaIssue, scaRelease, ScaSeverity.INFO, 1L, 2L); - if (scaIssueReleaseModifier != null) { - scaIssueRelease = scaIssueReleaseModifier.apply(scaIssueRelease); - } - dbClient.scaIssuesReleasesDao().insert(db.getSession(), scaIssueRelease); - return fromDtos(scaIssueRelease, scaIssue, Optional.ofNullable(scaVulnerabilityIssue), scaRelease); - } -} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaReleasesDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaReleasesDbTester.java deleted file mode 100644 index 0921c265bfa..00000000000 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaReleasesDbTester.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2025 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.db.sca; - -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; - -public class ScaReleasesDbTester { - private final DbTester db; - private final DbClient dbClient; - - public ScaReleasesDbTester(DbTester db) { - this.db = db; - this.dbClient = db.getDbClient(); - } - - public static ScaReleaseDto newScaReleaseDto(String suffix) { - return newScaReleaseDto("componentUuid_release_" + suffix, suffix, PackageManager.MAVEN, "packageName" + suffix); - } - - public static ScaReleaseDto newScaReleaseDto(String componentUuid, String suffix, PackageManager packageManager, String packageName) { - return new ScaReleaseDto("scaReleaseUuid" + suffix, - componentUuid, - "packageUrl" + suffix, - packageManager, - packageName, - "1.0.0-" + suffix, - "MIT", - "MIT", - true, - false, - 1L, - 2L); - } - - public ScaReleaseDto insertScaRelease(String componentUuid, String suffix) { - return insertScaRelease(componentUuid, suffix, PackageManager.MAVEN, "packageName" + suffix); - } - - public ScaReleaseDto insertScaRelease(String componentUuid, String suffix, PackageManager packageManager, String packageName) { - var scaReleaseDto = newScaReleaseDto(componentUuid, suffix, packageManager, packageName); - dbClient.scaReleasesDao().insert(db.getSession(), scaReleaseDto); - return scaReleaseDto; - } - - /** - * Inserts a release and also dependencyCount sca_dependencies that depend on that release. - */ - public ScaReleaseDto insertScaReleaseWithDependency(String componentUuid, String suffix, int dependencyCount, boolean direct, PackageManager packageManager, String packageName) { - var scaReleaseDto = insertScaRelease(componentUuid, suffix, packageManager, packageName); - while (dependencyCount > 0) { - db.getScaDependenciesDbTester().insertScaDependency(scaReleaseDto, suffix + "-" + dependencyCount, direct); - dependencyCount--; - } - return scaReleaseDto; - } -} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java index 0335b8fe354..d1ee49895e2 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/user/UserDbTester.java @@ -28,18 +28,18 @@ import java.util.Set; import java.util.function.Consumer; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.sonar.db.component.ComponentQualifiers; import org.sonar.api.security.DefaultGroups; -import org.sonar.api.web.UserRole; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.dismissmessage.MessageType; import org.sonar.db.entity.EntityDto; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.permission.GroupPermissionDto; +import org.sonar.db.permission.ProjectPermission; import org.sonar.db.permission.UserPermissionDto; import org.sonar.db.project.ProjectDto; import org.sonar.db.provisioning.GithubOrganizationGroupDto; @@ -51,10 +51,10 @@ import static java.util.Arrays.stream; import static java.util.stream.Collectors.toSet; import static org.apache.commons.lang3.RandomStringUtils.secure; import static org.sonar.db.permission.GlobalPermission.ADMINISTER; +import static org.sonar.db.permission.ProjectPermission.PUBLIC_PERMISSIONS; import static org.sonar.db.user.GroupTesting.newGroupDto; public class UserDbTester { - private static final Set<String> PUBLIC_PERMISSIONS = Set.of(UserRole.USER, UserRole.CODEVIEWER); public static final String PERMISSIONS_CANT_BE_GRANTED_ON_BRANCHES = "Permissions can't be granted on branches"; private final Random random = new SecureRandom(); @@ -208,7 +208,7 @@ public class UserDbTester { } public int countAllGroups() { - return db.getDbClient().groupDao().countByQuery(db.getSession(), new GroupQuery(null, null)); + return db.getDbClient().groupDao().countByQuery(db.getSession(), new GroupQuery(null, null, null, null)); } public Optional<ExternalGroupDto> selectExternalGroupByGroupUuid(String groupUuid) { @@ -253,10 +253,18 @@ public class UserDbTester { return dto; } + public GroupPermissionDto insertPermissionOnAnyone(ProjectPermission permission) { + return insertPermissionOnAnyone(permission.getKey()); + } + public GroupPermissionDto insertPermissionOnAnyone(GlobalPermission permission) { return insertPermissionOnAnyone(permission.getKey()); } + public Set<GroupPermissionDto> insertPermissionsOnGroup(GroupDto group, ProjectPermission... permissions) { + return insertPermissionsOnGroup(group, stream(permissions).map(ProjectPermission::getKey).toArray(String[]::new)); + } + public Set<GroupPermissionDto> insertPermissionsOnGroup(GroupDto group, String... permissions) { return stream(permissions) .map(p -> insertPermissionOnGroup(group, p)) @@ -277,9 +285,13 @@ public class UserDbTester { return insertPermissionOnGroup(group, permission.getKey()); } + public GroupPermissionDto insertPermissionOnGroup(GroupDto group, ProjectPermission permission) { + return insertPermissionOnGroup(group, permission.getKey()); + } + public GroupPermissionDto insertProjectPermissionOnAnyone(String permission, ComponentDto project) { checkArgument(!project.isPrivate(), "No permission to group AnyOne can be granted on a private project"); - checkArgument(!PUBLIC_PERMISSIONS.contains(permission), + checkArgument(!PUBLIC_PERMISSIONS.stream().map(ProjectPermission::getKey).collect(toSet()).contains(permission), "permission %s can't be granted on a public project", permission); Optional<BranchDto> branchDto = db.getDbClient().branchDao().selectByUuid(db.getSession(), project.branchUuid()); // I don't know if this check is worth it @@ -300,9 +312,13 @@ public class UserDbTester { return dto; } + public GroupPermissionDto insertEntityPermissionOnAnyone(ProjectPermission permission, EntityDto entity) { + return insertEntityPermissionOnAnyone(permission.getKey(), entity); + } + public GroupPermissionDto insertEntityPermissionOnAnyone(String permission, EntityDto entity) { checkArgument(!entity.isPrivate(), "No permission to group AnyOne can be granted on a private entity"); - checkArgument(!PUBLIC_PERMISSIONS.contains(permission), + checkArgument(!PUBLIC_PERMISSIONS.stream().map(ProjectPermission::getKey).collect(toSet()).contains(permission), "permission %s can't be granted on a public entity", permission); GroupPermissionDto dto = new GroupPermissionDto() .setUuid(Uuids.createFast()) @@ -315,13 +331,17 @@ public class UserDbTester { return dto; } - public void deleteProjectPermissionFromAnyone(EntityDto entity, String permission) { - db.getDbClient().groupPermissionDao().delete(db.getSession(), permission, null, null, entity); + public void deleteProjectPermissionFromAnyone(EntityDto entity, ProjectPermission permission) { + db.getDbClient().groupPermissionDao().delete(db.getSession(), permission.getKey(), null, null, entity); db.commit(); } + public GroupPermissionDto insertProjectPermissionOnGroup(GroupDto group, ProjectPermission permission, ComponentDto project) { + return insertProjectPermissionOnGroup(group, permission.getKey(), project); + } + public GroupPermissionDto insertProjectPermissionOnGroup(GroupDto group, String permission, ComponentDto project) { - checkArgument(project.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), + checkArgument(project.isPrivate() || !PUBLIC_PERMISSIONS.stream().map(ProjectPermission::getKey).collect(toSet()).contains(permission), "%s can't be granted on a public project", permission); Optional<BranchDto> branchDto = db.getDbClient().branchDao().selectByUuid(db.getSession(), project.branchUuid()); // I don't know if this check is worth it @@ -343,12 +363,20 @@ public class UserDbTester { return dto; } + public Set<GroupPermissionDto> insertEntityPermissionsOnGroup(GroupDto group, EntityDto entity, ProjectPermission... permissions) { + return insertEntityPermissionsOnGroup(group, entity, stream(permissions).map(ProjectPermission::getKey).toArray(String[]::new)); + } + public Set<GroupPermissionDto> insertEntityPermissionsOnGroup(GroupDto group, EntityDto entity, String... permissions) { return stream(permissions) .map(permission -> insertEntityPermissionOnGroup(group, permission, entity)) .collect(toSet()); } + public GroupPermissionDto insertEntityPermissionOnGroup(GroupDto group, ProjectPermission permission, EntityDto entity) { + return insertEntityPermissionOnGroup(group, permission.getKey(), entity); + } + public GroupPermissionDto insertEntityPermissionOnGroup(GroupDto group, String permission, EntityDto entity) { checkArgument(entity.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), "%s can't be granted on a public entity (project or portfolio)", permission); @@ -405,16 +433,20 @@ public class UserDbTester { db.commit(); } - public void deletePermissionFromUser(EntityDto project, UserDto user, String permission) { - db.getDbClient().userPermissionDao().deleteEntityPermission(db.getSession(), user, permission, project); + public void deletePermissionFromUser(EntityDto project, UserDto user, ProjectPermission permission) { + db.getDbClient().userPermissionDao().deleteEntityPermission(db.getSession(), user, permission.getKey(), project); db.commit(); } /** * Grant permission on given project */ + public UserPermissionDto insertProjectPermissionOnUser(UserDto user, ProjectPermission permission, ComponentDto project) { + return insertProjectPermissionOnUser(user, permission.getKey(), project); + } + public UserPermissionDto insertProjectPermissionOnUser(UserDto user, String permission, ComponentDto project) { - checkArgument(project.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), + checkArgument(project.isPrivate() || !PUBLIC_PERMISSIONS.stream().map(ProjectPermission::getKey).collect(toSet()).contains(permission), "%s can't be granted on a public project", permission); EntityDto entityDto; if (project.qualifier().equals(ComponentQualifiers.VIEW) || project.qualifier().equals(ComponentQualifiers.SUBVIEW)) { @@ -436,8 +468,12 @@ public class UserDbTester { return dto; } + public UserPermissionDto insertProjectPermissionOnUser(UserDto user, ProjectPermission permission, EntityDto project) { + return insertProjectPermissionOnUser(user, permission.getKey(), project); + } + public UserPermissionDto insertProjectPermissionOnUser(UserDto user, String permission, EntityDto project) { - checkArgument(project.isPrivate() || !PUBLIC_PERMISSIONS.contains(permission), + checkArgument(project.isPrivate() || !ProjectPermission.isPublic(permission), "%s can't be granted on a public project", permission); UserPermissionDto dto = new UserPermissionDto(Uuids.create(), permission, user.getUuid(), project.getUuid()); db.getDbClient().userPermissionDao().insert(db.getSession(), dto, project, user, null); |