Browse Source

SONAR-15915 Validate project key against forbidden phrases

tags/9.6.0.59041
Jacek 1 year ago
parent
commit
71c6caf8e9

+ 10
- 0
server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/CreateAction.java View File

@@ -19,6 +19,7 @@
*/
package org.sonar.server.project.ws;

import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.server.ws.Change;
@@ -99,9 +100,18 @@ public class CreateAction implements ProjectsWsAction {
@Override
public void handle(Request request, Response response) throws Exception {
CreateRequest createRequest = toCreateRequest(request);
validate(createRequest);
writeProtobuf(doHandle(createRequest), request, response);
}

private static void validate(CreateRequest createRequest) {
Set<String> forbiddenNamePhrases = Set.of(":BRANCH:", ":PULLREQUEST:");
if (forbiddenNamePhrases.stream().anyMatch(createRequest.getProjectKey()::contains)) {
throw new IllegalArgumentException(String.format("Invalid project key. Project key must not contain following phrases [%s]",
String.join(", ", forbiddenNamePhrases)));
}
}

private CreateWsResponse doHandle(CreateRequest request) {
try (DbSession dbSession = dbClient.openSession(false)) {
userSession.checkPermission(PROVISION_PROJECTS);

+ 21
- 0
server/sonar-webserver-webapi/src/test/java/org/sonar/server/project/ws/CreateActionTest.java View File

@@ -91,6 +91,27 @@ public class CreateActionTest {
when(projectDefaultVisibility.get(any())).thenReturn(Visibility.PUBLIC);
}

@Test
public void fail_if_invalid_project_name() {
userSession.addPermission(PROVISION_PROJECTS);

var createRequestBRANCHinKey = CreateRequest.builder()
.setProjectKey("test:BRANCH:test")
.setName(DEFAULT_PROJECT_NAME)
.build();
assertThatThrownBy(() -> call(createRequestBRANCHinKey))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Invalid project key. Project key must not contain following phrases [:PULLREQUEST:, :BRANCH:]");

var createRequestPRinKey = CreateRequest.builder()
.setProjectKey("test:PULLREQUEST:test")
.setName(DEFAULT_PROJECT_NAME)
.build();
assertThatThrownBy(() -> call(createRequestPRinKey))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Invalid project key. Project key must not contain following phrases [:PULLREQUEST:, :BRANCH:]");
}

@Test
public void create_project() {
userSession.addPermission(PROVISION_PROJECTS);

+ 7
- 0
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java View File

@@ -20,7 +20,9 @@
package org.sonar.scanner.scan;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
@@ -102,6 +104,11 @@ public class ProjectReactorValidator {
if (!ComponentKeys.isValidProjectKey(projectDefinition.getKey())) {
validationMessages.add(format("\"%s\" is not a valid project key. %s.", projectDefinition.getKey(), ALLOWED_CHARACTERS_MESSAGE));
}
Set<String> forbiddenNamePhrases = Set.of(":BRANCH:", ":PULLREQUEST:");
if (forbiddenNamePhrases.stream().anyMatch(projectDefinition.getKey()::contains)) {
validationMessages.add(format("\"%s\" is not a valid project key. Project key must not contain following phrases [%s]", projectDefinition.getKey(),
String.join(", ", forbiddenNamePhrases)));
}
}

private boolean isBranchFeatureAvailable() {

+ 18
- 1
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java View File

@@ -87,7 +87,7 @@ public class ProjectReactorValidatorTest {
}

@Test
public void failg_when_invalid_key() {
public void fail_when_invalid_key() {
ProjectReactor reactor = createProjectReactor("foo$bar");

assertThatThrownBy(() -> underTest.validate(reactor))
@@ -96,6 +96,23 @@ public class ProjectReactorValidatorTest {
+ " '-', '_', '.' and ':', with at least one non-digit.");
}

@Test
public void fail_when_key_contains_invalid_phrases() {
ProjectReactor reactorWithBranchInKey = createProjectReactor("test:BRANCH:test");

assertThatThrownBy(() -> underTest.validate(reactorWithBranchInKey))
.isInstanceOf(MessageException.class)
.hasMessageContainingAll("\"test:BRANCH:test\" is not a valid project key. "
+ "Project key must not contain following phrases", ":BRANCH:", ":PULLREQUEST:");

ProjectReactor reactorWithPRinKey = createProjectReactor("test:PULLREQUEST:test");

assertThatThrownBy(() -> underTest.validate(reactorWithPRinKey))
.isInstanceOf(MessageException.class)
.hasMessageContainingAll("\"test:PULLREQUEST:test\" is not a valid project key. "
+ "Project key must not contain following phrases", ":BRANCH:", ":PULLREQUEST:");
}

@Test
public void fail_when_only_digits() {
ProjectReactor reactor = createProjectReactor("12345");

Loading…
Cancel
Save