]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10046 adding minimum length validation to api/components
authorGuillaume Jambet <guillaume.jambet@sonarsource.com>
Tue, 7 Nov 2017 16:30:57 +0000 (17:30 +0100)
committerGuillaume Jambet <guillaume.jambet@gmail.com>
Thu, 9 Nov 2017 15:07:06 +0000 (16:07 +0100)
server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java
server/sonar-server/src/main/java/org/sonar/server/component/ws/SuggestionsAction.java
server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java
server/sonar-server/src/test/java/org/sonar/server/component/ws/TreeActionTest.java

index d6faf28ef75f57ca1b2e3d0d435cfbc9801ea8f5..1ab654c1fd3a3bb2601a1cc4877357adbcbe0070 100644 (file)
@@ -79,6 +79,7 @@ import static org.sonar.server.measure.index.ProjectMeasuresQuery.SORT_BY_NAME;
 import static org.sonar.server.ws.WsUtils.checkFound;
 import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH_PROJECTS;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
 import static org.sonarqube.ws.client.component.SearchProjectsRequest.DEFAULT_PAGE_SIZE;
@@ -104,7 +105,7 @@ public class SearchProjectsAction implements ComponentsWsAction {
 
   @Override
   public void define(WebService.NewController context) {
-    WebService.NewAction action = context.createAction("search_projects")
+    WebService.NewAction action = context.createAction(ACTION_SEARCH_PROJECTS)
       .setSince("6.2")
       .setDescription("Search for projects")
       .addPagingParams(DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE)
@@ -131,6 +132,7 @@ public class SearchProjectsAction implements ComponentsWsAction {
       .setPossibleValues(SUPPORTED_FACETS.stream().sorted().collect(MoreCollectors.toList(SUPPORTED_FACETS.size())));
     action
       .createParam(PARAM_FILTER)
+      .setMinimumLength(2)
       .setDescription("Filter of projects on name, key, measure value, quality gate, language, tag or whether a project is a favorite or not.<br>" +
         "The filter must be encoded to form a valid URL (for example '=' must be replaced by '%3D').<br>" +
         "Examples of use:" +
index 5d728d6ab7d9b532b849dc5031e41478ebdba87d..307587b35df86128e34c9124a570b5c9cddb9377 100644 (file)
@@ -51,8 +51,8 @@ import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.component.index.ComponentHit;
 import org.sonar.server.component.index.ComponentHitsPerQualifier;
 import org.sonar.server.component.index.ComponentIndex;
-import org.sonar.server.component.index.SuggestionQuery;
 import org.sonar.server.component.index.ComponentIndexResults;
+import org.sonar.server.component.index.SuggestionQuery;
 import org.sonar.server.es.DefaultIndexSettings;
 import org.sonar.server.favorite.FavoriteFinder;
 import org.sonar.server.user.UserSession;
@@ -122,8 +122,8 @@ public class SuggestionsAction implements ComponentsWsAction {
 
     action.createParam(PARAM_QUERY)
       .setRequired(false)
-      .setDescription("Search query with a minimum of two characters. Can contain several search tokens, separated by spaces. " +
-        "Search tokens with only one character will be ignored.")
+      .setMinimumLength(2)
+      .setDescription("Search query: can contain several search tokens separated by spaces.")
       .setExampleValue("sonar");
 
     action.createParam(PARAM_MORE)
index 5e742a29e82918e7577a3f2874ff2520bbfd82c7..5108087f1e58e2a8d3adbe6292892e8c230d3cad 100644 (file)
@@ -55,12 +55,12 @@ import org.sonarqube.ws.WsComponents.TreeWsResponse;
 import org.sonarqube.ws.client.component.TreeWsRequest;
 
 import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.FluentIterable.from;
 import static java.lang.String.CASE_INSENSITIVE_ORDER;
 import static java.lang.String.format;
 import static java.util.Collections.emptyMap;
 import static org.sonar.api.utils.Paging.offset;
 import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02;
+import static org.sonar.core.util.stream.MoreCollectors.toList;
 import static org.sonar.db.component.ComponentTreeQuery.Strategy.CHILDREN;
 import static org.sonar.db.component.ComponentTreeQuery.Strategy.LEAVES;
 import static org.sonar.server.component.ComponentFinder.ParamNames.COMPONENT_ID_AND_COMPONENT;
@@ -69,7 +69,6 @@ import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
 import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
 import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
-import static org.sonar.server.ws.WsUtils.checkRequest;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_TREE;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_COMPONENT;
@@ -148,8 +147,8 @@ public class TreeAction implements ComponentsWsAction {
       .setDescription(format("Limit search to: <ul>" +
         "<li>component names that contain the supplied string</li>" +
         "<li>component keys that are exactly the same as the supplied string</li>" +
-        "</ul>" +
-        "Must have at least %d characters", QUERY_MINIMUM_LENGTH))
+        "</ul>"))
+      .setMinimumLength(QUERY_MINIMUM_LENGTH)
       .setExampleValue("FILE_NAM");
 
     createQualifiersParameter(action, newQualifierParameterContext(i18n, resourceTypes));
@@ -204,7 +203,7 @@ public class TreeAction implements ComponentsWsAction {
     List<String> referenceComponentIds = components.stream()
       .map(ComponentDto::getCopyResourceUuid)
       .filter(Objects::nonNull)
-      .collect(MoreCollectors.toList());
+      .collect(toList());
     if (referenceComponentIds.isEmpty()) {
       return emptyMap();
     }
@@ -285,7 +284,7 @@ public class TreeAction implements ComponentsWsAction {
   }
 
   private static TreeWsRequest toTreeWsRequest(Request request) {
-    TreeWsRequest treeWsRequest = new TreeWsRequest()
+    return new TreeWsRequest()
       .setBaseComponentId(request.param(PARAM_COMPONENT_ID))
       .setBaseComponentKey(request.param(PARAM_COMPONENT))
       .setBranch(request.param(PARAM_BRANCH))
@@ -296,18 +295,11 @@ public class TreeAction implements ComponentsWsAction {
       .setAsc(request.mandatoryParamAsBoolean(Param.ASCENDING))
       .setPage(request.mandatoryParamAsInt(Param.PAGE))
       .setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE));
-    String searchQuery = treeWsRequest.getQuery();
-    checkRequest(searchQuery == null || searchQuery.length() >= QUERY_MINIMUM_LENGTH,
-      "The '%s' parameter must have at least %d characters", Param.TEXT_QUERY, QUERY_MINIMUM_LENGTH);
-
-    return treeWsRequest;
   }
 
   private static List<ComponentDto> paginateComponents(List<ComponentDto> components, TreeWsRequest wsRequest) {
-    return from(components)
-      .skip(offset(wsRequest.getPage(), wsRequest.getPageSize()))
-      .limit(wsRequest.getPageSize())
-      .toList();
+    return components.stream().skip(offset(wsRequest.getPage(), wsRequest.getPageSize()))
+      .limit(wsRequest.getPageSize()).collect(toList());
   }
 
   public static List<ComponentDto> sortComponents(List<ComponentDto> components, TreeWsRequest wsRequest) {
index 4efbd778940ee69eb61bb53edefcdd46ef3f804d..806621bdd8a76a831174d39147c7a5224aac2d1e 100644 (file)
@@ -47,7 +47,6 @@ import org.sonar.db.component.ResourceTypesRule;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.tester.UserSessionRule;
@@ -399,8 +398,8 @@ public class TreeActionTest {
 
   @Test
   public void fail_when_search_query_has_less_than_3_characters() {
-    expectedException.expect(BadRequestException.class);
-    expectedException.expectMessage("The 'q' parameter must have at least 3 characters");
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("'q' length (2) is shorter than the minimum authorized (3)");
     componentDb.insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
     db.commit();