aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZipeng WU <zipeng.wu@sonarsource.com>2021-10-20 18:41:34 +0200
committersonartech <sonartech@sonarsource.com>2021-10-22 20:03:28 +0000
commit2b665b2a21166eba85647d42f841eb0adb589b51 (patch)
tree2dee588e9b734ac6dbb4bb6482d971ee46178b00
parentde160ea89db1173a8aad783f3405cfa8eb040629 (diff)
downloadsonarqube-2b665b2a21166eba85647d42f841eb0adb589b51.tar.gz
sonarqube-2b665b2a21166eba85647d42f841eb0adb589b51.zip
SONAR-15440 Add permission delegate in ListAction
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java6
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java13
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java8
-rw-r--r--server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualitygate/ws/list-example.json6
-rw-r--r--server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualitygate/ws/show-example.json3
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ListActionTest.java42
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ShowActionTest.java35
-rw-r--r--sonar-ws/src/main/protobuf/ws-qualitygates.proto1
8 files changed, 93 insertions, 21 deletions
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java
index fd2178c771e..dab5673e874 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ListAction.java
@@ -69,11 +69,11 @@ public class ListAction implements QualityGatesWsAction {
try (DbSession dbSession = dbClient.openSession(false)) {
QualityGateDto defaultQualityGate = finder.getDefault(dbSession);
Collection<QualityGateDto> qualityGates = dbClient.qualityGateDao().selectAll(dbSession);
- writeProtobuf(buildResponse(qualityGates, defaultQualityGate), request, response);
+ writeProtobuf(buildResponse(dbSession, qualityGates, defaultQualityGate), request, response);
}
}
- private ListWsResponse buildResponse(Collection<QualityGateDto> qualityGates, @Nullable QualityGateDto defaultQualityGate) {
+ private ListWsResponse buildResponse(DbSession dbSession, Collection<QualityGateDto> qualityGates, @Nullable QualityGateDto defaultQualityGate) {
String defaultUuid = defaultQualityGate == null ? null : defaultQualityGate.getUuid();
ListWsResponse.Builder builder = ListWsResponse.newBuilder()
.setActions(ListWsResponse.RootActions.newBuilder().setCreate(wsSupport.isQualityGateAdmin()))
@@ -83,7 +83,7 @@ public class ListAction implements QualityGatesWsAction {
.setName(qualityGate.getName())
.setIsDefault(qualityGate.getUuid().equals(defaultUuid))
.setIsBuiltIn(qualityGate.isBuiltIn())
- .setActions(wsSupport.getActions(qualityGate, defaultQualityGate))
+ .setActions(wsSupport.getActions(dbSession, qualityGate, defaultQualityGate))
.build())
.collect(toList()));
ofNullable(defaultUuid).ifPresent(builder::setDefault);
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java
index a958f63c638..05077faf567 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWsSupport.java
@@ -67,17 +67,19 @@ public class QualityGatesWsSupport {
return userSession.hasPermission(ADMINISTER_QUALITY_GATES);
}
- Qualitygates.Actions getActions(QualityGateDto qualityGate, @Nullable QualityGateDto defaultQualityGate) {
+ Qualitygates.Actions getActions(DbSession dbSession, QualityGateDto qualityGate, @Nullable QualityGateDto defaultQualityGate) {
boolean isDefault = defaultQualityGate != null && Objects.equals(defaultQualityGate.getUuid(), qualityGate.getUuid());
boolean isBuiltIn = qualityGate.isBuiltIn();
boolean isQualityGateAdmin = isQualityGateAdmin();
+ boolean canLimitedEdit = isQualityGateAdmin || hasLimitedPermission(dbSession, qualityGate);
return Qualitygates.Actions.newBuilder()
.setCopy(isQualityGateAdmin)
.setRename(!isBuiltIn && isQualityGateAdmin)
- .setManageConditions(!isBuiltIn && isQualityGateAdmin)
+ .setManageConditions(!isBuiltIn && canLimitedEdit)
.setDelete(!isDefault && !isBuiltIn && isQualityGateAdmin)
.setSetAsDefault(!isDefault && isQualityGateAdmin)
.setAssociateProjects(!isDefault && isQualityGateAdmin)
+ .setDelegate(!isBuiltIn && canLimitedEdit)
.build();
}
@@ -89,12 +91,15 @@ public class QualityGatesWsSupport {
void checkCanLimitedEdit(DbSession dbSession, QualityGateDto qualityGate) {
checkNotBuiltIn(qualityGate);
if (!userSession.hasPermission(ADMINISTER_QUALITY_GATES)
- && !userHasPermission(dbSession, qualityGate)
- && !userHasGroupPermission(dbSession, qualityGate)) {
+ && !hasLimitedPermission(dbSession, qualityGate)) {
throw insufficientPrivilegesException();
}
}
+ boolean hasLimitedPermission(DbSession dbSession, QualityGateDto qualityGate) {
+ return userHasPermission(dbSession, qualityGate) || userHasGroupPermission(dbSession, qualityGate);
+ }
+
boolean userHasGroupPermission(DbSession dbSession, QualityGateDto qualityGate) {
return userSession.isLoggedIn() && dbClient.qualityGateGroupPermissionsDao().exists(dbSession, qualityGate, userSession.getGroups());
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java
index 2cbb7c96db8..db1ba240f02 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java
@@ -94,7 +94,7 @@ public class ShowAction implements QualityGatesWsAction {
Collection<QualityGateConditionDto> conditions = getConditions(dbSession, qualityGate);
Map<String, MetricDto> metricsByUuid = getMetricsByUuid(dbSession, conditions);
QualityGateDto defaultQualityGate = qualityGateFinder.getDefault(dbSession);
- writeProtobuf(buildResponse(qualityGate, defaultQualityGate, conditions, metricsByUuid), request, response);
+ writeProtobuf(buildResponse(dbSession, qualityGate, defaultQualityGate, conditions, metricsByUuid), request, response);
}
}
@@ -119,8 +119,8 @@ public class ShowAction implements QualityGatesWsAction {
.collect(uniqueIndex(MetricDto::getUuid));
}
- private ShowWsResponse buildResponse(QualityGateDto qualityGate, QualityGateDto defaultQualityGate,
- Collection<QualityGateConditionDto> conditions, Map<String, MetricDto> metricsByUuid) {
+ private ShowWsResponse buildResponse(DbSession dbSession, QualityGateDto qualityGate, QualityGateDto defaultQualityGate,
+ Collection<QualityGateConditionDto> conditions, Map<String, MetricDto> metricsByUuid) {
return ShowWsResponse.newBuilder()
.setId(qualityGate.getUuid())
.setName(qualityGate.getName())
@@ -128,7 +128,7 @@ public class ShowAction implements QualityGatesWsAction {
.addAllConditions(conditions.stream()
.map(toWsCondition(metricsByUuid))
.collect(toList()))
- .setActions(wsSupport.getActions(qualityGate, defaultQualityGate))
+ .setActions(wsSupport.getActions(dbSession, qualityGate, defaultQualityGate))
.build();
}
diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualitygate/ws/list-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualitygate/ws/list-example.json
index b9de9b682f4..cd36b8c6e34 100644
--- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualitygate/ws/list-example.json
+++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualitygate/ws/list-example.json
@@ -11,7 +11,8 @@
"copy": true,
"associateProjects": false,
"delete": false,
- "manageConditions": false
+ "manageConditions": false,
+ "delegate": false
}
},
{
@@ -25,7 +26,8 @@
"copy": true,
"associateProjects": true,
"delete": true,
- "manageConditions": true
+ "manageConditions": true,
+ "delegate": true
}
}
],
diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualitygate/ws/show-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualitygate/ws/show-example.json
index 6883a72566c..99858d38935 100644
--- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualitygate/ws/show-example.json
+++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/qualitygate/ws/show-example.json
@@ -22,6 +22,7 @@
"copy": true,
"associateProjects": true,
"delete": true,
- "manageConditions": true
+ "manageConditions": true,
+ "delegate": true
}
}
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ListActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ListActionTest.java
index 4abffdf987c..8250502410a 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ListActionTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ListActionTest.java
@@ -26,6 +26,7 @@ import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.component.TestComponentFinder;
import org.sonar.server.qualitygate.QualityGateFinder;
import org.sonar.server.tester.UserSessionRule;
@@ -124,11 +125,37 @@ public class ListActionTest {
assertThat(response.getQualitygatesList())
.extracting(QualityGate::getName,
qg -> qg.getActions().getRename(), qg -> qg.getActions().getDelete(), qg -> qg.getActions().getManageConditions(),
- qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(), qp -> qp.getActions().getAssociateProjects())
+ qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(), qp -> qp.getActions().getAssociateProjects(),
+ qp -> qp.getActions().getDelegate())
.containsExactlyInAnyOrder(
- tuple(defaultQualityGate.getName(), true, false, true, true, false, false),
- tuple(builtInQualityGate.getName(), false, false, false, true, true, true),
- tuple(otherQualityGate.getName(), true, true, true, true, true, true));
+ tuple(defaultQualityGate.getName(), true, false, true, true, false, false, true),
+ tuple(builtInQualityGate.getName(), false, false, false, true, true, true, false),
+ tuple(otherQualityGate.getName(), true, true, true, true, true, true, true));
+ }
+
+ @Test
+ public void actions_with_quality_gate_delegate_permission() {
+ QualityGateDto defaultQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way"));
+ QualityGateDto otherQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way - Without Coverage"));
+ UserDto user = db.users().insertUser();
+ db.qualityGates().addUserPermission(defaultQualityGate, user);
+ db.qualityGates().addUserPermission(otherQualityGate, user);
+ userSession.logIn(user);
+ db.qualityGates().setDefaultQualityGate(defaultQualityGate);
+
+ ListWsResponse response = ws.newRequest().executeProtobuf(ListWsResponse.class);
+
+ assertThat(response.getActions())
+ .extracting(ListWsResponse.RootActions::getCreate)
+ .isEqualTo(false);
+ assertThat(response.getQualitygatesList())
+ .extracting(QualityGate::getName,
+ qg -> qg.getActions().getRename(), qg -> qg.getActions().getDelete(), qg -> qg.getActions().getManageConditions(),
+ qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(), qp -> qp.getActions().getAssociateProjects(),
+ qp -> qp.getActions().getDelegate())
+ .containsExactlyInAnyOrder(
+ tuple(defaultQualityGate.getName(), false, false, true, false, false, false, true),
+ tuple(otherQualityGate.getName(), false, false, true, false, false, false, true));
}
@Test
@@ -146,10 +173,11 @@ public class ListActionTest {
assertThat(response.getQualitygatesList())
.extracting(QualityGate::getName,
qg -> qg.getActions().getRename(), qg -> qg.getActions().getDelete(), qg -> qg.getActions().getManageConditions(),
- qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(), qp -> qp.getActions().getAssociateProjects())
+ qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(), qp -> qp.getActions().getAssociateProjects(),
+ qp -> qp.getActions().getDelegate())
.containsExactlyInAnyOrder(
- tuple(defaultQualityGate.getName(), false, false, false, false, false, false),
- tuple(otherQualityGate.getName(), false, false, false, false, false, false));
+ tuple(defaultQualityGate.getName(), false, false, false, false, false, false, false),
+ tuple(otherQualityGate.getName(), false, false, false, false, false, false, false));
}
@Test
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ShowActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ShowActionTest.java
index 19c8bc2a5ea..de776d5dbe5 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ShowActionTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualitygate/ws/ShowActionTest.java
@@ -29,6 +29,7 @@ import org.sonar.db.DbTester;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.qualitygate.QualityGateConditionDto;
import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.db.user.UserDto;
import org.sonar.server.component.TestComponentFinder;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.qualitygate.QualityGateFinder;
@@ -200,6 +201,40 @@ public class ShowActionTest {
}
@Test
+ public void actions_when_delegate_quality_gate_administer() {
+ QualityGateDto defaultQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way"));
+ QualityGateDto otherQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way - Without Coverage"));
+ UserDto user = db.users().insertUser();
+ db.qualityGates().addUserPermission(defaultQualityGate, user);
+ db.qualityGates().addUserPermission(otherQualityGate, user);
+ userSession.logIn(user);
+ db.qualityGates().setDefaultQualityGate(defaultQualityGate);
+
+ ShowWsResponse response = ws.newRequest()
+ .setParam("name", defaultQualityGate.getName())
+ .executeProtobuf(ShowWsResponse.class);
+
+ assertThat(response.getActions())
+ .extracting(
+ Actions::getRename, Actions::getDelete, Actions::getManageConditions,
+ Actions::getCopy, Actions::getSetAsDefault, Actions::getAssociateProjects, Actions::getDelegate)
+ .containsExactlyInAnyOrder(
+ false, false, true, false, false, false, true);
+
+ response = ws.newRequest()
+ .setParam("name", otherQualityGate.getName())
+ .executeProtobuf(ShowWsResponse.class);
+
+ assertThat(response.getActions())
+ .extracting(
+ Actions::getRename, Actions::getDelete, Actions::getManageConditions,
+ Actions::getCopy, Actions::getSetAsDefault, Actions::getAssociateProjects, Actions::getDelegate)
+ .containsExactlyInAnyOrder(
+ false, false, true, false, false, false, true);
+
+ }
+
+ @Test
public void fail_when_no_name_or_id() {
QualityGateDto qualityGate = db.qualityGates().insertQualityGate();
diff --git a/sonar-ws/src/main/protobuf/ws-qualitygates.proto b/sonar-ws/src/main/protobuf/ws-qualitygates.proto
index e9aa2946124..e59873e098f 100644
--- a/sonar-ws/src/main/protobuf/ws-qualitygates.proto
+++ b/sonar-ws/src/main/protobuf/ws-qualitygates.proto
@@ -180,6 +180,7 @@ message Actions {
optional bool associateProjects = 4;
optional bool delete = 5;
optional bool manageConditions = 6;
+ optional bool delegate = 7;
}
// WS api/qualitygates/search_users