]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6470 SONAR-6475 Require admin permission to list group/user associations
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Tue, 2 Jun 2015 08:20:01 +0000 (10:20 +0200)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Tue, 2 Jun 2015 08:20:06 +0000 (10:20 +0200)
server/sonar-server/src/main/java/org/sonar/server/user/ws/GroupsAction.java
server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/UsersAction.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/GroupsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/UsersActionTest.java

index 1df8897c762a762a4ba94ca4036dc61bdba365d0..9538cd931045dac81fa7a157ead36ea39183277d 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.server.user.ws;
 
+import java.util.List;
+import javax.annotation.Nullable;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService.NewAction;
@@ -26,15 +28,13 @@ import org.sonar.api.server.ws.WebService.NewController;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.utils.Paging;
 import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.user.GroupMembershipDto;
 import org.sonar.core.user.GroupMembershipQuery;
 import org.sonar.core.user.UserDto;
 import org.sonar.server.db.DbClient;
-
-import javax.annotation.Nullable;
-
-import java.util.List;
+import org.sonar.server.user.UserSession;
 
 public class GroupsAction implements UsersWsAction {
 
@@ -42,13 +42,19 @@ public class GroupsAction implements UsersWsAction {
   private static final String PARAM_SELECTED = "selected";
 
   private static final String SELECTION_ALL = "all";
-  private static final String SELECTION_SELECTED = "selected";
+  private static final String SELECTION_SELECTED = PARAM_SELECTED;
   private static final String SELECTION_DESELECTED = "deselected";
 
+  private static final String FIELD_SELECTED = PARAM_SELECTED;
+  private static final String FIELD_DESCRIPTION = "description";
+  private static final String FIELD_NAME = "name";
+
   private final DbClient dbClient;
+  private final UserSession userSession;
 
-  public GroupsAction(DbClient dbClient) {
+  public GroupsAction(DbClient dbClient, UserSession userSession) {
     this.dbClient = dbClient;
+    this.userSession = userSession;
   }
 
   @Override
@@ -78,6 +84,8 @@ public class GroupsAction implements UsersWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
+    userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN);
+
     String login = request.mandatoryParam(PARAM_LOGIN);
     int pageSize = request.mandatoryParamAsInt(Param.PAGE_SIZE);
     int page = request.mandatoryParamAsInt(Param.PAGE);
@@ -112,9 +120,9 @@ public class GroupsAction implements UsersWsAction {
     json.name("groups").beginArray();
     for (GroupMembershipDto group : groups) {
       json.beginObject()
-        .prop("name", group.getName())
-        .prop("description", group.getDescription())
-        .prop("selected", group.getUserId() != null)
+        .prop(FIELD_NAME, group.getName())
+        .prop(FIELD_DESCRIPTION, group.getDescription())
+        .prop(FIELD_SELECTED, group.getUserId() != null)
         .endObject();
     }
     json.endArray();
index eabc744a71610a051bee000d52c178f8220f058b..526ddd114b980a6a0e9326c1c38ceefa895aff0c 100644 (file)
@@ -28,12 +28,14 @@ import org.sonar.api.server.ws.WebService.NewController;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.utils.Paging;
 import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.core.user.GroupMembershipQuery;
 import org.sonar.core.user.UserMembershipDto;
 import org.sonar.core.user.UserMembershipQuery;
 import org.sonar.server.db.DbClient;
+import org.sonar.server.user.UserSession;
 
 public class UsersAction implements UserGroupsWsAction {
 
@@ -41,13 +43,19 @@ public class UsersAction implements UserGroupsWsAction {
   private static final String PARAM_SELECTED = "selected";
 
   private static final String SELECTION_ALL = "all";
-  private static final String SELECTION_SELECTED = "selected";
+  private static final String SELECTION_SELECTED = PARAM_SELECTED;
   private static final String SELECTION_DESELECTED = "deselected";
 
+  private static final String FIELD_SELECTED = PARAM_SELECTED;
+  private static final String FIELD_NAME = "name";
+  private static final String FIELD_LOGIN = "login";
+
   private final DbClient dbClient;
+  private final UserSession userSession;
 
-  public UsersAction(DbClient dbClient) {
+  public UsersAction(DbClient dbClient, UserSession userSession) {
     this.dbClient = dbClient;
+    this.userSession = userSession;
   }
 
   @Override
@@ -75,6 +83,8 @@ public class UsersAction implements UserGroupsWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
+    userSession.checkLoggedIn().checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN);
+
     Long groupId = request.mandatoryParamAsLong(PARAM_ID);
     int pageSize = request.mandatoryParamAsInt(Param.PAGE_SIZE);
     int page = request.mandatoryParamAsInt(Param.PAGE);
@@ -109,9 +119,9 @@ public class UsersAction implements UserGroupsWsAction {
     json.name("users").beginArray();
     for (UserMembershipDto user : users) {
       json.beginObject()
-        .prop("login", user.getLogin())
-        .prop("name", user.getName())
-        .prop("selected", user.getGroupId() != null)
+        .prop(FIELD_LOGIN, user.getLogin())
+        .prop(FIELD_NAME, user.getName())
+        .prop(FIELD_SELECTED, user.getGroupId() != null)
         .endObject();
     }
     json.endArray();
index 1764914bd181c42a97719d33241f74798dd5f22b..c35d5cb0a06b98c586be5602be3fb95fda8d6751 100644 (file)
@@ -23,10 +23,11 @@ package org.sonar.server.user.ws;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.ClassRule;
+import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
 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;
@@ -34,7 +35,9 @@ import org.sonar.core.user.GroupMembershipDao;
 import org.sonar.core.user.UserDto;
 import org.sonar.core.user.UserGroupDto;
 import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
+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;
@@ -44,13 +47,11 @@ public class GroupsActionTest {
 
   @ClassRule
   public static final DbTester dbTester = new DbTester();
-
-  WebService.Controller controller;
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
 
   WsTester tester;
-
   DbClient dbClient;
-
   DbSession session;
 
   @Before
@@ -67,9 +68,8 @@ public class GroupsActionTest {
     session = dbClient.openSession(false);
     session.commit();
 
-    tester = new WsTester(new UsersWs(new GroupsAction(dbClient)));
-    controller = tester.controller("api/users");
-
+    tester = new WsTester(new UsersWs(new GroupsAction(dbClient, userSession)));
+    userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
   }
 
   @After
@@ -83,6 +83,13 @@ public class GroupsActionTest {
       .setParam("login", "john").execute();
   }
 
+  @Test(expected = ForbiddenException.class)
+  public void fail_on_missing_permission() throws Exception {
+    userSession.login("not-admin");
+    tester.newGetRequest("api/users", "groups")
+      .setParam("login", "john").execute();
+  }
+
   @Test
   public void empty_groups() throws Exception {
     createUser();
index 928e0c638a551b8649a5a97e32cb48192ee262d2..30c31d346cc84977b5d898d0b31e8a7c5dbfff99 100644 (file)
 
 package org.sonar.server.usergroups.ws;
 
-import org.sonar.server.ws.WsTester.TestRequest;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.ClassRule;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 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;
@@ -35,11 +35,14 @@ import org.sonar.core.user.GroupMembershipDao;
 import org.sonar.core.user.UserDto;
 import org.sonar.core.user.UserGroupDto;
 import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
+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;
 import org.sonar.server.ws.WsTester;
+import org.sonar.server.ws.WsTester.TestRequest;
 import org.sonar.test.DbTests;
 
 @Category(DbTests.class)
@@ -47,6 +50,8 @@ public class UsersActionTest {
 
   @ClassRule
   public static final DbTester dbTester = new DbTester();
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
 
   WsTester wsTester;
   DbClient dbClient;
@@ -66,7 +71,8 @@ public class UsersActionTest {
     session = dbClient.openSession(false);
     session.commit();
 
-    wsTester = new WsTester(new UserGroupsWs(new UsersAction(dbClient)));
+    wsTester = new WsTester(new UserGroupsWs(new UsersAction(dbClient, userSession)));
+    userSession.login("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
 
   }
 
@@ -82,6 +88,14 @@ public class UsersActionTest {
       .setParam("login", "john").execute();
   }
 
+  @Test(expected = ForbiddenException.class)
+  public void fail_on_missing_permission() throws Exception {
+    userSession.login("not-admin");
+    newUsersRequest()
+      .setParam("id", "42")
+      .setParam("login", "john").execute();
+  }
+
   private TestRequest newUsersRequest() {
     return wsTester.newGetRequest("api/usergroups", "users");
   }