From 8db7112f42868729c4b70165ebdd1fd3f3506405 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Tue, 9 Sep 2014 17:50:14 +0200 Subject: [PATCH] SONAR-5563 Apply a permission filter when searching for issues in ES --- .../server/activity/ActivityService.java | 4 +- .../activity/RubyQProfileActivityService.java | 10 +- .../server/activity/index/ActivityIndex.java | 18 +- .../server/activity/ws/SearchAction.java | 6 +- .../component/ws/ComponentAppAction.java | 4 +- .../org/sonar/server/issue/IssueService.java | 12 +- .../issue/db/IssueAuthorizationDao.java | 3 + .../sonar/server/issue/index/IssueIndex.java | 33 +++- .../sonar/server/issue/ws/SearchAction.java | 24 +-- .../server/qualityprofile/QProfileLoader.java | 5 +- .../qualityprofile/QProfileService.java | 4 +- .../server/qualityprofile/RuleActivator.java | 7 +- .../sonar/server/rule/DefaultRuleFinder.java | 6 +- .../sonar/server/rule/RubyRuleService.java | 8 +- .../org/sonar/server/rule/RuleService.java | 4 +- .../sonar/server/rule/index/RuleIndex.java | 37 +--- .../sonar/server/rule/ws/SearchAction.java | 10 +- .../{QueryOptions.java => QueryContext.java} | 45 +++-- .../sonar/server/search/ws/BaseMapping.java | 6 +- .../sonar/server/search/ws/SearchOptions.java | 5 +- .../sonar/server/user/RubyUserSession.java | 11 +- .../org/sonar/server/user/UserSession.java | 22 ++- .../org/sonar/server/user/db/GroupDao.java | 6 + .../activity/ActivityBackendMediumTest.java | 12 +- .../activity/ActivityServiceMediumTest.java | 28 +-- .../RubyQProfileActivityServiceTest.java | 8 +- .../component/ws/ComponentAppActionTest.java | 4 +- .../server/issue/IssueServiceMediumTest.java | 17 +- .../issue/db/IssueAuthorizationDaoTest.java | 2 +- .../issue/db/IssueBackendMediumTest.java | 12 +- .../issue/index/IssueIndexMediumTest.java | 175 ++++++++++++++-- .../server/issue/ws/IssuesWsMediumTest.java | 9 + .../QProfileServiceMediumTest.java | 22 +-- .../RuleActivatorMediumTest.java | 11 +- .../ws/QProfilesWsMediumTest.java | 4 +- .../server/rule/RegisterRulesMediumTest.java | 8 +- .../server/rule/RubyRuleServiceTest.java | 16 +- .../server/rule/RuleBackendMediumTest.java | 4 +- .../rule/index/RuleIndexMediumTest.java | 186 +++++++++--------- .../sonar/server/rule/ws/RuleMappingTest.java | 26 +-- ...OptionsTest.java => QueryContextTest.java} | 30 ++- .../server/search/ws/SearchOptionsTest.java | 4 +- .../sonar/server/user/MockUserSession.java | 5 + .../server/user/MockUserSessionTest.java | 3 +- .../server/user/RubyUserSessionTest.java | 8 +- .../sonar/server/user/db/GroupDaoTest.java | 8 + .../db/GroupDaoTest/find_by_user_login.xml | 32 +++ .../app/controllers/application_controller.rb | 5 +- .../issue/db/IssueAuthorizationMapper.java | 2 +- .../java/org/sonar/core/user/GroupMapper.java | 4 + .../issue/db/IssueAuthorizationMapper.xml | 2 +- .../org/sonar/core/user/GroupMapper.xml | 15 +- 52 files changed, 599 insertions(+), 353 deletions(-) rename server/sonar-server/src/main/java/org/sonar/server/search/{QueryOptions.java => QueryContext.java} (76%) rename server/sonar-server/src/test/java/org/sonar/server/search/{QueryOptionsTest.java => QueryContextTest.java} (80%) create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/find_by_user_login.xml diff --git a/server/sonar-server/src/main/java/org/sonar/server/activity/ActivityService.java b/server/sonar-server/src/main/java/org/sonar/server/activity/ActivityService.java index b5dd40037d5..b646957f573 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/activity/ActivityService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/activity/ActivityService.java @@ -27,7 +27,7 @@ import org.sonar.server.activity.index.ActivityIndex; import org.sonar.server.activity.index.ActivityQuery; import org.sonar.server.db.DbClient; import org.sonar.server.search.IndexClient; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.user.UserSession; @@ -79,7 +79,7 @@ public class ActivityService { return new ActivityQuery(); } - public Result search(ActivityQuery query, QueryOptions options) { + public Result search(ActivityQuery query, QueryContext options) { ActivityIndex index = indexClient.get(ActivityIndex.class); return new Result(index, index.search(query, options)); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/activity/RubyQProfileActivityService.java b/server/sonar-server/src/main/java/org/sonar/server/activity/RubyQProfileActivityService.java index d5715a20a62..9180dbf027d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/activity/RubyQProfileActivityService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/activity/RubyQProfileActivityService.java @@ -26,7 +26,7 @@ import org.sonar.api.utils.Paging; import org.sonar.server.qualityprofile.QProfileActivity; import org.sonar.server.qualityprofile.QProfileActivityQuery; import org.sonar.server.qualityprofile.QProfileService; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.util.RubyUtils; @@ -51,7 +51,7 @@ public class RubyQProfileActivityService implements ServerComponent, Startable { */ public QProfileActivityResult search(Map params) { QProfileActivityQuery query = new QProfileActivityQuery(); - QueryOptions queryOptions = new QueryOptions().setMaxLimit(); + QueryContext queryContext = new QueryContext().setMaxLimit(); List profileKeys = RubyUtils.toStrings(params.get("profileKeys")); if (profileKeys != null) { query.setQprofileKeys(profileKeys); @@ -66,10 +66,10 @@ public class RubyQProfileActivityService implements ServerComponent, Startable { } Integer page = RubyUtils.toInteger(params.get("p")); int pageIndex = page != null ? page : 1; - queryOptions.setPage(pageIndex, 50); + queryContext.setPage(pageIndex, 50); - Result result = service.searchActivities(query, queryOptions); - return new QProfileActivityResult(result.getHits(), Paging.create(queryOptions.getLimit(), pageIndex, Long.valueOf(result.getTotal()).intValue())); + Result result = service.searchActivities(query, queryContext); + return new QProfileActivityResult(result.getHits(), Paging.create(queryContext.getLimit(), pageIndex, Long.valueOf(result.getTotal()).intValue())); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndex.java b/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndex.java index f1e45d066b2..caf237b441f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/activity/index/ActivityIndex.java @@ -25,22 +25,14 @@ import org.elasticsearch.action.search.SearchType; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.index.query.AndFilterBuilder; -import org.elasticsearch.index.query.FilterBuilder; -import org.elasticsearch.index.query.FilterBuilders; -import org.elasticsearch.index.query.OrFilterBuilder; -import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.index.query.*; import org.elasticsearch.search.sort.SortOrder; import org.sonar.core.activity.Activity; import org.sonar.core.activity.db.ActivityDto; -import org.sonar.server.search.BaseIndex; -import org.sonar.server.search.IndexDefinition; -import org.sonar.server.search.IndexField; -import org.sonar.server.search.QueryOptions; -import org.sonar.server.search.Result; -import org.sonar.server.search.SearchClient; +import org.sonar.server.search.*; import javax.annotation.Nullable; + import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -98,11 +90,11 @@ public class ActivityIndex extends BaseIndex { return new Result(this, response); } - public SearchResponse search(ActivityQuery query, QueryOptions options) { + public SearchResponse search(ActivityQuery query, QueryContext options) { return search(query, options, null); } - public SearchResponse search(ActivityQuery query, QueryOptions options, + public SearchResponse search(ActivityQuery query, QueryContext options, @Nullable FilterBuilder domainFilter) { // Prepare query diff --git a/server/sonar-server/src/main/java/org/sonar/server/activity/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/activity/ws/SearchAction.java index d221caad86e..30eab19a4bd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/activity/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/activity/ws/SearchAction.java @@ -28,7 +28,7 @@ import org.sonar.api.utils.text.JsonWriter; import org.sonar.core.activity.Activity; import org.sonar.server.activity.ActivityService; import org.sonar.server.activity.index.ActivityQuery; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.search.ws.SearchOptions; @@ -73,9 +73,9 @@ public class SearchAction implements RequestHandler { public void handle(Request request, Response response) { ActivityQuery query = logService.newActivityQuery(); SearchOptions searchOptions = SearchOptions.create(request); - QueryOptions queryOptions = mapping.newQueryOptions(searchOptions); + QueryContext queryContext = mapping.newQueryOptions(searchOptions); - Result results = logService.search(query, queryOptions); + Result results = logService.search(query, queryContext); JsonWriter json = response.newJsonWriter().beginObject(); searchOptions.writeStatistics(json, results); diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java index 4cd7bfe2daf..941767dfc6e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentAppAction.java @@ -55,7 +55,7 @@ import org.sonar.server.rule.Rule; import org.sonar.server.rule.RuleService; import org.sonar.server.rule.index.RuleDoc; import org.sonar.server.rule.index.RuleQuery; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.ui.ViewProxy; import org.sonar.server.ui.Views; @@ -281,7 +281,7 @@ public class ComponentAppAction implements RequestHandler { } private void appendManualRules(JsonWriter json) { - Result result = ruleService.search(new RuleQuery().setRepositories(newArrayList(RuleDoc.MANUAL_REPOSITORY)), new QueryOptions().setMaxLimit()); + Result result = ruleService.search(new RuleQuery().setRepositories(newArrayList(RuleDoc.MANUAL_REPOSITORY)), new QueryContext().setMaxLimit()); if (result != null && !result.getHits().isEmpty()) { List manualRules = result.getHits(); json.name("manual_rules").beginArray(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java index 4c9172902e3..4ab13b1b6f1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java @@ -62,18 +62,12 @@ import org.sonar.server.issue.index.IssueIndex; import org.sonar.server.issue.index.IssueResult; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.search.IndexClient; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.user.UserSession; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @since 3.6 @@ -341,7 +335,7 @@ public class IssueService implements ServerComponent { return indexClient.get(IssueIndex.class).getByKey(key); } - public IssueResult search(IssueQuery query, QueryOptions options) { + public IssueResult search(IssueQuery query, QueryContext options) { IssueIndex issueIndex = indexClient.get(IssueIndex.class); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueAuthorizationDao.java b/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueAuthorizationDao.java index a827ee31fdc..39d4cb6280c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueAuthorizationDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueAuthorizationDao.java @@ -24,6 +24,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultHandler; +import org.sonar.api.security.DefaultGroups; import org.sonar.api.utils.System2; import org.sonar.api.web.UserRole; import org.sonar.core.issue.db.IssueAuthorizationDto; @@ -101,6 +102,7 @@ public class IssueAuthorizationDao extends BaseDao params = newHashMap(); params.put("date", date); params.put("permission", UserRole.USER); + params.put("anyone", DefaultGroups.ANYONE); Map authorizationDtoMap = newHashMap(); @@ -131,6 +133,7 @@ public class IssueAuthorizationDao extends BaseDao params = super.getSynchronizationParams(date); params.put("permission", UserRole.USER); + params.put("anyone", DefaultGroups.ANYONE); return params; } } 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 5819181b2f1..a58b008a963 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 @@ -26,23 +26,18 @@ import org.elasticsearch.action.search.SearchType; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.index.query.BoolFilterBuilder; -import org.elasticsearch.index.query.FilterBuilders; -import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.sonar.api.issue.IssueQuery; +import org.sonar.api.web.UserRole; import org.sonar.core.issue.db.IssueDto; -import org.sonar.server.search.BaseIndex; -import org.sonar.server.search.IndexDefinition; -import org.sonar.server.search.IndexField; -import org.sonar.server.search.QueryOptions; -import org.sonar.server.search.SearchClient; +import org.sonar.server.search.*; import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.Set; public class IssueIndex extends BaseIndex { @@ -113,7 +108,7 @@ public class IssueIndex extends BaseIndex { return new IssueDoc(fields); } - public SearchResponse search(IssueQuery query, QueryOptions options) { + public SearchResponse search(IssueQuery query, QueryContext options) { SearchRequestBuilder esSearch = getClient() .prepareSearch(this.getIndexName()) @@ -127,6 +122,24 @@ public class IssueIndex extends BaseIndex { BoolFilterBuilder esFilter = FilterBuilders.boolFilter(); + // Authorization + String user = options.getUserLogin(); + Set groups = options.getUserGroups(); + OrFilterBuilder groupsAndUser = FilterBuilders.orFilter(); + if (user != null) { + groupsAndUser.add(FilterBuilders.termFilter(IssueAuthorizationNormalizer.IssueAuthorizationField.USERS.field(), user)); + } + for (String group : groups) { + groupsAndUser.add(FilterBuilders.termFilter(IssueAuthorizationNormalizer.IssueAuthorizationField.GROUPS.field(), group)); + } + esFilter.must(FilterBuilders.hasParentFilter(IndexDefinition.ISSUES_AUTHORIZATION.getIndexType(), + QueryBuilders.filteredQuery( + QueryBuilders.matchAllQuery(), + FilterBuilders.boolFilter() + .must(FilterBuilders.termFilter(IssueAuthorizationNormalizer.IssueAuthorizationField.PERMISSION.field(), UserRole.USER), groupsAndUser) + .cache(true)) + )); + // Issue is assigned Filter if (query.assigned() != null && query.assigned()) { esFilter.must(FilterBuilders.existsFilter(IssueNormalizer.IssueField.ASSIGNEE.field())); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java index daa9e27e362..f19c3248a8e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java @@ -26,11 +26,7 @@ import com.google.common.collect.Iterables; import com.google.common.io.Resources; import org.sonar.api.component.Component; import org.sonar.api.i18n.I18n; -import org.sonar.api.issue.ActionPlan; -import org.sonar.api.issue.Issue; -import org.sonar.api.issue.IssueComment; -import org.sonar.api.issue.IssueQuery; -import org.sonar.api.issue.IssueQueryResult; +import org.sonar.api.issue.*; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.api.rules.Rule; @@ -50,7 +46,7 @@ import org.sonar.server.issue.IssueService; import org.sonar.server.issue.filter.IssueFilterParameters; import org.sonar.server.issue.index.IssueResult; import org.sonar.server.search.FacetValue; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.search.ws.SearchOptions; import org.sonar.server.user.UserSession; @@ -58,11 +54,7 @@ import org.sonar.server.user.UserSession; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import static com.google.common.collect.Lists.newArrayList; @@ -203,11 +195,11 @@ public class SearchAction implements RequestHandler { public void handle(Request request, Response response) { IssueQuery query = createQuery(request); SearchOptions searchOptions = SearchOptions.create(request); - QueryOptions queryOptions = new QueryOptions(); - queryOptions.setPage(searchOptions.page(), searchOptions.pageSize()); - queryOptions.setFacet(request.mandatoryParamAsBoolean(PARAM_FACETS)); + QueryContext queryContext = new QueryContext(); + queryContext.setPage(searchOptions.page(), searchOptions.pageSize()); + queryContext.setFacet(request.mandatoryParamAsBoolean(PARAM_FACETS)); - IssueResult results = service.search(query, queryOptions); + IssueResult results = service.search(query, queryContext); JsonWriter json = response.newJsonWriter(); json.beginObject(); @@ -225,7 +217,7 @@ public class SearchAction implements RequestHandler { // writeUsers(results, json); // writeActionPlans(results, json); - if (queryOptions.isFacet()) { + if (queryContext.isFacet()) { writeFacets(results, json); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileLoader.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileLoader.java index d55b8cdc7f8..1460a8950b4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileLoader.java @@ -33,9 +33,10 @@ import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleQuery; import org.sonar.server.search.FacetValue; import org.sonar.server.search.IndexClient; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import javax.annotation.CheckForNull; + import java.util.HashMap; import java.util.List; import java.util.Map; @@ -126,7 +127,7 @@ public class QProfileLoader implements ServerComponent { .setQProfileKey(key) .setActivation(true) .setStatuses(Lists.newArrayList(RuleStatus.DEPRECATED)), - new QueryOptions().setLimit(0)).getTotal(); + new QueryContext().setLimit(0)).getTotal(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileService.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileService.java index fde5a90ed2f..43a10b1ed6b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileService.java @@ -35,7 +35,7 @@ import org.sonar.server.activity.index.ActivityIndex; import org.sonar.server.db.DbClient; import org.sonar.server.rule.index.RuleQuery; import org.sonar.server.search.IndexClient; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.user.UserSession; @@ -204,7 +204,7 @@ public class QProfileService implements ServerComponent { UserSession.get().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); } - public Result searchActivities(QProfileActivityQuery query, QueryOptions options) { + public Result searchActivities(QProfileActivityQuery query, QueryContext options) { DbSession session = db.openSession(false); try { OrFilterBuilder activityFilter = FilterBuilders.orFilter(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java index 2fb2b565d6d..6bf1db54f80 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java @@ -21,7 +21,6 @@ package org.sonar.server.qualityprofile; import com.google.common.base.Splitter; import com.google.common.collect.Lists; -import org.apache.commons.lang.StringUtils; import org.sonar.api.ServerComponent; import org.sonar.api.server.rule.RuleParamType; import org.sonar.core.activity.Activity; @@ -42,7 +41,7 @@ import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleNormalizer; import org.sonar.server.rule.index.RuleQuery; import org.sonar.server.search.IndexClient; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.util.TypeValidations; @@ -390,7 +389,7 @@ public class RuleActivator implements ServerComponent { RuleIndex ruleIndex = index.get(RuleIndex.class); DbSession dbSession = db.openSession(false); try { - Result ruleSearchResult = ruleIndex.search(ruleQuery, new QueryOptions().setScroll(true) + Result ruleSearchResult = ruleIndex.search(ruleQuery, new QueryContext().setScroll(true) .setFieldsToReturn(Arrays.asList(RuleNormalizer.RuleField.KEY.field()))); Iterator rules = ruleSearchResult.scroll(); while (rules.hasNext()) { @@ -422,7 +421,7 @@ public class RuleActivator implements ServerComponent { try { RuleIndex ruleIndex = index.get(RuleIndex.class); BulkChangeResult result = new BulkChangeResult(); - Result ruleSearchResult = ruleIndex.search(ruleQuery, new QueryOptions().setScroll(true) + Result ruleSearchResult = ruleIndex.search(ruleQuery, new QueryContext().setScroll(true) .setFieldsToReturn(Arrays.asList(RuleNormalizer.RuleField.KEY.field()))); Iterator rules = ruleSearchResult.scroll(); while (rules.hasNext()) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/DefaultRuleFinder.java b/server/sonar-server/src/main/java/org/sonar/server/rule/DefaultRuleFinder.java index ddcd033de8d..bb96fd210b6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/DefaultRuleFinder.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/DefaultRuleFinder.java @@ -29,7 +29,7 @@ import org.sonar.server.rule.index.RuleDoc; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleQuery; import org.sonar.server.search.IndexClient; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import javax.annotation.CheckForNull; @@ -87,7 +87,7 @@ public class DefaultRuleFinder implements RuleFinder { } public final org.sonar.api.rules.Rule find(org.sonar.api.rules.RuleQuery query) { - Result result = index.search(toQuery(query), new QueryOptions()); + Result result = index.search(toQuery(query), new QueryContext()); if (!result.getHits().isEmpty()) { return toRule(result.getHits().get(0)); } else { @@ -97,7 +97,7 @@ public class DefaultRuleFinder implements RuleFinder { public final Collection findAll(org.sonar.api.rules.RuleQuery query) { List rules = newArrayList(); - for (Rule rule : index.search(toQuery(query), new QueryOptions()).getHits()) { + for (Rule rule : index.search(toQuery(query), new QueryContext()).getHits()) { rules.add(toRule(rule)); } return rules; diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/RubyRuleService.java b/server/sonar-server/src/main/java/org/sonar/server/rule/RubyRuleService.java index e2d9dcced82..29d6ef12df3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/RubyRuleService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/RubyRuleService.java @@ -31,7 +31,7 @@ import org.sonar.server.paging.PagingResult; import org.sonar.server.rule.index.RuleDoc; import org.sonar.server.rule.index.RuleNormalizer; import org.sonar.server.rule.index.RuleQuery; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.user.UserSession; import org.sonar.server.util.RubyUtils; @@ -84,7 +84,7 @@ public class RubyRuleService implements ServerComponent, Startable { query.setHasDebtCharacteristic(RubyUtils.toBoolean(params.get("hasDebtCharacteristic"))); query.setSortField(RuleNormalizer.RuleField.NAME); - QueryOptions options = new QueryOptions(); + QueryContext options = new QueryContext(); Integer pageSize = RubyUtils.toInteger(params.get("pageSize")); int size = pageSize != null ? pageSize : 50; if (size > -1) { @@ -94,7 +94,7 @@ public class RubyRuleService implements ServerComponent, Startable { Result result = service.search(query, options); return new PagedResult(result.getHits(), PagingResult.create(options.getLimit(), pageIndex, result.getTotal())); } else { - options = new QueryOptions().setScroll(true); + options = new QueryContext().setScroll(true); List rules = newArrayList(service.search(query, options).scroll()); return new PagedResult(rules, PagingResult.create(Integer.MAX_VALUE, 1, rules.size())); } @@ -104,7 +104,7 @@ public class RubyRuleService implements ServerComponent, Startable { * Used in manual_rules_controller.rb */ public List searchManualRules() { - return service.search(new RuleQuery().setRepositories(newArrayList(RuleDoc.MANUAL_REPOSITORY)).setSortField(RuleNormalizer.RuleField.NAME), new QueryOptions()).getHits(); + return service.search(new RuleQuery().setRepositories(newArrayList(RuleDoc.MANUAL_REPOSITORY)).setSortField(RuleNormalizer.RuleField.NAME), new QueryContext()).getHits(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/RuleService.java b/server/sonar-server/src/main/java/org/sonar/server/rule/RuleService.java index 924490bcb4a..85fab0b327a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/RuleService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/RuleService.java @@ -26,7 +26,7 @@ import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleNormalizer; import org.sonar.server.rule.index.RuleQuery; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.user.UserSession; @@ -68,7 +68,7 @@ public class RuleService implements ServerComponent { return new RuleQuery(); } - public Result search(RuleQuery query, QueryOptions options) { + public Result search(RuleQuery query, QueryContext options) { return index.search(query, options); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java index 53b6ca26d24..9811650de10 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndex.java @@ -27,14 +27,7 @@ import org.elasticsearch.action.search.SearchType; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.index.query.BoolFilterBuilder; -import org.elasticsearch.index.query.BoolQueryBuilder; -import org.elasticsearch.index.query.FilterBuilder; -import org.elasticsearch.index.query.FilterBuilders; -import org.elasticsearch.index.query.MatchQueryBuilder; -import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.index.query.SimpleQueryStringBuilder; +import org.elasticsearch.index.query.*; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; @@ -47,22 +40,12 @@ import org.sonar.api.server.debt.DebtCharacteristic; import org.sonar.core.rule.RuleDto; import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer; import org.sonar.server.rule.Rule; -import org.sonar.server.search.BaseIndex; -import org.sonar.server.search.IndexDefinition; -import org.sonar.server.search.IndexField; -import org.sonar.server.search.QueryOptions; -import org.sonar.server.search.Result; -import org.sonar.server.search.SearchClient; +import org.sonar.server.search.*; import javax.annotation.CheckForNull; + import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static com.google.common.collect.Lists.newArrayList; @@ -100,7 +83,7 @@ public class RuleIndex extends BaseIndex { return mapping; } - private void setFields(QueryOptions options, SearchRequestBuilder esSearch) { + private void setFields(QueryContext options, SearchRequestBuilder esSearch) { /* integrate Option's Fields */ Set fields = new HashSet(); if (!options.getFieldsToReturn().isEmpty()) { @@ -120,7 +103,7 @@ public class RuleIndex extends BaseIndex { esSearch.setFetchSource(fields.toArray(new String[fields.size()]), null); } - private void setFacets(QueryOptions options, SearchRequestBuilder esSearch) { + private void setFacets(QueryContext options, SearchRequestBuilder esSearch) { /* Integrate Facets */ if (options.isFacet()) { this.setFacets(esSearch); @@ -148,7 +131,7 @@ public class RuleIndex extends BaseIndex { } } - protected void setPagination(QueryOptions options, SearchRequestBuilder esSearch) { + protected void setPagination(QueryContext options, SearchRequestBuilder esSearch) { esSearch.setFrom(options.getOffset()); esSearch.setSize(options.getLimit()); } @@ -168,7 +151,7 @@ public class RuleIndex extends BaseIndex { } /* Build main query (search based) */ - protected QueryBuilder getQuery(RuleQuery query, QueryOptions options) { + protected QueryBuilder getQuery(RuleQuery query, QueryContext options) { // No contextual query case String queryText = query.getQueryText(); @@ -202,7 +185,7 @@ public class RuleIndex extends BaseIndex { } /* Build main filter (match based) */ - protected FilterBuilder getFilter(RuleQuery query, QueryOptions options) { + protected FilterBuilder getFilter(RuleQuery query, QueryContext options) { BoolFilterBuilder fb = FilterBuilders.boolFilter(); @@ -334,7 +317,7 @@ public class RuleIndex extends BaseIndex { } - public Result search(RuleQuery query, QueryOptions options) { + public Result search(RuleQuery query, QueryContext options) { SearchRequestBuilder esSearch = getClient() .prepareSearch(this.getIndexName()) .setTypes(this.getIndexType()) diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java index 2d90ff52a2b..9f22915bbc6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java @@ -34,7 +34,7 @@ import org.sonar.server.rule.RuleService; import org.sonar.server.rule.index.RuleNormalizer; import org.sonar.server.rule.index.RuleQuery; import org.sonar.server.search.FacetValue; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.search.ws.SearchOptions; @@ -212,10 +212,10 @@ public class SearchAction implements RequestHandler { public void handle(Request request, Response response) { RuleQuery query = createRuleQuery(ruleService.newRuleQuery(), request); SearchOptions searchOptions = SearchOptions.create(request); - QueryOptions queryOptions = mapping.newQueryOptions(searchOptions); - queryOptions.setFacet(request.mandatoryParamAsBoolean(PARAM_FACETS)); + QueryContext queryContext = mapping.newQueryOptions(searchOptions); + queryContext.setFacet(request.mandatoryParamAsBoolean(PARAM_FACETS)); - Result results = ruleService.search(query, queryOptions); + Result results = ruleService.search(query, queryContext); JsonWriter json = response.newJsonWriter().beginObject(); searchOptions.writeStatistics(json, results); @@ -223,7 +223,7 @@ public class SearchAction implements RequestHandler { if (searchOptions.hasField("actives")) { activeRuleCompleter.completeSearch(query, results.getHits(), json); } - if (queryOptions.isFacet()) { + if (queryContext.isFacet()) { writeFacets(results, json); } json.endObject().close(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/QueryOptions.java b/server/sonar-server/src/main/java/org/sonar/server/search/QueryContext.java similarity index 76% rename from server/sonar-server/src/main/java/org/sonar/server/search/QueryOptions.java rename to server/sonar-server/src/main/java/org/sonar/server/search/QueryContext.java index 46a14467241..a8dda8755d4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/search/QueryOptions.java +++ b/server/sonar-server/src/main/java/org/sonar/server/search/QueryContext.java @@ -20,19 +20,22 @@ package org.sonar.server.search; import com.google.common.base.Preconditions; -import com.google.common.collect.Sets; +import org.sonar.server.user.UserSession; import javax.annotation.Nullable; + import java.util.Arrays; import java.util.Collection; import java.util.Set; +import static com.google.common.collect.Sets.newHashSet; + /** * Various Elasticsearch request options: paging, sorting, fields and facets * * @since 4.4 */ -public class QueryOptions { +public class QueryContext { public static final int DEFAULT_OFFSET = 0; public static final int DEFAULT_LIMIT = 10; @@ -42,8 +45,15 @@ public class QueryOptions { private int offset = DEFAULT_OFFSET; private int limit = DEFAULT_LIMIT; private boolean facet = DEFAULT_FACET; - private Set fieldsToReturn = Sets.newHashSet(); + private Set fieldsToReturn = newHashSet(); private boolean scroll = false; + private String userLogin; + private Set userGroups = newHashSet(); + + public QueryContext() { + this.userLogin = UserSession.get().login(); + this.userGroups = UserSession.get().userGroups(); + } /** * Whether or not the search returns facets for the domain. Defaults to {@link #DEFAULT_OFFSET} @@ -55,7 +65,7 @@ public class QueryOptions { /** * Sets whether or not the search returns facets for the domain. */ - public QueryOptions setFacet(boolean facet) { + public QueryContext setFacet(boolean facet) { this.facet = facet; return this; } @@ -70,7 +80,7 @@ public class QueryOptions { /** * Sets whether or not the search result will be scrollable using an iterator */ - public QueryOptions setScroll(boolean scroll) { + public QueryContext setScroll(boolean scroll) { this.scroll = scroll; return this; } @@ -85,7 +95,7 @@ public class QueryOptions { /** * Sets the offset of the first result to return (zero-based). */ - public QueryOptions setOffset(int offset) { + public QueryContext setOffset(int offset) { Preconditions.checkArgument(offset >= 0, "Offset must be positive"); this.offset = offset; return this; @@ -94,7 +104,7 @@ public class QueryOptions { /** * Set offset and limit according to page approach */ - public QueryOptions setPage(int page, int pageSize) { + public QueryContext setPage(int page, int pageSize) { Preconditions.checkArgument(page >= 1, "Page must be greater or equal to 1 (got " + page + ")"); Preconditions.checkArgument(pageSize >= 0, "Page size must be greater or equal to 0 (got " + pageSize + ")"); setLimit(pageSize); @@ -112,12 +122,12 @@ public class QueryOptions { /** * Sets the limit on the number of results to return. */ - public QueryOptions setLimit(int limit) { + public QueryContext setLimit(int limit) { this.limit = Math.min(limit, MAX_LIMIT); return this; } - public QueryOptions setMaxLimit() { + public QueryContext setMaxLimit() { this.limit = MAX_LIMIT; return this; } @@ -126,22 +136,31 @@ public class QueryOptions { return fieldsToReturn; } - public QueryOptions setFieldsToReturn(@Nullable Collection c) { + public QueryContext setFieldsToReturn(@Nullable Collection c) { fieldsToReturn.clear(); if (c != null) { - this.fieldsToReturn = Sets.newHashSet(c); + this.fieldsToReturn = newHashSet(c); } return this; } - public QueryOptions addFieldsToReturn(@Nullable Collection c) { + public QueryContext addFieldsToReturn(@Nullable Collection c) { if (c != null) { fieldsToReturn.addAll(c); } return this; } - public QueryOptions addFieldsToReturn(String... c) { + public QueryContext addFieldsToReturn(String... c) { return addFieldsToReturn(Arrays.asList(c)); } + + public String getUserLogin() { + return userLogin; + } + + public Set getUserGroups() { + return userGroups; + } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/ws/BaseMapping.java b/server/sonar-server/src/main/java/org/sonar/server/search/ws/BaseMapping.java index 8a4096a47a8..6af489f43f9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/search/ws/BaseMapping.java +++ b/server/sonar-server/src/main/java/org/sonar/server/search/ws/BaseMapping.java @@ -25,7 +25,7 @@ import org.sonar.api.ServerComponent; import org.sonar.api.utils.text.JsonWriter; import org.sonar.server.search.BaseDoc; import org.sonar.server.search.IndexUtils; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import javax.annotation.Nullable; @@ -48,8 +48,8 @@ public abstract class BaseMapping implements ServerCom return mappers.keySet(); } - public QueryOptions newQueryOptions(SearchOptions options) { - QueryOptions result = new QueryOptions(); + public QueryContext newQueryOptions(SearchOptions options) { + QueryContext result = new QueryContext(); result.setPage(options.page(), options.pageSize()); List optionFields = options.fields(); if (optionFields != null) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/ws/SearchOptions.java b/server/sonar-server/src/main/java/org/sonar/server/search/ws/SearchOptions.java index ea246307e50..4b8e25f137d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/search/ws/SearchOptions.java +++ b/server/sonar-server/src/main/java/org/sonar/server/search/ws/SearchOptions.java @@ -22,11 +22,12 @@ package org.sonar.server.search.ws; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import javax.annotation.CheckForNull; import javax.annotation.Nullable; + import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -126,6 +127,6 @@ public class SearchOptions { .createParam(PARAM_PAGE_SIZE) .setDescription("Page size. Must be greater than 0.") .setExampleValue("20") - .setDefaultValue(String.valueOf(QueryOptions.DEFAULT_LIMIT)); + .setDefaultValue(String.valueOf(QueryContext.DEFAULT_LIMIT)); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/RubyUserSession.java b/server/sonar-server/src/main/java/org/sonar/server/user/RubyUserSession.java index 5ef9c192674..bd8dc0f9960 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/RubyUserSession.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/RubyUserSession.java @@ -23,12 +23,19 @@ import org.sonar.server.ui.JRubyI18n; import javax.annotation.Nullable; +import java.util.List; + public class RubyUserSession { /** * Invoked by Ruby code - see application_controller.rb */ - public static void setSession(@Nullable Integer userId, @Nullable String login, @Nullable String name, @Nullable String localeRubyKey) { - UserSession session = new UserSession().setLogin(login).setName(name).setUserId(userId).setLocale(JRubyI18n.toLocale(localeRubyKey)); + public static void setSession(@Nullable Integer userId, @Nullable String login, @Nullable String name, @Nullable List userGroups, @Nullable String localeRubyKey) { + UserSession session = new UserSession() + .setLogin(login) + .setName(name) + .setUserId(userId) + .setUserGroups(userGroups != null ? userGroups.toArray(new String[userGroups.size()]) : null) + .setLocale(JRubyI18n.toLocale(localeRubyKey)); UserSession.set(session); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/UserSession.java b/server/sonar-server/src/main/java/org/sonar/server/user/UserSession.java index 1bfc6f48ff0..98622a74b60 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/UserSession.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/UserSession.java @@ -24,6 +24,7 @@ import com.google.common.base.Strings; import com.google.common.collect.HashMultimap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.security.DefaultGroups; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.resource.ResourceDao; import org.sonar.core.resource.ResourceDto; @@ -35,14 +36,11 @@ import org.sonar.server.platform.Platform; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; +import static com.google.common.collect.Sets.newHashSet; /** * Part of the current HTTP session @@ -58,6 +56,7 @@ public class UserSession { private Integer userId; private String login; private String name; + private Set userGroups; private Locale locale = Locale.ENGLISH; List globalPermissions = null; @@ -66,6 +65,8 @@ public class UserSession { List projectPermissions = newArrayList(); UserSession() { + // Do not forget that when forceAuthentication is set to true, the Anyone group should not be set (but this will be check when authentication will be done in Java) + userGroups = newHashSet(DefaultGroups.ANYONE); } @CheckForNull @@ -98,6 +99,17 @@ public class UserSession { return this; } + public Set userGroups() { + return userGroups; + } + + UserSession setUserGroups(@Nullable String... userGroups) { + if (userGroups != null) { + this.userGroups.addAll(Arrays.asList(userGroups)); + } + return this; + } + public boolean isLoggedIn() { return login != null; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/db/GroupDao.java b/server/sonar-server/src/main/java/org/sonar/server/user/db/GroupDao.java index 9f6a5db3775..174dd1e959d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/db/GroupDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/db/GroupDao.java @@ -27,6 +27,8 @@ import org.sonar.core.user.GroupDto; import org.sonar.core.user.GroupMapper; import org.sonar.server.db.BaseDao; +import java.util.List; + /** * @since 3.2 */ @@ -52,4 +54,8 @@ public class GroupDao extends BaseDao { return item; } + public List findByUserLogin(DbSession session, String login){ + return mapper(session).selectByUserLogin(login); + } + } diff --git a/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityBackendMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityBackendMediumTest.java index 2ab0d3e88ba..e20aea65583 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityBackendMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityBackendMediumTest.java @@ -34,7 +34,7 @@ import org.sonar.server.activity.index.ActivityIndex; import org.sonar.server.activity.index.ActivityQuery; import org.sonar.server.db.DbClient; import org.sonar.server.platform.Platform; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.tester.ServerTester; @@ -108,7 +108,7 @@ public class ActivityBackendMediumTest { service.write(dbSession, Activity.Type.QPROFILE, "now"); dbSession.commit(); - Activity activity = service.search(new ActivityQuery(), new QueryOptions()).getHits().get(0); + Activity activity = service.search(new ActivityQuery(), new QueryContext()).getHits().get(0); assertThat(System.currentTimeMillis() - activity.time().getTime()).isLessThan(1000L); } @@ -131,7 +131,7 @@ public class ActivityBackendMediumTest { // 2. assert scrollable int count = 0; - SearchResponse result = index.search(new ActivityQuery(), new QueryOptions().setScroll(true)); + SearchResponse result = index.search(new ActivityQuery(), new QueryContext().setScroll(true)); Iterator logs = new Result(index, result).scroll(); while (logs.hasNext()) { logs.next(); @@ -142,7 +142,7 @@ public class ActivityBackendMediumTest { // 3 assert synchronize above IndexQueue threshold tester.clearIndexes(); tester.get(Platform.class).executeStartupTasks(); - result = index.search(new ActivityQuery(), new QueryOptions().setScroll(true)); + result = index.search(new ActivityQuery(), new QueryContext().setScroll(true)); logs = new Result(index, result).scroll(); count = 0; while (logs.hasNext()) { @@ -172,7 +172,7 @@ public class ActivityBackendMediumTest { // 2. assert scrollable int count = 0; - SearchResponse result = index.search(new ActivityQuery(), new QueryOptions().setScroll(true)); + SearchResponse result = index.search(new ActivityQuery(), new QueryContext().setScroll(true)); Iterator logs = new Result(index, result).scroll(); while (logs.hasNext()) { logs.next(); @@ -183,7 +183,7 @@ public class ActivityBackendMediumTest { // 3 assert synchronize above IndexQueue threshold tester.clearIndexes(); tester.get(Platform.class).executeStartupTasks(); - result = index.search(new ActivityQuery(), new QueryOptions().setScroll(true)); + result = index.search(new ActivityQuery(), new QueryContext().setScroll(true)); logs = new Result(index, result).scroll(); count = 0; while (logs.hasNext()) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityServiceMediumTest.java index cdd596d5ca6..d90fc8343f9 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityServiceMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/activity/ActivityServiceMediumTest.java @@ -36,7 +36,7 @@ import org.sonar.server.activity.db.ActivityDao; import org.sonar.server.activity.index.ActivityIndex; import org.sonar.server.activity.index.ActivityQuery; import org.sonar.server.db.DbClient; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.tester.ServerTester; @@ -85,7 +85,7 @@ public class ActivityServiceMediumTest { dbSession.commit(); assertThat(index.findAll().getTotal()).isEqualTo(1); - SearchResponse result = index.search(service.newActivityQuery(), new QueryOptions()); + SearchResponse result = index.search(service.newActivityQuery(), new QueryContext()); assertThat(result.getHits().getTotalHits()).isEqualTo(1L); Result activityResult = new Result(index, result); assertThat(activityResult.getHits().get(0).message()).isEqualTo(testValue); @@ -98,7 +98,7 @@ public class ActivityServiceMediumTest { dbSession.commit(); assertThat(index.findAll().getTotal()).isEqualTo(1); - SearchResponse result = index.search(service.newActivityQuery(), new QueryOptions()); + SearchResponse result = index.search(service.newActivityQuery(), new QueryContext()); assertThat(result.getHits().getTotalHits()).isEqualTo(1L); Result activityResult = new Result(index, result); assertThat(activityResult.getHits().get(0).details().get(test_key)).isEqualTo(test_value); @@ -113,15 +113,15 @@ public class ActivityServiceMediumTest { dbSession.commit(); assertThat(service.search(new ActivityQuery(), - new QueryOptions()).getHits()).hasSize(4); + new QueryContext()).getHits()).hasSize(4); assertThat(service.search(new ActivityQuery() .setTypes(ImmutableSet.of(Activity.Type.SERVER)), - new QueryOptions()).getHits()).hasSize(2); + new QueryContext()).getHits()).hasSize(2); assertThat(service.search(new ActivityQuery() .setTypes(ImmutableSet.of(Activity.Type.QPROFILE)), - new QueryOptions()).getHits()).hasSize(1); + new QueryContext()).getHits()).hasSize(1); } @Test @@ -143,28 +143,28 @@ public class ActivityServiceMediumTest { DateTime t2 = new DateTime().plusHours(1); assertThat(service.search(new ActivityQuery(), - new QueryOptions()).getHits()).hasSize(3); + new QueryContext()).getHits()).hasSize(3); assertThat(service.search(new ActivityQuery() .setSince(t0.minusSeconds(5).toDate()), - new QueryOptions()).getHits()).hasSize(3); + new QueryContext()).getHits()).hasSize(3); assertThat(service.search(new ActivityQuery() .setSince(t1.minusSeconds(5).toDate()), - new QueryOptions()).getHits()).hasSize(1); + new QueryContext()).getHits()).hasSize(1); assertThat(service.search(new ActivityQuery() .setSince(t2.minusSeconds(5).toDate()), - new QueryOptions()).getHits()).hasSize(0); + new QueryContext()).getHits()).hasSize(0); assertThat(service.search(new ActivityQuery() .setTo(t1.minusSeconds(5).toDate()), - new QueryOptions()).getHits()).hasSize(2); + new QueryContext()).getHits()).hasSize(2); assertThat(service.search(new ActivityQuery() .setSince(t1.minusSeconds(5).toDate()) .setTo(t2.plusSeconds(5).toDate()), - new QueryOptions()).getHits()).hasSize(1); + new QueryContext()).getHits()).hasSize(1); } private ActivityDto getActivityDto() { @@ -174,7 +174,7 @@ public class ActivityServiceMediumTest { @Test public void iterate_all() throws InterruptedException { - int max = QueryOptions.DEFAULT_LIMIT + 3; + int max = QueryContext.DEFAULT_LIMIT + 3; final String testValue = "hello world"; for (int i = 0; i < max; i++) { service.write(dbSession, Activity.Type.QPROFILE, testValue + "_" + i); @@ -184,7 +184,7 @@ public class ActivityServiceMediumTest { // 0. assert Base case assertThat(dao.findAll(dbSession)).hasSize(max); - SearchResponse result = index.search(service.newActivityQuery(), new QueryOptions().setScroll(true)); + SearchResponse result = index.search(service.newActivityQuery(), new QueryContext().setScroll(true)); assertThat(result.getHits().getTotalHits()).isEqualTo(max); Result activityResult = new Result(index, result); diff --git a/server/sonar-server/src/test/java/org/sonar/server/activity/RubyQProfileActivityServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/activity/RubyQProfileActivityServiceTest.java index 6a7d5cc2d21..ddc33112ad5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/activity/RubyQProfileActivityServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/activity/RubyQProfileActivityServiceTest.java @@ -34,7 +34,7 @@ import org.sonar.core.activity.Activity; import org.sonar.server.qualityprofile.QProfileActivity; import org.sonar.server.qualityprofile.QProfileActivityQuery; import org.sonar.server.qualityprofile.QProfileService; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import java.util.Date; @@ -53,7 +53,7 @@ public class RubyQProfileActivityServiceTest { ArgumentCaptor activityArgumentCaptor; @Captor - ArgumentCaptor queryOptionsArgumentCaptor; + ArgumentCaptor queryOptionsArgumentCaptor; RubyQProfileActivityService rubyQProfileActivityService; @@ -70,7 +70,7 @@ public class RubyQProfileActivityServiceTest { Result result = mock(Result.class); when(result.getHits()).thenReturn(Lists.newArrayList()); when(result.getTotal()).thenReturn(10L); - when(service.searchActivities(any(QProfileActivityQuery.class), any(QueryOptions.class))).thenReturn(result); + when(service.searchActivities(any(QProfileActivityQuery.class), any(QueryContext.class))).thenReturn(result); rubyQProfileActivityService.search(ImmutableMap.of("profileKeys", "PROFILE_KEY", "since", since, "to", to)); @@ -89,7 +89,7 @@ public class RubyQProfileActivityServiceTest { Result result = mock(Result.class); when(result.getHits()).thenReturn(Lists.newArrayList()); when(result.getTotal()).thenReturn(10L); - when(service.searchActivities(any(QProfileActivityQuery.class), any(QueryOptions.class))).thenReturn(result); + when(service.searchActivities(any(QProfileActivityQuery.class), any(QueryContext.class))).thenReturn(result); rubyQProfileActivityService.search(ImmutableMap.of()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java index c24e6e36ebf..edb05332e3e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentAppActionTest.java @@ -59,7 +59,7 @@ import org.sonar.server.measure.persistence.MeasureDao; import org.sonar.server.rule.Rule; import org.sonar.server.rule.RuleService; import org.sonar.server.rule.index.RuleQuery; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.ui.ViewProxy; import org.sonar.server.ui.Views; @@ -470,7 +470,7 @@ public class ComponentAppActionTest { when(rule.key()).thenReturn(RuleKey.of("manual", "API")); when(rule.name()).thenReturn("API"); when(result.getHits()).thenReturn(newArrayList(rule)); - when(ruleService.search(any(RuleQuery.class), any(QueryOptions.class))).thenReturn(result); + when(ruleService.search(any(RuleQuery.class), any(QueryContext.class))).thenReturn(result); WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", COMPONENT_KEY); request.execute().assertJson(getClass(), "app_with_manual_rules.json"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java index 53361becc3c..40813271558 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java @@ -24,9 +24,12 @@ import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.sonar.api.issue.IssueQuery; +import org.sonar.api.security.DefaultGroups; import org.sonar.api.utils.DateUtils; +import org.sonar.api.web.UserRole; import org.sonar.core.component.ComponentDto; import org.sonar.core.issue.db.IssueDto; +import org.sonar.core.permission.PermissionFacade; import org.sonar.core.persistence.DbSession; import org.sonar.core.rule.RuleDto; import org.sonar.server.component.persistence.ComponentDao; @@ -35,9 +38,10 @@ import org.sonar.server.issue.db.IssueDao; import org.sonar.server.issue.index.IssueResult; import org.sonar.server.rule.RuleTesting; import org.sonar.server.rule.db.RuleDao; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.tester.ServerTester; +import java.util.Date; import java.util.UUID; import static org.fest.assertions.Assertions.assertThat; @@ -78,6 +82,11 @@ public class IssueServiceMediumTest { .setKey("MyComponent") .setId(2L); tester.get(ComponentDao.class).insert(session, resource); + + // project can be seen by anyone + tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session); + db.issueAuthorizationDao().synchronizeAfter(session, new Date(0)); + session.commit(); } @@ -93,11 +102,11 @@ public class IssueServiceMediumTest { tester.get(IssueDao.class).insert(session, issue1, issue2); session.commit(); - IssueResult result = service.search(IssueQuery.builder().build(), new QueryOptions()); + IssueResult result = service.search(IssueQuery.builder().build(), new QueryContext()); assertThat(result.getHits()).hasSize(2); assertThat(result.getFacets()).isEmpty(); - result = service.search(IssueQuery.builder().build(), new QueryOptions().setFacet(true)); + result = service.search(IssueQuery.builder().build(), new QueryContext().setFacet(true)); assertThat(result.getFacets().keySet()).hasSize(4); assertThat(result.getFacetKeys("actionPlan")).hasSize(2); } @@ -109,7 +118,7 @@ public class IssueServiceMediumTest { tester.get(IssueDao.class).insert(session, issue1, issue2); session.commit(); - IssueResult result = service.search(IssueQuery.builder().build(), new QueryOptions()); + IssueResult result = service.search(IssueQuery.builder().build(), new QueryContext()); assertThat(result.projects()).hasSize(1); assertThat(result.components()).hasSize(1); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueAuthorizationDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueAuthorizationDaoTest.java index 38a1d7e5d59..ff7415bdc02 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueAuthorizationDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueAuthorizationDaoTest.java @@ -65,7 +65,7 @@ public class IssueAuthorizationDaoTest extends AbstractDaoTestCase { assertThat(dto.getProject()).isEqualTo("org.struts:struts"); assertThat(dto.getKey()).isEqualTo("org.struts:struts"); assertThat(dto.getPermission()).isEqualTo("user"); - assertThat(dto.getGroups()).containsExactly("anyone", "devs"); + assertThat(dto.getGroups()).containsExactly("Anyone", "devs"); assertThat(dto.getUsers()).containsExactly("user1"); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueBackendMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueBackendMediumTest.java index 01b25f0396a..2e9ad9494cf 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueBackendMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueBackendMediumTest.java @@ -191,11 +191,6 @@ public class IssueBackendMediumTest { assertThat(indexClient.get(IssueIndex.class).countAll()).isEqualTo(1); } - @Test - public void synchronize_issue_authorization_index() throws Exception { - - } - @Test public void issue_authorization_on_group() throws Exception { SearchClient searchClient = tester.get(SearchClient.class); @@ -302,14 +297,13 @@ public class IssueBackendMediumTest { } private SearchResponse searchIssueWithAuthorization(SearchClient searchClient, String user, String... groups) { - BoolFilterBuilder fb = FilterBuilders.boolFilter(); + BoolFilterBuilder permissionFilter = FilterBuilders.boolFilter(); OrFilterBuilder or = FilterBuilders.orFilter(FilterBuilders.termFilter("users", user)); for (String group : groups) { or.add(FilterBuilders.termFilter("groups", group)); } - fb.must(FilterBuilders.termFilter("permission", "read"), or).cache(true); - // fb.must(FilterBuilders.termFilter("permission", "read"), or); + permissionFilter.must(FilterBuilders.termFilter("permission", "read"), or).cache(true); SearchRequestBuilder request = searchClient.prepareSearch(IndexDefinition.ISSUES.getIndexName()).setTypes(IndexDefinition.ISSUES.getIndexType()) .setQuery( @@ -317,7 +311,7 @@ public class IssueBackendMediumTest { QueryBuilders.matchAllQuery(), FilterBuilders.hasParentFilter(IndexDefinition.ISSUES_AUTHORIZATION.getIndexType(), QueryBuilders.filteredQuery( - QueryBuilders.matchAllQuery(), fb) + QueryBuilders.matchAllQuery(), permissionFilter) ) ) ) diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java index a52a5c3b116..7a52af104c4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java @@ -26,18 +26,25 @@ import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.sonar.api.issue.IssueQuery; +import org.sonar.api.security.DefaultGroups; import org.sonar.api.utils.DateUtils; +import org.sonar.api.web.UserRole; import org.sonar.core.component.ComponentDto; import org.sonar.core.issue.db.IssueDto; +import org.sonar.core.permission.PermissionFacade; import org.sonar.core.persistence.DbSession; import org.sonar.core.rule.RuleDto; +import org.sonar.core.user.GroupDto; +import org.sonar.core.user.UserDto; import org.sonar.server.component.persistence.ComponentDao; import org.sonar.server.db.DbClient; import org.sonar.server.rule.RuleTesting; import org.sonar.server.rule.db.RuleDao; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.tester.ServerTester; +import org.sonar.server.user.MockUserSession; +import java.util.Date; import java.util.UUID; import static org.fest.assertions.Assertions.assertThat; @@ -76,6 +83,15 @@ public class IssueIndexMediumTest { .setKey("MyComponent") .setId(2L); tester.get(ComponentDao.class).insert(session, resource); + + // project can be seen by anyone + tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session); + db.issueAuthorizationDao().synchronizeAfter(session, new Date(0)); + + MockUserSession.set(); + + session.commit(); + session.clearCache(); } @After @@ -85,81 +101,200 @@ public class IssueIndexMediumTest { @Test public void filter_by_actionPlan() throws Exception { - String plan1 = "plan1"; String plan2 = "plan2"; - IssueDto issue1 = getIssue() + IssueDto issue1 = createIssue() .setActionPlanKey(plan1); - IssueDto issue2 = getIssue() + IssueDto issue2 = createIssue() .setActionPlanKey(plan2); db.issueDao().insert(session, issue1, issue2); session.commit(); IssueQuery.Builder query = IssueQuery.builder(); query.actionPlans(ImmutableList.of(plan1)); - SearchResponse result = index.search(query.build(), new QueryOptions()); + SearchResponse result = index.search(query.build(), new QueryContext()); + assertThat(result.getHits().getTotalHits()).isEqualTo(1L); query = IssueQuery.builder(); query.actionPlans(ImmutableList.of(plan2)); - result = index.search(query.build(), new QueryOptions()); + result = index.search(query.build(), new QueryContext()); assertThat(result.getHits().getTotalHits()).isEqualTo(1L); query = IssueQuery.builder(); query.actionPlans(ImmutableList.of(plan2, plan1)); - result = index.search(query.build(), new QueryOptions()); + result = index.search(query.build(), new QueryContext()); assertThat(result.getHits().getTotalHits()).isEqualTo(2L); } @Test public void is_assigned_filter() throws Exception { - String assignee = "steph"; - IssueDto issue1 = getIssue() + IssueDto issue1 = createIssue() .setAssignee(assignee); - IssueDto issue2 = getIssue(); + IssueDto issue2 = createIssue(); db.issueDao().insert(session, issue1, issue2); session.commit(); IssueQuery.Builder query = IssueQuery.builder(); - SearchResponse result = index.search(query.build(), new QueryOptions()); + SearchResponse result = index.search(query.build(), new QueryContext()); assertThat(result.getHits().getTotalHits()).isEqualTo(2L); query = IssueQuery.builder(); query.assigned(true); - result = index.search(query.build(), new QueryOptions()); + result = index.search(query.build(), new QueryContext()); assertThat(result.getHits().getTotalHits()).isEqualTo(1L); } @Test public void filter_assignee() throws Exception { - String assignee1 = "steph"; String assignee2 = "simon"; - IssueDto issue1 = getIssue() + IssueDto issue1 = createIssue() .setAssignee(assignee1); - IssueDto issue2 = getIssue() + IssueDto issue2 = createIssue() .setAssignee(assignee2); - IssueDto issue3 = getIssue(); + IssueDto issue3 = createIssue(); db.issueDao().insert(session, issue1, issue2, issue3); session.commit(); IssueQuery.Builder query = IssueQuery.builder(); - SearchResponse result = index.search(query.build(), new QueryOptions()); + SearchResponse result = index.search(query.build(), new QueryContext()); assertThat(result.getHits().getTotalHits()).isEqualTo(3L); query = IssueQuery.builder(); query.assignees(ImmutableList.of(assignee1)); - result = index.search(query.build(), new QueryOptions()); + result = index.search(query.build(), new QueryContext()); assertThat(result.getHits().getTotalHits()).isEqualTo(1L); query = IssueQuery.builder(); query.assignees(ImmutableList.of(assignee1, assignee2)); - result = index.search(query.build(), new QueryOptions()); + result = index.search(query.build(), new QueryContext()); assertThat(result.getHits().getTotalHits()).isEqualTo(2L); } - private IssueDto getIssue() { + @Test + public void authorized_issues_on_groups() throws Exception { + ComponentDto project1 = new ComponentDto() + .setId(10L) + .setKey("project1"); + ComponentDto project2 = new ComponentDto() + .setId(11L) + .setKey("project2"); + tester.get(ComponentDao.class).insert(session, project1, project2); + + IssueDto issue1 = createIssue().setRootComponent(project1); + IssueDto issue2 = createIssue().setRootComponent(project2); + db.issueDao().insert(session, issue1, issue2); + + // project1 can be seen by sonar-users + GroupDto groupDto = new GroupDto().setName("sonar-users"); + db.groupDao().insert(session, groupDto); + tester.get(PermissionFacade.class).insertGroupPermission(project1.getId(), groupDto.getName(), UserRole.USER, session); + + // project2 can be seen by sonar-admins + groupDto = new GroupDto().setName("sonar-admins"); + db.groupDao().insert(session, groupDto); + tester.get(PermissionFacade.class).insertGroupPermission(project2.getId(), groupDto.getName(), UserRole.USER, session); + + + db.issueAuthorizationDao().synchronizeAfter(session, new Date(0)); + + session.commit(); + session.clearCache(); + + IssueQuery.Builder query = IssueQuery.builder(); + + MockUserSession.set().setUserGroups("sonar-users"); + assertThat(index.search(query.build(), new QueryContext()).getHits().getTotalHits()).isEqualTo(1L); + + MockUserSession.set().setUserGroups("sonar-admins"); + assertThat(index.search(query.build(), new QueryContext()).getHits().getTotalHits()).isEqualTo(1L); + + MockUserSession.set().setUserGroups("sonar-users", "sonar-admins"); + assertThat(index.search(query.build(), new QueryContext()).getHits().getTotalHits()).isEqualTo(2L); + + MockUserSession.set().setUserGroups("another group"); + assertThat(index.search(query.build(), new QueryContext()).getHits().getTotalHits()).isEqualTo(0); + } + + @Test + public void authorized_issues_on_user() throws Exception { + ComponentDto project1 = new ComponentDto() + .setId(10L) + .setKey("project1"); + ComponentDto project2 = new ComponentDto() + .setId(11L) + .setKey("project2"); + tester.get(ComponentDao.class).insert(session, project1, project2); + + IssueDto issue1 = createIssue().setRootComponent(project1); + IssueDto issue2 = createIssue().setRootComponent(project2); + db.issueDao().insert(session, issue1, issue2); + + // project1 can be seen by john + UserDto john = new UserDto().setLogin("john").setName("john").setActive(true); + db.userDao().insert(session, john); + tester.get(PermissionFacade.class).insertUserPermission(project1.getId(), john.getId(), UserRole.USER, session); + + // project2 can be seen by max + UserDto max = new UserDto().setLogin("max").setName("max").setActive(true); + db.userDao().insert(session, max); + tester.get(PermissionFacade.class).insertUserPermission(project2.getId(), max.getId(), UserRole.USER, session); + + db.issueAuthorizationDao().synchronizeAfter(session, new Date(0)); + + session.commit(); + session.clearCache(); + + IssueQuery.Builder query = IssueQuery.builder(); + + MockUserSession.set().setLogin("john"); + assertThat(index.search(query.build(), new QueryContext()).getHits().getTotalHits()).isEqualTo(1L); + + MockUserSession.set().setLogin("max"); + assertThat(index.search(query.build(), new QueryContext()).getHits().getTotalHits()).isEqualTo(1L); + + MockUserSession.set().setLogin("another guy"); + assertThat(index.search(query.build(), new QueryContext()).getHits().getTotalHits()).isEqualTo(0L); + } + + @Test + public void authorized_issues_on_user_with_group() throws Exception { + ComponentDto project1 = new ComponentDto() + .setId(10L) + .setKey("project1"); + ComponentDto project2 = new ComponentDto() + .setId(11L) + .setKey("project2"); + tester.get(ComponentDao.class).insert(session, project1, project2); + + IssueDto issue1 = createIssue().setRootComponent(project1); + IssueDto issue2 = createIssue().setRootComponent(project2); + db.issueDao().insert(session, issue1, issue2); + + // project1 can be seen by john + UserDto john = new UserDto().setLogin("john").setName("john").setActive(true); + db.userDao().insert(session, john); + tester.get(PermissionFacade.class).insertUserPermission(project1.getId(), john.getId(), UserRole.USER, session); + + // project1 can be seen by sonar-users + GroupDto groupDto = new GroupDto().setName("sonar-users"); + db.groupDao().insert(session, groupDto); + tester.get(PermissionFacade.class).insertGroupPermission(project1.getId(), "sonar-users", UserRole.USER, session); + + db.issueAuthorizationDao().synchronizeAfter(session, new Date(0)); + + session.commit(); + session.clearCache(); + + IssueQuery.Builder query = IssueQuery.builder(); + + MockUserSession.set().setLogin("john").setUserGroups("sonar-users"); + assertThat(index.search(query.build(), new QueryContext()).getHits().getTotalHits()).isEqualTo(1L); + } + + private IssueDto createIssue() { return new IssueDto() .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) .setIssueUpdateDate(DateUtils.parseDate("2014-12-04")) diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java index 1a301d2920f..094bb6c66c1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java @@ -23,11 +23,14 @@ import org.junit.After; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; +import org.sonar.api.security.DefaultGroups; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.DateUtils; +import org.sonar.api.web.UserRole; import org.sonar.core.component.ComponentDto; import org.sonar.core.issue.db.IssueDto; import org.sonar.core.permission.GlobalPermissions; +import org.sonar.core.permission.PermissionFacade; import org.sonar.core.persistence.DbSession; import org.sonar.core.rule.RuleDto; import org.sonar.server.component.persistence.ComponentDao; @@ -38,6 +41,8 @@ import org.sonar.server.tester.ServerTester; import org.sonar.server.user.MockUserSession; import org.sonar.server.ws.WsTester; +import java.util.Date; + import static org.fest.assertions.Assertions.assertThat; public class IssuesWsMediumTest { @@ -114,6 +119,10 @@ public class IssuesWsMediumTest { .setProjectId(1L); tester.get(ComponentDao.class).insert(session, project); + // project can be seen by anyone + tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session); + db.issueAuthorizationDao().synchronizeAfter(session, new Date(0)); + ComponentDto resource = new ComponentDto() .setProjectId(1L) .setKey("MyComponent") diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileServiceMediumTest.java index 6985b4815df..b39658b17f1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileServiceMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileServiceMediumTest.java @@ -39,7 +39,7 @@ import org.sonar.server.db.DbClient; import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer; import org.sonar.server.rule.RuleTesting; import org.sonar.server.search.FacetValue; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.tester.ServerTester; import org.sonar.server.user.MockUserSession; @@ -154,7 +154,7 @@ public class QProfileServiceMediumTest { ); dbSession.commit(); - Result activities = service.searchActivities(new QProfileActivityQuery(), new QueryOptions()); + Result activities = service.searchActivities(new QProfileActivityQuery(), new QueryContext()); assertThat(activities.getHits()).hasSize(1); QProfileActivity activity = activities.getHits().get(0); @@ -183,7 +183,7 @@ public class QProfileServiceMediumTest { ); dbSession.commit(); - Result activities = service.searchActivities(new QProfileActivityQuery(), new QueryOptions()); + Result activities = service.searchActivities(new QProfileActivityQuery(), new QueryContext()); assertThat(activities.getHits()).hasSize(1); QProfileActivity activity = activities.getHits().get(0); @@ -206,7 +206,7 @@ public class QProfileServiceMediumTest { ); dbSession.commit(); - Result activities = service.searchActivities(new QProfileActivityQuery(), new QueryOptions()); + Result activities = service.searchActivities(new QProfileActivityQuery(), new QueryContext()); assertThat(activities.getHits()).hasSize(1); QProfileActivity activity = activities.getHits().get(0); @@ -227,7 +227,7 @@ public class QProfileServiceMediumTest { ); dbSession.commit(); - Result activities = service.searchActivities(new QProfileActivityQuery(), new QueryOptions()); + Result activities = service.searchActivities(new QProfileActivityQuery(), new QueryContext()); assertThat(activities.getHits()).hasSize(1); QProfileActivity activity = activities.getHits().get(0); @@ -245,18 +245,18 @@ public class QProfileServiceMediumTest { dbSession.commit(); // 0. Base case verify 2 activities in index - assertThat(service.searchActivities(new QProfileActivityQuery(), new QueryOptions()).getHits()) + assertThat(service.searchActivities(new QProfileActivityQuery(), new QueryContext()).getHits()) .hasSize(2); // 1. filter by QProfile List result = service.searchActivities(new QProfileActivityQuery() - .setQprofileKeys(ImmutableSet.of(XOO_P1_KEY)), new QueryOptions()).getHits(); + .setQprofileKeys(ImmutableSet.of(XOO_P1_KEY)), new QueryContext()).getHits(); assertThat(result).hasSize(1); // 1. filter by QProfiles assertThat(service.searchActivities(new QProfileActivityQuery() .setQprofileKeys(ImmutableSet.of(XOO_P1_KEY, XOO_P2_KEY)) - , new QueryOptions()).getHits()).hasSize(2); + , new QueryContext()).getHits()).hasSize(2); } @Test @@ -268,18 +268,18 @@ public class QProfileServiceMediumTest { dbSession.commit(); // 0. Base case verify 2 activities in index - assertThat(service.searchActivities(new QProfileActivityQuery(), new QueryOptions()).getHits()) + assertThat(service.searchActivities(new QProfileActivityQuery(), new QueryContext()).getHits()) .hasSize(2); // 1. filter by QProfile List result = service.searchActivities(new QProfileActivityQuery() - .setQprofileKeys(ImmutableSet.of("java-default")), new QueryOptions()).getHits(); + .setQprofileKeys(ImmutableSet.of("java-default")), new QueryContext()).getHits(); assertThat(result).hasSize(1); // 1. filter by QProfiles assertThat(service.searchActivities(new QProfileActivityQuery() .setQprofileKeys(ImmutableSet.of("java-default", "java-toto")) - , new QueryOptions()).getHits()).hasSize(2); + , new QueryContext()).getHits()).hasSize(2); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java index cf4cd585bff..ae5dc30e6ce 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java @@ -20,7 +20,10 @@ package org.sonar.server.qualityprofile; import com.google.common.collect.ImmutableMap; -import org.junit.*; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; @@ -38,7 +41,7 @@ import org.sonar.server.qualityprofile.index.ActiveRuleIndex; import org.sonar.server.rule.RuleTesting; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleQuery; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.tester.ServerTester; import javax.annotation.Nullable; @@ -761,7 +764,7 @@ public class RuleActivatorMediumTest { @Test public void bulk_activation() { // Generate more rules than the search's max limit - int bulkSize = QueryOptions.MAX_LIMIT + 10; + int bulkSize = QueryContext.MAX_LIMIT + 10; for (int i = 0; i < bulkSize; i++) { db.ruleDao().insert(dbSession, RuleTesting.newDto(RuleKey.of("bulk", "r_" + i)).setLanguage("xoo")); } @@ -770,7 +773,7 @@ public class RuleActivatorMediumTest { // 0. No active rules so far (base case) and plenty rules available verifyZeroActiveRules(XOO_P1_KEY); assertThat(tester.get(RuleIndex.class) - .search(new RuleQuery().setRepositories(Arrays.asList("bulk")), new QueryOptions()).getTotal()) + .search(new RuleQuery().setRepositories(Arrays.asList("bulk")), new QueryContext()).getTotal()) .isEqualTo(bulkSize); // 1. bulk activate all the rules diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java index c99be810262..6ec7fba2913 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java @@ -42,7 +42,7 @@ import org.sonar.server.qualityprofile.index.ActiveRuleIndex; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleQuery; import org.sonar.server.rule.ws.SearchAction; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.ws.SearchOptions; import org.sonar.server.tester.ServerTester; import org.sonar.server.user.MockUserSession; @@ -352,7 +352,7 @@ public class QProfilesWsMediumTest { // 2. Assert ActiveRule with BLOCKER severity assertThat(tester.get(RuleIndex.class).search( new RuleQuery().setSeverities(ImmutableSet.of("BLOCKER")), - new QueryOptions()).getHits()).hasSize(2); + new QueryContext()).getHits()).hasSize(2); // 1. Activate Rule with query returning 2 hits WsTester.TestRequest request = wsTester.newGetRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION); diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java index 790c8c1b647..8e91538ac7c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java @@ -47,7 +47,7 @@ import org.sonar.server.qualityprofile.RuleActivation; import org.sonar.server.qualityprofile.index.ActiveRuleIndex; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleQuery; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.tester.ServerTester; import org.sonar.server.user.MockUserSession; @@ -135,7 +135,7 @@ public class RegisterRulesMediumTest { assertThat(ruleParams).hasSize(2); // verify es - Result searchResult = ruleIndex.search(new RuleQuery(), new QueryOptions()); + Result searchResult = ruleIndex.search(new RuleQuery(), new QueryContext()); assertThat(searchResult.getTotal()).isEqualTo(1); assertThat(searchResult.getHits()).hasSize(1); Rule rule = ruleIndex.getByKey(RuleKey.of("xoo", "x1")); @@ -182,8 +182,8 @@ public class RegisterRulesMediumTest { register(rules); // verify that rules are indexed - Result searchResult = ruleIndex.search(new RuleQuery(), new QueryOptions()); - searchResult = ruleIndex.search(new RuleQuery().setKey("xoo:x1"), new QueryOptions()); + Result searchResult = ruleIndex.search(new RuleQuery(), new QueryContext()); + searchResult = ruleIndex.search(new RuleQuery().setKey("xoo:x1"), new QueryContext()); assertThat(searchResult.getTotal()).isEqualTo(1); assertThat(searchResult.getHits()).hasSize(1); assertThat(searchResult.getHits().get(0).key()).isEqualTo(RuleKey.of("xoo", "x1")); diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RubyRuleServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RubyRuleServiceTest.java index c16f5c4d890..3be473ffae7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RubyRuleServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/RubyRuleServiceTest.java @@ -32,7 +32,7 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleStatus; import org.sonar.server.paging.PagedResult; import org.sonar.server.rule.index.RuleQuery; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import org.sonar.server.user.UserSession; @@ -55,7 +55,7 @@ public class RubyRuleServiceTest { RuleUpdater updater; @Captor - ArgumentCaptor optionsCaptor; + ArgumentCaptor optionsCaptor; @Captor ArgumentCaptor ruleQueryCaptor; @@ -75,7 +75,7 @@ public class RubyRuleServiceTest { @Test public void search_rules() throws Exception { - when(ruleService.search(any(RuleQuery.class), any(QueryOptions.class))).thenReturn(mock(Result.class)); + when(ruleService.search(any(RuleQuery.class), any(QueryContext.class))).thenReturn(mock(Result.class)); HashMap params = newHashMap(); params.put("searchQuery", "Exception"); @@ -110,7 +110,7 @@ public class RubyRuleServiceTest { @Test public void search_rules_without_page_size_param() throws Exception { - when(ruleService.search(any(RuleQuery.class), any(QueryOptions.class))).thenReturn(mock(Result.class)); + when(ruleService.search(any(RuleQuery.class), any(QueryContext.class))).thenReturn(mock(Result.class)); HashMap params = newHashMap(); params.put("p", "1"); @@ -128,7 +128,7 @@ public class RubyRuleServiceTest { Result serviceResult = mock(Result.class); when(serviceResult.scroll()).thenReturn(rules.iterator()); - when(ruleService.search(any(RuleQuery.class), any(QueryOptions.class))).thenReturn(serviceResult); + when(ruleService.search(any(RuleQuery.class), any(QueryContext.class))).thenReturn(serviceResult); HashMap params = newHashMap(); params.put("pageSize", "-1"); @@ -142,7 +142,7 @@ public class RubyRuleServiceTest { @Test public void update_rule() throws Exception { - when(ruleService.search(any(RuleQuery.class), any(QueryOptions.class))).thenReturn(mock(Result.class)); + when(ruleService.search(any(RuleQuery.class), any(QueryContext.class))).thenReturn(mock(Result.class)); service.updateRule(ImmutableMap.of("ruleKey", "squid:S001")); @@ -151,11 +151,11 @@ public class RubyRuleServiceTest { @Test public void search_manual_rules() throws Exception { - when(ruleService.search(any(RuleQuery.class), any(QueryOptions.class))).thenReturn(mock(Result.class)); + when(ruleService.search(any(RuleQuery.class), any(QueryContext.class))).thenReturn(mock(Result.class)); service.searchManualRules(); - verify(ruleService).search(any(RuleQuery.class), any(QueryOptions.class)); + verify(ruleService).search(any(RuleQuery.class), any(QueryContext.class)); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleBackendMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/RuleBackendMediumTest.java index 6c3f5695cdd..54f914775de 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/RuleBackendMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/RuleBackendMediumTest.java @@ -37,7 +37,7 @@ import org.sonar.server.rule.db.RuleDao; import org.sonar.server.rule.index.RuleDoc; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleQuery; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.tester.ServerTester; import java.util.Collection; @@ -431,7 +431,7 @@ public class RuleBackendMediumTest { assertThat(index.getByKey(RuleTesting.XOO_X2)).isNotNull(); // 2. assert find does not get REMOVED - List rules = index.search(new RuleQuery(), new QueryOptions()).getHits(); + List rules = index.search(new RuleQuery(), new QueryContext()).getHits(); assertThat(rules).hasSize(1); assertThat(rules.get(0).key()).isEqualTo(RuleTesting.XOO_X1); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexMediumTest.java index 67a74ecb90e..4a0e0631132 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexMediumTest.java @@ -41,18 +41,12 @@ import org.sonar.server.rule.Rule; import org.sonar.server.rule.RuleTesting; import org.sonar.server.rule.db.RuleDao; import org.sonar.server.search.FacetValue; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; + +import java.util.*; import static com.google.common.collect.Lists.newArrayList; import static org.fest.assertions.Assertions.assertThat; @@ -108,11 +102,11 @@ public class RuleIndexMediumTest extends SearchMediumTest { // should not have any facet! RuleQuery query = new RuleQuery(); - Result result = index.search(query, new QueryOptions().setFacet(false)); + Result result = index.search(query, new QueryContext().setFacet(false)); assertThat(result.getFacets()).isEmpty(); // Repositories Facet is preset - result = index.search(query, new QueryOptions().setFacet(true)); + result = index.search(query, new QueryContext().setFacet(true)); assertThat(result.getFacets()).isNotNull(); assertThat(result.getFacets()).hasSize(3); @@ -136,7 +130,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { dao.insert(dbSession, RuleTesting.newDto(RuleKey.of("javascript", "S001"))); dbSession.commit(); - QueryOptions options = new QueryOptions().setFieldsToReturn(null); + QueryContext options = new QueryContext().setFieldsToReturn(null); Result results = index.search(new RuleQuery(), options); assertThat(results.getHits()).hasSize(1); Rule hit = Iterables.getFirst(results.getHits(), null); @@ -144,7 +138,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { assertThat(hit.htmlDescription()).isNotNull(); assertThat(hit.name()).isNotNull(); - options = new QueryOptions().setFieldsToReturn(Collections.emptyList()); + options = new QueryContext().setFieldsToReturn(Collections.emptyList()); results = index.search(new RuleQuery(), options); assertThat(results.getHits()).hasSize(1); hit = Iterables.getFirst(results.getHits(), null); @@ -158,7 +152,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { dao.insert(dbSession, RuleTesting.newDto(RuleKey.of("javascript", "S001"))); dbSession.commit(); - QueryOptions options = new QueryOptions(); + QueryContext options = new QueryContext(); options.addFieldsToReturn(RuleNormalizer.RuleField.LANGUAGE.field(), RuleNormalizer.RuleField.STATUS.field()); Result results = index.search(new RuleQuery(), options); assertThat(results.getHits()).hasSize(1); @@ -183,19 +177,19 @@ public class RuleIndexMediumTest extends SearchMediumTest { // substring RuleQuery query = new RuleQuery().setQueryText("test"); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); // substring query = new RuleQuery().setQueryText("partial match"); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); // case-insensitive query = new RuleQuery().setQueryText("TESTING"); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); // not found query = new RuleQuery().setQueryText("not present"); - assertThat(index.search(query, new QueryOptions()).getHits()).isEmpty(); + assertThat(index.search(query, new QueryContext()).getHits()).isEmpty(); } @Test @@ -207,16 +201,16 @@ public class RuleIndexMediumTest extends SearchMediumTest { // key RuleQuery query = new RuleQuery().setQueryText("X001"); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); // partial key does not match query = new RuleQuery().setQueryText("X00"); // TODO fix non-partial match for Key search - assertThat(index.search(query, new QueryOptions()).getHits()).isEmpty(); + assertThat(index.search(query, new QueryContext()).getHits()).isEmpty(); // repo:key -> nice-to-have ! query = new RuleQuery().setQueryText("javascript:X001"); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); } @Test @@ -228,12 +222,12 @@ public class RuleIndexMediumTest extends SearchMediumTest { // key RuleQuery query = new RuleQuery().setKey(RuleKey.of("javascript", "X001").toString()); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); // partial key does not match query = new RuleQuery().setKey("X001"); // TODO fix non-partial match for Key search - assertThat(index.search(query, new QueryOptions()).getHits()).isEmpty(); + assertThat(index.search(query, new QueryContext()).getHits()).isEmpty(); } @Test @@ -242,7 +236,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { dao.insert(dbSession, RuleTesting.newDto(RuleKey.of("java", "S002"))); dbSession.commit(); - Result results = index.search(new RuleQuery(), new QueryOptions()); + Result results = index.search(new RuleQuery(), new QueryContext()); assertThat(results.getTotal()).isEqualTo(2); assertThat(results.getHits()).hasSize(2); @@ -256,7 +250,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { } dbSession.commit(); - Result results = index.search(new RuleQuery(), new QueryOptions().setScroll(true)); + Result results = index.search(new RuleQuery(), new QueryContext().setScroll(true)); assertThat(results.getTotal()).isEqualTo(max); assertThat(results.getHits()).hasSize(0); @@ -300,11 +294,11 @@ public class RuleIndexMediumTest extends SearchMediumTest { dbSession.commit(); // 0. assert base case - assertThat(index.search(new RuleQuery(), new QueryOptions()).getTotal()).isEqualTo(2); + assertThat(index.search(new RuleQuery(), new QueryContext()).getTotal()).isEqualTo(2); assertThat(db.debtCharacteristicDao().selectCharacteristics()).hasSize(2); // 1. assert hasSubChar filter - assertThat(index.search(new RuleQuery().setHasDebtCharacteristic(true), new QueryOptions()).getTotal()) + assertThat(index.search(new RuleQuery().setHasDebtCharacteristic(true), new QueryContext()).getTotal()) .isEqualTo(2); } @@ -315,17 +309,17 @@ public class RuleIndexMediumTest extends SearchMediumTest { dbSession.commit(); RuleQuery query = new RuleQuery().setRepositories(Arrays.asList("checkstyle", "pmd")); - Result results = index.search(query, new QueryOptions()); + Result results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(1); assertThat(Iterables.getFirst(results.getHits(), null).key().rule()).isEqualTo("S002"); // no results query = new RuleQuery().setRepositories(Arrays.asList("checkstyle")); - assertThat(index.search(query, new QueryOptions()).getHits()).isEmpty(); + assertThat(index.search(query, new QueryContext()).getHits()).isEmpty(); // empty list => no filter query = new RuleQuery().setRepositories(Collections.emptyList()); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); } @Test @@ -336,22 +330,22 @@ public class RuleIndexMediumTest extends SearchMediumTest { dbSession.commit(); RuleQuery query = new RuleQuery().setLanguages(Arrays.asList("cobol", "js")); - Result results = index.search(query, new QueryOptions()); + Result results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(1); assertThat(Iterables.getFirst(results.getHits(), null).key().rule()).isEqualTo("S002"); // no results query = new RuleQuery().setLanguages(Arrays.asList("cpp")); - assertThat(index.search(query, new QueryOptions()).getHits()).isEmpty(); + assertThat(index.search(query, new QueryContext()).getHits()).isEmpty(); // empty list => no filter query = new RuleQuery().setLanguages(Collections.emptyList()); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); // null list => no filter query = new RuleQuery().setLanguages(null); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); } @Test @@ -376,36 +370,36 @@ public class RuleIndexMediumTest extends SearchMediumTest { Result results; // 0. we have 2 rules in index - results = index.search(new RuleQuery(), new QueryOptions()); + results = index.search(new RuleQuery(), new QueryContext()); assertThat(results.getHits()).hasSize(2); // filter by non-subChar query = new RuleQuery().setDebtCharacteristics(ImmutableSet.of("toto")); - assertThat(index.search(query, new QueryOptions()).getHits()).isEmpty(); + assertThat(index.search(query, new QueryContext()).getHits()).isEmpty(); // filter by subChar query = new RuleQuery().setDebtCharacteristics(ImmutableSet.of(char11.getKey())); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); // filter by Char query = new RuleQuery().setDebtCharacteristics(ImmutableSet.of(char1.getKey())); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); // filter by Char and SubChar query = new RuleQuery().setDebtCharacteristics(ImmutableSet.of(char11.getKey(), char1.getKey())); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); // match by Char query = new RuleQuery().setQueryText(char1.getKey()); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); // match by SubChar query = new RuleQuery().setQueryText(char11.getKey()); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); // match by SubChar & Char query = new RuleQuery().setQueryText(char11.getKey() + " " + char1.getKey()); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); } @Test @@ -453,26 +447,26 @@ public class RuleIndexMediumTest extends SearchMediumTest { Result results; // 0. we have 4 rules in index - results = index.search(new RuleQuery(), new QueryOptions()); + results = index.search(new RuleQuery(), new QueryContext()); assertThat(results.getHits()).hasSize(4); // filter by subChar query = new RuleQuery().setDebtCharacteristics(ImmutableSet.of(char11.getKey())); - assertThat(ruleKeys(index.search(query, new QueryOptions()).getHits())).containsOnly("S001", "S002", "S004"); + assertThat(ruleKeys(index.search(query, new QueryContext()).getHits())).containsOnly("S001", "S002", "S004"); query = new RuleQuery().setDebtCharacteristics(ImmutableSet.of(char21.getKey())); - assertThat(ruleKeys(index.search(query, new QueryOptions()).getHits())).containsOnly("S003"); + assertThat(ruleKeys(index.search(query, new QueryContext()).getHits())).containsOnly("S003"); // filter by Char query = new RuleQuery().setDebtCharacteristics(ImmutableSet.of(char1.getKey())); - assertThat(ruleKeys(index.search(query, new QueryOptions()).getHits())).containsOnly("S001", "S002", "S004"); + assertThat(ruleKeys(index.search(query, new QueryContext()).getHits())).containsOnly("S001", "S002", "S004"); query = new RuleQuery().setDebtCharacteristics(ImmutableSet.of(char2.getKey())); - assertThat(ruleKeys(index.search(query, new QueryOptions()).getHits())).containsOnly("S003"); + assertThat(ruleKeys(index.search(query, new QueryContext()).getHits())).containsOnly("S003"); // filter by Char and SubChar query = new RuleQuery().setDebtCharacteristics(ImmutableSet.of(char11.getKey(), char1.getKey(), char2.getKey(), char21.getKey())); - assertThat(ruleKeys(index.search(query, new QueryOptions()).getHits())).containsOnly("S001", "S002", "S003", "S004"); + assertThat(ruleKeys(index.search(query, new QueryContext()).getHits())).containsOnly("S001", "S002", "S003", "S004"); } @Test @@ -482,21 +476,21 @@ public class RuleIndexMediumTest extends SearchMediumTest { dbSession.commit(); RuleQuery query = new RuleQuery().setSeverities(Arrays.asList(Severity.INFO, Severity.MINOR)); - Result results = index.search(query, new QueryOptions()); + Result results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(1); assertThat(Iterables.getFirst(results.getHits(), null).key().rule()).isEqualTo("S002"); // no results query = new RuleQuery().setSeverities(Arrays.asList(Severity.MINOR)); - assertThat(index.search(query, new QueryOptions()).getHits()).isEmpty(); + assertThat(index.search(query, new QueryContext()).getHits()).isEmpty(); // empty list => no filter query = new RuleQuery().setSeverities(Collections.emptyList()); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); // null list => no filter query = new RuleQuery().setSeverities(null); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); } @Test @@ -506,21 +500,21 @@ public class RuleIndexMediumTest extends SearchMediumTest { dbSession.commit(); RuleQuery query = new RuleQuery().setStatuses(Arrays.asList(RuleStatus.DEPRECATED, RuleStatus.READY)); - Result results = index.search(query, new QueryOptions()); + Result results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(1); assertThat(Iterables.getFirst(results.getHits(), null).key().rule()).isEqualTo("S002"); // no results query = new RuleQuery().setStatuses(Arrays.asList(RuleStatus.DEPRECATED)); - assertThat(index.search(query, new QueryOptions()).getHits()).isEmpty(); + assertThat(index.search(query, new QueryContext()).getHits()).isEmpty(); // empty list => no filter query = new RuleQuery().setStatuses(Collections.emptyList()); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); // null list => no filter query = new RuleQuery().setStatuses(null); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); } @Test @@ -532,14 +526,14 @@ public class RuleIndexMediumTest extends SearchMediumTest { // ascending RuleQuery query = new RuleQuery().setSortField(RuleNormalizer.RuleField.NAME); - Result results = index.search(query, new QueryOptions()); + Result results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(3); assertThat(Iterables.getFirst(results.getHits(), null).key().rule()).isEqualTo("S002"); assertThat(Iterables.getLast(results.getHits(), null).key().rule()).isEqualTo("S003"); // descending query = new RuleQuery().setSortField(RuleNormalizer.RuleField.NAME).setAscendingSort(false); - results = index.search(query, new QueryOptions()); + results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(3); assertThat(Iterables.getFirst(results.getHits(), null).key().rule()).isEqualTo("S003"); assertThat(Iterables.getLast(results.getHits(), null).key().rule()).isEqualTo("S002"); @@ -577,25 +571,25 @@ public class RuleIndexMediumTest extends SearchMediumTest { // 1. get all active rules. Result result = index.search(new RuleQuery().setActivation(true), - new QueryOptions()); + new QueryContext()); assertThat(result.getHits()).hasSize(2); // 2. get all inactive rules. result = index.search(new RuleQuery().setActivation(false), - new QueryOptions()); + new QueryContext()); assertThat(result.getHits()).hasSize(1); assertThat(result.getHits().get(0).name()).isEqualTo(rule3.getName()); // 3. get all rules not active on profile index.search(new RuleQuery().setActivation(false).setQProfileKey(qualityProfileDto2.getKey()), - new QueryOptions()); + new QueryContext()); // TODO assertThat(result.getHits()).hasSize(1); // 4. get all active rules on profile result = index.search(new RuleQuery().setActivation(true) .setQProfileKey(qualityProfileDto2.getKey()), - new QueryOptions()); + new QueryContext()); assertThat(result.getHits()).hasSize(1); assertThat(result.getHits().get(0).name()).isEqualTo(rule1.getName()); @@ -637,17 +631,17 @@ public class RuleIndexMediumTest extends SearchMediumTest { // 0. get all rules Result result = index.search(new RuleQuery(), - new QueryOptions()); + new QueryContext()); assertThat(result.getHits()).hasSize(4); // 1. get all active rules result = index.search(new RuleQuery().setActivation(true), - new QueryOptions()); + new QueryContext()); assertThat(result.getHits()).hasSize(3); // 2. get all inactive rules. result = index.search(new RuleQuery().setActivation(false), - new QueryOptions()); + new QueryContext()); assertThat(result.getHits()).hasSize(1); assertThat(result.getHits().get(0).name()).isEqualTo(rule4.getName()); @@ -655,7 +649,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { result = index.search(new RuleQuery().setActivation(true) .setQProfileKey(qualityProfileDto1.getKey()) .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.INHERITED.name())), - new QueryOptions() + new QueryContext() ); assertThat(result.getHits()).hasSize(0); @@ -663,7 +657,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { result = index.search(new RuleQuery().setActivation(true) .setQProfileKey(qualityProfileDto2.getKey()) .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.INHERITED.name())), - new QueryOptions() + new QueryContext() ); assertThat(result.getHits()).hasSize(2); @@ -671,7 +665,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { result = index.search(new RuleQuery().setActivation(true) .setQProfileKey(qualityProfileDto1.getKey()) .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.OVERRIDES.name())), - new QueryOptions() + new QueryContext() ); assertThat(result.getHits()).hasSize(0); @@ -679,7 +673,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { result = index.search(new RuleQuery().setActivation(true) .setQProfileKey(qualityProfileDto2.getKey()) .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.OVERRIDES.name())), - new QueryOptions() + new QueryContext() ); assertThat(result.getHits()).hasSize(1); @@ -688,7 +682,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { .setQProfileKey(qualityProfileDto1.getKey()) .setInheritance(ImmutableSet.of( ActiveRule.Inheritance.INHERITED.name(), ActiveRule.Inheritance.OVERRIDES.name())), - new QueryOptions() + new QueryContext() ); assertThat(result.getHits()).hasSize(0); @@ -697,7 +691,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { .setQProfileKey(qualityProfileDto2.getKey()) .setInheritance(ImmutableSet.of( ActiveRule.Inheritance.INHERITED.name(), ActiveRule.Inheritance.OVERRIDES.name())), - new QueryOptions() + new QueryContext() ); assertThat(result.getHits()).hasSize(3); } @@ -732,38 +726,38 @@ public class RuleIndexMediumTest extends SearchMediumTest { // find all RuleQuery query = new RuleQuery(); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); // tag1 in query query = new RuleQuery().setQueryText("tag1"); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); - assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(), null).tags()).containsExactly("tag1"); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); + assertThat(Iterables.getFirst(index.search(query, new QueryContext()).getHits(), null).tags()).containsExactly("tag1"); // tag1 and tag2 in query query = new RuleQuery().setQueryText("tag1 tag2"); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); // tag2 in filter query = new RuleQuery().setTags(ImmutableSet.of("tag2")); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); - assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(), null).tags()).containsExactly("tag2"); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); + assertThat(Iterables.getFirst(index.search(query, new QueryContext()).getHits(), null).tags()).containsExactly("tag2"); // tag2 in filter and tag1 tag2 in query query = new RuleQuery().setTags(ImmutableSet.of("tag2")).setQueryText("tag1"); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(0); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(0); // tag2 in filter and tag1 in query query = new RuleQuery().setTags(ImmutableSet.of("tag2")).setQueryText("tag1 tag2"); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); - assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(), null).tags()).containsExactly("tag2"); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(1); + assertThat(Iterables.getFirst(index.search(query, new QueryContext()).getHits(), null).tags()).containsExactly("tag2"); // null list => no filter query = new RuleQuery().setTags(Collections.emptySet()); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); // null list => no filter query = new RuleQuery().setTags(null); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); } @Test @@ -774,26 +768,26 @@ public class RuleIndexMediumTest extends SearchMediumTest { // find all RuleQuery query = new RuleQuery(); - Result results = index.search(query, new QueryOptions()); + Result results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(2); // Only template query = new RuleQuery().setIsTemplate(true); - results = index.search(query, new QueryOptions()); + results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(1); assertThat(Iterables.getFirst(results.getHits(), null).key().rule()).isEqualTo("S002"); assertThat(Iterables.getFirst(results.getHits(), null).isTemplate()).isTrue(); // Only not template query = new RuleQuery().setIsTemplate(false); - results = index.search(query, new QueryOptions()); + results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(1); assertThat(Iterables.getFirst(results.getHits(), null).isTemplate()).isFalse(); assertThat(Iterables.getFirst(results.getHits(), null).key().rule()).isEqualTo("S001"); // null => no filter query = new RuleQuery().setIsTemplate(null); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); } @Test @@ -805,19 +799,19 @@ public class RuleIndexMediumTest extends SearchMediumTest { // find all RuleQuery query = new RuleQuery(); - Result results = index.search(query, new QueryOptions()); + Result results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(2); // Only custom rule query = new RuleQuery().setTemplateKey("java:S001"); - results = index.search(query, new QueryOptions()); + results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(1); assertThat(Iterables.getFirst(results.getHits(), null).key().rule()).isEqualTo("S001_MY_CUSTOM"); assertThat(Iterables.getFirst(results.getHits(), null).templateKey()).isEqualTo(RuleKey.of("java", "S001")); // null => no filter query = new RuleQuery().setTemplateKey(null); - assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(query, new QueryContext()).getHits()).hasSize(2); } @Test @@ -835,7 +829,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { // find all RuleQuery query = new RuleQuery(); - Result results = index.search(query, new QueryOptions()); + Result results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(2); // get params @@ -852,7 +846,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { // find all RuleQuery query = new RuleQuery(); - Result results = index.search(query, new QueryOptions()); + Result results = index.search(query, new QueryContext()); assertThat(results.getHits()).hasSize(2); // find custom rule @@ -867,7 +861,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { dbSession.commit(); // from 0 to 1 included - QueryOptions options = new QueryOptions(); + QueryContext options = new QueryContext(); options.setOffset(0).setLimit(2); Result results = index.search(new RuleQuery(), options); assertThat(results.getTotal()).isEqualTo(3); @@ -896,19 +890,19 @@ public class RuleIndexMediumTest extends SearchMediumTest { dbSession.commit(); // 0. find all rules; - assertThat(index.search(new RuleQuery(), new QueryOptions()).getHits()).hasSize(2); + assertThat(index.search(new RuleQuery(), new QueryContext()).getHits()).hasSize(2); // 1. find all rules available since a date; RuleQuery availableSinceQuery = new RuleQuery() .setAvailableSince(since); - List hits = index.search(availableSinceQuery, new QueryOptions()).getHits(); + List hits = index.search(availableSinceQuery, new QueryContext()).getHits(); assertThat(hits).hasSize(1); assertThat(hits.get(0).key()).isEqualTo(RuleKey.of("java", "S002")); // 2. find no new rules since tomorrow. RuleQuery availableSinceNowQuery = new RuleQuery() .setAvailableSince(DateUtils.addDays(since, 1)); - assertThat(index.search(availableSinceNowQuery, new QueryOptions()).getHits()).hasSize(0); + assertThat(index.search(availableSinceNowQuery, new QueryContext()).getHits()).hasSize(0); } @Test @@ -936,7 +930,7 @@ public class RuleIndexMediumTest extends SearchMediumTest { assertThat(rule.name()).isEqualTo(nameWithProtectedChars); RuleQuery protectedCharsQuery = new RuleQuery().setQueryText(nameWithProtectedChars); - List results = index.search(protectedCharsQuery, new QueryOptions()).getHits(); + List results = index.search(protectedCharsQuery, new QueryContext()).getHits(); assertThat(results).hasSize(1); assertThat(results.get(0).key()).isEqualTo(RuleTesting.XOO_X1); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleMappingTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleMappingTest.java index d809c8582ca..1bc90e35cd2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleMappingTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleMappingTest.java @@ -24,7 +24,7 @@ import org.sonar.api.resources.Languages; import org.sonar.api.server.debt.DebtModel; import org.sonar.api.server.ws.internal.SimpleGetRequest; import org.sonar.server.rule.index.RuleNormalizer; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.ws.SearchOptions; import org.sonar.server.text.MacroInterpreter; @@ -43,9 +43,9 @@ public class RuleMappingTest { SimpleGetRequest request = new SimpleGetRequest(); request.setParam("p", "1"); request.setParam("ps", "10"); - QueryOptions queryOptions = mapping.newQueryOptions(SearchOptions.create(request)); + QueryContext queryContext = mapping.newQueryOptions(SearchOptions.create(request)); - assertThat(queryOptions.getFieldsToReturn()).isEmpty(); + assertThat(queryContext.getFieldsToReturn()).isEmpty(); } @Test @@ -55,9 +55,9 @@ public class RuleMappingTest { request.setParam("p", "1"); request.setParam("ps", "10"); request.setParam("f", "repo,name,lang"); - QueryOptions queryOptions = mapping.newQueryOptions(SearchOptions.create(request)); + QueryContext queryContext = mapping.newQueryOptions(SearchOptions.create(request)); - assertThat(queryOptions.getFieldsToReturn()).containsOnly( + assertThat(queryContext.getFieldsToReturn()).containsOnly( RuleNormalizer.RuleField.REPOSITORY.field(), RuleNormalizer.RuleField.NAME.field(), RuleNormalizer.RuleField.LANGUAGE.field()); @@ -70,9 +70,9 @@ public class RuleMappingTest { request.setParam("p", "1"); request.setParam("ps", "10"); request.setParam("f", "langName"); - QueryOptions queryOptions = mapping.newQueryOptions(SearchOptions.create(request)); + QueryContext queryContext = mapping.newQueryOptions(SearchOptions.create(request)); - assertThat(queryOptions.getFieldsToReturn()).containsOnly(RuleNormalizer.RuleField.LANGUAGE.field()); + assertThat(queryContext.getFieldsToReturn()).containsOnly(RuleNormalizer.RuleField.LANGUAGE.field()); } @Test @@ -82,9 +82,9 @@ public class RuleMappingTest { request.setParam("p", "1"); request.setParam("ps", "10"); request.setParam("f", "debtRemFn"); - QueryOptions queryOptions = mapping.newQueryOptions(SearchOptions.create(request)); + QueryContext queryContext = mapping.newQueryOptions(SearchOptions.create(request)); - assertThat(queryOptions.getFieldsToReturn()).containsOnly( + assertThat(queryContext.getFieldsToReturn()).containsOnly( RuleNormalizer.RuleField.DEBT_FUNCTION_COEFFICIENT.field(), RuleNormalizer.RuleField.DEBT_FUNCTION_OFFSET.field(), RuleNormalizer.RuleField.DEBT_FUNCTION_TYPE.field(), @@ -100,9 +100,9 @@ public class RuleMappingTest { request.setParam("p", "1"); request.setParam("ps", "10"); request.setParam("f", "htmlNote"); - QueryOptions queryOptions = mapping.newQueryOptions(SearchOptions.create(request)); + QueryContext queryContext = mapping.newQueryOptions(SearchOptions.create(request)); - assertThat(queryOptions.getFieldsToReturn()).containsOnly(RuleNormalizer.RuleField.NOTE.field()); + assertThat(queryContext.getFieldsToReturn()).containsOnly(RuleNormalizer.RuleField.NOTE.field()); } @Test @@ -112,9 +112,9 @@ public class RuleMappingTest { request.setParam("p", "1"); request.setParam("ps", "10"); request.setParam("f", "debtChar"); - QueryOptions queryOptions = mapping.newQueryOptions(SearchOptions.create(request)); + QueryContext queryContext = mapping.newQueryOptions(SearchOptions.create(request)); - assertThat(queryOptions.getFieldsToReturn()).containsOnly( + assertThat(queryContext.getFieldsToReturn()).containsOnly( RuleNormalizer.RuleField.CHARACTERISTIC.field(), RuleNormalizer.RuleField.DEFAULT_CHARACTERISTIC.field()); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/search/QueryOptionsTest.java b/server/sonar-server/src/test/java/org/sonar/server/search/QueryContextTest.java similarity index 80% rename from server/sonar-server/src/test/java/org/sonar/server/search/QueryOptionsTest.java rename to server/sonar-server/src/test/java/org/sonar/server/search/QueryContextTest.java index 35b201f3577..8999c35fe44 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/search/QueryOptionsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/search/QueryContextTest.java @@ -21,16 +21,30 @@ package org.sonar.server.search; import com.google.common.collect.ImmutableList; +import org.junit.Before; import org.junit.Test; +import org.sonar.server.user.MockUserSession; import java.util.Arrays; import static org.fest.assertions.Assertions.assertThat; import static org.fest.assertions.Fail.fail; -public class QueryOptionsTest { +public class QueryContextTest { - QueryOptions options = new QueryOptions(); + QueryContext options; + + @Before + public void setUp() throws Exception { + MockUserSession.set().setLogin("john").setUserGroups("sonar-users"); + options = new QueryContext(); + } + + @Test + public void user_and_groups() throws Exception { + assertThat(options.getUserLogin()).isEqualTo("john"); + assertThat(options.getUserGroups()).containsOnly("sonar-users", "Anyone"); + } @Test public void page_shortcut_for_limit_and_offset() throws Exception { @@ -72,21 +86,21 @@ public class QueryOptionsTest { options.setLimit(42); assertThat(options.getLimit()).isEqualTo(42); - options.setLimit(QueryOptions.MAX_LIMIT + 10); - assertThat(options.getLimit()).isEqualTo(QueryOptions.MAX_LIMIT); + options.setLimit(QueryContext.MAX_LIMIT + 10); + assertThat(options.getLimit()).isEqualTo(QueryContext.MAX_LIMIT); } @Test public void set_max_limit() throws Exception { options.setMaxLimit(); - assertThat(options.getLimit()).isEqualTo(QueryOptions.MAX_LIMIT); + assertThat(options.getLimit()).isEqualTo(QueryContext.MAX_LIMIT); } @Test public void max_page_size() throws Exception { - options.setPage(3, QueryOptions.MAX_LIMIT + 10); - assertThat(options.getOffset()).isEqualTo(QueryOptions.MAX_LIMIT * 2); - assertThat(options.getLimit()).isEqualTo(QueryOptions.MAX_LIMIT); + options.setPage(3, QueryContext.MAX_LIMIT + 10); + assertThat(options.getOffset()).isEqualTo(QueryContext.MAX_LIMIT * 2); + assertThat(options.getLimit()).isEqualTo(QueryContext.MAX_LIMIT); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/search/ws/SearchOptionsTest.java b/server/sonar-server/src/test/java/org/sonar/server/search/ws/SearchOptionsTest.java index f2cbdf3a3f8..0d802c8aa6d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/search/ws/SearchOptionsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/search/ws/SearchOptionsTest.java @@ -26,7 +26,7 @@ import org.sonar.api.server.ws.RequestHandler; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.internal.SimpleGetRequest; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.QueryContext; import org.sonar.server.search.Result; import java.io.StringWriter; @@ -143,7 +143,7 @@ public class SearchOptionsTest { assertThat(page.defaultValue()).isEqualTo("1"); WebService.Param pageSize = searchAction.param("ps"); assertThat(pageSize).isNotNull(); - assertThat(pageSize.defaultValue()).isEqualTo("" + QueryOptions.DEFAULT_LIMIT); + assertThat(pageSize.defaultValue()).isEqualTo("" + QueryContext.DEFAULT_LIMIT); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/MockUserSession.java b/server/sonar-server/src/test/java/org/sonar/server/user/MockUserSession.java index 8ca959dac2e..834611d6c93 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/MockUserSession.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/MockUserSession.java @@ -75,6 +75,11 @@ public class MockUserSession extends UserSession { return this; } + public MockUserSession setUserGroups(@Nullable String... userGroups) { + super.setUserGroups(userGroups); + return this; + } + public MockUserSession setGlobalPermissions(String... globalPermissions) { this.globalPermissions = Arrays.asList(globalPermissions); return this; diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/MockUserSessionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/MockUserSessionTest.java index b125f052a04..2646b845eac 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/MockUserSessionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/MockUserSessionTest.java @@ -26,10 +26,11 @@ import static org.fest.assertions.Assertions.assertThat; public class MockUserSessionTest { @Test public void set_mock_session() { - MockUserSession.set().setLogin("simon"); + MockUserSession.set().setLogin("simon").setUserGroups("sonar-users"); UserSession mock = UserSession.get(); assertThat(mock.login()).isEqualTo("simon"); + assertThat(mock.userGroups()).containsOnly("sonar-users", "Anyone"); assertThat(mock.globalPermissions()).isEmpty(); assertThat(mock.isLoggedIn()).isTrue(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/RubyUserSessionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/RubyUserSessionTest.java index 725d33cb660..24737aecc3a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/RubyUserSessionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/RubyUserSessionTest.java @@ -23,12 +23,13 @@ import org.junit.Test; import java.util.Locale; +import static com.google.common.collect.Lists.newArrayList; import static org.fest.assertions.Assertions.assertThat; public class RubyUserSessionTest { @Test public void should_set_session() throws Exception { - RubyUserSession.setSession(123, "karadoc", "Karadoc", "fr"); + RubyUserSession.setSession(123, "karadoc", "Karadoc", newArrayList("sonar-users"), "fr"); UserSession session = UserSession.get(); @@ -36,13 +37,14 @@ public class RubyUserSessionTest { assertThat(session.login()).isEqualTo("karadoc"); assertThat(session.name()).isEqualTo("Karadoc"); assertThat(session.userId()).isEqualTo(123); + assertThat(session.userGroups()).containsOnly("sonar-users", "Anyone"); assertThat(session.isLoggedIn()).isTrue(); assertThat(session.locale()).isEqualTo(Locale.FRENCH); } @Test public void should_set_anonymous_session() throws Exception { - RubyUserSession.setSession(null, null, null, "fr"); + RubyUserSession.setSession(null, null, null, null, "fr"); UserSession session = UserSession.get(); @@ -50,9 +52,9 @@ public class RubyUserSessionTest { assertThat(session.login()).isNull(); assertThat(session.name()).isNull(); assertThat(session.userId()).isNull(); + assertThat(session.userGroups()).containsOnly("Anyone"); assertThat(session.isLoggedIn()).isFalse(); assertThat(session.locale()).isEqualTo(Locale.FRENCH); } - } diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/db/GroupDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/db/GroupDaoTest.java index 5a181da970f..1a82038abb1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/db/GroupDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/db/GroupDaoTest.java @@ -64,6 +64,14 @@ public class GroupDaoTest extends AbstractDaoTestCase { assertThat(group.getUpdatedAt()).isEqualTo(DateUtils.parseDate("2014-09-08")); } + @Test + public void find_by_user_login() throws Exception { + setupData("find_by_user_login"); + + assertThat(dao.findByUserLogin(session, "john")).hasSize(2); + assertThat(dao.findByUserLogin(session, "max")).isEmpty(); + } + @Test public void insert() throws Exception { when(system2.now()).thenReturn(DateUtils.parseDate("2014-09-08").getTime()); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/find_by_user_login.xml b/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/find_by_user_login.xml new file mode 100644 index 00000000000..ea360dd7af1 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/user/db/GroupDaoTest/find_by_user_login.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/application_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/application_controller.rb index b01a0792d25..693dfc18a7b 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/application_controller.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/application_controller.rb @@ -100,9 +100,10 @@ class ApplicationController < ActionController::Base end if current_user && current_user.id - Java::OrgSonarServerUser::RubyUserSession.setSession(current_user.id.to_i, current_user.login, current_user.name, I18n.locale.to_s) + user_groups_name = current_user.groups.collect {|g| g.name}.to_a + Java::OrgSonarServerUser::RubyUserSession.setSession(current_user.id.to_i, current_user.login, current_user.name, user_groups_name, I18n.locale.to_s) else - Java::OrgSonarServerUser::RubyUserSession.setSession(nil, nil, nil, I18n.locale.to_s) + Java::OrgSonarServerUser::RubyUserSession.setSession(nil, nil, nil, nil, I18n.locale.to_s) end end diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueAuthorizationMapper.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueAuthorizationMapper.java index ca81eccafae..689f9da6892 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueAuthorizationMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueAuthorizationMapper.java @@ -28,6 +28,6 @@ public interface IssueAuthorizationMapper { IssueAuthorizationDto selectByKey(String key); - IssueAuthorizationDto selectAfterDate(@Param("date") Date date, @Param("permission") String permission); + IssueAuthorizationDto selectAfterDate(@Param("date") Date date, @Param("permission") String permission, @Param("anyone") String anyoneGroup); } diff --git a/sonar-core/src/main/java/org/sonar/core/user/GroupMapper.java b/sonar-core/src/main/java/org/sonar/core/user/GroupMapper.java index 0edd9c3f331..95d0eef39c8 100644 --- a/sonar-core/src/main/java/org/sonar/core/user/GroupMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/user/GroupMapper.java @@ -22,11 +22,15 @@ package org.sonar.core.user; import javax.annotation.CheckForNull; +import java.util.List; + public interface GroupMapper { @CheckForNull GroupDto selectByKey(String name); + List selectByUserLogin(String userLogin); + void insert(GroupDto groupDto); } diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueAuthorizationMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueAuthorizationMapper.xml index eb451cf51ae..2ff34885ec6 100644 --- a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueAuthorizationMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueAuthorizationMapper.xml @@ -40,7 +40,7 @@ SELECT projects.kee AS project, NULL AS login, - 'anyone' AS permission_group, + #{anyone} AS permission_group, group_roles.role as permission_role FROM projects INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role = #{permission} diff --git a/sonar-core/src/main/resources/org/sonar/core/user/GroupMapper.xml b/sonar-core/src/main/resources/org/sonar/core/user/GroupMapper.xml index 4dd187badbe..87a6ea340c2 100644 --- a/sonar-core/src/main/resources/org/sonar/core/user/GroupMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/user/GroupMapper.xml @@ -14,7 +14,20 @@ + + -- 2.39.5