@@ -0,0 +1,85 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact 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.server.setting.ws; | |||
import com.google.common.collect.ImmutableSet; | |||
import java.util.Set; | |||
import java.util.stream.Stream; | |||
import org.sonar.api.Startable; | |||
import org.sonar.api.config.PropertyDefinition; | |||
import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.core.platform.PluginInfo; | |||
import org.sonar.core.platform.PluginRepository; | |||
import static java.util.stream.Collectors.toSet; | |||
import static java.util.stream.Stream.concat; | |||
import static org.sonar.api.CoreProperties.PERMANENT_SERVER_ID; | |||
import static org.sonar.api.CoreProperties.SERVER_ID; | |||
import static org.sonar.api.CoreProperties.SERVER_STARTTIME; | |||
import static org.sonar.api.PropertyType.LICENSE; | |||
import static org.sonar.server.setting.ws.SettingsPermissionPredicates.LICENSE_HASH_SUFFIX; | |||
/** | |||
* This class returns the list of settings required on scanner side (licenses, license hashes, server ids, etc.) | |||
*/ | |||
public class ScannerSettings implements Startable { | |||
private static final String SONAR_PREFIX = "sonar."; | |||
private static final Set<String> SERVER_SETTING_KEYS = ImmutableSet.of(PERMANENT_SERVER_ID, SERVER_STARTTIME, SERVER_ID); | |||
private final PropertyDefinitions propertyDefinitions; | |||
private final PluginRepository pluginRepository; | |||
private Set<String> scannerSettingKeys; | |||
public ScannerSettings(PropertyDefinitions propertyDefinitions, PluginRepository pluginRepository) { | |||
this.propertyDefinitions = propertyDefinitions; | |||
this.pluginRepository = pluginRepository; | |||
} | |||
@Override | |||
public void start() { | |||
this.scannerSettingKeys = concat(concat(loadLicenseKeys(), loadLicenseHashKeys()), | |||
SERVER_SETTING_KEYS.stream()).collect(toSet()); | |||
} | |||
private Stream<String> loadLicenseHashKeys() { | |||
return pluginRepository.getPluginInfos().stream() | |||
.map(PluginInfo::getKey) | |||
.map(key -> SONAR_PREFIX + key + LICENSE_HASH_SUFFIX); | |||
} | |||
private Stream<String> loadLicenseKeys() { | |||
return propertyDefinitions.getAll() | |||
.stream() | |||
.filter(setting -> setting.type().equals(LICENSE)) | |||
.map(PropertyDefinition::key); | |||
} | |||
Set<String> getScannerSettingKeys() { | |||
return scannerSettingKeys; | |||
} | |||
@Override | |||
public void stop() { | |||
// nothing to do | |||
} | |||
} |
@@ -36,6 +36,7 @@ public class SettingsWsModule extends Module { | |||
GenerateSecretKeyAction.class, | |||
CheckSecretKeyAction.class, | |||
SettingsUpdater.class, | |||
SettingValidations.class); | |||
SettingValidations.class, | |||
ScannerSettings.class); | |||
} | |||
} |
@@ -20,7 +20,6 @@ | |||
package org.sonar.server.setting.ws; | |||
import com.google.common.base.Splitter; | |||
import com.google.common.collect.ImmutableSet; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.HashSet; | |||
@@ -31,7 +30,6 @@ import java.util.Optional; | |||
import java.util.Set; | |||
import java.util.function.Function; | |||
import java.util.stream.Collectors; | |||
import java.util.stream.Stream; | |||
import org.sonar.api.config.PropertyDefinition; | |||
import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.api.server.ws.Request; | |||
@@ -49,14 +47,8 @@ import org.sonarqube.ws.client.setting.ValuesRequest; | |||
import static java.lang.String.format; | |||
import static java.util.stream.Stream.concat; | |||
import static org.apache.commons.lang.StringUtils.isEmpty; | |||
import static org.sonar.api.CoreProperties.PERMANENT_SERVER_ID; | |||
import static org.sonar.api.CoreProperties.SERVER_ID; | |||
import static org.sonar.api.CoreProperties.SERVER_STARTTIME; | |||
import static org.sonar.api.PropertyType.LICENSE; | |||
import static org.sonar.api.PropertyType.PROPERTY_SET; | |||
import static org.sonar.api.web.UserRole.USER; | |||
import static org.sonar.server.setting.ws.SettingsPermissionPredicates.LICENSE_HASH_SUFFIX; | |||
import static org.sonar.server.setting.ws.SettingsPermissionPredicates.LICENSE_SUFFIX; | |||
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; | |||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||
import static org.sonarqube.ws.client.setting.SettingsWsParameters.ACTION_VALUES; | |||
@@ -68,23 +60,23 @@ public class ValuesAction implements SettingsWsAction { | |||
private static final Splitter COMMA_SPLITTER = Splitter.on(","); | |||
private static final String COMMA_ENCODED_VALUE = "%2C"; | |||
private static final Set<String> ADDITIONAL_KEYS = ImmutableSet.of(PERMANENT_SERVER_ID, SERVER_STARTTIME, SERVER_ID); | |||
private final DbClient dbClient; | |||
private final ComponentFinder componentFinder; | |||
private final UserSession userSession; | |||
private final PropertyDefinitions propertyDefinitions; | |||
private final SettingsFinder settingsFinder; | |||
private final SettingsPermissionPredicates settingsPermissionPredicates; | |||
private final ScannerSettings scannerSettings; | |||
public ValuesAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, PropertyDefinitions propertyDefinitions, SettingsFinder settingsFinder, | |||
SettingsPermissionPredicates settingsPermissionPredicates) { | |||
SettingsPermissionPredicates settingsPermissionPredicates, ScannerSettings scannerSettings) { | |||
this.dbClient = dbClient; | |||
this.componentFinder = componentFinder; | |||
this.userSession = userSession; | |||
this.propertyDefinitions = propertyDefinitions; | |||
this.settingsFinder = settingsFinder; | |||
this.settingsPermissionPredicates = settingsPermissionPredicates; | |||
this.scannerSettings = scannerSettings; | |||
} | |||
@Override | |||
@@ -142,18 +134,7 @@ public class ValuesAction implements SettingsWsAction { | |||
if (!keys.isEmpty()) { | |||
return new HashSet<>(keys); | |||
} | |||
return concat( | |||
concat(loadLicenseHashKeys(), propertyDefinitions.getAll().stream().map(PropertyDefinition::key)), | |||
ADDITIONAL_KEYS.stream()) | |||
.collect(Collectors.toSet()); | |||
} | |||
private Stream<String> loadLicenseHashKeys() { | |||
return propertyDefinitions.getAll() | |||
.stream() | |||
.filter(setting -> setting.type().equals(LICENSE)) | |||
.map(PropertyDefinition::key) | |||
.map(setting -> setting.replace(LICENSE_SUFFIX, LICENSE_HASH_SUFFIX)); | |||
return concat(propertyDefinitions.getAll().stream().map(PropertyDefinition::key), scannerSettings.getScannerSettingKeys().stream()).collect(Collectors.toSet()); | |||
} | |||
private Optional<ComponentDto> loadComponent(DbSession dbSession, ValuesRequest valuesRequest) { |
@@ -0,0 +1,72 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact 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.server.setting.ws; | |||
import org.junit.Test; | |||
import org.sonar.api.config.PropertyDefinition; | |||
import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.core.platform.PluginInfo; | |||
import org.sonar.core.platform.PluginRepository; | |||
import static java.util.Arrays.asList; | |||
import static java.util.Collections.singletonList; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import static org.sonar.api.PropertyType.LICENSE; | |||
public class ScannerSettingsTest { | |||
private PropertyDefinitions definitions = new PropertyDefinitions(); | |||
private PluginRepository repository = mock(PluginRepository.class); | |||
private ScannerSettings underTest = new ScannerSettings(definitions, repository); | |||
@Test | |||
public void return_license_keys() throws Exception { | |||
definitions.addComponents(asList( | |||
PropertyDefinition.builder("foo").build(), | |||
PropertyDefinition.builder("myplugin.license.secured").type(LICENSE).build())); | |||
underTest.start(); | |||
assertThat(underTest.getScannerSettingKeys()).contains("myplugin.license.secured"); | |||
} | |||
@Test | |||
public void return_license_hash_keys() throws Exception { | |||
PluginInfo pluginInfo = mock(PluginInfo.class); | |||
when(pluginInfo.getKey()).thenReturn("myplugin"); | |||
when(repository.getPluginInfos()).thenReturn(singletonList(pluginInfo)); | |||
underTest.start(); | |||
assertThat(underTest.getScannerSettingKeys()).contains("sonar.myplugin.licenseHash.secured"); | |||
} | |||
@Test | |||
public void return_server_settings() throws Exception { | |||
definitions.addComponents(asList( | |||
PropertyDefinition.builder("foo").build(), | |||
PropertyDefinition.builder("myplugin.license.secured").type(LICENSE).build())); | |||
underTest.start(); | |||
assertThat(underTest.getScannerSettingKeys()).contains("sonar.server_id", "sonar.core.id", "sonar.core.startTime"); | |||
} | |||
} |
@@ -29,6 +29,6 @@ public class SettingsWsModuleTest { | |||
public void verify_count_of_added_components() { | |||
ComponentContainer container = new ComponentContainer(); | |||
new SettingsWsModule().configure(container); | |||
assertThat(container.size()).isEqualTo(12 + 2); | |||
assertThat(container.size()).isEqualTo(13 + 2); | |||
} | |||
} |
@@ -35,6 +35,8 @@ import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.api.config.PropertyFieldDefinition; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.platform.PluginInfo; | |||
import org.sonar.core.platform.PluginRepository; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDbTester; | |||
@@ -51,7 +53,10 @@ import org.sonarqube.ws.Settings; | |||
import org.sonarqube.ws.Settings.ValuesWsResponse; | |||
import static java.util.Arrays.asList; | |||
import static java.util.Collections.singletonList; | |||
import static org.assertj.core.api.Java6Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import static org.sonar.api.PropertyType.LICENSE; | |||
import static org.sonar.api.web.UserRole.ADMIN; | |||
import static org.sonar.api.web.UserRole.CODEVIEWER; | |||
@@ -78,19 +83,25 @@ public class ValuesActionTest { | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
DbClient dbClient = db.getDbClient(); | |||
PropertyDbTester propertyDb = new PropertyDbTester(db); | |||
ComponentDbTester componentDb = new ComponentDbTester(db); | |||
PropertyDefinitions definitions = new PropertyDefinitions(); | |||
SettingsFinder settingsFinder = new SettingsFinder(dbClient, definitions); | |||
private DbClient dbClient = db.getDbClient(); | |||
private PropertyDbTester propertyDb = new PropertyDbTester(db); | |||
private ComponentDbTester componentDb = new ComponentDbTester(db); | |||
private PropertyDefinitions definitions = new PropertyDefinitions(); | |||
private SettingsFinder settingsFinder = new SettingsFinder(dbClient, definitions); | |||
private PluginRepository repository = mock(PluginRepository.class); | |||
private ScannerSettings scannerSettings = new ScannerSettings(definitions, repository); | |||
ComponentDto project; | |||
private ComponentDto project; | |||
WsActionTester ws = new WsActionTester( | |||
new ValuesAction(dbClient, new ComponentFinder(dbClient), userSession, definitions, settingsFinder, new SettingsPermissionPredicates(userSession))); | |||
private WsActionTester ws = new WsActionTester( | |||
new ValuesAction(dbClient, new ComponentFinder(dbClient), userSession, definitions, settingsFinder, new SettingsPermissionPredicates(userSession), scannerSettings)); | |||
@Before | |||
public void setUp() throws Exception { | |||
PluginInfo pluginInfo = mock(PluginInfo.class); | |||
when(pluginInfo.getKey()).thenReturn("plugin"); | |||
when(repository.getPluginInfos()).thenReturn(singletonList(pluginInfo)); | |||
scannerSettings.start(); | |||
project = componentDb.insertComponent(newProjectDto()); | |||
} | |||
@@ -501,11 +512,11 @@ public class ValuesActionTest { | |||
newGlobalPropertyDto().setKey("secret.secured").setValue("password"), | |||
newGlobalPropertyDto().setKey("commercial.plugin").setValue("ABCD"), | |||
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"), | |||
newGlobalPropertyDto().setKey("plugin.licenseHash.secured").setValue("987654321")); | |||
newGlobalPropertyDto().setKey("sonar.plugin.licenseHash.secured").setValue("987654321")); | |||
ValuesWsResponse result = executeRequestForGlobalProperties(); | |||
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "commercial.plugin", "plugin.license.secured", "plugin.licenseHash.secured"); | |||
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "commercial.plugin", "plugin.license.secured", "sonar.plugin.licenseHash.secured"); | |||
} | |||
@Test | |||
@@ -521,11 +532,12 @@ public class ValuesActionTest { | |||
newGlobalPropertyDto().setKey("secret.secured").setValue("password"), | |||
newGlobalPropertyDto().setKey("commercial.plugin").setValue("ABCD"), | |||
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"), | |||
newGlobalPropertyDto().setKey("plugin.licenseHash.secured").setValue("987654321")); | |||
newGlobalPropertyDto().setKey("sonar.plugin.licenseHash.secured").setValue("987654321")); | |||
ValuesWsResponse result = executeRequestForGlobalProperties(); | |||
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "secret.secured", "commercial.plugin", "plugin.license.secured", "plugin.licenseHash.secured"); | |||
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "secret.secured", "commercial.plugin", "plugin.license.secured", | |||
"sonar.plugin.licenseHash.secured"); | |||
} | |||
@Test | |||
@@ -539,11 +551,11 @@ public class ValuesActionTest { | |||
newGlobalPropertyDto().setKey("foo").setValue("one"), | |||
newGlobalPropertyDto().setKey("secret.secured").setValue("password"), | |||
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"), | |||
newGlobalPropertyDto().setKey("plugin.licenseHash.secured").setValue("987654321")); | |||
newGlobalPropertyDto().setKey("sonar.plugin.licenseHash.secured").setValue("987654321")); | |||
ValuesWsResponse result = executeRequestForGlobalProperties(); | |||
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "secret.secured", "plugin.license.secured", "plugin.licenseHash.secured"); | |||
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "secret.secured", "plugin.license.secured", "sonar.plugin.licenseHash.secured"); | |||
} | |||
@Test | |||
@@ -557,11 +569,11 @@ public class ValuesActionTest { | |||
newComponentPropertyDto(project).setKey("foo").setValue("one"), | |||
newComponentPropertyDto(project).setKey("secret.secured").setValue("password"), | |||
newComponentPropertyDto(project).setKey("plugin.license.secured").setValue("ABCD"), | |||
newComponentPropertyDto(project).setKey("plugin.licenseHash.secured").setValue("987654321")); | |||
newComponentPropertyDto(project).setKey("sonar.plugin.licenseHash.secured").setValue("987654321")); | |||
ValuesWsResponse result = executeRequestForProjectProperties(); | |||
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "secret.secured", "plugin.license.secured", "plugin.licenseHash.secured"); | |||
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "secret.secured", "plugin.license.secured", "sonar.plugin.licenseHash.secured"); | |||
} | |||
@Test | |||
@@ -625,12 +637,12 @@ public class ValuesActionTest { | |||
newGlobalPropertyDto().setKey("sonar.core.id").setValue("ID"), | |||
newGlobalPropertyDto().setKey("sonar.core.startTime").setValue("2017-01-01"), | |||
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"), | |||
newGlobalPropertyDto().setKey("plugin.licenseHash.secured").setValue("987654321")); | |||
newGlobalPropertyDto().setKey("sonar.plugin.licenseHash.secured").setValue("987654321")); | |||
ValuesWsResponse result = executeRequestForGlobalProperties(); | |||
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("sonar.server_id", "sonar.core.id", "sonar.core.startTime", "plugin.license.secured", | |||
"plugin.licenseHash.secured"); | |||
"sonar.plugin.licenseHash.secured"); | |||
} | |||
@Test |