.description("Forcing user authentication stops un-logged users to access SonarQube.")
.type(PropertyType.BOOLEAN)
.category(CoreProperties.CATEGORY_SECURITY)
+ .build(),
+
+ PropertyDefinition.builder(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION)
+ .defaultValue(Boolean.toString(false))
+ .name("Prevent automatic project creation")
+ .description("Set to true to prevent automatic project creation at first analysis and force project provisioning.")
+ .type(PropertyType.BOOLEAN)
+ .category(CoreProperties.CATEGORY_SECURITY)
.build()
- );
+ );
}
}
package org.sonar.batch.scan;
import org.sonar.api.batch.bootstrap.ProjectBuilder;
-import org.sonar.api.batch.bootstrap.internal.ProjectBuilderContext;
import org.sonar.api.batch.bootstrap.ProjectReactor;
-import org.sonar.api.config.Settings;
+import org.sonar.api.batch.bootstrap.internal.ProjectBuilderContext;
import javax.annotation.Nullable;
public class ProjectReactorReady {
private final ProjectReactor reactor;
- private final Settings settings;
private ProjectBuilder[] projectBuilders;
private ProjectExclusions exclusions;
+ private ProjectReactorValidator validator;
- public ProjectReactorReady(ProjectExclusions exclusions, ProjectReactor reactor, Settings settings, @Nullable ProjectBuilder[] projectBuilders) {
+ public ProjectReactorReady(ProjectExclusions exclusions, ProjectReactor reactor, @Nullable ProjectBuilder[] projectBuilders, ProjectReactorValidator validator) {
this.exclusions = exclusions;
this.reactor = reactor;
- this.settings = settings;
this.projectBuilders = projectBuilders;
+ this.validator = validator;
}
- public ProjectReactorReady(ProjectExclusions exclusions, ProjectReactor reactor, Settings settings) {
- this(exclusions, reactor, settings, new ProjectBuilder[0]);
+ public ProjectReactorReady(ProjectExclusions exclusions, ProjectReactor reactor, ProjectReactorValidator validator) {
+ this(exclusions, reactor, new ProjectBuilder[0], validator);
}
public void start() {
exclusions.apply();
// 3 Validate final reactor
- ProjectReactorValidator validator = new ProjectReactorValidator(settings);
validator.validate(reactor);
}
}
*/
package org.sonar.batch.scan;
+import org.sonar.core.resource.ResourceDao;
import com.google.common.base.Joiner;
import org.apache.commons.lang.math.NumberUtils;
import org.codehaus.plexus.util.StringUtils;
private static final String VALID_MODULE_KEY_REGEXP = "[0-9a-zA-Z\\-_\\.:]+";
private final Settings settings;
+ private final ResourceDao resourceDao;
- public ProjectReactorValidator(Settings settings) {
+ public ProjectReactorValidator(Settings settings, ResourceDao resourceDao) {
this.settings = settings;
+ this.resourceDao = resourceDao;
}
public void validate(ProjectReactor reactor) {
+ if (settings.getBoolean(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION)) {
+ String projectKey = reactor.getRoot().getKey();
+ if (resourceDao.findByKey(projectKey) == null) {
+ throw new SonarException("Unable to scan non-existing project " + projectKey);
+ }
+ }
+
List<String> validationMessages = new ArrayList<String>();
for (ProjectDefinition moduleDef : reactor.getProjects()) {
validateModule(moduleDef, validationMessages);
new Phases().enable(Phases.Phase.values()),
DefaultProjectTree.class,
ProjectExclusions.class,
+ ProjectReactorValidator.class,
ProjectReactorReady.class,
DefaultProfileLoader.class,
DefaultSensorMatcher.class);
import org.junit.Test;
import org.sonar.api.batch.bootstrap.ProjectBuilder;
import org.sonar.api.batch.bootstrap.ProjectReactor;
-import org.sonar.api.config.Settings;
import static org.mockito.Mockito.mock;
@Test
public void should_do_nothing() {
// it's only a barrier
- ProjectReactorReady barrier = new ProjectReactorReady(mock(ProjectExclusions.class), mock(ProjectReactor.class), new Settings(),
- new ProjectBuilder[] {mock(ProjectBuilder.class)});
+ ProjectReactorReady barrier = new ProjectReactorReady(mock(ProjectExclusions.class), mock(ProjectReactor.class),
+ new ProjectBuilder[] {mock(ProjectBuilder.class)}, mock(ProjectReactorValidator.class));
barrier.start();
}
@Test
public void project_builders_should_be_optional() {
- ProjectReactorReady barrier = new ProjectReactorReady(mock(ProjectExclusions.class), mock(ProjectReactor.class), new Settings());
+ ProjectReactorReady barrier = new ProjectReactorReady(mock(ProjectExclusions.class), mock(ProjectReactor.class), mock(ProjectReactorValidator.class));
barrier.start();
}
}
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.sonar.api.component.Component;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.SonarException;
+import org.sonar.core.resource.ResourceDao;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class ProjectReactorValidatorTest {
private ProjectReactorValidator validator;
private Settings settings;
+ private ResourceDao resourceDao;
@Before
public void prepare() {
settings = new Settings();
- validator = new ProjectReactorValidator(settings);
+ resourceDao = mock(ResourceDao.class);
+ validator = new ProjectReactorValidator(settings, resourceDao);
+ }
+
+ @Test
+ public void not_fail_if_prosivioning_enforced_and_project_exists() throws Exception {
+ String key = "project-key";
+ settings.setProperty(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION, true);
+ when(resourceDao.findByKey(key)).thenReturn(mock(Component.class));
+ ProjectReactor reactor = createProjectReactor(key);
+ validator.validate(reactor);
+ }
+
+ @Test(expected = SonarException.class)
+ public void fail_if_prosivioning_enforced_and_project_not_provisioned() throws Exception {
+ String key = "project-key";
+ settings.setProperty(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION, true);
+ when(resourceDao.findByKey(key)).thenReturn(null);
+ ProjectReactor reactor = createProjectReactor(key);
+ validator.validate(reactor);
}
@Test
*/
package org.sonar.batch.scan;
+import org.sonar.core.resource.ResourceDao;
+
import org.junit.Test;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.batch.ProjectConfigurator;
import org.sonar.batch.bootstrap.TaskContainer;
import org.sonar.batch.phases.Phases;
-
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;
public void should_enable_all_phases() {
ScanTask task = new ScanTask(mock(TaskContainer.class));
ComponentContainer projectScanContainer = new ComponentContainer();
- projectScanContainer.add(mock(ProjectConfigurator.class), mock(ProjectReactor.class), mock(Settings.class), mock(ProjectSettingsReady.class));
+ projectScanContainer.add(mock(ProjectConfigurator.class), mock(ProjectReactor.class), mock(Settings.class), mock(ProjectSettingsReady.class), mock(ResourceDao.class));
task.scan(projectScanContainer);
Phases phases = projectScanContainer.getComponentByType(Phases.class);
* @since 3.7
*/
String DRY_RUN_READ_TIMEOUT_SEC = "sonar.dryRun.readTimeout";
+
+ /**
+ * @since 4.0
+ */
+ String CORE_PREVENT_AUTOMATIC_PROJECT_CREATION = "sonar.preventAutoProjectCreation";
}