]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10074 Add QP actions "delete" and "associateProjects"
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 29 Nov 2017 14:07:50 +0000 (15:07 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 4 Dec 2017 15:02:52 +0000 (16:02 +0100)
In api/qualityprofiles/search, the following actions are now availables :
- delete : Available when not built-it, not default, and have either QP admin permission or have rights to edit
- associateProjects : Available when not default and have either QP admin permission or have rights to edit

server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchData.java
server/sonar-server/src/main/resources/org/sonar/server/qualityprofile/ws/search-example.json
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java
sonar-ws/src/main/protobuf/ws-qualityprofiles.proto
tests/src/test/java/org/sonarqube/tests/qualityProfile/QualityProfilesEditTest.java

index cd83b7f721f303f0c61cd22728620c41b862a468..d3b5ce0d12b22892c3d7632b433f71341bc9abb9 100644 (file)
@@ -96,11 +96,14 @@ public class SearchAction implements QProfileWsAction {
       .setSince("5.2")
       .setDescription("Search quality profiles")
       .setHandler(this)
-      .setChangelog(new Change("6.5", format("The parameters '%s', '%s' and '%s' can be combined without any constraint", PARAM_DEFAULTS, PARAM_PROJECT, PARAM_LANGUAGE)))
+      .setChangelog(
+        new Change("6.5", format("The parameters '%s', '%s' and '%s' can be combined without any constraint", PARAM_DEFAULTS, PARAM_PROJECT, PARAM_LANGUAGE)),
+        new Change("6.6", "Add available actions 'edit', 'copy' and 'setAsDefault' and global action 'create'"),
+        new Change("7.0", "Add available actions 'delete' and 'associateProjects'")
+      )
       .setResponseExample(getClass().getResource("search-example.json"));
 
-    QProfileWsSupport.createOrganizationParam(action
-      )
+    QProfileWsSupport.createOrganizationParam(action)
       .setSince("6.4");
 
     action
@@ -165,8 +168,7 @@ public class SearchAction implements QProfileWsAction {
           dbClient.activeRuleDao().countActiveRulesByQuery(dbSession, builder.setProfiles(profiles).setRuleStatus(DEPRECATED).build()))
         .setProjectCountByProfileKey(dbClient.qualityProfileDao().countProjectsByOrganizationAndProfiles(dbSession, organization, profiles))
         .setDefaultProfileKeys(defaultProfiles)
-        .setEditableProfileKeys(editableProfiles)
-        .setGlobalQProfileAdmin(userSession.hasPermission(ADMINISTER_QUALITY_PROFILES, organization));
+        .setEditableProfileKeys(editableProfiles);
     }
   }
 
