]> source.dussan.org Git - sonarqube.git/commitdiff
Add query to keep authorized users for a project and a role 902/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 18 Apr 2016 07:28:59 +0000 (09:28 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 18 Apr 2016 09:30:35 +0000 (11:30 +0200)
sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java
sonar-db/src/main/java/org/sonar/db/user/AuthorizationDao.java
sonar-db/src/main/java/org/sonar/db/user/AuthorizationMapper.java
sonar-db/src/main/resources/org/sonar/db/user/AuthorizationMapper.xml
sonar-db/src/test/java/org/sonar/db/permission/UserWithPermissionDaoTest.java
sonar-db/src/test/java/org/sonar/db/user/AuthorizationDaoTest.java
sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_anomymous.xml [new file with mode: 0644]
sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_anonymous.xml [new file with mode: 0644]
sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_group.xml [new file with mode: 0644]
sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_user.xml [new file with mode: 0644]

index a347da0cf0a98f1cc776993f59f012cea8c4fae4..f7389dd7d6b3c3a1e8d29f920a2218678e7d210f 100644 (file)
@@ -143,4 +143,6 @@ public class PermissionDao implements Dao {
   private static PermissionMapper mapper(SqlSession session) {
     return session.getMapper(PermissionMapper.class);
   }
+
+
 }
index 761d302dff564d39c8b38fb6e23268ad6102ec4e..446f810af85d89a43acf907fa2f02ca5efb4e880 100644 (file)
@@ -25,6 +25,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.apache.ibatis.session.SqlSession;
 import org.sonar.db.Dao;
@@ -59,9 +60,10 @@ public class AuthorizationDao implements Dao {
     });
   }
 
-  /**
-   * Used by the Views Plugin
-   */
+  public Collection<Long> keepAuthorizedUsersForRoleAndProject(final DbSession session, final Collection<Long> userIds, final String role, final long projectId) {
+    return DatabaseUtils.executeLargeInputs(userIds, new SelectUsersByPermissionAndProject(session.getMapper(AuthorizationMapper.class), role, projectId));
+  }
+
   public boolean isAuthorizedComponentKey(String componentKey, @Nullable Integer userId, String role) {
     DbSession session = mybatis.openSession(false);
     try {
@@ -129,4 +131,21 @@ public class AuthorizationDao implements Dao {
       MyBatis.closeQuietly(session);
     }
   }
+
+  private static class SelectUsersByPermissionAndProject implements Function<List<Long>, List<Long>> {
+    private final AuthorizationMapper mapper;
+    private final String role;
+    private final long projectId;
+
+    private SelectUsersByPermissionAndProject(AuthorizationMapper mapper, String role, long projectId) {
+      this.mapper = mapper;
+      this.role = role;
+      this.projectId = projectId;
+    }
+
+    @Override
+    public List<Long> apply(@Nonnull List<Long> partitionOfIds) {
+      return mapper.keepAuthorizedUsersForRoleAndProject(role, projectId, partitionOfIds);
+    }
+  }
 }
index e3eea850331df0193f884cdfe3f785894a6d51ea..1f395b948d8cccd405f8f7556b232191a4c32a3e 100644 (file)
@@ -33,4 +33,6 @@ public interface AuthorizationMapper {
 
   List<String> keepAuthorizedComponentKeysForUser(@Param("userId") Integer userId, @Param("role") String role, @Param("componentKeys") Collection<String> componentKeys);
 
+  List<Long> keepAuthorizedUsersForRoleAndProject(@Param("role") String role, @Param("componentId") long componentId, @Param("userIds") List<Long> userIds);
+
 }
index f33a7ae06408f80715d91300d0c547a705bdf96b..8ddb1e09b2cf233f953d92c8440335e236abae27 100644 (file)
     </choose>
   </select>
 
+  <select id="keepAuthorizedUsersForRoleAndProject" parameterType="map" resultType="Long">
+    SELECT gu.user_id
+    FROM groups_users gu
+      INNER JOIN group_roles gr ON gr.group_id=gu.group_id
+    WHERE
+      gr.resource_id=#{componentId}
+      AND gr.role=#{role}
+      AND (gr.group_id IS NULL OR gr.group_id IN (
+        select gu.group_id from groups_users gu where gu.user_id in
+        <foreach collection="userIds" open="(" close=")" item="id" separator=",">
+          #{id}
+        </foreach>
+      ))
+    UNION
+    SELECT ur.user_id
+    FROM user_roles ur
+    WHERE
+      ur.resource_id=#{componentId}
+      AND ur.role=#{role}
+      AND ur.user_id IN
+      <foreach collection="userIds" open="(" close=")" item="id" separator=",">
+        #{id}
+      </foreach>
+  </select>
+
 </mapper>
