From 63f165ea9ec729f31d578f7f35483cba619e70d0 Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Wed, 21 Jun 2017 16:44:16 +0200 Subject: [PATCH] SONAR-9448 Sanitize api/qualityprofiles/activate_rules --- .../ws/ActivateRulesAction.java | 36 ++++++------ .../ws/ActivateRulesActionTest.java | 55 +++++++++++-------- .../ws/QProfilesWsMediumTest.java | 29 +++++----- .../QualityProfileWsParameters.java | 7 ++- 4 files changed, 71 insertions(+), 56 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 2521c9dcd18..bb8918fcf48 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 @@ -20,7 +20,6 @@ package org.sonar.server.qualityprofile.ws; import org.sonar.api.rule.Severity; -import org.sonar.api.server.ServerSide; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -32,17 +31,16 @@ import org.sonar.server.qualityprofile.RuleActivator; import org.sonar.server.rule.ws.RuleQueryFactory; 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.defineRuleSearchParameters; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_ACTIVATE_RULES; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_PROFILE; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_SEVERITY; -@ServerSide public class ActivateRulesAction implements QProfileWsAction { - public static final String PROFILE_KEY = "profile_key"; - public static final String SEVERITY = "activation_severity"; - - public static final String ACTIVATE_RULES_ACTION = "activate_rules"; - private final RuleQueryFactory ruleQueryFactory; private final UserSession userSession; private final RuleActivator ruleActivator; @@ -59,35 +57,39 @@ public class ActivateRulesAction implements QProfileWsAction { public void define(WebService.NewController controller) { WebService.NewAction activate = controller - .createAction(ACTIVATE_RULES_ACTION) - .setDescription("Bulk-activate rules on one or several Quality profiles") + .createAction(ACTION_ACTIVATE_RULES) + .setDescription("Bulk-activate rules on one quality profile.
" + + "Requires to be logged in and the 'Administer Quality Profiles' permission.") .setPost(true) .setSince("4.4") .setHandler(this); defineRuleSearchParameters(activate); - activate.createParam(PROFILE_KEY) - .setDescription("Quality Profile Key. To retrieve a profile key for a given language please see api/qualityprofiles/search") + activate.createParam(PARAM_TARGET_PROFILE) + .setDescription("Quality Profile key on which the rule activation is done. To retrieve a profile key please see api/qualityprofiles/search") + .setDeprecatedKey("profile_key", "6.5") .setRequired(true) - .setExampleValue("java:MyProfile"); + .setExampleValue(UUID_EXAMPLE_03); - activate.createParam(SEVERITY) - .setDescription("Optional severity of rules activated in bulk") + activate.createParam(PARAM_TARGET_SEVERITY) + .setDescription("Severity to set on the activated rules") + .setDeprecatedKey("activation_severity", "6.5") .setPossibleValues(Severity.ALL); } @Override public void handle(Request request, Response response) throws Exception { - String qualityProfileKey = request.mandatoryParam(PROFILE_KEY); + String qualityProfileKey = request.mandatoryParam(PARAM_TARGET_PROFILE); userSession.checkLoggedIn(); BulkChangeResult result; try (DbSession dbSession = dbClient.openSession(false)) { QProfileDto profile = wsSupport.getProfile(dbSession, fromKey(qualityProfileKey)); wsSupport.checkPermission(dbSession, profile); wsSupport.checkNotBuiltInt(profile); - result = ruleActivator.bulkActivate(dbSession, ruleQueryFactory.createRuleQuery(dbSession, request), profile, request.param(SEVERITY)); + result = ruleActivator.bulkActivate(dbSession, ruleQueryFactory.createRuleQuery(dbSession, request), profile, request.param(PARAM_TARGET_SEVERITY)); } - BulkChangeWsResponse.writeResponse(result, response); + + writeResponse(result, response); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java index 4c53be97188..1074eda558a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java @@ -43,34 +43,36 @@ import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_PROFILE; public class ActivateRulesActionTest { @Rule - public DbTester dbTester = DbTester.create(); + public DbTester db = DbTester.create(); @Rule public UserSessionRule userSession = UserSessionRule.standalone(); @Rule - public ExpectedException thrown = ExpectedException.none(); + public ExpectedException expectedException = ExpectedException.none(); - private DbClient dbClient = dbTester.getDbClient(); + private DbClient dbClient = db.getDbClient(); private RuleActivator ruleActivator = mock(RuleActivator.class); - private QProfileWsSupport wsSupport = new QProfileWsSupport(dbClient, userSession, TestDefaultOrganizationProvider.from(dbTester)); + private QProfileWsSupport wsSupport = new QProfileWsSupport(dbClient, userSession, TestDefaultOrganizationProvider.from(db)); private RuleQueryFactory ruleQueryFactory = mock(RuleQueryFactory.class); - private ActivateRulesAction underTest = new ActivateRulesAction(ruleQueryFactory, userSession, ruleActivator, wsSupport, dbClient); - private WsActionTester wsActionTester = new WsActionTester(underTest); + + private WsActionTester ws = new WsActionTester(new ActivateRulesAction(ruleQueryFactory, userSession, ruleActivator, wsSupport, dbClient)); + private OrganizationDto defaultOrganization; private OrganizationDto organization; @Before public void before() { - defaultOrganization = dbTester.getDefaultOrganization(); - organization = dbTester.organizations().insert(); + defaultOrganization = db.getDefaultOrganization(); + organization = db.organizations().insert(); } @Test public void define_bulk_activate_rule_action() { - WebService.Action definition = wsActionTester.getDef(); + WebService.Action definition = ws.getDef(); assertThat(definition).isNotNull(); assertThat(definition.isPost()).isTrue(); assertThat(definition.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder( @@ -80,42 +82,46 @@ public class ActivateRulesActionTest { "is_template", "inheritance", "qprofile", - "activation_severity", + "targetSeverity", "tags", "asc", "q", "active_severities", "s", "repositories", - "profile_key", + "targetProfile", "statuses", "rule_key", "available_since", "activation", "severities", - "organization" - ); + "organization"); + WebService.Param targetProfile = definition.param("targetProfile"); + assertThat(targetProfile.deprecatedKey()).isEqualTo("profile_key"); + WebService.Param targetSeverity = definition.param("targetSeverity"); + assertThat(targetSeverity.deprecatedKey()).isEqualTo("activation_severity"); } @Test public void should_fail_if_not_logged_in() { - TestRequest request = wsActionTester.newRequest() + TestRequest request = ws.newRequest() .setMethod("POST") - .setParam("profile_key", randomAlphanumeric(UUID_SIZE)); + .setParam(PARAM_TARGET_PROFILE, randomAlphanumeric(UUID_SIZE)); + + expectedException.expect(UnauthorizedException.class); - thrown.expect(UnauthorizedException.class); request.execute(); } @Test public void fail_if_built_in_profile() { userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization); - QProfileDto qualityProfile = dbTester.qualityProfiles().insert(defaultOrganization, p -> p.setIsBuiltIn(true)); - TestRequest request = wsActionTester.newRequest() + QProfileDto qualityProfile = db.qualityProfiles().insert(defaultOrganization, p -> p.setIsBuiltIn(true)); + TestRequest request = ws.newRequest() .setMethod("POST") - .setParam("profile_key", qualityProfile.getKee()); + .setParam(PARAM_TARGET_PROFILE, qualityProfile.getKee()); - thrown.expect(BadRequestException.class); + expectedException.expect(BadRequestException.class); request.execute(); } @@ -123,12 +129,13 @@ public class ActivateRulesActionTest { @Test public void should_fail_if_not_organization_quality_profile_administrator() { userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization); - QProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization); - TestRequest request = wsActionTester.newRequest() + QProfileDto qualityProfile = db.qualityProfiles().insert(organization); + TestRequest request = ws.newRequest() .setMethod("POST") - .setParam("profile_key", qualityProfile.getKee()); + .setParam(PARAM_TARGET_PROFILE, qualityProfile.getKee()); + + expectedException.expect(ForbiddenException.class); - thrown.expect(ForbiddenException.class); request.execute(); } } 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 3e5bc43204f..aafab74035f 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 @@ -58,11 +58,14 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; import static org.sonar.server.qualityprofile.ws.QProfilesWs.API_ENDPOINT; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_ACTIVATE_RULE; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_ACTIVATE_RULES; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_DEACTIVATE_RULE; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROFILE; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_RESET; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_RULE; import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_SEVERITY; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_PROFILE; +import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_SEVERITY; import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES; import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE; @@ -285,8 +288,8 @@ public class QProfilesWsMediumTest { assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty(); // 1. Activate Rule - WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ActivateRulesAction.ACTIVATE_RULES_ACTION); - request.setParam(ActivateActionParameters.PARAM_PROFILE_KEY, profile.getKee()); + WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULES); + request.setParam(PARAM_TARGET_PROFILE, profile.getKee()); request.setParam(PARAM_LANGUAGES, "java"); request.execute().assertJson(getClass(), "bulk_activate_rule.json"); dbSession.clearCache(); @@ -309,8 +312,8 @@ public class QProfilesWsMediumTest { assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).isEmpty(); // 1. Activate Rule - WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ActivateRulesAction.ACTIVATE_RULES_ACTION); - request.setParam(ActivateActionParameters.PARAM_PROFILE_KEY, php.getKee()); + WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULES); + request.setParam(PARAM_TARGET_PROFILE, php.getKee()); request.setParam(PARAM_LANGUAGES, "php"); request.execute().assertJson(getClass(), "bulk_activate_rule_not_all.json"); dbSession.clearCache(); @@ -332,8 +335,8 @@ public class QProfilesWsMediumTest { assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty(); // 1. Activate Rule with query returning 0 hits - WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ActivateRulesAction.ACTIVATE_RULES_ACTION); - request.setParam(ActivateActionParameters.PARAM_PROFILE_KEY, profile.getKee()); + WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULES); + request.setParam(PARAM_TARGET_PROFILE, profile.getKee()); request.setParam(Param.TEXT_QUERY, "php"); request.execute(); dbSession.clearCache(); @@ -342,8 +345,8 @@ public class QProfilesWsMediumTest { assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(0); // 1. Activate Rule with query returning 1 hits - request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ActivateRulesAction.ACTIVATE_RULES_ACTION); - request.setParam(ActivateActionParameters.PARAM_PROFILE_KEY, profile.getKee()); + request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULES); + request.setParam(PARAM_TARGET_PROFILE, profile.getKee()); request.setParam(Param.TEXT_QUERY, "world"); request.execute(); dbSession.commit(); @@ -368,9 +371,9 @@ public class QProfilesWsMediumTest { new SearchOptions()).getIds()).hasSize(2); // 1. Activate Rule with query returning 2 hits - WsTester.TestRequest request = ws.newPostRequest(API_ENDPOINT, ActivateRulesAction.ACTIVATE_RULES_ACTION); - request.setParam(ActivateRulesAction.PROFILE_KEY, profile.getKee()); - request.setParam(ActivateRulesAction.SEVERITY, "MINOR"); + WsTester.TestRequest request = ws.newPostRequest(API_ENDPOINT, ACTION_ACTIVATE_RULES); + request.setParam(PARAM_TARGET_PROFILE, profile.getKee()); + request.setParam(PARAM_TARGET_SEVERITY, "MINOR"); request.execute(); dbSession.commit(); @@ -394,8 +397,8 @@ public class QProfilesWsMediumTest { dbSession.commit(); // 1. Activate Rule - WsTester.TestRequest request = ws.newPostRequest(API_ENDPOINT, ActivateRulesAction.ACTIVATE_RULES_ACTION); - request.setParam(ActivateActionParameters.PARAM_PROFILE_KEY, javaProfile.getKee()); + WsTester.TestRequest request = ws.newPostRequest(API_ENDPOINT, ACTION_ACTIVATE_RULES); + request.setParam(PARAM_TARGET_PROFILE, javaProfile.getKee()); request.setParam(PARAM_QPROFILE, javaProfile.getKee()); request.setParam("activation", "false"); request.execute().assertJson(getClass(), "does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json"); diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/QualityProfileWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/QualityProfileWsParameters.java index 8ce547d3a5b..19fd430ca7f 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/QualityProfileWsParameters.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualityprofile/QualityProfileWsParameters.java @@ -22,6 +22,7 @@ package org.sonarqube.ws.client.qualityprofile; public class QualityProfileWsParameters { public static final String CONTROLLER_QUALITY_PROFILES = "api/qualityprofiles"; + public interface ActivateActionParameters { String PARAM_PROFILE_KEY = "profile_key"; } @@ -30,8 +31,9 @@ public class QualityProfileWsParameters { public interface RestoreActionParameters { String PARAM_BACKUP = "backup"; } - public static final String ACTION_ACTIVATE_RULE = "activate_rule"; + public static final String ACTION_ACTIVATE_RULE = "activate_rule"; + public static final String ACTION_ACTIVATE_RULES = "activate_rules"; public static final String ACTION_ADD_PROJECT = "add_project"; public static final String ACTION_CHANGE_PARENT = "change_parent"; public static final String ACTION_COPY = "copy"; @@ -56,8 +58,9 @@ public class QualityProfileWsParameters { public static final String PARAM_PROJECT_UUID = "projectUuid"; public static final String PARAM_RESET = "reset"; public static final String PARAM_RULE = "rule"; - public static final String PARAM_RULE_KEY = "ruleKey"; public static final String PARAM_SEVERITY = "severity"; + public static final String PARAM_TARGET_PROFILE = "targetProfile"; + public static final String PARAM_TARGET_SEVERITY = "targetSeverity"; public static final String PARAM_TO_NAME = "toName"; private QualityProfileWsParameters() { -- 2.39.5