]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8857 make api/qualityprofiles/activate_rule organization aware
authorDaniel Schwarz <daniel.schwarz@sonarsource.com>
Thu, 23 Mar 2017 14:44:35 +0000 (15:44 +0100)
committerDaniel Schwarz <bartfastiel@users.noreply.github.com>
Thu, 23 Mar 2017 19:57:55 +0000 (20:57 +0100)
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileService.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRuleAction.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRuleAction.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRuleActionTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java

index b62c919fa9d4318ba8258f6a8b65d9e73697646d..4bd22cc921c97e13b4741f254d872f206f420e4b 100644 (file)
  */
 package org.sonar.server.qualityprofile;
 
-import java.util.List;
 import javax.annotation.Nullable;
 import org.sonar.api.server.ServerSide;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
 import org.sonar.server.organization.DefaultOrganizationProvider;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
 import org.sonar.server.rule.index.RuleQuery;
 import org.sonar.server.user.UserSession;
 
@@ -34,38 +30,16 @@ import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_
 @ServerSide
 public class QProfileService {
 
-  private final DbClient db;
-  private final ActiveRuleIndexer activeRuleIndexer;
   private final RuleActivator ruleActivator;
   private final UserSession userSession;
   private final DefaultOrganizationProvider defaultOrganizationProvider;
 
-  public QProfileService(DbClient db, ActiveRuleIndexer activeRuleIndexer, RuleActivator ruleActivator,
-    UserSession userSession, DefaultOrganizationProvider defaultOrganizationProvider) {
-    this.db = db;
-    this.activeRuleIndexer = activeRuleIndexer;
+  public QProfileService(RuleActivator ruleActivator, UserSession userSession, DefaultOrganizationProvider defaultOrganizationProvider) {
     this.ruleActivator = ruleActivator;
     this.userSession = userSession;
     this.defaultOrganizationProvider = defaultOrganizationProvider;
   }
 
-  /**
-   * Activate a rule on a Quality profile. Update configuration (severity/parameters) if the rule is already
-   * activated.
-   */
-  public List<ActiveRuleChange> activate(String profileKey, RuleActivation activation) {
-    verifyAdminPermission();
-    DbSession dbSession = db.openSession(false);
-    try {
-      List<ActiveRuleChange> changes = ruleActivator.activate(dbSession, activation, profileKey);
-      dbSession.commit();
-      activeRuleIndexer.index(changes);
-      return changes;
-    } finally {
-      dbSession.close();
-    }
-  }
-
   public BulkChangeResult bulkActivate(RuleQuery ruleQuery, String profile, @Nullable String severity) {
     verifyAdminPermission();
     return ruleActivator.bulkActivate(ruleQuery, profile, severity);
index c70949d85be88e0a57cd567652bb5e2f392269e7..342421b64e8957f419870bc67c8b7848436b0ac3 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.qualityprofile.ws;
 
+import java.util.List;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.server.ServerSide;
@@ -27,8 +28,16 @@ import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.KeyValueFormat;
 import org.sonar.core.util.Uuids;
-import org.sonar.server.qualityprofile.QProfileService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.permission.OrganizationPermission;
+import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.server.qualityprofile.ActiveRuleChange;
 import org.sonar.server.qualityprofile.RuleActivation;
+import org.sonar.server.qualityprofile.RuleActivator;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
+import org.sonar.server.user.UserSession;
 
 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_ACTIVATE_RULE;
 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ActivateActionParameters.PARAM_PARAMS;
@@ -40,10 +49,18 @@ import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.
 @ServerSide
 public class ActivateRuleAction implements QProfileWsAction {
 
-  private final QProfileService service;
+  private final DbClient dbClient;
+  private final RuleActivator ruleActivator;
+  private final UserSession userSession;
+  private final QProfileWsSupport wsSupport;
+  private final ActiveRuleIndexer activeRuleIndexer;
 
-  public ActivateRuleAction(QProfileService service) {
-    this.service = service;
+  public ActivateRuleAction(DbClient dbClient, RuleActivator ruleActivator, UserSession userSession, QProfileWsSupport wsSupport, ActiveRuleIndexer activeRuleIndexer) {
+    this.dbClient = dbClient;
+    this.ruleActivator = ruleActivator;
+    this.userSession = userSession;
+    this.wsSupport = wsSupport;
+    this.activeRuleIndexer = activeRuleIndexer;
   }
 
   public void define(WebService.NewController controller) {
@@ -88,10 +105,23 @@ public class ActivateRuleAction implements QProfileWsAction {
       activation.setParameters(KeyValueFormat.parse(params));
     }
     activation.setReset(Boolean.TRUE.equals(request.paramAsBoolean(PARAM_RESET)));
-    service.activate(request.mandatoryParam(PARAM_PROFILE_KEY), activation);
+    String profileKey = request.mandatoryParam(PARAM_PROFILE_KEY);
+    userSession.checkLoggedIn();
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      checkPermission(dbSession, profileKey);
+      List<ActiveRuleChange> changes = ruleActivator.activate(dbSession, activation, profileKey);
+      dbSession.commit();
+      activeRuleIndexer.index(changes);
+    }
   }
 
   private static RuleKey readRuleKey(Request request) {
     return RuleKey.parse(request.mandatoryParam(PARAM_RULE_KEY));
   }
+
+  private void checkPermission(DbSession dbSession, String qualityProfileKey) {
+    QualityProfileDto qualityProfile = dbClient.qualityProfileDao().selectByKey(dbSession, qualityProfileKey);
+    OrganizationDto organization = wsSupport.getOrganization(dbSession, qualityProfile);
+    userSession.checkPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+  }
 }
index e1173d8d632626547984f354bfb815dc53f48ecd..33331dc2dfae506b93b8a6e4e256897cc85760e5 100644 (file)
@@ -78,13 +78,13 @@ public class DeactivateRuleAction implements QProfileWsAction {
     String qualityProfileKey = request.mandatoryParam(PARAM_PROFILE_KEY);
     userSession.checkLoggedIn();
     try (DbSession dbSession = dbClient.openSession(false)) {
-      checkPermission(qualityProfileKey, dbSession);
+      checkPermission(dbSession, qualityProfileKey);
       ActiveRuleKey activeRuleKey = ActiveRuleKey.of(qualityProfileKey, ruleKey);
       ruleActivator.deactivateAndUpdateIndex(dbSession, activeRuleKey);
     }
   }
 
-  private void checkPermission(String qualityProfileKey, DbSession dbSession) {
+  private void checkPermission(DbSession dbSession, String qualityProfileKey) {
     QualityProfileDto qualityProfile = dbClient.qualityProfileDao().selectByKey(dbSession, qualityProfileKey);
     OrganizationDto organization = wsSupport.getOrganization(dbSession, qualityProfile);
     userSession.checkPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
index 381f1b1a1cf0c5a39745dad840c4c11dd0c90ef0..9192c520ffc26237e5f6a235ebd58a090b7f8e85 100644 (file)
  */
 package org.sonar.server.qualityprofile.ws;
 
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.server.qualityprofile.QProfileService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.permission.OrganizationPermission;
+import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.db.rule.RuleTesting;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
+import org.sonar.server.qualityprofile.RuleActivation;
+import org.sonar.server.qualityprofile.RuleActivator;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
 
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.data.MapEntry.entry;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE;
 
 public class ActivateRuleActionTest {
 
+  @Rule
+  public DbTester dbTester = DbTester.create();
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  private DbClient dbClient = dbTester.getDbClient();
+  private RuleActivator ruleActivator = mock(RuleActivator.class);
+  private QProfileWsSupport wsSupport = new QProfileWsSupport(dbClient, userSession, TestDefaultOrganizationProvider.from(dbTester));
+  private ActiveRuleIndexer activeRuleIndexer = mock(ActiveRuleIndexer.class);
+  private ActivateRuleAction underTest = new ActivateRuleAction(dbClient, ruleActivator, userSession, wsSupport, activeRuleIndexer);
+  private WsActionTester wsActionTester = new WsActionTester(underTest);
+  private OrganizationDto defaultOrganization;
+  private OrganizationDto organization;
+
+  @Before
+  public void before() {
+    defaultOrganization = dbTester.getDefaultOrganization();
+    organization = dbTester.organizations().insert();
+  }
+
   @Test
   public void define_activate_rule_action() {
-    ActivateRuleAction action = new ActivateRuleAction(mock(QProfileService.class));
-    WebService.Action definition = new WsActionTester(action).getDef();
+    WebService.Action definition = wsActionTester.getDef();
     assertThat(definition).isNotNull();
     assertThat(definition.isPost()).isTrue();
     assertThat(definition.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("severity", "profile_key", "reset", "rule_key", "params");
   }
+
+  @Test
+  public void should_fail_if_not_logged_in() {
+    TestRequest request = wsActionTester.newRequest()
+      .setMethod("POST")
+      .setParam("rule_key", RuleTesting.newRuleDto().getKey().toString())
+      .setParam("profile_key", randomAlphanumeric(UUID_SIZE));
+
+    thrown.expect(UnauthorizedException.class);
+    request.execute();
+  }
+
+  @Test
+  public void should_fail_if_not_organization_quality_profile_administrator() {
+    userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);
+    QualityProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization);
+    TestRequest request = wsActionTester.newRequest()
+      .setMethod("POST")
+      .setParam("rule_key", RuleTesting.newRuleDto().getKey().toString())
+      .setParam("profile_key", qualityProfile.getKey());
+
+    thrown.expect(ForbiddenException.class);
+    request.execute();
+  }
+
+  @Test
+  public void activate_rule_in_default_organization() {
+    userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);
+    QualityProfileDto qualityProfile = dbTester.qualityProfiles().insert(defaultOrganization);
+    RuleKey ruleKey = RuleTesting.randomRuleKey();
+    TestRequest request = wsActionTester.newRequest()
+      .setMethod("POST")
+      .setParam("rule_key", ruleKey.toString())
+      .setParam("profile_key", qualityProfile.getKey())
+      .setParam("severity", "BLOCKER")
+      .setParam("params", "key1=v1;key2=v2")
+      .setParam("reset", "false");
+    request.execute();
+
+    ArgumentCaptor<RuleActivation> captor = ArgumentCaptor.forClass(RuleActivation.class);
+    Mockito.verify(ruleActivator).activate(any(DbSession.class), captor.capture(), eq(qualityProfile.getKey()));
+    assertThat(captor.getValue().getRuleKey()).isEqualTo(ruleKey);
+    assertThat(captor.getValue().getSeverity()).isEqualTo(Severity.BLOCKER);
+    assertThat(captor.getValue().getParameters()).containsExactly(entry("key1", "v1"), entry("key2", "v2"));
+    assertThat(captor.getValue().isReset()).isFalse();
+  }
+
+  @Test
+  public void activate_rule_in_specific_organization() {
+    userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
+    QualityProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization);
+    RuleKey ruleKey = RuleTesting.randomRuleKey();
+    TestRequest request = wsActionTester.newRequest()
+      .setMethod("POST")
+      .setParam("rule_key", ruleKey.toString())
+      .setParam("profile_key", qualityProfile.getKey())
+      .setParam("severity", "BLOCKER")
+      .setParam("params", "key1=v1;key2=v2")
+      .setParam("reset", "false");
+
+    request.execute();
+
+    ArgumentCaptor<RuleActivation> captor = ArgumentCaptor.forClass(RuleActivation.class);
+    Mockito.verify(ruleActivator).activate(any(DbSession.class), captor.capture(), eq(qualityProfile.getKey()));
+    assertThat(captor.getValue().getRuleKey()).isEqualTo(ruleKey);
+    assertThat(captor.getValue().getSeverity()).isEqualTo(Severity.BLOCKER);
+    assertThat(captor.getValue().getParameters()).containsExactly(entry("key1", "v1"), entry("key2", "v2"));
+    assertThat(captor.getValue().isReset()).isFalse();
+  }
 }
index 09917e0d9a90066886358cdf63078823dddbdc9c..6a4167001ecf3cd3827af43aaef55e557b266906 100644 (file)
@@ -36,7 +36,6 @@ import org.sonar.db.DbTester;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.qualityprofile.ActiveRuleDto;
 import org.sonar.db.qualityprofile.QualityProfileDto;
-import org.sonar.db.qualityprofile.QualityProfileTesting;
 import org.sonar.db.rule.RuleDefinitionDto;
 import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleTesting;
@@ -60,9 +59,6 @@ import org.sonar.server.util.TypeValidations;
 import org.sonar.server.ws.WsActionTester;
 import org.sonar.test.JsonAssert;
 
-import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
-import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
-
 public class InheritanceActionTest {
 
   @Rule
@@ -106,8 +102,6 @@ public class InheritanceActionTest {
       activeRuleIndexer,
       userSession);
     service = new QProfileService(
-      dbClient,
-      activeRuleIndexer,
       ruleActivator,
       userSession,
       defaultOrganizationProvider);
@@ -177,38 +171,6 @@ public class InheritanceActionTest {
       .setMethod("GET").setParam("profileKey", "polop").execute();
   }
 
-  @Test
-  public void stat_for_all_profiles() {
-    userSession.logIn()
-      .addPermission(ADMINISTER_QUALITY_PROFILES, organization.getUuid());
-
-    String language = randomAlphanumeric(20);
-
-    QualityProfileDto profile1 = QualityProfileTesting.newQualityProfileDto()
-      .setOrganizationUuid(organization.getUuid())
-      .setLanguage(language);
-    QualityProfileDto profile2 = QualityProfileTesting.newQualityProfileDto()
-      .setOrganizationUuid(organization.getUuid())
-      .setLanguage(language);
-    dbClient.qualityProfileDao().insert(dbSession, profile1, profile2);
-
-    RuleDto rule = RuleTesting.newRuleDto()
-      .setSeverity("MINOR")
-      .setLanguage(profile1.getLanguage());
-    dbClient.ruleDao().insert(dbSession, rule.getDefinition());
-    dbSession.commit();
-
-    userSession.logIn()
-      .addPermission(ADMINISTER_QUALITY_PROFILES, dbTester.getDefaultOrganization().getUuid());
-
-    service.activate(profile1.getKey(), new RuleActivation(rule.getKey()).setSeverity("MINOR"));
-    service.activate(profile2.getKey(), new RuleActivation(rule.getKey()).setSeverity("BLOCKER"));
-    activeRuleIndexer.index();
-
-    userSession.logIn()
-      .addPermission(ADMINISTER_QUALITY_PROFILES, organization.getUuid());
-  }
-
   private QualityProfileDto createProfile(String lang, String name, String key) {
     QualityProfileDto profile = QProfileTesting.newQProfileDto(organization, new QProfileName(lang, name), key);
     dbClient.qualityProfileDao().insert(dbSession, profile);
index 485efbac593b717428bdca0ad24026c6c7d0b5d2..186a8b3487070c6097e97fafcbdf64b8bf0c09a4 100644 (file)
@@ -49,9 +49,9 @@ import org.sonar.db.rule.RuleTesting;
 import org.sonar.server.es.SearchOptions;
 import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.platform.Platform;
-import org.sonar.server.qualityprofile.QProfileService;
 import org.sonar.server.qualityprofile.QProfileTesting;
 import org.sonar.server.qualityprofile.RuleActivation;
+import org.sonar.server.qualityprofile.RuleActivator;
 import org.sonar.server.rule.index.RuleIndex;
 import org.sonar.server.rule.index.RuleQuery;
 import org.sonar.server.tester.ServerTester;
@@ -124,7 +124,7 @@ public class RegisterRulesMediumTest {
     dbSession.commit();
     dbSession.clearCache();
     RuleActivation activation = new RuleActivation(RuleTesting.XOO_X1);
-    TESTER.get(QProfileService.class).activate(QProfileTesting.XOO_P1_KEY, activation);
+    TESTER.get(RuleActivator.class).activate(dbSession, activation, QProfileTesting.XOO_P1_KEY);
 
     // Restart, repo xoo still exists -> deactivate x1
     register(new Rules() {
@@ -155,7 +155,8 @@ public class RegisterRulesMediumTest {
     dbSession.commit();
     dbSession.clearCache();
     RuleActivation activation = new RuleActivation(RuleTesting.XOO_X1);
-    TESTER.get(QProfileService.class).activate(QProfileTesting.XOO_P1_KEY, activation);
+    TESTER.get(RuleActivator.class).activate(dbSession, activation, QProfileTesting.XOO_P1_KEY);
+    dbSession.commit();
 
     // Restart without xoo
     register(null);
@@ -191,7 +192,8 @@ public class RegisterRulesMediumTest {
     dbSession.clearCache();
     RuleActivation activation = new RuleActivation(RuleTesting.XOO_X1);
     activation.setParameter("format", "txt");
-    TESTER.get(QProfileService.class).activate(QProfileTesting.XOO_P1_KEY, activation);
+    TESTER.get(RuleActivator.class).activate(dbSession, activation, QProfileTesting.XOO_P1_KEY);
+    dbSession.commit();
 
     // Default value of "min" is changed, "format" is removed, "format2" is added, "max" is added with a default value
     register(new Rules() {
@@ -231,7 +233,7 @@ public class RegisterRulesMediumTest {
 
     // User adds tag
     TESTER.get(RuleUpdater.class).update(dbSession, RuleUpdate.createForPluginRule(RuleTesting.XOO_X1).setTags(newHashSet("tag2")), userSessionRule);
-    dbSession.clearCache();
+    dbSession.commit();
 
     rule = ruleDao.selectOrFailByKey(dbSession, defaultOrganizationUuid, RuleTesting.XOO_X1);
     assertThat(rule.getSystemTags()).containsOnly("tag1");