aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2018-07-06 14:25:13 +0200
committerSonarTech <sonartech@sonarsource.com>2018-07-11 20:21:22 +0200
commit364fc3b7439e8241ed4094837f9dd835375d09cc (patch)
tree51dc90b36b1b5fcea41e5edaa32c3f38bab1f5aa
parent5e0d13684f4fb81c44d14939c63c45db8e836391 (diff)
downloadsonarqube-364fc3b7439e8241ed4094837f9dd835375d09cc.tar.gz
sonarqube-364fc3b7439e8241ed4094837f9dd835375d09cc.zip
SONAR-10945 Active rules search is only for member on paid organizations
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRulesAction.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java7
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java160
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java181
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/rule/ws/ShowAction.java2
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/rule/ws/app-example.json26
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/rule/ws/AppActionTest.java36
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleQueryFactoryTest.java51
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java136
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java34
11 files changed, 319 insertions, 319 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java
index aea1c6848a7..3b6a8dbb71f 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java
@@ -36,7 +36,7 @@ import org.sonar.server.user.UserSession;
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_03;
import static org.sonar.server.qualityprofile.ws.BulkChangeWsResponse.writeResponse;
import static org.sonar.server.qualityprofile.ws.QProfileReference.fromKey;
-import static org.sonar.server.rule.ws.SearchAction.defineGenericRuleSearchParameters;
+import static org.sonar.server.rule.ws.RuleWsSupport.defineGenericRuleSearchParameters;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_ACTIVATE_RULES;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_KEY;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_SEVERITY;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRulesAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRulesAction.java
index b561083f917..8f55070c382 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRulesAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRulesAction.java
@@ -34,12 +34,11 @@ import org.sonar.server.user.UserSession;
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_04;
import static org.sonar.server.qualityprofile.ws.BulkChangeWsResponse.writeResponse;
-import static org.sonar.server.rule.ws.SearchAction.defineGenericRuleSearchParameters;
+import static org.sonar.server.rule.ws.RuleWsSupport.defineGenericRuleSearchParameters;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_DEACTIVATE_RULES;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_KEY;
public class DeactivateRulesAction implements QProfileWsAction {
- public static final String SEVERITY = "activation_severity";
private final RuleQueryFactory ruleQueryFactory;
private final UserSession userSession;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java
index 0df84c49176..c96ae59ab49 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java
@@ -88,8 +88,6 @@ public class RuleQueryFactory {
Date availableSince = request.paramAsDate(PARAM_AVAILABLE_SINCE);
query.setAvailableSince(availableSince != null ? availableSince.getTime() : null);
query.setStatuses(toEnums(request.paramAsStrings(PARAM_STATUSES), RuleStatus.class));
- Boolean activation = request.paramAsBoolean(PARAM_ACTIVATION);
- query.setActivation(activation);
// Order is important : 1. Load profile, 2. Load organization either from parameter or from profile, 3. Load compare to profile
setProfile(dbSession, query, request);
@@ -97,7 +95,9 @@ public class RuleQueryFactory {
setCompareToProfile(dbSession, query, request);
QProfileDto profile = query.getQProfile();
query.setLanguages(profile == null ? request.paramAsStrings(PARAM_LANGUAGES) : ImmutableList.of(profile.getLanguage()));
-
+ if (wsSupport.areActiveRulesVisible(query.getOrganization())) {
+ query.setActivation(request.paramAsBoolean(PARAM_ACTIVATION));
+ }
query.setTags(request.paramAsStrings(PARAM_TAGS));
query.setInheritance(request.paramAsStrings(PARAM_INHERITANCE));
query.setActiveSeverities(request.paramAsStrings(PARAM_ACTIVE_SEVERITIES));
@@ -139,7 +139,6 @@ public class RuleQueryFactory {
checkArgument(organization.getUuid().equals(inputOrganization.getUuid()),
format("The specified quality profile '%s' is not part of the specified organization '%s'", profile.getKee(), organizationKey));
}
- wsSupport.checkMembershipOnPaidOrganization(organization);
query.setOrganization(organization);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java
index a54dea98130..e9d529117f5 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java
@@ -25,19 +25,47 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.rules.RuleType;
import org.sonar.api.server.ServerSide;
+import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.qualityprofile.ActiveRuleInheritance;
+import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.user.UserSession;
+import static org.sonar.api.server.ws.WebService.Param.ASCENDING;
+import static org.sonar.api.server.ws.WebService.Param.SORT;
+import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
+import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
+import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02;
import static org.sonar.core.util.stream.MoreCollectors.toSet;
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
import static org.sonar.db.organization.OrganizationDto.Subscription.PAID;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_AVAILABLE_SINCE;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_COMPARE_TO_PROFILE;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INCLUDE_EXTERNAL;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INHERITANCE;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_TEMPLATE;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ORGANIZATION;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_RULE_KEY;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SEVERITIES;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TEMPLATE_KEY;
+import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TYPES;
import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
@ServerSide
@@ -65,7 +93,6 @@ public class RuleWsSupport {
OrganizationDto organization = checkFoundWithOptional(
dbClient.organizationDao().selectByKey(dbSession, organizationOrDefaultKey),
"No organization with key '%s'", organizationOrDefaultKey);
- checkMembershipOnPaidOrganization(organization);
return organization;
}
@@ -74,11 +101,136 @@ public class RuleWsSupport {
return dbClient.userDao().selectByUuids(dbSession, userUuids).stream().collect(uniqueIndex(UserDto::getUuid));
}
- void checkMembershipOnPaidOrganization(OrganizationDto organization) {
+ boolean areActiveRulesVisible(OrganizationDto organization) {
if (!organization.getSubscription().equals(PAID)) {
- return;
+ return true;
}
- userSession.checkMembership(organization);
+ return userSession.hasMembership(organization);
}
+ public static void defineGenericRuleSearchParameters(WebService.NewAction action) {
+ action
+ .createParam(TEXT_QUERY)
+ .setMinimumLength(2)
+ .setDescription("UTF-8 search query")
+ .setExampleValue("xpath");
+
+ action
+ .createParam(PARAM_RULE_KEY)
+ .setDescription("Key of rule to search for")
+ .setExampleValue("squid:S001");
+
+ action
+ .createParam(PARAM_REPOSITORIES)
+ .setDescription("Comma-separated list of repositories")
+ .setExampleValue("checkstyle,findbugs");
+
+ action
+ .createParam(PARAM_SEVERITIES)
+ .setDescription("Comma-separated list of default severities. Not the same than severity of rules in Quality profiles.")
+ .setPossibleValues(Severity.ALL)
+ .setExampleValue("CRITICAL,BLOCKER");
+
+ action
+ .createParam(PARAM_LANGUAGES)
+ .setDescription("Comma-separated list of languages")
+ .setExampleValue("java,js");
+
+ action
+ .createParam(PARAM_STATUSES)
+ .setDescription("Comma-separated list of status codes")
+ .setPossibleValues(RuleStatus.values())
+ .setExampleValue(RuleStatus.READY);
+
+ action
+ .createParam(PARAM_AVAILABLE_SINCE)
+ .setDescription("Filters rules added since date. Format is yyyy-MM-dd")
+ .setExampleValue("2014-06-22");
+
+ action
+ .createParam(PARAM_TAGS)
+ .setDescription("Comma-separated list of tags. Returned rules match any of the tags (OR operator)")
+ .setExampleValue("security,java8");
+
+ action
+ .createParam(PARAM_TYPES)
+ .setSince("5.5")
+ .setDescription("Comma-separated list of types. Returned rules match any of the tags (OR operator)")
+ .setPossibleValues(RuleType.values())
+ .setExampleValue(RuleType.BUG);
+
+ action
+ .createParam(PARAM_ACTIVATION)
+ .setDescription("Filter rules that are activated or deactivated on the selected Quality profile. Ignored if " +
+ "the parameter '" + PARAM_QPROFILE + "' is not set.")
+ .setBooleanPossibleValues();
+
+ action
+ .createParam(PARAM_QPROFILE)
+ .setDescription("Quality profile key to filter on. Used only if the parameter '" +
+ PARAM_ACTIVATION + "' is set.")
+ .setExampleValue(UUID_EXAMPLE_01);
+
+ action.createParam(PARAM_COMPARE_TO_PROFILE)
+ .setDescription("Quality profile key to filter rules that are activated. Meant to compare easily to profile set in '%s'", PARAM_QPROFILE)
+ .setInternal(true)
+ .setSince("6.5")
+ .setExampleValue(UUID_EXAMPLE_02);
+
+ action
+ .createParam(PARAM_INHERITANCE)
+ .setDescription("Comma-separated list of values of inheritance for a rule within a quality profile. Used only if the parameter '" +
+ PARAM_ACTIVATION + "' is set.")
+ .setPossibleValues(ActiveRuleInheritance.NONE.name(),
+ ActiveRuleInheritance.INHERITED.name(),
+ ActiveRuleInheritance.OVERRIDES.name())
+ .setExampleValue(ActiveRuleInheritance.INHERITED.name() + "," +
+ ActiveRuleInheritance.OVERRIDES.name());
+
+ action
+ .createParam(PARAM_ACTIVE_SEVERITIES)
+ .setDescription("Comma-separated list of activation severities, i.e the severity of rules in Quality profiles.")
+ .setPossibleValues(Severity.ALL)
+ .setExampleValue("CRITICAL,BLOCKER");
+
+ action
+ .createParam(PARAM_IS_TEMPLATE)
+ .setDescription("Filter template rules")
+ .setBooleanPossibleValues();
+
+ action
+ .createParam(PARAM_TEMPLATE_KEY)
+ .setDescription("Key of the template rule to filter on. Used to search for the custom rules based on this template.")
+ .setExampleValue("java:S001");
+
+ action
+ .createParam(SORT)
+ .setDescription("Sort field")
+ .setPossibleValues(RuleIndexDefinition.SORT_FIELDS)
+ .setExampleValue(RuleIndexDefinition.SORT_FIELDS.iterator().next());
+
+ action
+ .createParam(ASCENDING)
+ .setDescription("Ascending sort")
+ .setBooleanPossibleValues()
+ .setDefaultValue(true);
+
+ action.createParam(PARAM_ORGANIZATION)
+ .setDescription("Organization key")
+ .setRequired(false)
+ .setInternal(true)
+ .setExampleValue("my-org")
+ .setSince("6.4");
+ }
+
+ static void defineIsExternalParam(WebService.NewAction action) {
+ action
+ .createParam(PARAM_INCLUDE_EXTERNAL)
+ .setDescription("Include external engine rules in the results")
+ .setDefaultValue(false)
+ .setBooleanPossibleValues()
+ .setSince("7.2");
+ }
+
+
}
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 0027b0542fa..d2d9fa4a388 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
@@ -36,7 +36,6 @@ import java.util.Objects;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
import org.sonar.api.server.ws.Change;
@@ -53,9 +52,7 @@ import org.sonar.db.user.UserDto;
import org.sonar.server.es.Facets;
import org.sonar.server.es.SearchIdResult;
import org.sonar.server.es.SearchOptions;
-import org.sonar.server.qualityprofile.ActiveRuleInheritance;
import org.sonar.server.rule.index.RuleIndex;
-import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleQuery;
import org.sonarqube.ws.Common;
import org.sonarqube.ws.Rules.SearchResponse;
@@ -66,10 +63,6 @@ import static org.sonar.api.server.ws.WebService.Param.FACETS;
import static org.sonar.api.server.ws.WebService.Param.FIELDS;
import static org.sonar.api.server.ws.WebService.Param.PAGE;
import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
-import static org.sonar.api.server.ws.WebService.Param.SORT;
-import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
-import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
-import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02;
import static org.sonar.server.es.SearchOptions.MAX_LIMIT;
import static org.sonar.server.rule.index.RuleIndex.ALL_STATUSES_EXCEPT_REMOVED;
import static org.sonar.server.rule.index.RuleIndex.FACET_ACTIVE_SEVERITIES;
@@ -81,22 +74,12 @@ import static org.sonar.server.rule.index.RuleIndex.FACET_STATUSES;
import static org.sonar.server.rule.index.RuleIndex.FACET_TAGS;
import static org.sonar.server.rule.index.RuleIndex.FACET_TYPES;
import static org.sonar.server.rule.ws.RulesWsParameters.OPTIONAL_FIELDS;
-import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
-import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_AVAILABLE_SINCE;
-import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_COMPARE_TO_PROFILE;
-import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INCLUDE_EXTERNAL;
-import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INHERITANCE;
-import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_TEMPLATE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
-import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ORGANIZATION;
-import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES;
-import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_RULE_KEY;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SEVERITIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS;
-import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TEMPLATE_KEY;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TYPES;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
@@ -159,7 +142,23 @@ public class SearchAction implements RulesWsAction {
Iterator<String> it = OPTIONAL_FIELDS.iterator();
paramFields.setExampleValue(format("%s,%s", it.next(), it.next()));
- doDefinition(action);
+ action.setDescription("Search for a collection of relevant rules matching a specified query.<br/>" +
+ "Since 5.5, following fields in the response have been deprecated :" +
+ "<ul>" +
+ "<li>\"effortToFixDescription\" becomes \"gapDescription\"</li>" +
+ "<li>\"debtRemFnCoeff\" becomes \"remFnGapMultiplier\"</li>" +
+ "<li>\"defaultDebtRemFnCoeff\" becomes \"defaultRemFnGapMultiplier\"</li>" +
+ "<li>\"debtRemFnOffset\" becomes \"remFnBaseEffort\"</li>" +
+ "<li>\"defaultDebtRemFnOffset\" becomes \"defaultRemFnBaseEffort\"</li>" +
+ "<li>\"debtOverloaded\" becomes \"remFnOverloaded\"</li>" +
+ "</ul>")
+ .setResponseExample(getClass().getResource("search-example.json"))
+ .setSince("4.4")
+ .setHandler(this);
+
+ // Rule-specific search parameters
+ RuleWsSupport.defineGenericRuleSearchParameters(action);
+ RuleWsSupport.defineIsExternalParam(action);
}
@Override
@@ -190,150 +189,6 @@ public class SearchAction implements RulesWsAction {
response.setPs(context.getLimit());
}
- private void doDefinition(WebService.NewAction action) {
- action.setDescription("Search for a collection of relevant rules matching a specified query.<br/>" +
- "Since 5.5, following fields in the response have been deprecated :" +
- "<ul>" +
- "<li>\"effortToFixDescription\" becomes \"gapDescription\"</li>" +
- "<li>\"debtRemFnCoeff\" becomes \"remFnGapMultiplier\"</li>" +
- "<li>\"defaultDebtRemFnCoeff\" becomes \"defaultRemFnGapMultiplier\"</li>" +
- "<li>\"debtRemFnOffset\" becomes \"remFnBaseEffort\"</li>" +
- "<li>\"defaultDebtRemFnOffset\" becomes \"defaultRemFnBaseEffort\"</li>" +
- "<li>\"debtOverloaded\" becomes \"remFnOverloaded\"</li>" +
- "</ul>")
- .setResponseExample(getClass().getResource("search-example.json"))
- .setSince("4.4")
- .setHandler(this);
-
- // Rule-specific search parameters
- defineGenericRuleSearchParameters(action);
- defineIsExternalParam(action);
- }
-
- static void defineIsExternalParam(WebService.NewAction action) {
- action
- .createParam(PARAM_INCLUDE_EXTERNAL)
- .setDescription("Include external engine rules in the results")
- .setDefaultValue(false)
- .setBooleanPossibleValues()
- .setSince("7.2");
- }
-
- public static void defineGenericRuleSearchParameters(WebService.NewAction action) {
- action
- .createParam(TEXT_QUERY)
- .setMinimumLength(2)
- .setDescription("UTF-8 search query")
- .setExampleValue("xpath");
-
- action
- .createParam(PARAM_RULE_KEY)
- .setDescription("Key of rule to search for")
- .setExampleValue("squid:S001");
-
- action
- .createParam(PARAM_REPOSITORIES)
- .setDescription("Comma-separated list of repositories")
- .setExampleValue("checkstyle,findbugs");
-
- action
- .createParam(PARAM_SEVERITIES)
- .setDescription("Comma-separated list of default severities. Not the same than severity of rules in Quality profiles.")
- .setPossibleValues(Severity.ALL)
- .setExampleValue("CRITICAL,BLOCKER");
-
- action
- .createParam(PARAM_LANGUAGES)
- .setDescription("Comma-separated list of languages")
- .setExampleValue("java,js");
-
- action
- .createParam(PARAM_STATUSES)
- .setDescription("Comma-separated list of status codes")
- .setPossibleValues(RuleStatus.values())
- .setExampleValue(RuleStatus.READY);
-
- action
- .createParam(PARAM_AVAILABLE_SINCE)
- .setDescription("Filters rules added since date. Format is yyyy-MM-dd")
- .setExampleValue("2014-06-22");
-
- action
- .createParam(PARAM_TAGS)
- .setDescription("Comma-separated list of tags. Returned rules match any of the tags (OR operator)")
- .setExampleValue("security,java8");
-
- action
- .createParam(PARAM_TYPES)
- .setSince("5.5")
- .setDescription("Comma-separated list of types. Returned rules match any of the tags (OR operator)")
- .setPossibleValues(RuleType.values())
- .setExampleValue(RuleType.BUG);
-
- action
- .createParam(PARAM_ACTIVATION)
- .setDescription("Filter rules that are activated or deactivated on the selected Quality profile. Ignored if " +
- "the parameter '" + PARAM_QPROFILE + "' is not set.")
- .setBooleanPossibleValues();
-
- action
- .createParam(PARAM_QPROFILE)
- .setDescription("Quality profile key to filter on. Used only if the parameter '" +
- PARAM_ACTIVATION + "' is set.")
- .setExampleValue(UUID_EXAMPLE_01);
-
- action.createParam(PARAM_COMPARE_TO_PROFILE)
- .setDescription("Quality profile key to filter rules that are activated. Meant to compare easily to profile set in '%s'", PARAM_QPROFILE)
- .setInternal(true)
- .setSince("6.5")
- .setExampleValue(UUID_EXAMPLE_02);
-
- action
- .createParam(PARAM_INHERITANCE)
- .setDescription("Comma-separated list of values of inheritance for a rule within a quality profile. Used only if the parameter '" +
- PARAM_ACTIVATION + "' is set.")
- .setPossibleValues(ActiveRuleInheritance.NONE.name(),
- ActiveRuleInheritance.INHERITED.name(),
- ActiveRuleInheritance.OVERRIDES.name())
- .setExampleValue(ActiveRuleInheritance.INHERITED.name() + "," +
- ActiveRuleInheritance.OVERRIDES.name());
-
- action
- .createParam(PARAM_ACTIVE_SEVERITIES)
- .setDescription("Comma-separated list of activation severities, i.e the severity of rules in Quality profiles.")
- .setPossibleValues(Severity.ALL)
- .setExampleValue("CRITICAL,BLOCKER");
-
- action
- .createParam(PARAM_IS_TEMPLATE)
- .setDescription("Filter template rules")
- .setBooleanPossibleValues();
-
- action
- .createParam(PARAM_TEMPLATE_KEY)
- .setDescription("Key of the template rule to filter on. Used to search for the custom rules based on this template.")
- .setExampleValue("java:S001");
-
- action
- .createParam(SORT)
- .setDescription("Sort field")
- .setPossibleValues(RuleIndexDefinition.SORT_FIELDS)
- .setExampleValue(RuleIndexDefinition.SORT_FIELDS.iterator().next());
-
- action
- .createParam(ASCENDING)
- .setDescription("Ascending sort")
- .setBooleanPossibleValues()
- .setDefaultValue(true);
-
- action.createParam(PARAM_ORGANIZATION)
- .setDescription("Organization key")
- .setRequired(false)
- .setInternal(true)
- .setExampleValue("my-org")
- .setSince("6.4");
- }
-
private void writeRules(DbSession dbSession, SearchResponse.Builder response, SearchResult result, SearchOptions context) {
Map<String, UserDto> usersByUuid = ruleWsSupport.getUsersByUuid(dbSession, result.rules);
result.rules.forEach(rule -> response.addRules(mapper.toWsRule(rule.getDefinition(), result, context.getFields(), rule.getMetadata(), usersByUuid)));
@@ -396,7 +251,7 @@ public class SearchAction implements RulesWsAction {
private void doContextResponse(DbSession dbSession, SearchRequest request, SearchResult result, SearchResponse.Builder response, RuleQuery query) {
SearchOptions contextForResponse = loadCommonContext(request);
writeRules(dbSession, response, result, contextForResponse);
- if (contextForResponse.getFields().contains("actives")) {
+ if (contextForResponse.getFields().contains("actives") && ruleWsSupport.areActiveRulesVisible(query.getOrganization())) {
activeRuleCompleter.completeSearch(dbSession, query, result.rules, response);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/ShowAction.java
index bd374a495f7..fd860930aa4 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/ShowAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/ShowAction.java
@@ -127,7 +127,7 @@ public class ShowAction implements RulesWsAction {
RuleDto rule = searchResult.getRules().get(0);
responseBuilder.setRule(mapper.toWsRule(rule.getDefinition(), searchResult, Collections.emptySet(), rule.getMetadata(),
ruleWsSupport.getUsersByUuid(dbSession, searchResult.getRules())));
- if (request.mandatoryParamAsBoolean(PARAM_ACTIVES)) {
+ if (request.mandatoryParamAsBoolean(PARAM_ACTIVES) && ruleWsSupport.areActiveRulesVisible(organization)) {
activeRuleCompleter.completeShow(dbSession, organization, rule.getDefinition()).forEach(responseBuilder::addActives);
}
return responseBuilder.build();
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/rule/ws/app-example.json b/server/sonar-server/src/main/resources/org/sonar/server/rule/ws/app-example.json
index cbd43235667..b8dc5cbc67c 100644
--- a/server/sonar-server/src/main/resources/org/sonar/server/rule/ws/app-example.json
+++ b/server/sonar-server/src/main/resources/org/sonar/server/rule/ws/app-example.json
@@ -1,31 +1,5 @@
{
"canWrite": false,
- "qualityprofiles": [
- {
- "key": "java-top-profile-without-formatting-conventions-50037",
- "name": "Default - Top",
- "lang": "java",
- "isBuiltIn": false
- },
- {
- "key": "java-sonar-way-80423",
- "name": "Sonar way",
- "lang": "java",
- "isBuiltIn": true
- },
- {
- "key": "js-sonar-way",
- "name": "Sonar way",
- "lang": "js",
- "isBuiltIn": true
- },
- {
- "key": "php-sonar-way-05548",
- "name": "Sonar way",
- "lang": "php",
- "isBuiltIn": true
- }
- ],
"languages": {
"js": "JavaScript",
"java": "Java",
diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/AppActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/AppActionTest.java
index d2e73661f75..f1815782807 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/AppActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/AppActionTest.java
@@ -30,20 +30,15 @@ import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.rule.RuleRepositoryDto;
-import org.sonar.db.user.UserDto;
-import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.language.LanguageTesting;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
-import org.sonarqube.ws.Rules;
-import static java.lang.String.format;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.db.organization.OrganizationDto.Subscription.PAID;
import static org.sonar.test.JsonAssert.assertJson;
public class AppActionTest {
@@ -111,24 +106,6 @@ public class AppActionTest {
}
@Test
- public void response_on_paid_organization() {
- OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addMembership(organization);
-
- String json = ws.newRequest()
- .setParam("organization", organization.getKey())
- .execute().getInput();;
-
- assertJson(json).isSimilarTo("{" +
- "\"languages\": {" +
- " \"xoo\": \"Xoo\"," +
- " \"ws\": \"Whitespace\"" +
- " }" +
- "}");
- }
-
- @Test
public void canWrite_is_true_if_user_is_profile_administrator_of_default_organization() {
userSession.addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, db.getDefaultOrganization());
@@ -182,19 +159,6 @@ public class AppActionTest {
.execute();
}
- @Test
- public void fail_on_paid_organization_when_not_member() {
- OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
- db.rules().insert();
-
- expectedException.expect(ForbiddenException.class);
- expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey()));
-
- ws.newRequest()
- .setParam("organization", organization.getKey())
- .executeProtobuf(Rules.SearchResponse.class);
- }
-
private void insertRules() {
RuleRepositoryDto repo1 = new RuleRepositoryDto("xoo", "xoo", "SonarQube");
RuleRepositoryDto repo2 = new RuleRepositoryDto("squid", "ws", "SonarQube");
diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleQueryFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleQueryFactoryTest.java
index d18c61f35fc..58cb0ad5005 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleQueryFactoryTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleQueryFactoryTest.java
@@ -31,8 +31,6 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.QProfileDto;
-import org.sonar.db.user.UserDto;
-import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.rule.index.RuleQuery;
@@ -41,7 +39,6 @@ import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsAction;
import org.sonar.server.ws.WsActionTester;
-import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.rule.RuleStatus.DEPRECATED;
import static org.sonar.api.rule.RuleStatus.READY;
@@ -56,6 +53,7 @@ import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
import static org.sonar.db.organization.OrganizationDto.Subscription.PAID;
import static org.sonar.db.qualityprofile.ActiveRuleDto.INHERITED;
import static org.sonar.db.qualityprofile.ActiveRuleDto.OVERRIDES;
+import static org.sonar.server.rule.ws.RuleWsSupport.defineGenericRuleSearchParameters;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_AVAILABLE_SINCE;
@@ -73,7 +71,6 @@ import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TEMPLATE_KEY;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TYPES;
-import static org.sonar.server.rule.ws.SearchAction.defineGenericRuleSearchParameters;
public class RuleQueryFactoryTest {
@@ -257,27 +254,28 @@ public class RuleQueryFactoryTest {
}
@Test
- public void filter_by_qprofile_when_subscription_is_paid_and_user_is_member() {
+ public void activation_is_kept_when_member_of_paid_organization() {
OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addMembership(organization);
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setName("Sonar way").setLanguage("xoo").setKee("sonar-way"));
+ userSession.logIn(db.users().insertUser()).addMembership(organization);
- RuleQuery result = execute(PARAM_QPROFILE, qualityProfile.getKee());
+ RuleQuery result = execute(
+ PARAM_ACTIVATION, "true",
+ PARAM_QPROFILE, profile.getKee());
- assertThat(result.getOrganization().getUuid()).isEqualTo(organization.getUuid());
+ assertThat(result.getActivation()).isTrue();
}
@Test
- public void filter_by_organization_when_subscription_is_paid_and_user_is_member() {
+ public void activation_is_set_to_null_when_not_member_of_paid_organization() {
OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addMembership(organization);
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setName("Sonar way").setLanguage("xoo").setKee("sonar-way"));
- RuleQuery result = execute(PARAM_ORGANIZATION, organization.getKey());
+ RuleQuery result = execute(
+ PARAM_ACTIVATION, "true",
+ PARAM_QPROFILE, profile.getKee());
- assertThat(result.getOrganization().getUuid()).isEqualTo(organization.getUuid());
+ assertThat(result.getActivation()).isNull();
}
@Test
@@ -347,27 +345,6 @@ public class RuleQueryFactoryTest {
PARAM_COMPARE_TO_PROFILE, "unknown");
}
- @Test
- public void fail_when_searching_by_organization_when_subscription_is_paid_and_user_is_not_member() {
- OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
-
- expectedException.expect(ForbiddenException.class);
- expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey()));
-
- execute(PARAM_ORGANIZATION, organization.getKey());
- }
-
- @Test
- public void fail_when_searching_by_qprofile_when_subscription_is_paid_and_user_is_not_member() {
- OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
-
- expectedException.expect(ForbiddenException.class);
- expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey()));
-
- execute(PARAM_QPROFILE, qualityProfile.getKee());
- }
-
private void assertResult(RuleQuery result, QProfileDto qualityProfile, QProfileDto compareToQualityProfile) {
assertThat(result.getKey()).isEqualTo("ruleKey");
diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java
index 6114ac6ab6e..1176a9efa1d 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java
@@ -45,7 +45,6 @@ import org.sonar.db.rule.RuleMetadataDto;
import org.sonar.db.rule.RuleParamDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.EsTester;
-import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.language.LanguageTesting;
import org.sonar.server.organization.DefaultOrganizationProvider;
@@ -70,7 +69,6 @@ import org.sonarqube.ws.Rules;
import org.sonarqube.ws.Rules.Rule;
import org.sonarqube.ws.Rules.SearchResponse;
-import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Collections.singleton;
@@ -83,6 +81,7 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.sonar.api.rule.Severity.BLOCKER;
+import static org.sonar.api.server.ws.WebService.Param.FIELDS;
import static org.sonar.db.organization.OrganizationDto.Subscription.PAID;
import static org.sonar.db.rule.RuleTesting.setSystemTags;
import static org.sonar.db.rule.RuleTesting.setTags;
@@ -159,8 +158,8 @@ public class SearchActionTest {
@Test
public void return_all_rules() {
- RuleDefinitionDto rule1 = createJavaRule();
- RuleDefinitionDto rule2 = createJavaRule();
+ RuleDefinitionDto rule1 = db.rules().insert(r1 -> r1.setLanguage("java"));
+ RuleDefinitionDto rule2 = db.rules().insert(r1 -> r1.setLanguage("java"));
indexRules();
verify(r -> {
@@ -192,8 +191,8 @@ public class SearchActionTest {
@Test
public void filter_by_rule_key() {
- RuleDefinitionDto rule1 = createJavaRule();
- RuleDefinitionDto rule2 = createJavaRule();
+ RuleDefinitionDto rule1 = db.rules().insert(r1 -> r1.setLanguage("java"));
+ RuleDefinitionDto rule2 = db.rules().insert(r1 -> r1.setLanguage("java"));
indexRules();
verify(r -> r.setParam(PARAM_RULE_KEY, rule1.getKey().toString()), rule1);
@@ -263,7 +262,7 @@ public class SearchActionTest {
@Test
public void return_all_rule_fields_by_default() {
- RuleDefinitionDto rule = createJavaRule();
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java"));
indexRules();
Rules.SearchResponse response = ws.newRequest().executeProtobuf(Rules.SearchResponse.class);
@@ -282,7 +281,7 @@ public class SearchActionTest {
@Test
public void return_subset_of_fields() {
- RuleDefinitionDto rule = createJavaRule();
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java"));
indexRules();
Rules.SearchResponse response = ws.newRequest()
@@ -311,9 +310,9 @@ public class SearchActionTest {
@Test
public void should_filter_on_organization_specific_tags() {
OrganizationDto organization = db.organizations().insert();
- RuleDefinitionDto rule1 = createJavaRule();
+ RuleDefinitionDto rule1 = db.rules().insert(r -> r.setLanguage("java"));
RuleMetadataDto metadata1 = insertMetadata(organization, rule1, setTags("tag1", "tag2"));
- RuleDefinitionDto rule2 = createJavaRule();
+ RuleDefinitionDto rule2 = db.rules().insert(r -> r.setLanguage("java"));
RuleMetadataDto metadata2 = insertMetadata(organization, rule2);
indexRules();
@@ -327,13 +326,13 @@ public class SearchActionTest {
@Test
public void when_searching_for_several_tags_combine_them_with_OR() {
OrganizationDto organization = db.organizations().insert();
- RuleDefinitionDto bothTagsRule = createJavaRule();
+ RuleDefinitionDto bothTagsRule = db.rules().insert(r -> r.setLanguage("java"));
insertMetadata(organization, bothTagsRule, setTags("tag1", "tag2"));
- RuleDefinitionDto oneTagRule = createJavaRule();
+ RuleDefinitionDto oneTagRule = db.rules().insert(r -> r.setLanguage("java"));
insertMetadata(organization, oneTagRule, setTags("tag1"));
- RuleDefinitionDto otherTagRule = createJavaRule();
+ RuleDefinitionDto otherTagRule = db.rules().insert(r -> r.setLanguage("java"));
insertMetadata(organization, otherTagRule, setTags("tag2"));
- RuleDefinitionDto noTagRule = createJavaRule();
+ RuleDefinitionDto noTagRule = db.rules().insert(r -> r.setLanguage("java"));
insertMetadata(organization, noTagRule, setTags());
indexRules();
@@ -406,7 +405,7 @@ public class SearchActionTest {
@Test
public void should_return_organization_specific_tags() {
OrganizationDto organization = db.organizations().insert();
- RuleDefinitionDto rule = createJavaRule();
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java"));
RuleMetadataDto metadata = insertMetadata(organization, rule, setTags("tag1", "tag2"));
indexRules();
@@ -444,7 +443,7 @@ public class SearchActionTest {
@Test
public void should_return_specified_fields() {
- RuleDefinitionDto rule = createJavaRule();
+ RuleDefinitionDto rule = db.rules().insert(r1 -> r1.setLanguage("java"));
indexRules();
checkField(rule, "repo", Rule::getRepo, rule.getRepositoryKey());
@@ -632,14 +631,13 @@ public class SearchActionTest {
public void search_all_active_rules() {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage("java"));
- RuleDefinitionDto rule = createJavaRule();
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java"));
RuleActivation activation = RuleActivation.create(rule.getId(), BLOCKER, null);
qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation));
indexRules();
SearchResponse result = ws.newRequest()
- .setParam("f", "")
.setParam("q", rule.getName())
.setParam("activation", "true")
.setParam("organization", organization.getKey())
@@ -658,9 +656,7 @@ public class SearchActionTest {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage("java"));
QProfileDto waterproofProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage("java"));
-
- RuleDefinitionDto rule = createJavaRule();
-
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java"));
RuleParamDto ruleParam1 = db.rules().insertRuleParam(rule, p -> p.setDefaultValue("some value")
.setType("STRING")
.setDescription("My small description")
@@ -680,11 +676,7 @@ public class SearchActionTest {
RuleActivation activation = RuleActivation.create(rule.getId());
List<ActiveRuleChange> activeRuleChanges1 = qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation));
qProfileRules.activateAndCommit(db.getSession(), waterproofProfile, singleton(activation));
-
assertThat(activeRuleChanges1).hasSize(1);
-
- db.commit();
-
indexRules();
indexActiveRules();
@@ -701,9 +693,8 @@ public class SearchActionTest {
assertThat(result.getActives().getActives().get(rule.getKey().toString())).isNotNull();
assertThat(result.getActives().getActives().get(rule.getKey().toString()).getActiveListList()).hasSize(1);
- Rules.Active activeList = result.getActives().getActives().get(rule.getKey().toString()).getActiveList(0);
-
// The rule without value is not inserted
+ Rules.Active activeList = result.getActives().getActives().get(rule.getKey().toString()).getActiveList(0);
assertThat(activeList.getParamsCount()).isEqualTo(2);
assertThat(activeList.getParamsList()).extracting("key", "value").containsExactlyInAnyOrder(
tuple(ruleParam1.getName(), ruleParam1.getDefaultValue()),
@@ -724,7 +715,7 @@ public class SearchActionTest {
OrganizationDto organization = db.organizations().insert();
QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage("java"));
- RuleDefinitionDto rule = createJavaRule();
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java"));
RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setDefaultValue("some value")
.setType("STRING")
@@ -922,34 +913,92 @@ public class SearchActionTest {
}
@Test
- public void returns_rules_on_paid_organization() {
+ public void active_rules_are_returned_when_member_of_paid_organization() {
OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
- RuleDefinitionDto rule = db.rules().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage("java"));
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java"));
+ RuleActivation activation = RuleActivation.create(rule.getId(), BLOCKER, null);
+ qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation));
+ userSession.logIn(db.users().insertUser()).addMembership(organization);
+
indexRules();
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addMembership(organization);
SearchResponse result = ws.newRequest()
- .setParam("organization", organization.getKey())
+ .setParam(FIELDS, "actives")
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
.executeProtobuf(SearchResponse.class);
- assertThat(result.getRulesList())
- .extracting(Rule::getKey)
- .containsExactlyInAnyOrder(rule.getKey().toString());
+ assertThat(result.getRulesCount()).isEqualTo(1);
+ assertThat(result.getActives().getActivesMap()).isNotEmpty();
}
@Test
- public void fail_on_paid_organization_when_not_member() {
+ public void active_rules_are_not_returned_when_not_member_of_paid_organization() {
OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
- db.rules().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage("java"));
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java"));
+ RuleActivation activation = RuleActivation.create(rule.getId(), BLOCKER, null);
+ qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation));
+
indexRules();
- expectedException.expect(ForbiddenException.class);
- expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey()));
+ SearchResponse result = ws.newRequest()
+ .setParam(FIELDS, "actives")
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .executeProtobuf(SearchResponse.class);
- ws.newRequest()
- .setParam("organization", organization.getKey())
+ assertThat(result.getRulesCount()).isEqualTo(1);
+ assertThat(result.getActives().getActivesMap()).isEmpty();
+ }
+
+ @Test
+ public void search_for_active_rules_when_member_of_paid_organization() {
+ OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage("java"));
+ // Rule1 is activated on profile
+ RuleDefinitionDto rule1 = db.rules().insert(r -> r.setLanguage("java"));
+ RuleActivation activation = RuleActivation.create(rule1.getId(), BLOCKER, null);
+ qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation));
+ // Rule2 is not activated
+ RuleDefinitionDto rule2 = db.rules().insert(r -> r.setLanguage("java"));
+ userSession.logIn(db.users().insertUser()).addMembership(organization);
+
+ indexRules();
+
+ SearchResponse result = ws.newRequest()
+ .setParam(FIELDS, "actives")
+ .setParam(PARAM_QPROFILE, profile.getKee())
+ .setParam(PARAM_ACTIVATION, "true")
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
.executeProtobuf(SearchResponse.class);
+
+ assertThat(result.getRulesList()).extracting(Rule::getKey)
+ .containsExactlyInAnyOrder(rule1.getKey().toString());
+ }
+
+ @Test
+ public void search_for_active_rules_is_ignored_when_not_member_of_paid_organization() {
+ OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
+ QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage("java"));
+ // Rule1 is activated on profile
+ RuleDefinitionDto rule1 = db.rules().insert(r -> r.setLanguage("java"));
+ RuleActivation activation = RuleActivation.create(rule1.getId(), BLOCKER, null);
+ qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation));
+ // Rule2 is not activated
+ RuleDefinitionDto rule2 = db.rules().insert(r -> r.setLanguage("java"));
+
+ indexRules();
+
+ SearchResponse result = ws.newRequest()
+ .setParam(FIELDS, "actives")
+ .setParam(PARAM_QPROFILE, profile.getKee())
+ .setParam(PARAM_ACTIVATION, "true")
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .executeProtobuf(SearchResponse.class);
+
+ // the 2 rules are returned as filter on profile is ignored
+ assertThat(result.getRulesList()).extracting(Rule::getKey)
+ .containsExactlyInAnyOrder(rule1.getKey().toString(), rule2.getKey().toString());
}
@SafeVarargs
@@ -995,7 +1044,4 @@ public class SearchActionTest {
activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
}
- private RuleDefinitionDto createJavaRule() {
- return db.rules().insert(r -> r.setLanguage("java"));
- }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java
index 3b860357eeb..a3f3d7b8797 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java
@@ -51,6 +51,7 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.sonar.db.organization.OrganizationDto.Subscription.PAID;
import static org.sonar.db.rule.RuleDto.Format.MARKDOWN;
import static org.sonar.db.rule.RuleTesting.newCustomRule;
import static org.sonar.db.rule.RuleTesting.newTemplateRule;
@@ -359,6 +360,39 @@ public class ShowActionTest {
}
@Test
+ public void active_rules_are_returned_when_member_of_paid_organization() {
+ OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
+ RuleDefinitionDto rule = db.rules().insert();
+ QProfileDto qProfile = db.qualityProfiles().insert(organization);
+ ActiveRuleDto activeRule = db.qualityProfiles().activateRule(qProfile, rule);
+ userSession.logIn(db.users().insertUser()).addMembership(organization);
+
+ ShowResponse result = ws.newRequest()
+ .setParam(PARAM_KEY, rule.getKey().toString())
+ .setParam(PARAM_ACTIVES, "true")
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .executeProtobuf(ShowResponse.class);
+
+ assertThat(result.getActivesList()).isNotEmpty();
+ }
+
+ @Test
+ public void active_rules_are_not_returned_when_not_member_of_paid_organization() {
+ OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
+ RuleDefinitionDto rule = db.rules().insert();
+ QProfileDto qProfile = db.qualityProfiles().insert(organization);
+ ActiveRuleDto activeRule = db.qualityProfiles().activateRule(qProfile, rule);
+
+ ShowResponse result = ws.newRequest()
+ .setParam(PARAM_KEY, rule.getKey().toString())
+ .setParam(PARAM_ACTIVES, "true")
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
+ .executeProtobuf(ShowResponse.class);
+
+ assertThat(result.getActivesList()).isEmpty();
+ }
+
+ @Test
public void throw_NotFoundException_if_organization_cannot_be_found() {
RuleDefinitionDto rule = db.rules().insert();