@@ -197,15 +199,14 @@ public class SearchAction implements QProfileWsAction {
     UserDto user = dbClient.userDao().selectActiveUserByLogin(dbSession, login);
     checkState(user != null, "User with login '%s' is not found'", login);
 
-    return
-      Stream.concat(
-        dbClient.qProfileEditUsersDao().selectQProfileUuidsByOrganizationAndUser(dbSession, organization, user).stream(),
-        dbClient.qProfileEditGroupsDao().selectQProfileUuidsByOrganizationAndGroups(dbSession, organization, userSession.getGroups()).stream())
-        .collect(toList());
+    return Stream.concat(
+      dbClient.qProfileEditUsersDao().selectQProfileUuidsByOrganizationAndUser(dbSession, organization, user).stream(),
+      dbClient.qProfileEditGroupsDao().selectQProfileUuidsByOrganizationAndGroups(dbSession, organization, userSession.getGroups()).stream())
+      .collect(toList());
   }
 
   private List<QProfileDto> searchProfiles(DbSession dbSession, SearchRequest request, OrganizationDto organization, List<QProfileDto> defaultProfiles,
-                                           @Nullable ComponentDto project) {
+    @Nullable ComponentDto project) {
     Collection<QProfileDto> profiles = selectAllProfiles(dbSession, organization);
 
     return profiles.stream()
@@ -256,10 +257,10 @@ public class SearchAction implements QProfileWsAction {
   private SearchWsResponse buildResponse(SearchData data) {
     List<QProfileDto> profiles = data.getProfiles();
     Map<String, QProfileDto> profilesByKey = profiles.stream().collect(Collectors.toMap(QProfileDto::getKee, identity()));
+    boolean isGlobalQProfileAdmin = userSession.hasPermission(ADMINISTER_QUALITY_PROFILES, data.getOrganization());
 
     SearchWsResponse.Builder response = SearchWsResponse.newBuilder();
-    response.setActions(SearchWsResponse.Actions.newBuilder().setCreate(data.isGlobalQProfileAdmin()));
-
+    response.setActions(SearchWsResponse.Actions.newBuilder().setCreate(isGlobalQProfileAdmin));
     for (QProfileDto profile : profiles) {
       QualityProfile.Builder profileBuilder = response.addProfilesBuilder();
 
@@ -284,11 +285,12 @@ public class SearchAction implements QProfileWsAction {
       profileBuilder.setIsBuiltIn(profile.isBuiltIn());
 
       profileBuilder.setActions(SearchWsResponse.QualityProfile.Actions.newBuilder()
-        .setEdit(data.isEditable(profile))
-        .setSetAsDefault(data.isGlobalQProfileAdmin())
-        .setCopy(data.isGlobalQProfileAdmin()));
+        .setEdit(!profile.isBuiltIn() && (isGlobalQProfileAdmin || data.isEditable(profile)))
+        .setSetAsDefault(!isDefault && isGlobalQProfileAdmin)
+        .setCopy(isGlobalQProfileAdmin)
+        .setDelete(!isDefault && !profile.isBuiltIn() && (isGlobalQProfileAdmin || data.isEditable(profile)))
+        .setAssociateProjects(!isDefault && (isGlobalQProfileAdmin || data.isEditable(profile))));
     }
-
     return response.build();
   }
 
index d07bfcb13d3f6e45cb0087839b0135c62915b53b..20e4a7ad79363634443ca8ac84fea7d17bfe187f 100644 (file)
@@ -39,7 +39,6 @@ class SearchData {
   private Map<String, Long> projectCountByProfileKey;
   private Set<String> defaultProfileKeys;
   private Set<String> editableProfileKeys;
-  private boolean isGlobalQProfileAdmin;
 
   SearchData setOrganization(OrganizationDto organization) {
     this.organization = organization;
@@ -96,7 +95,7 @@ class SearchData {
   }
 
   boolean isEditable(QProfileDto profile) {
-    return !profile.isBuiltIn() && (isGlobalQProfileAdmin || editableProfileKeys.contains(profile.getKee()));
+    return editableProfileKeys.contains(profile.getKee());
   }
 
   SearchData setEditableProfileKeys(List<String> editableProfileKeys) {
@@ -104,12 +103,4 @@ class SearchData {
     return this;
   }
 
-  boolean isGlobalQProfileAdmin() {
-    return isGlobalQProfileAdmin;
-  }
-
-  SearchData setGlobalQProfileAdmin(boolean globalQProfileAdmin) {
-    isGlobalQProfileAdmin = globalQProfileAdmin;
-    return this;
-  }
 }
index 7c3eabe8acc8c1588b17d70756201434c4c4c811..eb13119b881487126eb4c37567239b3e92f404c6 100644 (file)
@@ -15,7 +15,9 @@
       "actions": {
         "edit": false,
         "setAsDefault": false,
-        "copy": false
+        "copy": false,
+        "delete": false,
+        "associateProjects": false
       }
     },
     {
@@ -37,7 +39,9 @@
       "actions": {
         "edit": true,
         "setAsDefault": false,
-        "copy": false
+        "copy": false,
+        "delete": true,
+        "associateProjects": true
       }
     },
     {
@@ -55,7 +59,9 @@
       "actions": {
         "edit": true,
         "setAsDefault": false,
-        "copy": false
+        "copy": false,
+        "delete": false,
+        "associateProjects": false
       }
     },
     {
@@ -72,7 +78,9 @@
       "actions": {
         "edit": false,
         "setAsDefault": false,
-        "copy": false
+        "copy": false,
+        "delete": false,
+        "associateProjects": false
       }
     }
   ],
index 289ec3904f60eb456f51ab3094d3b658a6b39dce..7beee7087dea9cb2d4337f5bec14b672ee0de10e 100644 (file)
@@ -97,7 +97,10 @@ public class SearchActionTest {
 
     assertThat(definition.changelog())
       .extracting(Change::getVersion, Change::getDescription)
-      .containsExactlyInAnyOrder(tuple("6.5", "The parameters 'defaults', 'project' and 'language' can be combined without any constraint"));
+      .containsExactlyInAnyOrder(
+        tuple("6.5", "The parameters 'defaults', 'project' and 'language' can be combined without any constraint"),
+        tuple("6.6", "Add available actions 'edit', 'copy' and 'setAsDefault' and global action 'create'"),
+        tuple("7.0", "Add available actions 'delete' and 'associateProjects'"));
 
     WebService.Param organization = definition.param("organization");
     assertThat(organization).isNotNull();
@@ -328,16 +331,21 @@ public class SearchActionTest {
     OrganizationDto organization = db.organizations().insert();
     QProfileDto customProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey()));
     QProfileDto builtInProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey()).setIsBuiltIn(true));
