aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenoît Gianinetti <benoit.gianinetti@sonarsource.com>2019-05-16 14:18:42 +0200
committerSonarTech <sonartech@sonarsource.com>2019-05-20 20:21:07 +0200
commitbf7776ff7da0661c5a966a869e7dae1760fce038 (patch)
treef3651d50fbc426694a6094cbd1fca1af644195cf
parent919604b531633e97a29964f4e4cf72bf1f058f78 (diff)
downloadsonarqube-bf7776ff7da0661c5a966a869e7dae1760fce038.tar.gz
sonarqube-bf7776ff7da0661c5a966a869e7dae1760fce038.zip
SONARCLOUD-628 Allow UTF-8 characters in project key
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java2
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java6
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkUpdateKeyActionTest.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java6
-rw-r--r--sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java36
-rw-r--r--sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java35
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java3
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java28
12 files changed, 55 insertions, 90 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java
index 84d686173c9..3b2802be577 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java
@@ -233,7 +233,7 @@ public class ComponentKeyUpdaterDao implements Dao {
private static void checkNewNameOfAllModules(Set<ResourceDto> modules, String stringToReplace, String replacementString, ComponentKeyUpdaterMapper mapper) {
for (ResourceDto module : modules) {
String newKey = computeNewKey(module.getKey(), stringToReplace, replacementString);
- checkArgument(isValidProjectKey(newKey), "Malformed key for '%s'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", newKey);
+ checkProjectKey(newKey);
if (mapper.countResourceByKey(newKey) > 0) {
throw new IllegalArgumentException("Impossible to update key: a component with key \"" + newKey + "\" already exists.");
}
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java
index d41c321949e..faf276cf947 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java
@@ -314,9 +314,9 @@ public class ComponentKeyUpdaterDaoTest {
ComponentDto project = db.components().insertPrivateProject();
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Malformed key for 'my?project?key'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
+ thrown.expectMessage("Malformed key for ' '. Project key cannot be empty nor contain whitespaces.");
- underTest.bulkUpdateKey(dbSession, project.uuid(), project.getDbKey(), "my?project?key", doNotReturnAnyRekeyedResource());
+ underTest.bulkUpdateKey(dbSession, project.uuid(), project.getDbKey(), " ", doNotReturnAnyRekeyedResource());
}
@Test
@@ -377,7 +377,7 @@ public class ComponentKeyUpdaterDaoTest {
thrown.expect(IllegalArgumentException.class);
- underTest.simulateBulkUpdateKey(dbSession, "A", "project", "project?");
+ underTest.simulateBulkUpdateKey(dbSession, "A", "project", " ");
}
@Test
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
index f72e0c6803c..2b25909072c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
@@ -102,7 +102,7 @@ public class ComponentService {
}
private static void checkProjectOrModuleKeyFormat(String key) {
- checkRequest(isValidProjectKey(key), "Malformed key for '%s'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", key);
+ checkRequest(isValidProjectKey(key), "Malformed key for '%s'. It cannot be empty nor contain whitespaces.", key);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java
index 974e4c9aafa..9a8db67b0a7 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java
@@ -163,8 +163,7 @@ public class ComponentUpdater {
}
private void checkKeyFormat(String qualifier, String key) {
- checkRequest(isValidProjectKey(key),
- "Malformed key for %s: %s. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", getQualifierToDisplay(qualifier), key);
+ checkRequest(isValidProjectKey(key), "Malformed key for %s: '%s'. It cannot be empty nor contain whitespaces.", getQualifierToDisplay(qualifier), key);
}
private void checkLegacyBranchFormat(String qualifier, @Nullable String branch) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java
index 706996052ab..66583ddfbf2 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java
@@ -153,20 +153,20 @@ public class ComponentServiceUpdateKeyTest {
logInAsProjectAdministrator(project);
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Malformed key for ''. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
+ expectedException.expectMessage("Malformed key for ''. It cannot be empty nor contain whitespaces.");
underTest.updateKey(dbSession, project, "");
}
@Test
- public void fail_if_new_key_is_not_formatted_correctly() {
+ public void fail_if_new_key_is_invalid() {
ComponentDto project = insertSampleRootProject();
logInAsProjectAdministrator(project);
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Malformed key for 'sample?root'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
+ expectedException.expectMessage("Malformed key for 'sample root'. It cannot be empty nor contain whitespaces.");
- underTest.updateKey(dbSession, project, "sample?root");
+ underTest.updateKey(dbSession, project, "sample root");
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java
index 6581277f23f..9739cfae408 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java
@@ -304,11 +304,11 @@ public class ComponentUpdaterTest {
@Test
public void fail_when_key_has_bad_format() {
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Malformed key for Project: 1234");
+ expectedException.expectMessage("Malformed key for Project: ' '");
underTest.create(db.getSession(),
NewComponent.newComponentBuilder()
- .setKey("1234")
+ .setKey(" ")
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build(),
@@ -318,11 +318,11 @@ public class ComponentUpdaterTest {
@Test
public void properly_fail_when_key_contains_percent_character() {
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Malformed key for Project: project%Key");
+ expectedException.expectMessage("Malformed key for Project: ' '");
underTest.create(db.getSession(),
NewComponent.newComponentBuilder()
- .setKey("project%Key")
+ .setKey(" ")
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build(),
diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkUpdateKeyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkUpdateKeyActionTest.java
index 726d87dbc73..aa3e20bf131 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkUpdateKeyActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkUpdateKeyActionTest.java
@@ -183,9 +183,9 @@ public class BulkUpdateKeyActionTest {
insertMyProject();
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Malformed key for 'my?project'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
+ expectedException.expectMessage("Malformed key for 'my aproject'. Project key cannot be empty nor contain whitespaces.");
- callByKey(MY_PROJECT_KEY, FROM, "my?");
+ callByKey(MY_PROJECT_KEY, FROM, "my a");
}
@Test
@@ -193,9 +193,9 @@ public class BulkUpdateKeyActionTest {
insertMyProject();
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Malformed key for 'my?project'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
+ expectedException.expectMessage("Malformed key for 'my aproject'. Project key cannot be empty nor contain whitespaces.");
- callDryRunByKey(MY_PROJECT_KEY, FROM, "my?");
+ callDryRunByKey(MY_PROJECT_KEY, FROM, "my a");
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
index 5be7889c667..ebae2a8d207 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
@@ -305,14 +305,14 @@ public class CreateActionTest {
}
@Test
- public void properly_fail_when_project_key_contains_percent_character() {
+ public void properly_fail_when_invalid_project_key() {
userSession.addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Malformed key for Project: project%Key. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
+ expectedException.expectMessage("Malformed key for Project: 'project Key'. It cannot be empty nor contain whitespaces.");
call(CreateRequest.builder()
- .setKey("project%Key")
+ .setKey("project Key")
.setName(DEFAULT_PROJECT_NAME)
.build());
}
diff --git a/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java b/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java
index a3bb4fb1453..e4d59ea1dd8 100644
--- a/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java
+++ b/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java
@@ -30,11 +30,12 @@ public final class ComponentKeys {
public static final int MAX_COMPONENT_KEY_LENGTH = 400;
/*
- * Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit
+ * Must not be blank or empty
*/
- private static final String VALID_PROJECT_KEY_REGEXP = "[\\p{Alnum}\\-_.:]*[\\p{Alpha}\\-_.:]+[\\p{Alnum}\\-_.:]*";
+ private static final String VALID_PROJECT_KEY_REGEXP = "[^\\p{javaWhitespace}]+";
private static final String VALID_PROJECT_KEY_ISSUES_MODE_REGEXP = "[\\p{Alnum}\\-_.:/]*[\\p{Alpha}\\-_.:/]+[\\p{Alnum}\\-_.:/]*";
+
/*
* Allowed characters are alphanumeric, '-', '_', '.' and '/'
*/
@@ -60,18 +61,7 @@ public final class ComponentKeys {
}
/**
- * <p>Test if given parameter is valid for a project. Valid format is:</p>
- * <ul>
- * <li>Allowed characters:
- * <ul>
- * <li>Uppercase ASCII letters A-Z</li>
- * <li>Lowercase ASCII letters a-z</li>
- * <li>ASCII digits 0-9</li>
- * <li>Punctuation signs dash '-', underscore '_', period '.' and colon ':'</li>
- * </ul>
- * </li>
- * <li>At least one non-digit</li>
- * </ul>
+ * Test if given parameter is valid for a project. A key is valid if it doesn't contain whitespaces.
*
* @return <code>true</code> if <code>keyCandidate</code> can be used for a project
*/
@@ -85,12 +75,24 @@ public final class ComponentKeys {
* @throws IllegalArgumentException if the format is incorrect
*/
public static void checkProjectKey(String keyCandidate) {
- checkArgument(isValidProjectKey(keyCandidate), "Malformed key for '%s'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.",
- keyCandidate);
+ checkArgument(isValidProjectKey(keyCandidate), "Malformed key for '%s'. %s", keyCandidate, "Project key cannot be empty nor contain whitespaces.");
}
/**
- * Same as {@link #isValidProjectKey(String)}, but allows additionally '/'.
+ * <p>Test if given parameter is valid for a project. Valid format is:</p>
+ * <ul>
+ * <li>Allowed characters:
+ * <ul>
+ * <li>Uppercase ASCII letters A-Z</li>
+ * <li>Lowercase ASCII letters a-z</li>
+ * <li>ASCII digits 0-9</li>
+ * <li>Punctuation signs dash '-', underscore '_', period '.', colon ':' and slash '/'</li>
+ * </ul>
+ * </li>
+ * <li>At least one non-digit</li>
+ * </ul>
+ *
+ * @return <code>true</code> if <code>keyCandidate</code> can be used for a project in issues mode
*/
public static boolean isValidProjectKeyIssuesMode(String keyCandidate) {
return keyCandidate.matches(VALID_PROJECT_KEY_ISSUES_MODE_REGEXP);
diff --git a/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java b/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java
index a328a0c586b..7f555664e29 100644
--- a/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java
@@ -47,13 +47,17 @@ public class ComponentKeysTest {
}
@Test
- public void isValidModuleKey() {
- assertThat(ComponentKeys.isValidProjectKey("")).isFalse();
+ public void isValidProjectKey() {
assertThat(ComponentKeys.isValidProjectKey("abc")).isTrue();
- assertThat(ComponentKeys.isValidProjectKey("0123")).isFalse();
- assertThat(ComponentKeys.isValidProjectKey("ab 12")).isFalse();
+ assertThat(ComponentKeys.isValidProjectKey("0123")).isTrue();
assertThat(ComponentKeys.isValidProjectKey("ab_12")).isTrue();
- assertThat(ComponentKeys.isValidProjectKey("ab/12")).isFalse();
+ assertThat(ComponentKeys.isValidProjectKey("ab/12")).isTrue();
+ assertThat(ComponentKeys.isValidProjectKey("코드품질")).isTrue();
+ assertThat(ComponentKeys.isValidProjectKey("")).isFalse();
+ assertThat(ComponentKeys.isValidProjectKey(" ")).isFalse();
+ assertThat(ComponentKeys.isValidProjectKey("ab 12")).isFalse();
+ assertThat(ComponentKeys.isValidProjectKey(" ab")).isFalse();
+ assertThat(ComponentKeys.isValidProjectKey("ab ")).isFalse();
}
@Test
@@ -79,37 +83,22 @@ public class ComponentKeysTest {
}
@Test
- public void checkModuleKey_with_correct_keys() {
+ public void checkProjectKey_with_correct_keys() {
ComponentKeys.checkProjectKey("abc");
ComponentKeys.checkProjectKey("a-b_1.:2");
}
@Test
- public void checkModuleKey_fail_if_only_digit() {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Malformed key for '0123'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
-
- ComponentKeys.checkProjectKey("0123");
- }
-
- @Test
- public void checkModuleKey_fail_if_key_is_empty() {
+ public void checkProjectKey_fail_if_key_is_empty() {
expectedException.expect(IllegalArgumentException.class);
ComponentKeys.checkProjectKey("");
}
@Test
- public void checkModuleKey_fail_if_space() {
+ public void checkProjectKey_fail_if_space() {
expectedException.expect(IllegalArgumentException.class);
ComponentKeys.checkProjectKey("ab 12");
}
-
- @Test
- public void checkModuleKey_fail_if_special_characters_not_allowed() {
- expectedException.expect(IllegalArgumentException.class);
-
- ComponentKeys.checkProjectKey("ab/12");
- }
}
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 c49d685c9c3..d16261393e9 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
@@ -117,8 +117,7 @@ public class ProjectReactorValidator {
private static void validateModule(ProjectDefinition moduleDef, List<String> validationMessages) {
if (!ComponentKeys.isValidProjectKey(moduleDef.getKey())) {
- validationMessages.add(format("\"%s\" is not a valid project or module key. "
- + "Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", moduleDef.getKey()));
+ validationMessages.add(format("\"%s\" is not a valid project or module key. It cannot be empty nor contain whitespaces.", moduleDef.getKey()));
}
}
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 90ec4d316d3..cfda303ff0d 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
@@ -91,28 +91,14 @@ public class ProjectReactorValidatorTest {
public void allow_slash_issues_mode() {
when(mode.isIssues()).thenReturn(true);
underTest.validate(createProjectReactor("project/key"));
-
- when(mode.isIssues()).thenReturn(false);
- thrown.expect(MessageException.class);
- thrown.expectMessage("is not a valid project or module key");
- underTest.validate(createProjectReactor("project/key"));
}
@Test
public void fail_with_invalid_key() {
- ProjectReactor reactor = createProjectReactor("foo$bar");
-
- thrown.expect(MessageException.class);
- thrown.expectMessage("\"foo$bar\" is not a valid project or module key");
- underTest.validate(reactor);
- }
-
- @Test
- public void fail_with_backslash_in_key() {
- ProjectReactor reactor = createProjectReactor("foo\\bar");
+ ProjectReactor reactor = createProjectReactor(" ");
thrown.expect(MessageException.class);
- thrown.expectMessage("\"foo\\bar\" is not a valid project or module key");
+ thrown.expectMessage("\" \" is not a valid project or module key");
underTest.validate(reactor);
}
@@ -156,16 +142,6 @@ public class ProjectReactorValidatorTest {
}
@Test
- public void fail_with_only_digits() {
- ProjectReactor reactor = createProjectReactor("12345");
-
- thrown.expect(MessageException.class);
- thrown.expectMessage("\"12345\" is not a valid project or module key");
-
- underTest.validate(reactor);
- }
-
- @Test
public void fail_when_branch_name_is_specified_but_branch_plugin_not_present() {
ProjectDefinition def = ProjectDefinition.create().setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "foo");
ProjectReactor reactor = new ProjectReactor(def);