index a7891ba046c0c94599d6e1a4da834cdb738800c6..5b37c0897c0c07473d741949ae51c96d948aa0c3 100644 (file)
@@ -41,7 +41,6 @@ import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
 import static org.sonar.api.web.UserRole.USER;
 import static org.sonar.db.user.UserTesting.newUserDto;
 
-
 public class UserWithPermissionDaoTest {
 
   private static final long COMPONENT_ID = 100L;
index 635c8da8cc82e20d50f3824270a292d9ddb05d65..328eb7c58dc377826a036ae53d55263026400c2d 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.db.user;
 
-import com.google.common.collect.Sets;
 import java.util.Collection;
 import java.util.Collections;
 import org.junit.Rule;
@@ -27,6 +26,7 @@ import org.junit.Test;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
 
+import static com.google.common.collect.Sets.newHashSet;
 import static org.assertj.core.api.Assertions.assertThat;
 
 
@@ -49,14 +49,14 @@ public class AuthorizationDaoTest {
     dbTester.prepareDbUnit(getClass(), "user_should_be_authorized.xml");
 
     Collection<Long> componentIds = authorization.keepAuthorizedProjectIds(dbTester.getSession(),
-      Sets.newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT),
+      newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT),
       USER, "user");
 
     assertThat(componentIds).containsOnly(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT);
 
     // user does not have the role "admin"
     componentIds = authorization.keepAuthorizedProjectIds(dbTester.getSession(),
-      Sets.newHashSet(PROJECT_ID),
+      newHashSet(PROJECT_ID),
       USER, "admin");
     assertThat(componentIds).isEmpty();
 
@@ -69,10 +69,10 @@ public class AuthorizationDaoTest {
   public void keep_authorized_project_ids_for_user() {
     dbTester.prepareDbUnit(getClass(), "keep_authorized_project_ids_for_user.xml");
 
-    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), Sets.newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT), USER, "user")).containsOnly(PROJECT_ID);
+    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT), USER, "user")).containsOnly(PROJECT_ID);
 
     // user does not have the role "admin"
-    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), Sets.newHashSet(PROJECT_ID), USER, "admin")).isEmpty();
+    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), newHashSet(PROJECT_ID), USER, "admin")).isEmpty();
 
     // Empty list
     assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), Collections.<Long>emptySet(), USER, "admin")).isEmpty();
@@ -82,10 +82,10 @@ public class AuthorizationDaoTest {
   public void keep_authorized_project_ids_for_group() {
     dbTester.prepareDbUnit(getClass(), "keep_authorized_project_ids_for_group.xml");
 
-    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), Sets.newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT), USER, "user")).containsOnly(PROJECT_ID);
+    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT), USER, "user")).containsOnly(PROJECT_ID);
 
     // user does not have the role "admin"
-    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), Sets.newHashSet(PROJECT_ID), USER, "admin")).isEmpty();
+    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), newHashSet(PROJECT_ID), USER, "admin")).isEmpty();
 
     // Empty list
     assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), Collections.<Long>emptySet(), USER, "admin")).isEmpty();
@@ -95,10 +95,10 @@ public class AuthorizationDaoTest {
   public void keep_authorized_project_ids_for_anonymous() {
     dbTester.prepareDbUnit(getClass(), "keep_authorized_project_ids_for_anonymous.xml");
 
-    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), Sets.newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT), null, "user")).containsOnly(PROJECT_ID);
+    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT), null, "user")).containsOnly(PROJECT_ID);
 
     // user does not have the role "admin"
-    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), Sets.newHashSet(PROJECT_ID), null, "admin")).isEmpty();
+    assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), newHashSet(PROJECT_ID), null, "admin")).isEmpty();
 
     // Empty list
     assertThat(authorization.keepAuthorizedProjectIds(dbTester.getSession(), Collections.<Long>emptySet(), null, "admin")).isEmpty();
