From 96b001dde8e74bec827cb369024e5376aa7f7604 Mon Sep 17 00:00:00 2001 From: "antoine.vinot" Date: Wed, 29 Nov 2023 12:29:14 +0100 Subject: [PATCH] SONAR-21109 - Fix permission issue on api/project_links/delete endpoint --- .../server/projectlink/ws/DeleteActionIT.java | 24 +++++++++++++++---- .../server/projectlink/ws/DeleteAction.java | 23 +++++++++++++----- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/DeleteActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/DeleteActionIT.java index 303237ba097..7942433a0f4 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/DeleteActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/projectlink/ws/DeleteActionIT.java @@ -27,11 +27,14 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ProjectLinkDto; +import org.sonar.db.permission.GlobalPermission; import org.sonar.db.project.ProjectDto; +import org.sonar.server.component.TestComponentFinder; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; @@ -49,7 +52,7 @@ public class DeleteActionIT { private final DbClient dbClient = db.getDbClient(); private final DbSession dbSession = db.getSession(); - private final WsActionTester ws = new WsActionTester(new DeleteAction(dbClient, userSession)); + private final WsActionTester ws = new WsActionTester(new DeleteAction(dbClient, userSession, TestComponentFinder.from(db))); @Test public void no_response() { @@ -74,6 +77,17 @@ public class DeleteActionIT { assertLinkIsDeleted(link.getUuid()); } + @Test + public void delete_whenGlobalAdminPermission_shouldDeleteLink() { + ProjectDto project = db.components().insertPrivateProject().getProjectDto(); + ProjectLinkDto link = db.projectLinks().insertCustomLink(project); + userSession.logIn().addPermission(GlobalPermission.ADMINISTER); + + deleteLink(link); + + assertLinkIsDeleted(link.getUuid()); + } + @Test public void keep_links_of_another_project() { ProjectDto project1 = db.components().insertPrivateProject().getProjectDto(); @@ -101,11 +115,11 @@ public class DeleteActionIT { @Test public void fail_on_unknown_link() { - assertThatThrownBy(() -> ws.newRequest() + TestRequest testRequest = ws.newRequest() .setMethod("POST") - .setParam(PARAM_ID, "UNKNOWN") - .execute()) - .isInstanceOf(NotFoundException.class); + .setParam(PARAM_ID, "UNKNOWN"); + assertThatThrownBy(testRequest::execute) + .isInstanceOf(NotFoundException.class); } @Test diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java index ee2b0a5cd53..8d1a94e733f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectlink/ws/DeleteAction.java @@ -26,21 +26,27 @@ import org.sonar.api.web.UserRole; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ProjectLinkDto; +import org.sonar.db.permission.GlobalPermission; +import org.sonar.db.project.ProjectDto; +import org.sonar.server.component.ComponentFinder; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.user.UserSession; import static org.sonar.db.component.ProjectLinkDto.PROVIDED_TYPES; +import static org.sonar.server.component.ComponentFinder.ParamNames.PROJECT_ID_AND_KEY; import static org.sonar.server.projectlink.ws.ProjectLinksWsParameters.ACTION_DELETE; import static org.sonar.server.projectlink.ws.ProjectLinksWsParameters.PARAM_ID; public class DeleteAction implements ProjectLinksWsAction { private final DbClient dbClient; private final UserSession userSession; + private final ComponentFinder componentFinder; - public DeleteAction(DbClient dbClient, UserSession userSession) { + public DeleteAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder) { this.dbClient = dbClient; this.userSession = userSession; + this.componentFinder = componentFinder; } @Override @@ -70,7 +76,9 @@ public class DeleteAction implements ProjectLinksWsAction { ProjectLinkDto link = dbClient.projectLinkDao().selectByUuid(dbSession, id); link = NotFoundException.checkFound(link, "Link with id '%s' not found", id); - checkProjectAdminPermission(link); + componentFinder.getProjectByUuidOrKey(dbSession, link.getProjectUuid(), null, PROJECT_ID_AND_KEY); + ProjectDto projectDto = componentFinder.getProjectByUuidOrKey(dbSession, link.getProjectUuid(), null, PROJECT_ID_AND_KEY); + checkProjectAdminPermission(projectDto); checkNotProvided(link); dbClient.projectLinkDao().delete(dbSession, link.getUuid()); @@ -78,13 +86,16 @@ public class DeleteAction implements ProjectLinksWsAction { } } + private void checkProjectAdminPermission(ProjectDto projectDto) { + if (userSession.hasPermission(GlobalPermission.ADMINISTER)) { + return; + } + userSession.checkEntityPermission(UserRole.ADMIN, projectDto); + } + private static void checkNotProvided(ProjectLinkDto link) { String type = link.getType(); boolean isProvided = type != null && PROVIDED_TYPES.contains(type); BadRequestException.checkRequest(!isProvided, "Provided link cannot be deleted."); } - - private void checkProjectAdminPermission(ProjectLinkDto link) { - userSession.checkComponentUuidPermission(UserRole.ADMIN, link.getProjectUuid()); - } } -- 2.39.5