diff options
author | alain <108417558+alain-kermis-sonarsource@users.noreply.github.com> | 2022-10-20 11:29:15 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-10-20 20:03:02 +0000 |
commit | 690cc97185196f8efa976425878cbfd569c74f3c (patch) | |
tree | 7c74fcb8982e311356d633c7f9a6c0c147dd371f /server/sonar-webserver-webapi | |
parent | 344dcf9cea680693d62ca73a19eb7c652d5ca271 (diff) | |
download | sonarqube-690cc97185196f8efa976425878cbfd569c74f3c.tar.gz sonarqube-690cc97185196f8efa976425878cbfd569c74f3c.zip |
SONAR-17456 Fix SSF-326
Diffstat (limited to 'server/sonar-webserver-webapi')
2 files changed, 30 insertions, 5 deletions
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java index 19306b34ea7..ed824818842 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java @@ -35,12 +35,14 @@ import org.sonar.api.server.ws.WebService; import org.sonar.core.platform.PluginInfo; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.permission.GlobalPermission; import org.sonar.db.plugin.PluginDto; import org.sonar.db.plugin.PluginDto.Type; import org.sonar.core.plugin.PluginType; import org.sonar.server.plugins.ServerPlugin; import org.sonar.server.plugins.ServerPluginRepository; import org.sonar.server.plugins.UpdateCenterMatrixFactory; +import org.sonar.server.user.UserSession; import org.sonar.updatecenter.common.Plugin; import org.sonarqube.ws.Plugins.InstalledPluginsWsResponse; import org.sonarqube.ws.Plugins.PluginDetails; @@ -53,6 +55,7 @@ import static java.util.stream.Collectors.toMap; import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_COMPARATOR; import static org.sonar.server.plugins.ws.PluginWSCommons.buildPluginDetails; import static org.sonar.server.plugins.ws.PluginWSCommons.compatiblePluginsByKey; +import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; import static org.sonar.server.ws.WsUtils.writeProtobuf; /** @@ -62,11 +65,13 @@ public class InstalledAction implements PluginsWsAction { private static final String FIELD_CATEGORY = "category"; private static final String PARAM_TYPE = "type"; + private final UserSession userSession; private final ServerPluginRepository serverPluginRepository; private final UpdateCenterMatrixFactory updateCenterMatrixFactory; private final DbClient dbClient; - public InstalledAction(ServerPluginRepository serverPluginRepository, UpdateCenterMatrixFactory updateCenterMatrixFactory, DbClient dbClient) { + public InstalledAction(ServerPluginRepository serverPluginRepository, UserSession userSession, UpdateCenterMatrixFactory updateCenterMatrixFactory, DbClient dbClient) { + this.userSession = userSession; this.serverPluginRepository = serverPluginRepository; this.updateCenterMatrixFactory = updateCenterMatrixFactory; this.dbClient = dbClient; @@ -75,9 +80,11 @@ public class InstalledAction implements PluginsWsAction { @Override public void define(WebService.NewController controller) { WebService.NewAction action = controller.createAction("installed") - .setDescription("Get the list of all the plugins installed on the SonarQube instance, sorted by plugin name.") + .setDescription("Get the list of all the plugins installed on the SonarQube instance, sorted by plugin name.<br/>" + + "Requires authentication.") .setSince("5.2") .setChangelog( + new Change("9.7", "Authentication check added"), new Change("8.0", "The 'documentationPath' field is added"), new Change("7.0", "The fields 'compressedHash' and 'compressedFilename' are added"), new Change("6.6", "The 'filename' field is added"), @@ -91,7 +98,7 @@ public class InstalledAction implements PluginsWsAction { .setDescription(format("Comma-separated list of the additional fields to be returned in response. No additional field is returned by default. Possible values are:" + "<ul>" + "<li>%s - category as defined in the Update Center. A connection to the Update Center is needed</li>" + - "</lu>", FIELD_CATEGORY)) + "</ul>", FIELD_CATEGORY)) .setSince("5.6"); action.createParam(PARAM_TYPE) @@ -103,6 +110,10 @@ public class InstalledAction implements PluginsWsAction { @Override public void handle(Request request, Response response) throws Exception { + if (!userSession.isLoggedIn() && !userSession.hasPermission(GlobalPermission.SCAN)) { + throw insufficientPrivilegesException(); + } + String typeParam = request.param(PARAM_TYPE); SortedSet<ServerPlugin> installedPlugins = loadInstalledPlugins(typeParam); Map<String, PluginDto> dtosByKey; diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java index 423fb7658ca..208032a9a7e 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java @@ -41,11 +41,14 @@ import org.sonar.api.utils.System2; import org.sonar.core.platform.PluginInfo; import org.sonar.db.DbTester; import org.sonar.db.plugin.PluginDto.Type; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.plugins.PluginFilesAndMd5.FileAndMd5; import org.sonar.core.plugin.PluginType; import org.sonar.server.plugins.ServerPlugin; import org.sonar.server.plugins.ServerPluginRepository; import org.sonar.server.plugins.UpdateCenterMatrixFactory; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; import org.sonar.updatecenter.common.Plugin; import org.sonar.updatecenter.common.UpdateCenter; @@ -54,10 +57,11 @@ import org.sonar.updatecenter.common.Version; 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.assertThatThrownBy; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.sonar.test.JsonAssert.assertJson; @@ -71,10 +75,12 @@ public class InstalledActionTest { public TemporaryFolder temp = new TemporaryFolder(); @Rule public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone().logIn(); private UpdateCenterMatrixFactory updateCenterMatrixFactory = mock(UpdateCenterMatrixFactory.class, RETURNS_DEEP_STUBS); private ServerPluginRepository serverPluginRepository = mock(ServerPluginRepository.class); - private InstalledAction underTest = new InstalledAction(serverPluginRepository, updateCenterMatrixFactory, db.getDbClient()); + private InstalledAction underTest = new InstalledAction(serverPluginRepository, userSession, updateCenterMatrixFactory, db.getDbClient()); private WsActionTester tester = new WsActionTester(underTest); @DataProvider @@ -486,6 +492,14 @@ public class InstalledActionTest { assertThat(response).containsOnlyOnce("name2"); } + @Test + public void fail_if_not_logged_in() { + userSession.anonymous(); + TestRequest testRequest = tester.newRequest(); + assertThatThrownBy(testRequest::execute) + .isInstanceOf(ForbiddenException.class); + } + private ServerPlugin plugin(String key, String name) throws IOException { File file = temp.newFile(); PluginInfo info = new PluginInfo(key) |