Skip to content

Commit

Permalink
SONAR-9139 Check 'Administer Quality Profiles' permission when creati…
Browse files Browse the repository at this point in the history
…ng custom rule
  • Loading branch information
julienlancelot committed Apr 20, 2017
1 parent e322ad7 commit 76f302c
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 9 deletions.
Expand Up @@ -65,19 +65,22 @@ public class CreateAction implements RulesWsAction {
private final RuleCreator ruleCreator;
private final RuleMapper ruleMapper;
private final OrganizationFlags organizationFlags;
private final RuleWsSupport ruleWsSupport;

public CreateAction(DbClient dbClient, RuleCreator ruleCreator, RuleMapper ruleMapper, OrganizationFlags organizationFlags) {
public CreateAction(DbClient dbClient, RuleCreator ruleCreator, RuleMapper ruleMapper, OrganizationFlags organizationFlags, RuleWsSupport ruleWsSupport) {
this.dbClient = dbClient;
this.ruleCreator = ruleCreator;
this.ruleMapper = ruleMapper;
this.organizationFlags = organizationFlags;
this.ruleWsSupport = ruleWsSupport;
}

@Override
public void define(WebService.NewController controller) {
WebService.NewAction action = controller
.createAction("create")
.setDescription("Create a custom rule")
.setDescription("Create a custom rule.<br>" +
"Requires the 'Administer Quality Profiles' permission")
.setSince("4.4")
.setChangelog(
new Change("5.5", "Creating manual rule is not more possible"),
Expand Down Expand Up @@ -137,6 +140,7 @@ public void define(WebService.NewController controller) {

@Override
public void handle(Request request, Response response) throws Exception {
ruleWsSupport.checkQProfileAdminPermission();
String customKey = request.mandatoryParam(PARAM_CUSTOM_KEY);
try (DbSession dbSession = dbClient.openSession(false)) {
organizationFlags.checkDisabled(dbSession);
Expand Down
Expand Up @@ -41,7 +41,8 @@ public DeleteAction(RuleDeleter ruleDeleter, RuleWsSupport ruleWsSupport) {
public void define(WebService.NewController controller) {
WebService.NewAction action = controller
.createAction("delete")
.setDescription("Delete custom rule")
.setDescription("Delete custom rule.<br/>" +
"Requires the 'Administer Quality Profiles' permission")
.setSince("4.4")
.setPost(true)
.setHandler(this);
Expand Down
Expand Up @@ -93,7 +93,8 @@ public void define(WebService.NewController controller) {
WebService.NewAction action = controller
.createAction("update")
.setPost(true)
.setDescription("Update an existing rule")
.setDescription("Update an existing rule.<br>" +
"Requires the 'Administer Quality Profiles' permission")
.setSince("4.4")
.setHandler(this);

Expand Down
Expand Up @@ -32,11 +32,15 @@
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.server.es.EsTester;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.organization.TestOrganizationFlags;
import org.sonar.server.rule.RuleCreator;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.text.MacroInterpreter;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
Expand All @@ -46,6 +50,7 @@
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
import static org.sonar.db.rule.RuleTesting.newCustomRule;
import static org.sonar.db.rule.RuleTesting.newTemplateRule;
import static org.sonar.server.util.TypeValidationsTesting.newFullTypeValidations;
Expand All @@ -58,29 +63,35 @@ public class CreateActionTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();

@Rule
public UserSessionRule userSession = UserSessionRule.standalone();

@Rule
public DbTester db = DbTester.create(system2);

@Rule
public EsTester es = new EsTester(new RuleIndexDefinition(new MapSettings()));

private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone();
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);

private WsActionTester wsTester = new WsActionTester(new CreateAction(db.getDbClient(),
private WsActionTester ws = new WsActionTester(new CreateAction(db.getDbClient(),
new RuleCreator(system2, new RuleIndexer(es.client(), db.getDbClient()), db.getDbClient(), newFullTypeValidations(),
TestDefaultOrganizationProvider.from(db)),
new RuleMapper(new Languages(), createMacroInterpreter()), organizationFlags));
new RuleMapper(new Languages(), createMacroInterpreter()), organizationFlags,
new RuleWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider)));

@Test
public void create_custom_rule() {
logInAsQProfileAdministrator();
organizationFlags.setEnabled(false);
// Template rule
RuleDto templateRule = newTemplateRule(RuleKey.of("java", "S001"), db.getDefaultOrganization());
db.rules().insert(templateRule.getDefinition());
db.rules().insertOrUpdateMetadata(templateRule.getMetadata().setRuleId(templateRule.getId()));
db.rules().insertRuleParam(templateRule.getDefinition(), param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(".*"));

String result = wsTester.newRequest()
String result = ws.newRequest()
.setParam("custom_key", "MY_CUSTOM")
.setParam("template_key", templateRule.getKey().toString())
.setParam("name", "My custom rule")
Expand Down Expand Up @@ -117,6 +128,7 @@ public void create_custom_rule() {

@Test
public void create_custom_rule_with_prevent_reactivation_param_to_true() {
logInAsQProfileAdministrator();
organizationFlags.setEnabled(false);
RuleDefinitionDto templateRule = newTemplateRule(RuleKey.of("java", "S001")).getDefinition();
db.rules().insert(templateRule);
Expand All @@ -130,7 +142,7 @@ public void create_custom_rule_with_prevent_reactivation_param_to_true() {
.setSeverity(Severity.MAJOR);
db.rules().insert(customRule);

TestResponse response = wsTester.newRequest()
TestResponse response = ws.newRequest()
.setParam("custom_key", "MY_CUSTOM")
.setParam("template_key", templateRule.getKey().toString())
.setParam("name", "My custom rule")
Expand All @@ -155,12 +167,13 @@ public void create_custom_rule_with_prevent_reactivation_param_to_true() {

@Test
public void fail_to_create_rule_when_organizations_are_enabled() throws Exception {
logInAsQProfileAdministrator();
organizationFlags.setEnabled(true);

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Organization support is enabled");

wsTester.newRequest()
ws.newRequest()
.setParam("custom_key", "MY_CUSTOM")
.setParam("template_key", "java:S001")
.setParam("name", "My custom rule")
Expand All @@ -169,10 +182,32 @@ public void fail_to_create_rule_when_organizations_are_enabled() throws Exceptio
.execute();
}

@Test
public void throw_ForbiddenException_if_not_profile_administrator() throws Exception {
userSession.logIn();

expectedException.expect(ForbiddenException.class);

ws.newRequest().execute();
}

@Test
public void throw_UnauthorizedException_if_not_logged_in() throws Exception {
expectedException.expect(UnauthorizedException.class);

ws.newRequest().execute();
}

private static MacroInterpreter createMacroInterpreter() {
MacroInterpreter macroInterpreter = mock(MacroInterpreter.class);
doAnswer(returnsFirstArg()).when(macroInterpreter).interpret(anyString());
return macroInterpreter;
}

private void logInAsQProfileAdministrator() {
userSession
.logIn()
.addPermission(ADMINISTER_QUALITY_PROFILES, defaultOrganizationProvider.get().getUuid());
}

}
Expand Up @@ -38,6 +38,8 @@
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.es.EsClient;
import org.sonar.server.es.EsTester;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.rule.RuleUpdater;
Expand Down Expand Up @@ -309,6 +311,22 @@ public void fail_to_update_custom_when_description_is_empty() {
.execute();
}

@Test
public void throw_ForbiddenException_if_not_profile_administrator() throws Exception {
userSession.logIn();

expectedException.expect(ForbiddenException.class);

ws.newRequest().setMethod("POST").execute();
}

@Test
public void throw_UnauthorizedException_if_not_logged_in() throws Exception {
expectedException.expect(UnauthorizedException.class);

ws.newRequest().setMethod("POST").execute();
}

private void logInAsQProfileAdministrator() {
userSession
.logIn()
Expand Down

0 comments on commit 76f302c

Please sign in to comment.