diff options
author | Daniel Schwarz <bartfastiel@users.noreply.github.com> | 2017-10-25 18:08:20 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2017-10-26 02:08:20 +1000 |
commit | a27abe36c63f21ed0e8c4b5adf05c36187da7f4a (patch) | |
tree | 66c580feffa803823254d4b251567ca62570f505 | |
parent | 0aa52a10e3957c281e2cabb8ef42b70b490af12a (diff) | |
download | sonarqube-a27abe36c63f21ed0e8c4b5adf05c36187da7f4a.tar.gz sonarqube-a27abe36c63f21ed0e8c4b5adf05c36187da7f4a.zip |
SONAR-7992 Restrict length of version names
* SONAR-7992 Restrict length of name in api/project_analyses/update_event
to 100 characters
* SONAR-7992 Restrict length of version name of an analysis
* SONAR-7992 Restrict length of version name of SnapshotDto
* SONAR-7992 Include the module's name in the validation error message
6 files changed, 86 insertions, 7 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDto.java index e326b4da511..1dfec6f1b93 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDto.java @@ -22,6 +22,8 @@ package org.sonar.db.component; import javax.annotation.CheckForNull; import javax.annotation.Nullable; +import static com.google.common.base.Preconditions.checkArgument; + public final class SnapshotDto { /** @@ -29,6 +31,7 @@ public final class SnapshotDto { */ public static final String STATUS_UNPROCESSED = "U"; public static final String STATUS_PROCESSED = "P"; + public static final int MAX_VERSION_LENGTH = 100; private Long id; private String uuid; @@ -116,6 +119,10 @@ public final class SnapshotDto { } public SnapshotDto setVersion(@Nullable String version) { + if (version != null) { + checkArgument(version.length() <= MAX_VERSION_LENGTH, + "Event name length (%s) is longer than the maximum authorized (%s). '%s' was provided.", version.length(), MAX_VERSION_LENGTH, version); + } this.version = version; return this; } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/SnapshotDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/SnapshotDtoTest.java index 4b8dd3e26af..5cbed4b6e3d 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/SnapshotDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/SnapshotDtoTest.java @@ -19,13 +19,19 @@ */ package org.sonar.db.component; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import static org.apache.commons.lang.StringUtils.repeat; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.utils.DateUtils.parseDate; public class SnapshotDtoTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Test public void test_getter_and_setter() throws Exception { SnapshotDto snapshotDto = new SnapshotDto() @@ -48,4 +54,17 @@ public class SnapshotDtoTest { assertThat(snapshotDto.getPeriodDate()).isEqualTo(parseDate("2014-06-01").getTime()); } + @Test + public void fail_if_version_name_is_longer_then_100_characters() throws Exception { + SnapshotDto snapshotDto = new SnapshotDto(); + snapshotDto.setVersion(null); + snapshotDto.setVersion("1.0"); + snapshotDto.setVersion(repeat("a", 100)); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Event name length (101) is longer than the maximum authorized (100). " + + "'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' was provided."); + + snapshotDto.setVersion(repeat("a", 101)); + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java index 75ac36478dc..488d39d6d5f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java @@ -52,6 +52,7 @@ import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameter import static org.sonarqube.ws.client.projectanalysis.ProjectAnalysesWsParameters.PARAM_NAME; public class UpdateEventAction implements ProjectAnalysesWsAction { + private static final int MAX_NAME_LENGTH = 100; private final DbClient dbClient; private final UserSession userSession; @@ -100,6 +101,7 @@ public class UpdateEventAction implements ProjectAnalysesWsAction { .of(getDbEvent(dbSession, request)) .peek(checkPermissions()) .peek(checkModifiable()) + .peek(checkVersionNameLength(request)) .map(updateNameAndDescription(request)) .peek(checkNonConflictingOtherEvents(dbSession)) .peek(updateInDb(dbSession)) @@ -146,6 +148,16 @@ public class UpdateEventAction implements ProjectAnalysesWsAction { }; } + private static Consumer<EventDto> checkVersionNameLength(UpdateEventRequest request) { + String name = request.getName(); + return candidateEvent -> { + if (name != null && VERSION.getLabel().equals(candidateEvent.getCategory())) { + checkArgument(name.length() <= MAX_NAME_LENGTH, + "Version length (%s) is longer than the maximum authorized (%s). '%s' was provided.", name.length(), MAX_NAME_LENGTH, name); + } + }; + } + private SnapshotDto getAnalysis(DbSession dbSession, EventDto event) { return dbClient.snapshotDao().selectByUuid(dbSession, event.getAnalysisUuid()) .orElseThrow(() -> new IllegalStateException(format("Analysis '%s' is not found", event.getAnalysisUuid()))); diff --git a/server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/UpdateEventActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/UpdateEventActionTest.java index bae882ed3c1..48d788a1406 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/UpdateEventActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/projectanalysis/ws/UpdateEventActionTest.java @@ -41,6 +41,7 @@ import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.ProjectAnalyses; import org.sonarqube.ws.ProjectAnalyses.UpdateEventResponse; +import static org.apache.commons.lang.StringUtils.repeat; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.core.util.Protobuf.setNullable; import static org.sonar.db.component.SnapshotTesting.newAnalysis; @@ -223,6 +224,22 @@ public class UpdateEventActionTest { call("E2", "E1 name"); } + @Test + public void limit_version_name_length_to_100_for_analysis_events() { + SnapshotDto analysis = createAnalysisAndLogInAsProjectAdministrator("5.6"); + db.events().insertEvent(newEvent(analysis).setUuid("E1").setCategory(OTHER.getLabel()).setName("E1 name")); + db.events().insertEvent(newEvent(analysis).setUuid("E2").setCategory(VERSION.getLabel()).setName("E2 name")); + + call("E1", repeat("a", 100)); + call("E1", repeat("a", 101)); + call("E2", repeat("a", 100)); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Version length (101) is longer than the maximum authorized (100). 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' was provided"); + + call("E2", repeat("a", 101)); + } + private UpdateEventResponse call(@Nullable String eventUuid, @Nullable String name) { TestRequest request = ws.newRequest() .setMethod(POST.name()); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java index e9b5a5bd054..f91f4067fd5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java @@ -104,6 +104,11 @@ public class ProjectReactorValidator { validationMessages.add(String.format("\"%s\" is not a valid project or module key. " + "Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", moduleDef.getKey())); } + String originalVersion = moduleDef.getOriginalVersion(); + if (originalVersion != null && originalVersion.length() > 100) { + validationMessages.add(String.format("\"%s\" is not a valid version name for module \"%s\". " + + "The maximum length for version numbers is 100 characters.", originalVersion, moduleDef.getKey())); + } } private static void validateBranch(List<String> validationMessages, @Nullable String branch) { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java index 9a3c0a86158..dbfafbe23f4 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java @@ -19,6 +19,8 @@ */ package org.sonar.scanner.scan; +import java.util.Arrays; +import java.util.function.Consumer; import java.util.Optional; import org.junit.Before; import org.junit.Rule; @@ -32,6 +34,7 @@ import org.sonar.api.utils.MessageException; import org.sonar.core.config.ScannerProperties; import org.sonar.scanner.bootstrap.GlobalConfiguration; +import static org.apache.commons.lang.StringUtils.repeat; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; @@ -187,17 +190,33 @@ public class ProjectReactorValidatorTest { validator.validate(reactor); } - private ProjectReactor createProjectReactor(String projectKey) { - ProjectDefinition def = ProjectDefinition.create().setProperty(CoreProperties.PROJECT_KEY_PROPERTY, projectKey); - ProjectReactor reactor = new ProjectReactor(def); - return reactor; + @Test + public void not_fail_with_valid_version() { + validator.validate(createProjectReactor("foo", def -> def.setVersion("1.0"))); + validator.validate(createProjectReactor("foo", def -> def.setVersion("2017-10-16"))); + validator.validate(createProjectReactor("foo", def -> def.setVersion(repeat("a", 100)))); + } + + @Test + public void fail_with_too_long_version() { + ProjectReactor reactor = createProjectReactor("foo", def -> def.setVersion(repeat("a", 101))); + + thrown.expect(MessageException.class); + thrown.expectMessage("\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" is not a valid version name for module \"foo\". " + + "The maximum length for version numbers is 100 characters."); + + validator.validate(reactor); } private ProjectReactor createProjectReactor(String projectKey, String branch) { + return createProjectReactor(projectKey, def -> def + .setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, branch)); + } + + private ProjectReactor createProjectReactor(String projectKey, Consumer<ProjectDefinition>... consumers) { ProjectDefinition def = ProjectDefinition.create() - .setProperty(CoreProperties.PROJECT_KEY_PROPERTY, projectKey) - .setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, branch); + .setProperty(CoreProperties.PROJECT_KEY_PROPERTY, projectKey); + Arrays.stream(consumers).forEach(c -> c.accept(def)); return new ProjectReactor(def); } - } |