Browse Source

SONAR-9863 Do not return licenses hashed in api/settings/value

tags/6.7
Julien Lancelot 6 years ago
parent
commit
49c5faaf21

+ 0
- 6
server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java View File

@@ -36,11 +36,9 @@ import org.sonar.api.web.UserRole;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
import org.sonar.db.MyBatis;
import org.sonar.db.WildcardPosition;

import static com.google.common.base.Preconditions.checkArgument;
import static org.apache.commons.lang.StringUtils.repeat;
import static org.sonar.db.DaoDatabaseUtils.buildLikeValue;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
import static org.sonar.db.DatabaseUtils.executeLargeInputsWithoutOutput;

@@ -163,10 +161,6 @@ public class PropertiesDao implements Dao {
return executeLargeInputs(componentIds, getMapper(session)::selectByComponentIds);
}

public List<PropertyDto> selectGlobalPropertiesByKeyQuery(DbSession session, String keyQuery) {
return getMapper(session).selectGlobalPropertiesByKeyQuery(buildLikeValue(keyQuery, WildcardPosition.BEFORE_AND_AFTER));
}

/**
* Saves the specified property and its value.
* <p>

+ 0
- 11
server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml View File

@@ -157,17 +157,6 @@
</where>
</select>

<select id="selectGlobalPropertiesByKeyQuery" resultType="ScrapProperty">
select
<include refid="columnsToScrapPropertyDto"/>
from
properties p
where
p.resource_id is null
and p.user_id is null
and p.prop_key like #{textQuery,jdbcType=VARCHAR}
</select>

<select id="selectIdsByOrganizationAndUser" parameterType="map" resultType="long">
select py.id
from properties py

+ 0
- 18
server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java View File

@@ -436,24 +436,6 @@ public class PropertiesDaoTest {
assertThat(underTest.selectPropertiesByKeysAndComponentIds(session, newHashSet("unknown"), newHashSet(123456789L))).isEmpty();
}

@Test
public void select_global_properties_by_key_query() throws SQLException {
// global
insertProperty("sonar.plugin1.licenseHash.secured", "one", null, null);
insertProperty("sonar.plugin2.licenseHash.secured", "two", null, null);
// on component and user
insertProperty("sonar.plugin1.licenseHash.secure", "one", 10L, null);
insertProperty("sonar.plugin1.licenseHash.secure", "two", 10L, 100);

assertThat(underTest.selectGlobalPropertiesByKeyQuery(dbTester.getSession(), ".licenseHash.secured")).extracting(PropertyDto::getKey, PropertyDto::getValue)
.containsOnly(tuple("sonar.plugin1.licenseHash.secured", "one"), tuple("sonar.plugin2.licenseHash.secured", "two"));
assertThat(underTest.selectGlobalPropertiesByKeyQuery(dbTester.getSession(), "plugin1.licenseHash.secured")).extracting(PropertyDto::getKey, PropertyDto::getValue)
.containsOnly(tuple("sonar.plugin1.licenseHash.secured", "one"));
assertThat(underTest.selectGlobalPropertiesByKeyQuery(dbTester.getSession(), "plugin1")).extracting(PropertyDto::getKey, PropertyDto::getValue)
.containsOnly(tuple("sonar.plugin1.licenseHash.secured", "one"));
assertThat(underTest.selectGlobalPropertiesByKeyQuery(dbTester.getSession(), "unknown")).isEmpty();
}

@Test
public void saveProperty_inserts_global_properties_when_they_do_not_exist_in_db() {
when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5);

+ 0
- 69
server/sonar-server/src/main/java/org/sonar/server/setting/ws/ScannerSettings.java View File

@@ -1,69 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2017 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.server.setting.ws;

import com.google.common.collect.ImmutableSet;
import java.util.Set;
import java.util.stream.Stream;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.property.PropertyDto;

import static java.util.stream.Collectors.toSet;
import static java.util.stream.Stream.concat;
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.SettingsWsSupport.LICENSE_HASH_SUFFIX;

/**
* This class returns the list of settings required on scanner side (licenses, license hashes, server ids, etc.)
*/
public class ScannerSettings {

private static final Set<String> SERVER_SETTING_KEYS = ImmutableSet.of(SERVER_STARTTIME, SERVER_ID);

private final DbClient dbClient;
private final PropertyDefinitions propertyDefinitions;

public ScannerSettings(DbClient dbClient, PropertyDefinitions propertyDefinitions) {
this.dbClient = dbClient;
this.propertyDefinitions = propertyDefinitions;
}

Set<String> getScannerSettingKeys(DbSession dbSession) {
return concat(concat(loadLicenseKeys(), loadLicenseHashKeys(dbSession)),
SERVER_SETTING_KEYS.stream()).collect(toSet());
}

private Stream<String> loadLicenseHashKeys(DbSession dbSession) {
return dbClient.propertiesDao().selectGlobalPropertiesByKeyQuery(dbSession, LICENSE_HASH_SUFFIX).stream().map(PropertyDto::getKey);
}

private Stream<String> loadLicenseKeys() {
return propertyDefinitions.getAll()
.stream()
.filter(setting -> setting.type().equals(LICENSE))
.map(PropertyDefinition::key);
}

}

