diff options
author | Teryk Bellahsene <teryk.bellahsene@sonarsource.com> | 2015-06-26 16:46:16 +0200 |
---|---|---|
committer | Teryk Bellahsene <teryk.bellahsene@sonarsource.com> | 2015-06-26 16:46:25 +0200 |
commit | 568ac968c81d2e5b29fbb427c40637fdde207f6c (patch) | |
tree | c0501726e5116025e9478d6c2fbefe9f6f85ffc3 /server | |
parent | 99897bc10286b663aaed0e28465dd35d6d9c6cbc (diff) | |
download | sonarqube-568ac968c81d2e5b29fbb427c40637fdde207f6c.tar.gz sonarqube-568ac968c81d2e5b29fbb427c40637fdde207f6c.zip |
SONAR-6615 ws custom_measures/search requires 'Administer System' permission or 'Administer' permission on the project
Diffstat (limited to 'server')
6 files changed, 59 insertions, 37 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CreateAction.java index 129bf9d24ab..9ea34b0146c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CreateAction.java @@ -27,11 +27,9 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; import org.sonar.core.component.ComponentDto; import org.sonar.core.measure.custom.db.CustomMeasureDto; import org.sonar.core.metric.db.MetricDto; -import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; import org.sonar.server.db.DbClient; @@ -42,6 +40,7 @@ import org.sonar.server.user.index.UserDoc; import org.sonar.server.user.index.UserIndex; import static com.google.common.base.Preconditions.checkArgument; +import static org.sonar.server.measure.custom.ws.CustomMeasureValidator.checkPermissions; import static org.sonar.server.measure.custom.ws.CustomMeasureValueDescription.measureValueDescription; public class CreateAction implements CustomMeasuresWsAction { @@ -116,7 +115,7 @@ public class CreateAction implements CustomMeasuresWsAction { try { ComponentDto component = searchProject(dbSession, request); MetricDto metric = searchMetric(dbSession, request); - checkPermissions(component); + checkPermissions(userSession, component); checkIsProjectOrModule(component); checkMeasureDoesNotExistAlready(dbSession, component, metric); UserDoc user = userIndex.getByLogin(userSession.getLogin()); @@ -145,14 +144,6 @@ public class CreateAction implements CustomMeasuresWsAction { } } - private void checkPermissions(ComponentDto component) { - if (userSession.hasGlobalPermission(GlobalPermissions.SYSTEM_ADMIN)) { - return; - } - - userSession.checkLoggedIn().checkProjectUuidPermission(UserRole.ADMIN, component.projectUuid()); - } - private void checkMeasureDoesNotExistAlready(DbSession dbSession, ComponentDto component, MetricDto metric) { int nbMeasuresOnSameMetricAndMeasure = dbClient.customMeasureDao().countByComponentIdAndMetricId(dbSession, component.uuid(), metric.getId()); if (nbMeasuresOnSameMetricAndMeasure > 0) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CustomMeasureValidator.java b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CustomMeasureValidator.java index f698c7d21bc..68cb3e5c76c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CustomMeasureValidator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CustomMeasureValidator.java @@ -23,8 +23,12 @@ package org.sonar.server.measure.custom.ws; import org.sonar.api.PropertyType; import org.sonar.api.measures.Metric; import org.sonar.api.server.ServerSide; +import org.sonar.api.web.UserRole; +import org.sonar.core.component.ComponentDto; import org.sonar.core.measure.custom.db.CustomMeasureDto; import org.sonar.core.metric.db.MetricDto; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.user.UserSession; import org.sonar.server.util.TypeValidations; @ServerSide @@ -95,4 +99,12 @@ public class CustomMeasureValidator { typeValidations.validate(valueAsString, PropertyType.BOOLEAN.name(), null); measure.setValue(Boolean.parseBoolean(valueAsString) ? 1.0d : 0.0d); } + + public static void checkPermissions(UserSession userSession, ComponentDto component) { + if (userSession.hasGlobalPermission(GlobalPermissions.SYSTEM_ADMIN)) { + return; + } + + userSession.checkLoggedIn().checkProjectUuidPermission(UserRole.ADMIN, component.projectUuid()); + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/MetricsAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/MetricsAction.java index 858020602da..47e6424d1c4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/MetricsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/MetricsAction.java @@ -26,10 +26,8 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; import org.sonar.core.component.ComponentDto; import org.sonar.core.metric.db.MetricDto; -import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; import org.sonar.server.db.DbClient; @@ -38,6 +36,7 @@ import org.sonar.server.metric.ws.MetricJsonWriter; import org.sonar.server.user.UserSession; import static com.google.common.base.Preconditions.checkArgument; +import static org.sonar.server.measure.custom.ws.CustomMeasureValidator.checkPermissions; public class MetricsAction implements CustomMeasuresWsAction { public static final String ACTION = "metrics"; @@ -78,7 +77,7 @@ public class MetricsAction implements CustomMeasuresWsAction { try { ComponentDto project = searchProject(dbSession, request); - checkPermissions(project); + checkPermissions(userSession, project); List<MetricDto> metrics = searchMetrics(dbSession, project); writeResponse(response.newJsonWriter(), metrics); @@ -119,12 +118,4 @@ public class MetricsAction implements CustomMeasuresWsAction { return project; } - - private void checkPermissions(ComponentDto component) { - if (userSession.hasGlobalPermission(GlobalPermissions.SYSTEM_ADMIN)) { - return; - } - - userSession.checkLoggedIn().checkProjectUuidPermission(UserRole.ADMIN, component.projectUuid()); - } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/SearchAction.java index b27e2534291..fecf851b57b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/SearchAction.java @@ -42,10 +42,12 @@ import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; import org.sonar.server.db.DbClient; import org.sonar.server.es.SearchOptions; +import org.sonar.server.user.UserSession; import org.sonar.server.user.index.UserIndex; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Sets.newHashSet; +import static org.sonar.server.measure.custom.ws.CustomMeasureValidator.checkPermissions; public class SearchAction implements CustomMeasuresWsAction { @@ -56,17 +58,20 @@ public class SearchAction implements CustomMeasuresWsAction { private final DbClient dbClient; private final UserIndex userIndex; private final CustomMeasureJsonWriter customMeasureJsonWriter; + private final UserSession userSession; - public SearchAction(DbClient dbClient, UserIndex userIndex, CustomMeasureJsonWriter customMeasureJsonWriter) { + public SearchAction(DbClient dbClient, UserIndex userIndex, CustomMeasureJsonWriter customMeasureJsonWriter, UserSession userSession) { this.dbClient = dbClient; this.userIndex = userIndex; this.customMeasureJsonWriter = customMeasureJsonWriter; + this.userSession = userSession; } @Override public void define(WebService.NewController context) { WebService.NewAction action = context.createAction(ACTION) - .setDescription("List custom measures. The project id or project key must be provided.") + .setDescription("List custom measures. The project id or project key must be provided.<br />" + + "Requires 'Administer System' permission or 'Administer' permission on the project.") .setSince("5.2") .addFieldsParam(CustomMeasureJsonWriter.OPTIONAL_FIELDS) .addPagingParams(100) @@ -94,6 +99,7 @@ public class SearchAction implements CustomMeasuresWsAction { DbSession dbSession = dbClient.openSession(false); try { ComponentDto project = searchProject(dbSession, projectUuid, projectKey); + checkPermissions(userSession, project); Long lastAnalysisDateMs = searchLastSnapshot(dbSession, project); List<CustomMeasureDto> customMeasures = searchCustomMeasures(dbSession, project, searchOptions); int nbCustomMeasures = countTotalOfCustomMeasures(dbSession, project); diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/UpdateAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/UpdateAction.java index 94ffe2e6167..2124aad6f01 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/UpdateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/UpdateAction.java @@ -27,17 +27,16 @@ import org.sonar.api.server.ws.WebService; import org.sonar.api.user.User; import org.sonar.api.utils.System2; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.api.web.UserRole; import org.sonar.core.component.ComponentDto; import org.sonar.core.measure.custom.db.CustomMeasureDto; import org.sonar.core.metric.db.MetricDto; -import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; import org.sonar.server.db.DbClient; import org.sonar.server.user.UserSession; import org.sonar.server.user.index.UserIndex; +import static org.sonar.server.measure.custom.ws.CustomMeasureValidator.checkPermissions; import static org.sonar.server.measure.custom.ws.CustomMeasureValueDescription.measureValueDescription; public class UpdateAction implements CustomMeasuresWsAction { @@ -97,7 +96,7 @@ public class UpdateAction implements CustomMeasuresWsAction { CustomMeasureDto customMeasure = dbClient.customMeasureDao().selectById(dbSession, id); MetricDto metric = dbClient.metricDao().selectById(dbSession, customMeasure.getMetricId()); ComponentDto component = dbClient.componentDao().selectByUuid(dbSession, customMeasure.getComponentUuid()); - checkPermissions(component); + checkPermissions(userSession, component); User user = userIndex.getByLogin(userSession.getLogin()); setValue(customMeasure, value, metric); @@ -108,7 +107,7 @@ public class UpdateAction implements CustomMeasuresWsAction { dbSession.commit(); JsonWriter json = response.newJsonWriter(); - customMeasureJsonWriter.write(json, customMeasure, metric, component, user, true, CustomMeasureJsonWriter.OPTIONAL_FIELDS ); + customMeasureJsonWriter.write(json, customMeasure, metric, component, user, true, CustomMeasureJsonWriter.OPTIONAL_FIELDS); json.close(); } finally { MyBatis.closeQuietly(dbSession); @@ -132,12 +131,4 @@ public class UpdateAction implements CustomMeasuresWsAction { throw new IllegalArgumentException("Value or description must be provided."); } } - - private void checkPermissions(ComponentDto component) { - if (userSession.hasGlobalPermission(GlobalPermissions.SYSTEM_ADMIN)) { - return; - } - - userSession.checkLoggedIn().checkProjectUuidPermission(UserRole.ADMIN, component.projectUuid()); - } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/custom/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/custom/ws/SearchActionTest.java index bff6d7a27f0..d609b3f12d3 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/custom/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/custom/ws/SearchActionTest.java @@ -33,9 +33,11 @@ import org.sonar.api.config.Settings; import org.sonar.api.measures.Metric.ValueType; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.DateUtils; +import org.sonar.api.web.UserRole; import org.sonar.core.component.ComponentDto; import org.sonar.core.measure.custom.db.CustomMeasureDto; import org.sonar.core.metric.db.MetricDto; +import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.DbTester; import org.sonar.server.component.ComponentTesting; @@ -44,6 +46,7 @@ import org.sonar.server.component.db.ComponentDao; import org.sonar.server.component.db.SnapshotDao; import org.sonar.server.db.DbClient; import org.sonar.server.es.EsTester; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.measure.custom.persistence.CustomMeasureDao; import org.sonar.server.metric.persistence.MetricDao; @@ -92,8 +95,9 @@ public class SearchActionTest { db.truncateTables(); CustomMeasureJsonWriter customMeasureJsonWriter = new CustomMeasureJsonWriter(new UserJsonWriter(userSessionRule)); UserIndex userIndex = new UserIndex(es.client()); - ws = new WsTester(new CustomMeasuresWs(new SearchAction(dbClient, userIndex, customMeasureJsonWriter))); + ws = new WsTester(new CustomMeasuresWs(new SearchAction(dbClient, userIndex, customMeasureJsonWriter, userSessionRule))); defaultProject = insertDefaultProject(); + userSessionRule.login("login").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); } @After @@ -208,6 +212,19 @@ public class SearchActionTest { } @Test + public void search_as_project_admin() throws Exception { + userSessionRule.login("login").addProjectUuidPermissions(UserRole.ADMIN, DEFAULT_PROJECT_UUID); + MetricDto metric1 = insertCustomMetric(1); + insertCustomMeasure(1, metric1); + + String response = newRequest() + .setParam(SearchAction.PARAM_PROJECT_ID, DEFAULT_PROJECT_UUID) + .execute().outputAsString(); + + assertThat(response).contains("text-value-1"); + } + + @Test public void empty_json_when_no_measure() throws Exception { WsTester.Result response = newRequest() .setParam(SearchAction.PARAM_PROJECT_KEY, DEFAULT_PROJECT_KEY) @@ -242,6 +259,20 @@ public class SearchActionTest { newRequest().setParam(SearchAction.PARAM_PROJECT_ID, "wrong-project-uuid").execute(); } + @Test + public void fail_when_not_enough_privileges() throws Exception { + expectedException.expect(ForbiddenException.class); + userSessionRule.login("login"); + MetricDto metric1 = insertCustomMetric(1); + insertCustomMeasure(1, metric1); + + String response = newRequest() + .setParam(SearchAction.PARAM_PROJECT_ID, DEFAULT_PROJECT_UUID) + .execute().outputAsString(); + + assertThat(response).contains("text-value-1"); + } + private ComponentDto insertDefaultProject() { return insertProject(DEFAULT_PROJECT_UUID, DEFAULT_PROJECT_KEY); } |