@@ -141,14 +141,14 @@ public class AuthorizationDaoTest {
     dbTester.prepareDbUnit(getClass(), "group_should_be_authorized.xml");
 
     Collection<Long> componentIds = authorization.keepAuthorizedProjectIds(dbTester.getSession(),
-      Sets.newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT),
+      newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT),
       USER, "user");
 
     assertThat(componentIds).containsOnly(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT);
 
     // group does not have the role "admin"
     componentIds = authorization.keepAuthorizedProjectIds(dbTester.getSession(),
-      Sets.newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT),
+      newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT),
       USER, "admin");
     assertThat(componentIds).isEmpty();
   }
@@ -158,14 +158,14 @@ public class AuthorizationDaoTest {
     dbTester.prepareDbUnit(getClass(), "anonymous_should_be_authorized.xml");
 
     Collection<Long> componentIds = authorization.keepAuthorizedProjectIds(dbTester.getSession(),
-      Sets.newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT),
+      newHashSet(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT),
       null, "user");
 
     assertThat(componentIds).containsOnly(PROJECT_ID, PROJECT_ID_WITHOUT_SNAPSHOT);
 
     // group does not have the role "admin"
     componentIds = authorization.keepAuthorizedProjectIds(dbTester.getSession(),
-      Sets.newHashSet(PROJECT_ID),
+      newHashSet(PROJECT_ID),
       null, "admin");
     assertThat(componentIds).isEmpty();
   }
@@ -282,4 +282,43 @@ public class AuthorizationDaoTest {
     assertThat(authorization.selectGlobalPermissions("anyone_user")).containsOnly("user", "profileadmin");
   }
 
+  @Test
+  public void keep_authorized_users_for_role_and_project_for_user() {
+    dbTester.prepareDbUnit(getClass(), "keep_authorized_users_for_role_and_project_for_user.xml");
+
+    assertThat(authorization.keepAuthorizedUsersForRoleAndProject(dbTester.getSession(),
+      // Only 100 and 101 has 'user' role on project
+      newHashSet(100L, 101L, 102L), "user", PROJECT_ID)).containsOnly(100L, 101L);
+
+    // user does not have the role "admin"
+    assertThat(authorization.keepAuthorizedUsersForRoleAndProject(dbTester.getSession(), newHashSet(100L), "admin", PROJECT_ID)).isEmpty();
+
+    // Empty list
+    assertThat(authorization.keepAuthorizedUsersForRoleAndProject(dbTester.getSession(), Collections.<Long>emptySet(), "user", PROJECT_ID)).isEmpty();
+  }
+
+  @Test
+  public void keep_authorized_users_for_role_and_project_for_group() {
+    dbTester.prepareDbUnit(getClass(), "keep_authorized_users_for_role_and_project_for_group.xml");
+
+    assertThat(authorization.keepAuthorizedUsersForRoleAndProject(dbTester.getSession(),
+      // Only 100 and 101 has 'user' role on project
+      newHashSet(100L, 101L, 102L), "user", PROJECT_ID)).containsOnly(100L, 101L);
+
+    // user does not have the role "admin"
+    assertThat(authorization.keepAuthorizedUsersForRoleAndProject(dbTester.getSession(), newHashSet(100L), "admin", PROJECT_ID)).isEmpty();
+
+    // Empty list
+    assertThat(authorization.keepAuthorizedUsersForRoleAndProject(dbTester.getSession(), Collections.<Long>emptySet(), "user", PROJECT_ID)).isEmpty();
+  }
+
+  @Test
+  public void keep_authorized_users_for_role_and_project_for_anonymous() {
+    dbTester.prepareDbUnit(getClass(), "keep_authorized_users_for_role_and_project_for_anonymous.xml");
+
+    assertThat(authorization.keepAuthorizedUsersForRoleAndProject(dbTester.getSession(),
+      // Only 100 and 101 has 'user' role on project
+      newHashSet(100L, 101L, 102L), "user", PROJECT_ID)).containsOnly(100L, 101L);
+  }
+
 }