+ 1
- 2
server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingsWsModule.java View File

@@ -36,7 +36,6 @@ public class SettingsWsModule extends Module {
GenerateSecretKeyAction.class,
CheckSecretKeyAction.class,
SettingsUpdater.class,
SettingValidations.class,
ScannerSettings.class);
SettingValidations.class);
}
}

+ 1
- 1
server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingsWsSupport.java View File

@@ -46,7 +46,7 @@ public class SettingsWsSupport {
public static final String DOT_SECURED = ".secured";
public static final String DOT_LICENSE = ".license";
private static final String LICENSE_SUFFIX = DOT_LICENSE + DOT_SECURED;
static final String LICENSE_HASH_SUFFIX = ".licenseHash" + DOT_SECURED;
private static final String LICENSE_HASH_SUFFIX = ".licenseHash" + DOT_SECURED;

private final DefaultOrganizationProvider defaultOrganizationProvider;
private final UserSession userSession;

+ 9
- 10
server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java View File

@@ -20,9 +20,9 @@
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;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -47,6 +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.SERVER_ID;
import static org.sonar.api.CoreProperties.SERVER_STARTTIME;
import static org.sonar.api.PropertyType.PROPERTY_SET;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
@@ -61,6 +63,7 @@ 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> SERVER_SETTING_KEYS = ImmutableSet.of(SERVER_STARTTIME, SERVER_ID);

private final DbClient dbClient;
private final ComponentFinder componentFinder;
@@ -68,17 +71,15 @@ public class ValuesAction implements SettingsWsAction {
private final PropertyDefinitions propertyDefinitions;
private final SettingsFinder settingsFinder;
private final SettingsWsSupport settingsWsSupport;
private final ScannerSettings scannerSettings;

public ValuesAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, PropertyDefinitions propertyDefinitions, SettingsFinder settingsFinder,
SettingsWsSupport settingsWsSupport, ScannerSettings scannerSettings) {
SettingsWsSupport settingsWsSupport) {
this.dbClient = dbClient;
this.componentFinder = componentFinder;
this.userSession = userSession;
this.propertyDefinitions = propertyDefinitions;
this.settingsFinder = settingsFinder;
this.settingsWsSupport = settingsWsSupport;
this.scannerSettings = scannerSettings;
}

@Override
@@ -120,7 +121,7 @@ public class ValuesAction implements SettingsWsAction {
ValuesRequest valuesRequest = toWsRequest(request);
Optional<ComponentDto> component = loadComponent(dbSession, valuesRequest);

Set<String> keys = loadKeys(dbSession, valuesRequest);
Set<String> keys = loadKeys(valuesRequest);
Map<String, String> keysToDisplayMap = getKeysToDisplayMap(keys);
List<Setting> settings = loadSettings(dbSession, component, keysToDisplayMap.keySet());
return new ValuesResponseBuilder(settings, component, keysToDisplayMap).build();
@@ -137,12 +138,10 @@ public class ValuesAction implements SettingsWsAction {
return builder.build();
}

private Set<String> loadKeys(DbSession dbSession, ValuesRequest valuesRequest) {
private Set<String> loadKeys(ValuesRequest valuesRequest) {
List<String> keys = valuesRequest.getKeys();
if (keys.isEmpty()) {
return concat(propertyDefinitions.getAll().stream().map(PropertyDefinition::key), scannerSettings.getScannerSettingKeys(dbSession).stream()).collect(Collectors.toSet());
}
return new HashSet<>(keys);
return keys.isEmpty() ? concat(propertyDefinitions.getAll().stream().map(PropertyDefinition::key), SERVER_SETTING_KEYS.stream()).collect(Collectors.toSet())
: ImmutableSet.copyOf(keys);
}

private Optional<ComponentDto> loadComponent(DbSession dbSession, ValuesRequest valuesRequest) {

+ 0
- 67
server/sonar-server/src/test/java/org/sonar/server/setting/ws/ScannerSettingsTest.java View File

@@ -1,67 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2017 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.server.setting.ws;

import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.PropertyType.LICENSE;
import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto;

public class ScannerSettingsTest {

@Rule
public DbTester db = DbTester.create(System2.INSTANCE);

private PropertyDefinitions definitions = new PropertyDefinitions();

private ScannerSettings underTest = new ScannerSettings(db.getDbClient(), definitions);

@Test
public void return_license_keys() throws Exception {
definitions.addComponents(asList(
PropertyDefinition.builder("foo").build(),
PropertyDefinition.builder("myplugin.license.secured").type(LICENSE).build()));

assertThat(underTest.getScannerSettingKeys(db.getSession())).contains("myplugin.license.secured");
}

@Test
public void return_license_hash_keys() throws Exception {
db.properties().insertProperty(newGlobalPropertyDto("sonar.myplugin.licenseHash.secured", "hash"));

assertThat(underTest.getScannerSettingKeys(db.getSession())).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()));

assertThat(underTest.getScannerSettingKeys(db.getSession())).contains("sonar.core.id", "sonar.core.startTime");
}
}

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/setting/ws/SettingsWsModuleTest.java View File

@@ -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(13 + 2);
assertThat(container.size()).isEqualTo(12 + 2);
}
}

