]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6465 Require admin permission now that we send sensitive data
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Fri, 22 May 2015 09:25:06 +0000 (11:25 +0200)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Tue, 26 May 2015 14:04:31 +0000 (16:04 +0200)
server/sonar-server/src/main/java/org/sonar/server/user/ws/SearchAction.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/SearchActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java

index 2868829d06525581e86ee6a51485b2c36c78893b..28a06a356a951dd726d292227bef302f2236bfd4 100644 (file)
@@ -36,10 +36,12 @@ import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.es.SearchOptions;
 import org.sonar.server.es.SearchResult;
+import org.sonar.server.user.UserSession;
 import org.sonar.server.user.index.UserDoc;
 import org.sonar.server.user.index.UserIndex;
 
@@ -54,16 +56,18 @@ public class SearchAction implements UsersWsAction {
 
   private final UserIndex userIndex;
   private final DbClient dbClient;
+  private final UserSession userSession;
 
-  public SearchAction(UserIndex userIndex, DbClient dbClient) {
+  public SearchAction(UserIndex userIndex, DbClient dbClient, UserSession userSession) {
     this.userIndex = userIndex;
     this.dbClient = dbClient;
+    this.userSession = userSession;
   }
 
   @Override
   public void define(WebService.NewController controller) {
     WebService.NewAction action = controller.createAction("search")
-      .setDescription("Get a list of active users.")
+      .setDescription("Get a list of active users. Requires Administer System permission.")
       .setSince("3.6")
       .setHandler(this)
       .setResponseExample(getClass().getResource("example-search.json"));
@@ -77,6 +81,8 @@ public class SearchAction implements UsersWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
+    userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN);
+
     SearchOptions options = new SearchOptions()
       .setPage(request.mandatoryParamAsInt(Param.PAGE), request.mandatoryParamAsInt(Param.PAGE_SIZE));
     List<String> fields = request.paramAsStrings(Param.FIELDS);
index c5177efbcaa564e479927c3d7150beb3d6602bb3..2a1370d1eab603a1e611620c0a10d7aec17b61a8 100644 (file)
@@ -26,10 +26,12 @@ import java.util.List;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.ClassRule;
+import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
+import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.DbTester;
 import org.sonar.core.user.GroupDto;
@@ -38,6 +40,8 @@ import org.sonar.core.user.UserDto;
 import org.sonar.core.user.UserGroupDto;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.es.EsTester;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.user.db.GroupDao;
 import org.sonar.server.user.db.UserDao;
 import org.sonar.server.user.db.UserGroupDao;
@@ -56,6 +60,9 @@ public class SearchActionTest {
   @ClassRule
   public static final EsTester esTester = new EsTester().addDefinitions(new UserIndexDefinition(new Settings()));
 
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+
   WebService.Controller controller;
 
   WsTester tester;
@@ -79,7 +86,7 @@ public class SearchActionTest {
     session = dbClient.openSession(false);
 
     index = new UserIndex(esTester.client());
-    tester = new WsTester(new UsersWs(new SearchAction(index, dbClient)));
+    tester = new WsTester(new UsersWs(new SearchAction(index, dbClient, userSession)));
     controller = tester.controller("api/users");
   }
 
@@ -90,6 +97,7 @@ public class SearchActionTest {
 
   @Test
   public void search_empty() throws Exception {
+    loginAsAdmin();
     tester.newGetRequest("api/users", "search").execute().assertJson(getClass(), "empty.json");
   }
 
@@ -97,6 +105,7 @@ public class SearchActionTest {
   public void search_without_parameters() throws Exception {
     injectUsers(5);
 
+    loginAsAdmin();
     tester.newGetRequest("api/users", "search").execute().assertJson(getClass(), "five_users.json");
   }
 
@@ -104,6 +113,7 @@ public class SearchActionTest {
   public void search_with_query() throws Exception {
     injectUsers(5);
 
+    loginAsAdmin();
     tester.newGetRequest("api/users", "search").setParam("q", "user-1").execute().assertJson(getClass(), "user_one.json");
   }
 
@@ -111,6 +121,7 @@ public class SearchActionTest {
   public void search_with_paging() throws Exception {
     injectUsers(10);
 
+    loginAsAdmin();
     tester.newGetRequest("api/users", "search").setParam("ps", "5").execute().assertJson(getClass(), "page_one.json");
     tester.newGetRequest("api/users", "search").setParam("ps", "5").setParam("p", "2").execute().assertJson(getClass(), "page_two.json");
   }
@@ -119,6 +130,8 @@ public class SearchActionTest {
   public void search_with_fields() throws Exception {
     injectUsers(1);
 
+    loginAsAdmin();
+
     assertThat(tester.newGetRequest("api/users", "search").execute().outputAsString())
       .contains("login")
       .contains("name")
@@ -165,9 +178,16 @@ public class SearchActionTest {
     dbClient.userGroupDao().insert(session, new UserGroupDto().setGroupId(group2.getId()).setUserId(users.get(0).getId()));
     session.commit();
 
+    loginAsAdmin();
     tester.newGetRequest("api/users", "search").execute().assertJson(getClass(), "user_with_groups.json");
   }
 
+  @Test(expected = ForbiddenException.class)
+  public void fail_on_missing_permission() throws Exception {
+    userSession.login("not-admin");
+    tester.newGetRequest("api/users", "search").execute();
+  }
+
   private List<UserDto> injectUsers(int numberOfUsers) throws Exception {
     List<UserDto> userDtos = Lists.newArrayList();
     long createdAt = System.currentTimeMillis();
@@ -200,4 +220,8 @@ public class SearchActionTest {
     esTester.putDocuments(UserIndexDefinition.INDEX, UserIndexDefinition.TYPE_USER, users);
     return userDtos;
   }
+
+  private void loginAsAdmin() {
+    userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
+  }
 }
index 8a2a5f43c46186824f168fbb607129c07506dd53..c59fa79aabef4ff890be2281e826353ff7273f6d 100644 (file)
@@ -27,6 +27,7 @@ import org.sonar.api.i18n.I18n;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.user.UserSession;
 import org.sonar.server.user.UserUpdater;
 import org.sonar.server.user.index.UserIndex;
 import org.sonar.server.ws.WsTester;
@@ -47,7 +48,7 @@ public class UsersWsTest {
       new CurrentAction(userSessionRule),
       new DeactivateAction(mock(UserIndex.class), mock(UserUpdater.class), userSessionRule),
       new ChangePasswordAction(mock(UserUpdater.class), userSessionRule),
-      new SearchAction(mock(UserIndex.class), mock(DbClient.class))));
+      new SearchAction(mock(UserIndex.class), mock(DbClient.class), mock(UserSession.class))));
     controller = tester.controller("api/users");
   }