aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java38
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGateWsSupport.java85
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/list-example.json19
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ListActionTest.java51
-rw-r--r--sonar-ws/src/main/protobuf/ws-qualitygates.proto13
-rw-r--r--sonar-ws/src/main/protobuf/ws-qualityprofiles.proto2
8 files changed, 179 insertions, 33 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java
index 6e97f2355f1..ee9980dc112 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java
@@ -30,6 +30,7 @@ import org.sonar.server.qualitygate.ws.DestroyAction;
import org.sonar.server.qualitygate.ws.GetByProjectAction;
import org.sonar.server.qualitygate.ws.ListAction;
import org.sonar.server.qualitygate.ws.ProjectStatusAction;
+import org.sonar.server.qualitygate.ws.QGateWsSupport;
import org.sonar.server.qualitygate.ws.QualityGatesWs;
import org.sonar.server.qualitygate.ws.QualityGatesWsSupport;
import org.sonar.server.qualitygate.ws.RenameAction;
@@ -50,6 +51,7 @@ public class QualityGateModule extends Module {
QgateProjectFinder.class,
QualityGateFinder.class,
// WS
+ QGateWsSupport.class,
QualityGatesWsSupport.class,
QualityGatesWs.class,
ListAction.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java
index fe9e93dfd13..a3fc1cbc0d2 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java
@@ -21,30 +21,29 @@ package org.sonar.server.qualitygate.ws;
import com.google.common.io.Resources;
import java.util.Collection;
-import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import org.apache.commons.lang.StringUtils;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.property.PropertyDto;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonarqube.ws.Qualitygates.ListWsResponse;
+import org.sonarqube.ws.Qualitygates.ListWsResponse.QualityGate;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.core.util.stream.MoreCollectors.toList;
-import static org.sonar.server.qualitygate.QualityGates.SONAR_QUALITYGATE_PROPERTY;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
public class ListAction implements QualityGatesWsAction {
private final DbClient dbClient;
+ private final QGateWsSupport wsSupport;
- public ListAction(DbClient dbClient) {
+ public ListAction(DbClient dbClient, QGateWsSupport wsSupport) {
this.dbClient = dbClient;
+ this.wsSupport = wsSupport;
}
@Override
@@ -56,50 +55,35 @@ public class ListAction implements QualityGatesWsAction {
.setChangelog(
new Change("7.0", "'isDefault' field is added on quality gate"),
new Change("7.0", "'default' field on root level is deprecated"),
- new Change("7.0", "'isBuiltIn' field is added in the response"))
+ new Change("7.0", "'isBuiltIn' field is added in the response"),
+ new Change("7.0", "'actions' fields are added in the response"))
.setHandler(this);
}
@Override
public void handle(Request request, Response response) {
try (DbSession dbSession = dbClient.openSession(false)) {
- QualityGateDto defaultQualityGate = getDefault(dbSession);
+ QualityGateDto defaultQualityGate = wsSupport.getDefault(dbSession);
Collection<QualityGateDto> qualityGates = dbClient.qualityGateDao().selectAll(dbSession);
writeProtobuf(buildResponse(qualityGates, defaultQualityGate), request, response);
}
}
- private static ListWsResponse buildResponse(Collection<QualityGateDto> qualityGates, @Nullable QualityGateDto defaultQualityGate) {
+ private ListWsResponse buildResponse(Collection<QualityGateDto> qualityGates, @Nullable QualityGateDto defaultQualityGate) {
Long defaultId = defaultQualityGate == null ? null : defaultQualityGate.getId();
ListWsResponse.Builder builder = ListWsResponse.newBuilder()
+ .setActions(ListWsResponse.RootActions.newBuilder().setCreate(wsSupport.isQualityGateAdmin()))
.addAllQualitygates(qualityGates.stream()
- .map(qualityGate -> ListWsResponse.QualityGate.newBuilder()
+ .map(qualityGate -> QualityGate.newBuilder()
.setId(qualityGate.getId())
.setName(qualityGate.getName())
.setIsDefault(qualityGate.getId().equals(defaultId))
.setIsBuiltIn(qualityGate.isBuiltIn())
+ .setActions(wsSupport.getActions(qualityGate, defaultQualityGate))
.build())
.collect(toList()));
setNullable(defaultId, builder::setDefault);
return builder.build();
}
- @CheckForNull
- private QualityGateDto getDefault(DbSession dbSession) {
- Long defaultId = getDefaultId(dbSession);
- if (defaultId == null) {
- return null;
- }
- return dbClient.qualityGateDao().selectById(dbSession, defaultId);
- }
-
- @CheckForNull
- private Long getDefaultId(DbSession dbSession) {
- PropertyDto defaultQgate = dbClient.propertiesDao().selectGlobalProperty(dbSession, SONAR_QUALITYGATE_PROPERTY);
- if (defaultQgate == null || StringUtils.isBlank(defaultQgate.getValue())) {
- return null;
- }
- return Long.valueOf(defaultQgate.getValue());
- }
-
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGateWsSupport.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGateWsSupport.java
new file mode 100644
index 00000000000..0a67641c680
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGateWsSupport.java
@@ -0,0 +1,85 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.qualitygate.ws;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.server.ServerSide;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.user.UserSession;
+import org.sonarqube.ws.Qualitygates;
+
+import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES;
+import static org.sonar.server.qualitygate.QualityGates.SONAR_QUALITYGATE_PROPERTY;
+
+@ServerSide
+public class QGateWsSupport {
+
+ private final DbClient dbClient;
+ private final UserSession userSession;
+ private final DefaultOrganizationProvider defaultOrganizationProvider;
+
+ public QGateWsSupport(DbClient dbClient, UserSession userSession, DefaultOrganizationProvider defaultOrganizationProvider) {
+ this.dbClient = dbClient;
+ this.userSession = userSession;
+ this.defaultOrganizationProvider = defaultOrganizationProvider;
+ }
+
+ boolean isQualityGateAdmin() {
+ return userSession.hasPermission(ADMINISTER_QUALITY_GATES, defaultOrganizationProvider.get().getUuid());
+ }
+
+ Qualitygates.Actions getActions(QualityGateDto qualityGate, @Nullable QualityGateDto defaultQualityGate) {
+ Long defaultId = defaultQualityGate == null ? null : defaultQualityGate.getId();
+ boolean isDefault = qualityGate.getId().equals(defaultId);
+ boolean isBuiltIn = qualityGate.isBuiltIn();
+ boolean isQualityGateAdmin = isQualityGateAdmin();
+ return Qualitygates.Actions.newBuilder()
+ .setCopy(isQualityGateAdmin)
+ .setEdit(!isBuiltIn && isQualityGateAdmin)
+ .setSetAsDefault(!isDefault && isQualityGateAdmin)
+ .setAssociateProjects(!isDefault && isQualityGateAdmin)
+ .build();
+ }
+
+ @CheckForNull
+ QualityGateDto getDefault(DbSession dbSession) {
+ Long defaultId = getDefaultId(dbSession);
+ if (defaultId == null) {
+ return null;
+ }
+ return dbClient.qualityGateDao().selectById(dbSession, defaultId);
+ }
+
+ @CheckForNull
+ private Long getDefaultId(DbSession dbSession) {
+ PropertyDto defaultQgate = dbClient.propertiesDao().selectGlobalProperty(dbSession, SONAR_QUALITYGATE_PROPERTY);
+ if (defaultQgate == null || StringUtils.isBlank(defaultQgate.getValue())) {
+ return null;
+ }
+ return Long.valueOf(defaultQgate.getValue());
+ }
+
+}
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/list-example.json b/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/list-example.json
index 547b8d4e863..270dc554203 100644
--- a/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/list-example.json
+++ b/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/list-example.json
@@ -4,14 +4,29 @@
"id": 2,
"name": "Sonar way",
"isDefault": true,
- "isBuiltIn": true
+ "isBuiltIn": true,
+ "actions": {
+ "edit": false,
+ "setAsDefault": false,
+ "copy": true,
+ "associateProjects": false
+ }
},
{
"id": 4,
"name": "Sonar way - Without Coverage",
"isDefault": false,
- "isBuiltIn": false
+ "isBuiltIn": false,
+ "actions": {
+ "edit": true,
+ "setAsDefault": true,
+ "copy": true,
+ "associateProjects": true
+ }
}
],
+ "actions": {
+ "create": true
+ },
"default": 2
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java
index 622d9fc6236..36d9eba904b 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java
@@ -29,6 +29,6 @@ public class QualityGateModuleTest {
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new QualityGateModule().configure(container);
- assertThat(container.size()).isEqualTo(24 + 2);
+ assertThat(container.size()).isEqualTo(25 + 2);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ListActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ListActionTest.java
index 83f27cd2025..108ef2da489 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ListActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ListActionTest.java
@@ -27,12 +27,16 @@ import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbTester;
import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.Qualitygates.ListWsResponse.QualityGate;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.tuple;
+import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES;
+import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
import static org.sonar.test.JsonAssert.assertJson;
import static org.sonarqube.ws.Qualitygates.ListWsResponse;
@@ -44,8 +48,9 @@ public class ListActionTest {
public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public DbTester db = DbTester.create();
+ private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
- private WsActionTester ws = new WsActionTester(new ListAction(db.getDbClient()));
+ private WsActionTester ws = new WsActionTester(new ListAction(db.getDbClient(), new QGateWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider)));
@Test
public void verify_definition() {
@@ -58,12 +63,14 @@ public class ListActionTest {
.containsExactlyInAnyOrder(
tuple("7.0", "'isDefault' field is added on quality gate"),
tuple("7.0", "'default' field on root level is deprecated"),
- tuple("7.0", "'isBuiltIn' field is added in the response"));
+ tuple("7.0", "'isBuiltIn' field is added in the response"),
+ tuple("7.0", "'actions' fields are added in the response"));
assertThat(action.params()).isEmpty();
}
@Test
public void json_example() {
+ userSession.logIn("admin").addPermission(ADMINISTER_QUALITY_GATES, defaultOrganizationProvider.get().getUuid());
QualityGateDto defaultQualityGate = db.qualityGates().insertQualityGate(qualityGate -> qualityGate.setName("Sonar way").setBuiltIn(true));
db.qualityGates().insertQualityGate(qualityGate -> qualityGate.setName("Sonar way - Without Coverage").setBuiltIn(false));
db.qualityGates().setDefaultQualityGate(defaultQualityGate);
@@ -127,6 +134,46 @@ public class ListActionTest {
}
@Test
+ public void actions_with_quality_gate_administer_permission() {
+ userSession.logIn("john").addPermission(ADMINISTER_QUALITY_GATES, defaultOrganizationProvider.get().getUuid());
+ QualityGateDto defaultQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way").setBuiltIn(true));
+ QualityGateDto otherQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way - Without Coverage").setBuiltIn(false));
+ db.qualityGates().setDefaultQualityGate(defaultQualityGate);
+
+ ListWsResponse response = ws.newRequest().executeProtobuf(ListWsResponse.class);
+
+ assertThat(response.getActions())
+ .extracting(ListWsResponse.RootActions::getCreate)
+ .containsExactlyInAnyOrder(true);
+ assertThat(response.getQualitygatesList())
+ .extracting(QualityGate::getName,
+ qg -> qg.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(), qp -> qp.getActions().getAssociateProjects())
+ .containsExactlyInAnyOrder(
+ tuple(defaultQualityGate.getName(), false, true, false, false),
+ tuple(otherQualityGate.getName(), true, true, true, true));
+ }
+
+ @Test
+ public void actions_without_quality_gate_administer_permission() {
+ userSession.logIn("john").addPermission(ADMINISTER_QUALITY_PROFILES, defaultOrganizationProvider.get().getUuid());
+ QualityGateDto defaultQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way").setBuiltIn(true));
+ QualityGateDto otherQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way - Without Coverage").setBuiltIn(false));
+ db.qualityGates().setDefaultQualityGate(defaultQualityGate);
+
+ ListWsResponse response = ws.newRequest().executeProtobuf(ListWsResponse.class);
+
+ assertThat(response.getActions())
+ .extracting(ListWsResponse.RootActions::getCreate)
+ .containsExactlyInAnyOrder(false);
+ assertThat(response.getQualitygatesList())
+ .extracting(QualityGate::getName,
+ qg -> qg.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(), qp -> qp.getActions().getAssociateProjects())
+ .containsExactlyInAnyOrder(
+ tuple(defaultQualityGate.getName(), false, false, false, false),
+ tuple(otherQualityGate.getName(), false, false, false, false));
+ }
+
+ @Test
public void empty() {
ListWsResponse response = ws.newRequest().executeProtobuf(ListWsResponse.class);
diff --git a/sonar-ws/src/main/protobuf/ws-qualitygates.proto b/sonar-ws/src/main/protobuf/ws-qualitygates.proto
index 57658d9996f..15e2ab342e3 100644
--- a/sonar-ws/src/main/protobuf/ws-qualitygates.proto
+++ b/sonar-ws/src/main/protobuf/ws-qualitygates.proto
@@ -140,13 +140,26 @@ message ListWsResponse {
repeated QualityGate qualitygates = 1;
// Deprecated since 7.0
optional int64 default = 2;
+ optional RootActions actions = 3;
message QualityGate {
optional int64 id = 1;
optional string name = 2;
optional bool isDefault = 3;
optional bool isBuiltIn = 4;
+ optional Actions actions = 5;
}
+
+ message RootActions {
+ optional bool create = 1;
+ }
+}
+
+message Actions {
+ optional bool edit = 1;
+ optional bool setAsDefault = 2;
+ optional bool copy = 3;
+ optional bool associateProjects = 4;
}
diff --git a/sonar-ws/src/main/protobuf/ws-qualityprofiles.proto b/sonar-ws/src/main/protobuf/ws-qualityprofiles.proto
index e4d9df36abc..0b0039a2506 100644
--- a/sonar-ws/src/main/protobuf/ws-qualityprofiles.proto
+++ b/sonar-ws/src/main/protobuf/ws-qualityprofiles.proto
@@ -54,7 +54,7 @@ message SearchWsResponse {
optional bool edit = 1;
optional bool setAsDefault = 2;
optional bool copy = 3;
- }
+ }
}
message Actions {