+ 16
- 29
server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java View File

@@ -88,13 +88,12 @@ public class ValuesActionTest {
private ComponentDbTester componentDb = new ComponentDbTester(db);
private PropertyDefinitions definitions = new PropertyDefinitions();
private SettingsFinder settingsFinder = new SettingsFinder(dbClient, definitions);
private ScannerSettings scannerSettings = new ScannerSettings(db.getDbClient(), definitions);
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private SettingsWsSupport support = new SettingsWsSupport(defaultOrganizationProvider, userSession);
private ComponentDto project;

private WsActionTester ws = new WsActionTester(
new ValuesAction(dbClient, TestComponentFinder.from(db), userSession, definitions, settingsFinder, support, scannerSettings));
new ValuesAction(dbClient, TestComponentFinder.from(db), userSession, definitions, settingsFinder, support));

@Before
public void setUp() throws Exception {
@@ -518,7 +517,7 @@ public class ValuesActionTest {
}

@Test
public void return_license_with_hash_settings_when_authenticated_but_not_admin() throws Exception {
public void return_license_settings_when_authenticated_but_not_admin() throws Exception {
logIn();
definitions.addComponents(asList(
PropertyDefinition.builder("foo").build(),
@@ -529,13 +528,11 @@ public class ValuesActionTest {
newGlobalPropertyDto().setKey("foo").setValue("one"),
newGlobalPropertyDto().setKey("secret.secured").setValue("password"),
newGlobalPropertyDto().setKey("commercial.plugin").setValue("ABCD"),
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"),
newGlobalPropertyDto().setKey("sonar.plugin.licenseHash.secured").setValue("987654321"));
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"));

ValuesWsResponse result = executeRequestForGlobalProperties();

assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "commercial.plugin", "plugin.license.secured",
"sonar.plugin.licenseHash.secured");
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "commercial.plugin", "plugin.license.secured");
}

@Test
@@ -550,13 +547,11 @@ public class ValuesActionTest {
newGlobalPropertyDto().setKey("foo").setValue("one"),
newGlobalPropertyDto().setKey("secret.secured").setValue("password"),
newGlobalPropertyDto().setKey("commercial.plugin").setValue("ABCD"),
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"),
newGlobalPropertyDto().setKey("sonar.plugin.licenseHash.secured").setValue("987654321"));
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"));

ValuesWsResponse result = executeRequestForGlobalProperties();

assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "secret.secured", "commercial.plugin", "plugin.license.secured",
"sonar.plugin.licenseHash.secured");
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "secret.secured", "commercial.plugin", "plugin.license.secured");
}