+    QProfileDto defaultProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey()));
+    db.qualityProfiles().setAsDefault(defaultProfile);
     UserDto user = db.users().insertUser();
     userSession.logIn(user).addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
 
     SearchWsResponse result = call(ws.newRequest()
       .setParam(PARAM_ORGANIZATION, organization.getKey()));
 
-    assertThat(result.getProfilesList()).extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault())
+    assertThat(result.getProfilesList())
+      .extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
+        qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
       .containsExactlyInAnyOrder(
-        tuple(customProfile.getKee(), true, true, true),
-        tuple(builtInProfile.getKee(), false, true, true));
+        tuple(customProfile.getKee(), true, true, true, true, true),
+        tuple(builtInProfile.getKee(), false, true, true, false, true),
+        tuple(defaultProfile.getKee(), true, true, false, false, false));
     assertThat(result.getActions().getCreate()).isTrue();
   }
 
@@ -357,12 +365,14 @@ public class SearchActionTest {
     SearchWsResponse result = call(ws.newRequest()
       .setParam(PARAM_ORGANIZATION, organization.getKey()));
 
-    assertThat(result.getProfilesList()).extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault())
+    assertThat(result.getProfilesList())
+      .extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
+        qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
       .containsExactlyInAnyOrder(
-        tuple(profile1.getKee(), true, false, false),
-        tuple(profile2.getKee(), false, false, false),
-        tuple(profile3.getKee(), true, false, false),
-        tuple(builtInProfile.getKee(), false, false, false));
+        tuple(profile1.getKee(), true, false, false, true, true),
+        tuple(profile2.getKee(), false, false, false, false, false),
+        tuple(profile3.getKee(), true, false, false, true, true),
+        tuple(builtInProfile.getKee(), false, false, false, false, false));
     assertThat(result.getActions().getCreate()).isFalse();
   }
 
@@ -375,8 +385,10 @@ public class SearchActionTest {
     SearchWsResponse result = call(ws.newRequest()
       .setParam(PARAM_ORGANIZATION, organization.getKey()));
 
-    assertThat(result.getProfilesList()).extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault())
-      .containsExactlyInAnyOrder(tuple(profile.getKee(), false, false, false));
+    assertThat(result.getProfilesList())
+      .extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
+        qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
+      .containsExactlyInAnyOrder(tuple(profile.getKee(), false, false, false, false, false));
     assertThat(result.getActions().getCreate()).isFalse();
   }
 
index 0b0039a2506e887c52434a0d9e7e1fcdf72defda..ddb6ebbe8ff86a092c237bcfe95e9c1599018815 100644 (file)
@@ -54,7 +54,9 @@ message SearchWsResponse {
         optional bool edit = 1;
         optional bool setAsDefault = 2;
         optional bool copy = 3;
-    }
+        optional bool associateProjects = 4;
+        optional bool delete = 5;
+      }
   }
 
   message Actions {
index 6b6ed14999339ee7c449a11f77c57e74ee1f1606..9598bb0432fa8992dfd414cfb18cd2ea85c1b35d 100644 (file)
@@ -24,8 +24,8 @@ import java.util.function.Predicate;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonarqube.tests.Category6Suite;
 import org.sonarqube.qa.util.Tester;
+import org.sonarqube.tests.Category6Suite;
 import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Organizations.Organization;
 import org.sonarqube.ws.Qualityprofiles.CreateWsResponse;
@@ -213,11 +213,12 @@ public class QualityProfilesEditTest {
       .qProfiles().service().search(new SearchRequest().setOrganizationKey(organization.getKey()));
     assertThat(result.getActions().getCreate()).isFalse();
     assertThat(result.getProfilesList())
-      .extracting(SearchWsResponse.QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault())
+      .extracting(SearchWsResponse.QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
+        qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
       .contains(
-        tuple(xooProfile1.getKey(), true, false, false),
-        tuple(xooProfile2.getKey(), true, false, false),
-        tuple(xooProfile3.getKey(), false, false, false));
+        tuple(xooProfile1.getKey(), true, false, false, true, true),
+        tuple(xooProfile2.getKey(), true, false, false, true, true),
+        tuple(xooProfile3.getKey(), false, false, false, false, false));
   }
 
   @Test
@@ -231,9 +232,10 @@ public class QualityProfilesEditTest {
       .qProfiles().service().search(new SearchRequest().setOrganizationKey(organization.getKey()));
     assertThat(result.getActions().getCreate()).isTrue();
     assertThat(result.getProfilesList())
-      .extracting(SearchWsResponse.QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault())
+      .extracting(SearchWsResponse.QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
+        qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
       .contains(
-        tuple(xooProfile.getKey(), true, true, true));
+        tuple(xooProfile.getKey(), true, true, true, true, true));
   }
 
   @Test