diff --git a/sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_anomymous.xml b/sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_anomymous.xml
new file mode 100644 (file)
index 0000000..4de4f32
--- /dev/null
@@ -0,0 +1,18 @@
+<dataset>
+
+  <!-- users 100 and 101 have no direct grant access, but are in the group 200 that has the role "user" on the project 300  -->
+  <user_roles id="1" user_id="100" resource_id="999" role="user"/>
+  <user_roles id="2" user_id="101" resource_id="999" role="user"/>
+  <user_roles id="3" user_id="102" resource_id="999" role="user"/>
+
+  <groups_users user_id="100" group_id="200"/>
+  <groups_users user_id="101" group_id="200"/>
+  <groups_users user_id="102" group_id="201"/>
+
+  <group_roles id="1" group_id="[null]" resource_id="300" role="user"/>
+  <group_roles id="2" group_id="201" resource_id="400" role="user"/>
+
+  <projects id="300" kee="pj-w-snapshot" uuid="DEFG" module_uuid="[null]"/>
+  <projects id="400" kee="pj-wo-snapshot" uuid="EFGH" module_uuid="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_anonymous.xml b/sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_anonymous.xml
new file mode 100644 (file)
index 0000000..491e1f8
--- /dev/null
@@ -0,0 +1,26 @@
+<dataset>
+
+  <!-- Users 100 and 101 are 'user' on project 300 -->
+  <user_roles id="1" user_id="100" resource_id="300" role="user"/>
+  <user_roles id="2" user_id="101" resource_id="300" role="user"/>
+  <user_roles id="3" user_id="102" resource_id="300" role="admin"/>
+  <!-- User 100 is 'user' on project 400 -->
+  <user_roles id="4" user_id="100" resource_id="400" role="user"/>
+
+  <groups_users user_id="100" group_id="200"/>
+  <group_roles id="1" group_id="200" resource_id="400" role="user"/>
+
+  <projects id="300" kee="pj-w-snapshot" uuid="DEFG" module_uuid="[null]"/>
+  <projects id="400" kee="pj-wo-snapshot" uuid="EFGH" module_uuid="[null]"/>
+
+
+  <!-- user 100 has no direct grant access, but is in the group 200 that has the role "user"
+    on the project 300  -->
+  <!--<user_roles id="1" user_id="100" resource_id="999" role="user"/>-->
+
+  <!--<groups_users user_id="100" group_id="200"/>-->
+
+  <!--<group_roles id="1" group_id="200" resource_id="300" role="user"/>-->
+  <!--<group_roles id="2" group_id="200" resource_id="400" role="user"/>-->
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_group.xml b/sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_group.xml
new file mode 100644 (file)
index 0000000..c813b02
--- /dev/null
@@ -0,0 +1,18 @@
+<dataset>
+
+  <!-- users 100 and 101 have no direct grant access, but are in the group 200 that has the role "user" on the project 300  -->
+  <user_roles id="1" user_id="100" resource_id="999" role="user"/>
+  <user_roles id="2" user_id="101" resource_id="999" role="user"/>
+  <user_roles id="3" user_id="102" resource_id="999" role="user"/>
+
+  <groups_users user_id="100" group_id="200"/>
+  <groups_users user_id="101" group_id="200"/>
+  <groups_users user_id="102" group_id="201"/>
+
+  <group_roles id="1" group_id="200" resource_id="300" role="user"/>
+  <group_roles id="2" group_id="201" resource_id="400" role="user"/>
+
+  <projects id="300" kee="pj-w-snapshot" uuid="DEFG" module_uuid="[null]"/>
+  <projects id="400" kee="pj-wo-snapshot" uuid="EFGH" module_uuid="[null]"/>
+
+</dataset>
diff --git a/sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_user.xml b/sonar-db/src/test/resources/org/sonar/db/user/AuthorizationDaoTest/keep_authorized_users_for_role_and_project_for_user.xml
new file mode 100644 (file)
index 0000000..e6328ec
--- /dev/null
@@ -0,0 +1,15 @@
+<dataset>
+
+  <!-- Users 100 and 101 are 'user' on project 300 -->
+  <user_roles id="1" user_id="100" resource_id="300" role="user"/>
+  <user_roles id="2" user_id="101" resource_id="300" role="user"/>
+  <user_roles id="3" user_id="102" resource_id="300" role="admin"/>
+  <user_roles id="4" user_id="100" resource_id="400" role="user"/>
+
+  <groups_users user_id="100" group_id="200"/>
+  <group_roles id="1" group_id="200" resource_id="400" role="user"/>
+
+  <projects id="300" kee="pj-w-snapshot" uuid="DEFG" module_uuid="[null]"/>
+  <projects id="400" kee="pj-wo-snapshot" uuid="EFGH" module_uuid="[null]"/>
+
+</dataset>