@Test
@@ -575,13 +570,12 @@ public class ValuesActionTest {
newGlobalPropertyDto().setKey("global.secret.secured").setValue("very secret"),
newComponentPropertyDto(project).setKey("secret.secured").setValue("password"),
newComponentPropertyDto(project).setKey("commercial.plugin").setValue("ABCD"),
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"),
newGlobalPropertyDto().setKey("sonar.plugin.licenseHash.secured").setValue("987654321"));
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"));

ValuesWsResponse result = executeRequestForProjectProperties();

assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "global.secret.secured", "secret.secured", "commercial.plugin",
"plugin.license.secured", "sonar.plugin.licenseHash.secured");
"plugin.license.secured");
}

@Test
@@ -606,12 +600,11 @@ public class ValuesActionTest {
propertyDb.insertProperties(
newGlobalPropertyDto().setKey("foo").setValue("one"),
newGlobalPropertyDto().setKey("secret.secured").setValue("password"),
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"),
newGlobalPropertyDto().setKey("sonar.plugin.licenseHash.secured").setValue("987654321"));
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"));

ValuesWsResponse result = executeRequestForGlobalProperties();

assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "secret.secured", "plugin.license.secured", "sonar.plugin.licenseHash.secured");
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "secret.secured", "plugin.license.secured");
}

@Test
@@ -626,13 +619,11 @@ public class ValuesActionTest {
newComponentPropertyDto(project).setKey("foo").setValue("one"),
newGlobalPropertyDto().setKey("global.secret.secured").setValue("very secret"),
newComponentPropertyDto(project).setKey("secret.secured").setValue("password"),
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"),
newGlobalPropertyDto().setKey("sonar.plugin.licenseHash.secured").setValue("987654321"));
newGlobalPropertyDto().setKey("plugin.license.secured").setValue("ABCD"));

ValuesWsResponse result = executeRequestForProjectProperties();

assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "global.secret.secured", "secret.secured", "plugin.license.secured",
"sonar.plugin.licenseHash.secured");
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("foo", "global.secret.secured", "secret.secured", "plugin.license.secured");
}

@Test
@@ -702,16 +693,12 @@ public class ValuesActionTest {
logInAsAdmin();
definitions.addComponent(PropertyDefinition.builder("plugin.license.secured").type(LICENSE).build());
propertyDb.insertProperties(
newGlobalPropertyDto().setKey("sonar.server_id").setValue("12345"),
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("sonar.plugin.licenseHash.secured").setValue("987654321"));
newGlobalPropertyDto().setKey("sonar.core.startTime").setValue("2017-01-01"));

ValuesWsResponse result = executeRequestForGlobalProperties();

assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("sonar.core.id", "sonar.core.startTime", "plugin.license.secured",
"sonar.plugin.licenseHash.secured");
assertThat(result.getSettingsList()).extracting(Settings.Setting::getKey).containsOnly("sonar.core.id", "sonar.core.startTime");
}

@Test
@@ -735,7 +722,7 @@ public class ValuesActionTest {
definitions.addComponent(PropertyDefinition.builder("sonar.leak.period").onQualifiers(PROJECT).build());
propertyDb.insertProperties(newComponentPropertyDto(branch).setKey("sonar.leak.period").setValue("two"));

ValuesWsResponse result = ws.newRequest()
ValuesWsResponse result = ws.newRequest()
.setParam("keys", "sonar.leak.period")
.setParam("component", branch.getKey())
.setParam("branch", branch.getBranch())
@@ -753,7 +740,7 @@ public class ValuesActionTest {
definitions.addComponent(PropertyDefinition.builder("sonar.leak.period").onQualifiers(PROJECT).build());
propertyDb.insertProperties(newComponentPropertyDto(project).setKey("sonar.leak.period").setValue("two"));

ValuesWsResponse result = ws.newRequest()
ValuesWsResponse result = ws.newRequest()
.setParam("keys", "sonar.leak.period")
.setParam("component", branch.getKey())
.setParam("branch", branch.getBranch())

Loading…
Cancel
Save