ソースを参照

SONAR-14606 make consent required when startup with external plugins

tags/8.9.0.43852
Zipeng WU 3年前
コミット
8b518c6bcc

+ 73
- 0
server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/PluginConsentVerifier.java ファイルの表示

@@ -0,0 +1,73 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.plugins;

import java.util.Optional;

import org.picocontainer.Startable;
import org.sonar.core.extension.PluginRiskConsent;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.property.PropertyDto;

import static org.sonar.core.config.CorePropertyDefinitions.PLUGINS_RISK_CONSENT;
import static org.sonar.core.extension.PluginRiskConsent.NOT_ACCEPTED;
import static org.sonar.core.extension.PluginRiskConsent.REQUIRED;

public class PluginConsentVerifier implements Startable {
private final ServerPluginRepository pluginRepository;
private final DbClient dbClient;

public PluginConsentVerifier(ServerPluginRepository pluginRepository, DbClient dbClient) {
this.pluginRepository = pluginRepository;
this.dbClient = dbClient;
}

@Override
public void start() {
boolean hasExternalPlugins = pluginRepository.getPlugins().stream().anyMatch(plugin -> plugin.getType().equals(PluginType.EXTERNAL));
try (DbSession session = dbClient.openSession(false)) {
PropertyDto property = Optional.ofNullable(dbClient.propertiesDao().selectGlobalProperty(session, PLUGINS_RISK_CONSENT))
.orElse(defaultPluginRiskConsentProperty());
if (hasExternalPlugins && NOT_ACCEPTED == PluginRiskConsent.valueOf(property.getValue())) {
property.setValue(REQUIRED.name());
dbClient.propertiesDao().saveProperty(session, property);
session.commit();
} else if (!hasExternalPlugins && REQUIRED == PluginRiskConsent.valueOf(property.getValue())) {
property.setValue(NOT_ACCEPTED.name());
dbClient.propertiesDao().saveProperty(session, property);
session.commit();
}
}
}

private static PropertyDto defaultPluginRiskConsentProperty() {
PropertyDto property = new PropertyDto();
property.setKey(PLUGINS_RISK_CONSENT);
property.setValue(NOT_ACCEPTED.name());
return property;
}

@Override
public void stop() {
// Nothing to do
}

}

+ 138
- 0
server/sonar-webserver-api/src/test/java/org/sonar/server/plugins/PluginConsentVerifierTest.java ファイルの表示

@@ -0,0 +1,138 @@
/*
* SonarQube
* Copyright (C) 2009-2021 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.plugins;

import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.core.extension.PluginRiskConsent;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.property.PropertyDto;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.core.config.CorePropertyDefinitions.PLUGINS_RISK_CONSENT;
import static org.sonar.core.extension.PluginRiskConsent.ACCEPTED;
import static org.sonar.core.extension.PluginRiskConsent.NOT_ACCEPTED;
import static org.sonar.core.extension.PluginRiskConsent.REQUIRED;
import static org.sonar.server.plugins.PluginType.BUNDLED;
import static org.sonar.server.plugins.PluginType.EXTERNAL;

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

private DbClient dbClient = db.getDbClient();
private ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class);
private PluginConsentVerifier underTest = new PluginConsentVerifier(pluginRepository, dbClient);

@Test
public void require_consent_when_exist_external_plugins_and_not_accepted() {
setupExternalPluginConsent(NOT_ACCEPTED);
setupExternalPlugin();

underTest.start();

assertThat(dbClient.propertiesDao().selectGlobalProperty(PLUGINS_RISK_CONSENT))
.extracting(PropertyDto::getValue)
.isEqualTo(REQUIRED.name());
}

@Test
public void require_consent_when_exist_external_plugins_and_consent_property_not_exist() {
setupExternalPlugin();

underTest.start();

assertThat(dbClient.propertiesDao().selectGlobalProperty(PLUGINS_RISK_CONSENT))
.extracting(PropertyDto::getValue)
.isEqualTo(REQUIRED.name());
}

@Test
public void consent_does_not_change_when_value_is_accepted() {
setupExternalPluginConsent(ACCEPTED);
setupExternalPlugin();

underTest.start();

assertThat(dbClient.propertiesDao().selectGlobalProperty(PLUGINS_RISK_CONSENT))
.extracting(PropertyDto::getValue)
.isEqualTo(ACCEPTED.name());
}

@Test
public void consent_does_not_change_when_value_is_required() {
setupExternalPluginConsent(REQUIRED);
setupExternalPlugin();

underTest.start();

assertThat(dbClient.propertiesDao().selectGlobalProperty(PLUGINS_RISK_CONSENT))
.extracting(PropertyDto::getValue)
.isEqualTo(REQUIRED.name());
}

@Test
public void consent_should_be_not_accepted_when_there_is_no_external_plugin_and_never_been_accepted() {
setupExternalPluginConsent(REQUIRED);
setupBundledPlugin();

underTest.start();

assertThat(dbClient.propertiesDao().selectGlobalProperty(PLUGINS_RISK_CONSENT))
.extracting(PropertyDto::getValue)
.isEqualTo(NOT_ACCEPTED.name());
}

@Test
public void do_nothing_when_there_is_no_external_plugin() {
setupExternalPluginConsent(NOT_ACCEPTED);
setupBundledPlugin();

underTest.start();

assertThat(dbClient.propertiesDao().selectGlobalProperty(PLUGINS_RISK_CONSENT))
.extracting(PropertyDto::getValue)
.isEqualTo(NOT_ACCEPTED.name());
}

private void setupExternalPluginConsent(PluginRiskConsent pluginRiskConsent) {
dbClient.propertiesDao().saveProperty(new PropertyDto()
.setKey(PLUGINS_RISK_CONSENT)
.setValue(pluginRiskConsent.name()));
}

private void setupExternalPlugin() {
ServerPlugin plugin = mock(ServerPlugin.class);
when(plugin.getType()).thenReturn(EXTERNAL);
when(pluginRepository.getPlugins()).thenReturn(asList(plugin));
}

private void setupBundledPlugin() {
ServerPlugin plugin = mock(ServerPlugin.class);
when(plugin.getType()).thenReturn(BUNDLED);
when(pluginRepository.getPlugins()).thenReturn(asList(plugin));
}

}

+ 3
- 1
server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java ファイルの表示

@@ -28,6 +28,7 @@ import org.sonar.server.ce.queue.CeQueueCleaner;
import org.sonar.server.es.IndexerStartupTask;
import org.sonar.server.platform.ServerLifecycleNotifier;
import org.sonar.server.platform.web.RegisterServletFilters;
import org.sonar.server.plugins.PluginConsentVerifier;
import org.sonar.server.qualitygate.ProjectsInWarningDaemon;
import org.sonar.server.qualitygate.RegisterQualityGates;
import org.sonar.server.qualityprofile.BuiltInQProfileInsertImpl;
@@ -72,7 +73,8 @@ public class PlatformLevelStartup extends PlatformLevel {
RenameDeprecatedPropertyKeys.class,
CeQueueCleaner.class,
UpgradeSuggestionsCleaner.class,
DefaultAdminCredentialsVerifierImpl.class);
DefaultAdminCredentialsVerifierImpl.class,
PluginConsentVerifier.class);

// RegisterServletFilters makes the WebService engine of Level4 served by the MasterServletFilter, therefore it
// must be started after all the other startup tasks

読み込み中…
キャンセル
保存