]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8857 support organization in api/qualityprofiles/copy
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 16 Mar 2017 15:40:11 +0000 (16:40 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 23 Mar 2017 16:38:34 +0000 (17:38 +0100)
- verify permission on the related organization
- create the target profile (if needed) on the same organization
- no need to add the WS parameter "organization" because
"fromKey" is self-sufficient to identify the profile.

server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileCopier.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CopyAction.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileCopierMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CopyActionTest.java

index 8ea3e37967b30bb8ec2364162657188ce2414dc0..7f54187922e20cc732ce8fec24bd73e20ca3dfc6 100644 (file)
@@ -51,14 +51,13 @@ public class QProfileCopier {
     this.temp = temp;
   }
 
-  public QualityProfileDto copyToName(DbSession dbSession, String fromKey, String toName) {
-    QualityProfileDto from = db.qualityProfileDao().selectOrFailByKey(dbSession, fromKey);
-    OrganizationDto organization = db.organizationDao().selectByUuid(dbSession, from.getOrganizationUuid())
-      .orElseThrow(() -> new IllegalStateException("Organization with UUID [" + from.getOrganizationUuid() + "] does not exist"));
-    QualityProfileDto to = prepareTarget(dbSession, organization, from, toName);
+  public QualityProfileDto copyToName(DbSession dbSession, QualityProfileDto sourceProfile, String toName) {
+    OrganizationDto organization = db.organizationDao().selectByUuid(dbSession, sourceProfile.getOrganizationUuid())
+      .orElseThrow(() -> new IllegalStateException("Organization with UUID [" + sourceProfile.getOrganizationUuid() + "] does not exist"));
+    QualityProfileDto to = prepareTarget(dbSession, organization, sourceProfile, toName);
     File backupFile = temp.newFile();
     try {
-      backup(dbSession, from, backupFile);
+      backup(dbSession, sourceProfile, backupFile);
       restore(dbSession, backupFile, to);
       return to;
     } finally {
@@ -66,13 +65,13 @@ public class QProfileCopier {
     }
   }
 
-  private QualityProfileDto prepareTarget(DbSession dbSession, OrganizationDto organization, QualityProfileDto from, String toName) {
-    QProfileName toProfileName = new QProfileName(from.getLanguage(), toName);
-    verify(from, toProfileName);
+  private QualityProfileDto prepareTarget(DbSession dbSession, OrganizationDto organization, QualityProfileDto sourceProfile, String toName) {
+    QProfileName toProfileName = new QProfileName(sourceProfile.getLanguage(), toName);
+    verify(sourceProfile, toProfileName);
     QualityProfileDto toProfile = db.qualityProfileDao().selectByNameAndLanguage(organization, toProfileName.getName(), toProfileName.getLanguage(), dbSession);
     if (toProfile == null) {
       toProfile = factory.checkAndCreate(dbSession, organization, toProfileName);
-      toProfile.setParentKee(from.getParentKee());
+      toProfile.setParentKee(sourceProfile.getParentKee());
       db.qualityProfileDao().update(dbSession, toProfile);
       dbSession.commit();
     }
index 9627e4c7a4fabcc6359590f15efa1f3053d2ff05..8d2c3ea501ff0e1139a76f633b20b3721b7d46b0 100644 (file)
@@ -28,8 +28,10 @@ import org.sonar.api.server.ws.WebService.NewAction;
 import org.sonar.core.util.Uuids;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.permission.OrganizationPermission;
 import org.sonar.db.qualityprofile.QualityProfileDto;
 import org.sonar.server.qualityprofile.QProfileCopier;
+import org.sonar.server.user.UserSession;
 
 public class CopyAction implements QProfileWsAction {
 
@@ -39,29 +41,31 @@ public class CopyAction implements QProfileWsAction {
   private final DbClient dbClient;
   private final QProfileCopier profileCopier;
   private final Languages languages;
-  private final QProfileWsSupport qProfileWsSupport;
+  private final UserSession userSession;
+  private final QProfileWsSupport wsSupport;
 
-  public CopyAction(DbClient dbClient, QProfileCopier profileCopier, Languages languages, QProfileWsSupport qProfileWsSupport) {
+  public CopyAction(DbClient dbClient, QProfileCopier profileCopier, Languages languages, UserSession userSession, QProfileWsSupport wsSupport) {
     this.dbClient = dbClient;
     this.profileCopier = profileCopier;
     this.languages = languages;
-    this.qProfileWsSupport = qProfileWsSupport;
+    this.userSession = userSession;
+    this.wsSupport = wsSupport;
   }
 
   @Override
   public void define(WebService.NewController controller) {
-    NewAction setDefault = controller.createAction("copy")
+    NewAction action = controller.createAction("copy")
         .setSince("5.2")
         .setDescription("Copy a quality profile. Require Administer Quality Profiles permission.")
         .setPost(true)
         .setHandler(this);
 
-    setDefault.createParam(PARAM_PROFILE_NAME)
+    action.createParam(PARAM_PROFILE_NAME)
         .setDescription("The name for the new quality profile.")
         .setExampleValue("My Sonar way")
         .setRequired(true);
 
-    setDefault.createParam(PARAM_PROFILE_KEY)
+    action.createParam(PARAM_PROFILE_KEY)
         .setDescription("The key of a quality profile.")
         .setExampleValue(Uuids.UUID_EXAMPLE_01)
         .setRequired(true);
@@ -69,13 +73,16 @@ public class CopyAction implements QProfileWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
-    qProfileWsSupport.checkQProfileAdminPermission();
+    userSession.checkLoggedIn();
 
     String newName = request.mandatoryParam(PARAM_PROFILE_NAME);
     String profileKey = request.mandatoryParam(PARAM_PROFILE_KEY);
 
     try (DbSession dbSession = dbClient.openSession(false)) {
-      QualityProfileDto copiedProfile = profileCopier.copyToName(dbSession, profileKey, newName);
+      QualityProfileDto sourceProfile = wsSupport.getProfile(dbSession, QProfileReference.fromKey(profileKey));
+      userSession.checkPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, sourceProfile.getOrganizationUuid());
+
+      QualityProfileDto copiedProfile = profileCopier.copyToName(dbSession, sourceProfile, newName);
 
       String languageKey = copiedProfile.getLanguage();
       Language language = languages.get(copiedProfile.getLanguage());
index 3a2212ba5537ee855186d7be5f49317f23cc5dc0..ce4b91a1aca0e2244fcc608b6f318c771061ae4b 100644 (file)
@@ -64,6 +64,7 @@ public class QProfileCopierMediumTest {
   private RuleIndexer ruleIndexer;
   private ActiveRuleIndexer activeRuleIndexer;
   private OrganizationDto organization;
+  private QualityProfileDto sourceProfile;
 
   @Before
   public void before() {
@@ -85,7 +86,8 @@ public class QProfileCopierMediumTest {
       .setName("max").setDefaultValue("10").setType(RuleParamType.INTEGER.type()));
 
     // create pre-defined profile
-    db.qualityProfileDao().insert(dbSession, QProfileTesting.newXooP1(organization));
+    sourceProfile = QProfileTesting.newXooP1(organization);
+    db.qualityProfileDao().insert(dbSession, sourceProfile);
     dbSession.commit();
     dbSession.clearCache();
     ruleIndexer.index();
@@ -108,7 +110,7 @@ public class QProfileCopierMediumTest {
     activeRuleIndexer.index();
 
     // target does not exist
-    copier.copyToName(dbSession, QProfileTesting.XOO_P1_KEY, QProfileTesting.XOO_P2_NAME.getName());
+    copier.copyToName(dbSession, sourceProfile, QProfileTesting.XOO_P2_NAME.getName());
 
     verifyOneActiveRule(QProfileTesting.XOO_P2_NAME, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
   }
@@ -138,7 +140,7 @@ public class QProfileCopierMediumTest {
     activeRuleIndexer.index();
 
     // copy -> reset x1 and deactivate x2
-    copier.copyToName(dbSession, QProfileTesting.XOO_P1_KEY, QProfileTesting.XOO_P2_NAME.getName());
+    copier.copyToName(dbSession, sourceProfile, QProfileTesting.XOO_P2_NAME.getName());
 
     verifyOneActiveRule(QProfileTesting.XOO_P2_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
   }
@@ -158,7 +160,7 @@ public class QProfileCopierMediumTest {
     activeRuleIndexer.index();
 
     // copy child -> profile2 is created with parent P1
-    copier.copyToName(dbSession, QProfileTesting.XOO_P1_KEY, QProfileTesting.XOO_P2_NAME.getName());
+    copier.copyToName(dbSession, sourceProfile, QProfileTesting.XOO_P2_NAME.getName());
 
     verifyOneActiveRule(QProfileTesting.XOO_P2_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
     QualityProfileDto profile2Dto = db.qualityProfileDao().selectByKey(dbSession, QProfileTesting.XOO_P2_KEY);
@@ -176,7 +178,7 @@ public class QProfileCopierMediumTest {
     activeRuleIndexer.index();
 
     try {
-      copier.copyToName(dbSession, QProfileTesting.XOO_P1_KEY, QProfileTesting.XOO_P1_NAME.getName());
+      copier.copyToName(dbSession, sourceProfile, QProfileTesting.XOO_P1_NAME.getName());
       fail();
     } catch (IllegalArgumentException e) {
       assertThat(e).hasMessage("Source and target profiles are equal: P1");
index f14312dca52315ff01708df2741fb486c6d25103..8c6342ef576d6c54a7d00deaba449b5f8173dc59 100644 (file)
@@ -55,8 +55,7 @@ import static org.sonar.test.JsonAssert.assertJson;
 
 public class CopyActionTest {
 
-  private static final String LANGUAGE_1 = "lang1";
-  private static final String LANGUAGE_2 = "lang2";
+  private static final String A_LANGUAGE = "lang1";
 
   @Rule
   public DbTester db = DbTester.create();
@@ -70,9 +69,9 @@ public class CopyActionTest {
   private TestBackuper backuper = new TestBackuper();
   private QProfileCopier profileCopier = new QProfileCopier(db.getDbClient(), profileFactory, backuper, tempDir);
   private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
-  private Languages languages = LanguageTesting.newLanguages(LANGUAGE_1, LANGUAGE_2);
+  private Languages languages = LanguageTesting.newLanguages(A_LANGUAGE);
   private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider);
-  private CopyAction underTest = new CopyAction(db.getDbClient(), profileCopier, languages, wsSupport);
+  private CopyAction underTest = new CopyAction(db.getDbClient(), profileCopier, languages, userSession, wsSupport);
   private WsActionTester tester = new WsActionTester(underTest);
 
   @Test
@@ -91,8 +90,10 @@ public class CopyActionTest {
 
   @Test
   public void create_profile_with_specified_name_and_copy_rules_from_source_profile() throws Exception {
-    logInAsQProfileAdministrator();
-    QualityProfileDto sourceProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE_1));
+    OrganizationDto organization = db.organizations().insert();
+    logInAsQProfileAdministrator(organization);
+
+    QualityProfileDto sourceProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE));
     TestResponse response = tester.newRequest()
       .setMethod("POST")
       .setParam("fromKey", sourceProfile.getKey())
@@ -108,7 +109,7 @@ public class CopyActionTest {
       "  \"isDefault\": false," +
       "  \"isInherited\": false" +
       "}");
-    QualityProfileDto loadedProfile = db.getDbClient().qualityProfileDao().selectByNameAndLanguage(db.getDefaultOrganization(), "target-name", sourceProfile.getLanguage(),
+    QualityProfileDto loadedProfile = db.getDbClient().qualityProfileDao().selectByNameAndLanguage(organization, "target-name", sourceProfile.getLanguage(),
       db.getSession());
     assertThat(loadedProfile.getKey()).isEqualTo(generatedUuid);
     assertThat(loadedProfile.isDefault()).isFalse();
@@ -123,10 +124,11 @@ public class CopyActionTest {
   }
 
   @Test
-  public void copy_rules_on_existing_profile() throws Exception {
-    logInAsQProfileAdministrator();
-    QualityProfileDto sourceProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE_1));
-    QualityProfileDto targetProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE_1));
+  public void copy_rules_on_existing_profile_in_default_organization() throws Exception {
+    OrganizationDto organization = db.organizations().insert();
+    logInAsQProfileAdministrator(organization);
+    QualityProfileDto sourceProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE));
+    QualityProfileDto targetProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE));
 
     TestResponse response = tester.newRequest()
       .setMethod("POST")
@@ -151,10 +153,11 @@ public class CopyActionTest {
 
   @Test
   public void create_profile_with_same_parent_as_source_profile() throws Exception {
-    logInAsQProfileAdministrator();
+    OrganizationDto organization = db.organizations().insert();
+    logInAsQProfileAdministrator(organization);
 
-    QualityProfileDto parentProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE_1));
-    QualityProfileDto sourceProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE_1), p -> p.setParentKee(parentProfile.getKey()));
+    QualityProfileDto parentProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE));
+    QualityProfileDto sourceProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE), p -> p.setParentKee(parentProfile.getKey()));
 
     TestResponse response = tester.newRequest()
       .setMethod("POST")
@@ -171,7 +174,7 @@ public class CopyActionTest {
       "  \"isDefault\": false," +
       "  \"isInherited\": true" +
       "}");
-    QualityProfileDto loadedProfile = db.getDbClient().qualityProfileDao().selectByNameAndLanguage(db.getDefaultOrganization(), "target-name", sourceProfile.getLanguage(),
+    QualityProfileDto loadedProfile = db.getDbClient().qualityProfileDao().selectByNameAndLanguage(organization, "target-name", sourceProfile.getLanguage(),
       db.getSession());
     assertThat(loadedProfile.getKey()).isEqualTo(generatedUuid);
     assertThat(loadedProfile.isDefault()).isFalse();
@@ -199,23 +202,42 @@ public class CopyActionTest {
       .execute();
   }
 
+  @Test
+  public void throw_ForbiddenException_if_not_profile_administrator_of_organization() {
+    OrganizationDto organization = db.organizations().insert();
+    QualityProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE));
+    userSession.logIn().addPermission(OrganizationPermission.SCAN, organization);
+
+    expectedException.expect(ForbiddenException.class);
+    expectedException.expectMessage("Insufficient privileges");
+
+    tester.newRequest()
+      .setMethod("POST")
+      .setParam("fromKey", profile.getKey())
+      .setParam("toName", "bar")
+      .execute();
+  }
+
   @Test
   public void throw_ForbiddenException_if_not_profile_administrator() {
-    userSession.logIn().addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization());
+    OrganizationDto organization = db.organizations().insert();
+    QualityProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(A_LANGUAGE));
+    userSession.logIn().addPermission(OrganizationPermission.SCAN, organization);
 
     expectedException.expect(ForbiddenException.class);
     expectedException.expectMessage("Insufficient privileges");
 
     tester.newRequest()
       .setMethod("POST")
-      .setParam("fromKey", "foo")
+      .setParam("fromKey", profile.getKey())
       .setParam("toName", "bar")
       .execute();
   }
 
   @Test
   public void fail_if_parameter_fromKey_is_missing() throws Exception {
-    logInAsQProfileAdministrator();
+    OrganizationDto organization = db.organizations().insert();
+    logInAsQProfileAdministrator(organization);
 
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("The 'fromKey' parameter is missing");
@@ -227,7 +249,8 @@ public class CopyActionTest {
 
   @Test
   public void fail_if_parameter_toName_is_missing() throws Exception {
-    logInAsQProfileAdministrator();
+    OrganizationDto organization = db.organizations().insert();
+    logInAsQProfileAdministrator(organization);
 
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("The 'toName' parameter is missing");
@@ -237,10 +260,10 @@ public class CopyActionTest {
       .execute();
   }
 
-  private void logInAsQProfileAdministrator() {
+  private void logInAsQProfileAdministrator(OrganizationDto organization) {
     userSession
       .logIn()
-      .addPermission(ADMINISTER_QUALITY_PROFILES, defaultOrganizationProvider.get().getUuid());
+      .addPermission(ADMINISTER_QUALITY_PROFILES, organization);
   }
 
   private static class TestBackuper implements QProfileBackuper {