From a9ddab4c2e126e21ee921b826a0490eb0e9d39b2 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Wed, 30 Nov 2016 14:08:18 +0100 Subject: [PATCH] SONAR-8437 fix facet "assigned_to_me" of api/issues/search --- .../sonar/server/issue/index/IssueIndex.java | 5 +- .../issue/ws/SearchActionMediumTest.java | 56 ++++++++++++------- ...st_escape_login_of_authenticated_user.json | 23 ++++++++ 3 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/assignedToMe_facet_must_escape_login_of_authenticated_user.json diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java index f221cb380ba..5ecce37b558 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java @@ -83,6 +83,7 @@ import org.sonar.server.user.UserSession; import org.sonar.server.view.index.ViewIndexDefinition; import static com.google.common.collect.Lists.newArrayList; +import static org.sonar.server.es.EsUtils.escapeSpecialRegexChars; import static org.sonarqube.ws.client.issue.IssueFilterParameters.ASSIGNEES; import static org.sonarqube.ws.client.issue.IssueFilterParameters.AUTHORS; import static org.sonarqube.ws.client.issue.IssueFilterParameters.CREATED_AT; @@ -572,7 +573,9 @@ public class IssueIndex extends BaseIndex { FilterAggregationBuilder facetTopAggregation = AggregationBuilders .filter(facetName + "__filter") .filter(facetFilter) - .subAggregation(addEffortAggregationIfNeeded(query, AggregationBuilders.terms(facetName + "__terms").field(fieldName).include(login))); + .subAggregation(addEffortAggregationIfNeeded(query, AggregationBuilders.terms(facetName + "__terms") + .field(fieldName) + .include(escapeSpecialRegexChars(login)))); builder.addAggregation( AggregationBuilders.global(facetName) diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java index aa04415b7d4..af10a6c32e1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java @@ -55,6 +55,8 @@ import org.sonar.server.ws.WsTester; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.server.issue.ws.IssuesWs.API_ENDPOINT; +import static org.sonar.server.issue.ws.SearchAction.SEARCH_ACTION; import static org.sonarqube.ws.client.issue.IssueFilterParameters.ADDITIONAL_FIELDS; import static org.sonarqube.ws.client.issue.IssueFilterParameters.COMPONENTS; import static org.sonarqube.ws.client.issue.IssueFilterParameters.DEPRECATED_FACET_MODE_DEBT; @@ -104,7 +106,7 @@ public class SearchActionMediumTest { @Test public void empty_search() throws Exception { - WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION); + WsTester.TestRequest request = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION); WsTester.Result result = request.execute(); assertThat(result).isNotNull(); @@ -135,7 +137,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute(); + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION).execute(); result.assertJson(this.getClass(), "response_contains_all_fields_except_additional_fields.json"); } @@ -169,7 +171,7 @@ public class SearchActionMediumTest { tester.get(IssueIndexer.class).indexAll(); userSessionRule.login("john"); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .setParam("additionalFields", "comments,users") .execute(); result.assertJson(this.getClass(), "issue_with_comments.json"); @@ -205,7 +207,7 @@ public class SearchActionMediumTest { tester.get(IssueIndexer.class).indexAll(); userSessionRule.login("john"); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).setParam(HIDE_COMMENTS, "true").execute(); + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION).setParam(HIDE_COMMENTS, "true").execute(); result.assertJson(this.getClass(), "issue_with_comment_hidden.json"); assertThat(result.outputAsString()).doesNotContain("fabrice"); } @@ -227,7 +229,7 @@ public class SearchActionMediumTest { tester.get(IssueIndexer.class).indexAll(); userSessionRule.login("john"); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .setParam("additionalFields", "_all").execute(); result.assertJson(this.getClass(), "load_additional_fields.json"); } @@ -252,7 +254,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .execute(); result.assertJson(this.getClass(), "issue_on_removed_file.json"); } @@ -267,7 +269,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute(); + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION).execute(); assertThat(result.outputAsString()).contains("\"componentId\":" + file.getId() + ","); } @@ -284,7 +286,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).setParam(COMPONENTS, file.getKey()).execute(); + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION).setParam(COMPONENTS, file.getKey()).execute(); result.assertJson(this.getClass(), "apply_paging_with_one_component.json"); } @@ -299,7 +301,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).setParam(ADDITIONAL_FIELDS, "_all").execute(); + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION).setParam(ADDITIONAL_FIELDS, "_all").execute(); result.assertJson(this.getClass(), "components_contains_sub_projects.json"); } @@ -320,7 +322,7 @@ public class SearchActionMediumTest { tester.get(IssueIndexer.class).indexAll(); userSessionRule.login("john"); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .setParam("resolved", "false") .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,languages,actionPlans,types") .execute(); @@ -344,7 +346,7 @@ public class SearchActionMediumTest { tester.get(IssueIndexer.class).indexAll(); userSessionRule.login("john"); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .setParam("resolved", "false") .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,languages,actionPlans") .setParam("facetMode", FACET_MODE_EFFORT) @@ -369,7 +371,7 @@ public class SearchActionMediumTest { tester.get(IssueIndexer.class).indexAll(); userSessionRule.login("john"); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .setParam("resolved", "false") .setParam("severities", "MAJOR,MINOR") .setParam("languages", "xoo,polop,palap") @@ -378,6 +380,18 @@ public class SearchActionMediumTest { result.assertJson(this.getClass(), "display_zero_facets.json"); } + @Test + public void assignedToMe_facet_must_escape_login_of_authenticated_user() throws Exception { + // login looks like an invalid regexp + userSessionRule.login("foo["); + + // should not fail + wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) + .setParam(WebService.Param.FACETS, "assigned_to_me") + .execute() + .assertJson(this.getClass(), "assignedToMe_facet_must_escape_login_of_authenticated_user.json"); + } + @Test public void filter_by_assigned_to_me() throws Exception { db.userDao().insert(session, new UserDto().setLogin("john").setName("John").setEmail("john@email.com")); @@ -414,7 +428,7 @@ public class SearchActionMediumTest { tester.get(IssueIndexer.class).indexAll(); userSessionRule.login("john"); - wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .setParam("resolved", "false") .setParam("assignees", "__me__") .setParam(WebService.Param.FACETS, "assignees,assigned_to_me") @@ -445,7 +459,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); - wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .setParam("resolved", "false") .setParam("assignees", "__me__") .execute() @@ -488,7 +502,7 @@ public class SearchActionMediumTest { tester.get(IssueIndexer.class).indexAll(); userSessionRule.login("john-bob.polop"); - wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .setParam("resolved", "false") .setParam("assignees", "alice") .setParam(WebService.Param.FACETS, "assignees,assigned_to_me") @@ -514,7 +528,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .setParam("sort", IssueQuery.SORT_BY_UPDATE_DATE) .setParam("asc", "false") .execute(); @@ -534,7 +548,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); - WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION); + WsTester.TestRequest request = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION); request.setParam(WebService.Param.PAGE, "2"); request.setParam(WebService.Param.PAGE_SIZE, "9"); @@ -555,7 +569,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); - WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION); + WsTester.TestRequest request = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION); request.setParam(WebService.Param.PAGE, "1"); request.setParam(WebService.Param.PAGE_SIZE, "-1"); @@ -576,7 +590,7 @@ public class SearchActionMediumTest { session.commit(); tester.get(IssueIndexer.class).indexAll(); - WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION); + WsTester.TestRequest request = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION); request.setParam(PAGE_INDEX, "2"); request.setParam(PAGE_SIZE, "9"); @@ -586,7 +600,7 @@ public class SearchActionMediumTest { @Test public void default_page_size_is_100() throws Exception { - WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION); + WsTester.TestRequest request = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION); WsTester.Result result = request.execute(); result.assertJson(this.getClass(), "default_page_size_is_100.json"); @@ -609,7 +623,7 @@ public class SearchActionMediumTest { tester.get(IssueIndexer.class).indexAll(); userSessionRule.login("john"); - WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION) + WsTester.Result result = wsTester.newGetRequest(API_ENDPOINT, SEARCH_ACTION) .setParam("resolved", "false") .setParam(WebService.Param.FACETS, "severities") .setParam("facetMode", DEPRECATED_FACET_MODE_DEBT) diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/assignedToMe_facet_must_escape_login_of_authenticated_user.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/assignedToMe_facet_must_escape_login_of_authenticated_user.json new file mode 100644 index 00000000000..45df34e8f53 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/assignedToMe_facet_must_escape_login_of_authenticated_user.json @@ -0,0 +1,23 @@ +{ + "total": 0, + "p": 1, + "ps": 100, + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 0 + }, + "issues": [], + "components": [], + "facets": [ + { + "property": "assigned_to_me", + "values": [ + { + "val": "foo[", + "count": 0 + } + ] + } + ] +} -- 2.39.5