]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8227 Replace selection of date by projects in authorization index
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 17 Oct 2016 16:03:13 +0000 (18:03 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 20 Oct 2016 11:12:07 +0000 (13:12 +0200)
server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationDao.java
server/sonar-server/src/main/java/org/sonar/server/permission/index/AuthorizationIndexer.java
server/sonar-server/src/main/java/org/sonar/server/permission/index/package-info.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ApplyPermissionsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationDaoTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/index/AuthorizationIndexerTester.java

index 066a9f2f5425ddab70b5a821b0dae2c7a5c522c4..b585a05e35fa8a417b90d49e99ef5dc47c0d3d6b 100644 (file)
 package org.sonar.server.permission.index;
 
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.dbutils.DbUtils;
@@ -32,6 +33,9 @@ import org.apache.commons.lang.StringUtils;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 
+import static org.sonar.db.DatabaseUtils.executeLargeInputs;
+import static org.sonar.db.DatabaseUtils.repeatCondition;
+
 /**
  * No streaming because of union of joins -> no need to use ResultSetIterator
  */
@@ -75,108 +79,118 @@ public class AuthorizationDao {
     }
   }
 
-  private static final String SQL_TEMPLATE =
-    "SELECT " +
-      "  project_authorization.project as project, " +
-      "  project_authorization.login as login, " +
-      "  project_authorization.permission_group as permission_group, " +
-      "  project_authorization.updated_at as updated_at " +
-      "FROM ( " +
-
-      // project is returned when no authorization
-      "      SELECT " +
-      "      projects.uuid AS project, " +
-      "      projects.authorization_updated_at AS updated_at, " +
-      "      NULL AS login, " +
-      "      NULL  AS permission_group " +
-      "      FROM projects " +
-      "      WHERE " +
-      "        projects.qualifier = 'TRK' " +
-      "        AND projects.copy_component_uuid is NULL " +
-      "        {dateCondition} " +
-      "      UNION " +
-
-      // users
-
-      "      SELECT " +
-      "      projects.uuid AS project, " +
-      "      projects.authorization_updated_at AS updated_at, " +
-      "      users.login  AS login, " +
-      "      NULL  AS permission_group " +
-      "      FROM projects " +
-      "      INNER JOIN user_roles ON user_roles.resource_id = projects.id AND user_roles.role = 'user' " +
-      "      INNER JOIN users ON users.id = user_roles.user_id " +
-      "      WHERE " +
-      "        projects.qualifier = 'TRK' " +
-      "        AND projects.copy_component_uuid is NULL " +
-      "        {dateCondition} " +
-      "      UNION " +
-
-      // groups without Anyone
-
-      "      SELECT " +
-      "      projects.uuid AS project, " +
-      "      projects.authorization_updated_at AS updated_at, " +
-      "      NULL  AS login, " +
-      "      groups.name  AS permission_group " +
-      "      FROM projects " +
-      "      INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role = 'user' " +
-      "      INNER JOIN groups ON groups.id = group_roles.group_id " +
-      "      WHERE " +
-      "        projects.qualifier = 'TRK' " +
-      "        AND projects.copy_component_uuid is NULL " +
-      "        {dateCondition} " +
-      "        AND group_id IS NOT NULL " +
-      "      UNION " +
-
-      // Anyone groups
-
-      "      SELECT " +
-      "      projects.uuid AS project, " +
-      "      projects.authorization_updated_at AS updated_at, " +
-      "      NULL         AS login, " +
-      "      'Anyone'     AS permission_group " +
-      "      FROM projects " +
-      "      INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role='user' " +
-      "      WHERE " +
-      "        projects.qualifier = 'TRK' " +
-      "        AND projects.copy_component_uuid is NULL " +
-      "        {dateCondition} " +
-      "        AND group_roles.group_id IS NULL " +
-      "    ) project_authorization";
-
-  Collection<Dto> selectAfterDate(DbClient dbClient, DbSession session, long afterDate) {
+  private static final String SQL_TEMPLATE = "SELECT " +
+    "  project_authorization.project as project, " +
+    "  project_authorization.login as login, " +
+    "  project_authorization.permission_group as permission_group, " +
+    "  project_authorization.updated_at as updated_at " +
+    "FROM ( " +
+
+    // project is returned when no authorization
+    "      SELECT " +
+    "      projects.uuid AS project, " +
+    "      projects.authorization_updated_at AS updated_at, " +
+    "      NULL AS login, " +
+    "      NULL  AS permission_group " +
+    "      FROM projects " +
+    "      WHERE " +
+    "        projects.qualifier = 'TRK' " +
+    "        AND projects.copy_component_uuid is NULL " +
+    "        {projectsCondition} " +
+    "      UNION " +
+
+    // users
+
+    "      SELECT " +
+    "      projects.uuid AS project, " +
+    "      projects.authorization_updated_at AS updated_at, " +
+    "      users.login  AS login, " +
+    "      NULL  AS permission_group " +
+    "      FROM projects " +
+    "      INNER JOIN user_roles ON user_roles.resource_id = projects.id AND user_roles.role = 'user' " +
+    "      INNER JOIN users ON users.id = user_roles.user_id " +
+    "      WHERE " +
+    "        projects.qualifier = 'TRK' " +
+    "        AND projects.copy_component_uuid is NULL " +
+    "        {projectsCondition} " +
+    "      UNION " +
+
+    // groups without Anyone
+
+    "      SELECT " +
+    "      projects.uuid AS project, " +
+    "      projects.authorization_updated_at AS updated_at, " +
+    "      NULL  AS login, " +
+    "      groups.name  AS permission_group " +
+    "      FROM projects " +
+    "      INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role = 'user' " +
+    "      INNER JOIN groups ON groups.id = group_roles.group_id " +
+    "      WHERE " +
+    "        projects.qualifier = 'TRK' " +
+    "        AND projects.copy_component_uuid is NULL " +
+    "        {projectsCondition} " +
+    "        AND group_id IS NOT NULL " +
+    "      UNION " +
+
+    // Anyone groups
+
+    "      SELECT " +
+    "      projects.uuid AS project, " +
+    "      projects.authorization_updated_at AS updated_at, " +
+    "      NULL         AS login, " +
+    "      'Anyone'     AS permission_group " +
+    "      FROM projects " +
+    "      INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role='user' " +
+    "      WHERE " +
+    "        projects.qualifier = 'TRK' " +
+    "        AND projects.copy_component_uuid is NULL " +
+    "        {projectsCondition} " +
+    "        AND group_roles.group_id IS NULL " +
+    "    ) project_authorization";
+
+  List<Dto> selectAfterDate(DbClient dbClient, DbSession session, List<String> projectUuids) {
+    if (projectUuids.isEmpty()) {
+      return doSelectAfterDate(dbClient, session, Collections.emptyList());
+    }
+    return executeLargeInputs(projectUuids, subProjectUuids -> doSelectAfterDate(dbClient, session, subProjectUuids));
+  }
+
+  private List<Dto> doSelectAfterDate(DbClient dbClient, DbSession session, List<String> projectUuids) {
     try {
-      Map<String, Dto> dtosByProjectUuid = Maps.newHashMap();
+      Map<String, Dto> dtosByProjectUuid = new HashMap<>();
       PreparedStatement stmt = null;
       ResultSet rs = null;
       try {
-        stmt = createStatement(dbClient, session, afterDate);
+        stmt = createStatement(dbClient, session, projectUuids);
         rs = stmt.executeQuery();
         while (rs.next()) {
           processRow(rs, dtosByProjectUuid);
         }
-        return dtosByProjectUuid.values();
+        return new ArrayList<>(dtosByProjectUuid.values());
       } finally {
         DbUtils.closeQuietly(rs);
         DbUtils.closeQuietly(stmt);
       }
     } catch (SQLException e) {
-      throw new IllegalStateException("Fail to select authorizations after date: " + afterDate, e);
+      throw new IllegalStateException("Fail to select authorizations", e);
     }
   }
 
-  private static PreparedStatement createStatement(DbClient dbClient, DbSession session, long afterDate) throws SQLException {
+  private static PreparedStatement createStatement(DbClient dbClient, DbSession session, List<String> projectUuids) throws SQLException {
     String sql;
-    if (afterDate > 0L) {
-      sql = StringUtils.replace(SQL_TEMPLATE, "{dateCondition}", " AND projects.authorization_updated_at>? ");
+    if (!projectUuids.isEmpty()) {
+      sql = StringUtils.replace(SQL_TEMPLATE, "{projectsCondition}", " AND (" + repeatCondition("projects.uuid = ?", projectUuids.size(), "OR") + ")");
     } else {
-      sql = StringUtils.replace(SQL_TEMPLATE, "{dateCondition}", "");
+      sql = StringUtils.replace(SQL_TEMPLATE, "{projectsCondition}", "");
     }
     PreparedStatement stmt = dbClient.getMyBatis().newScrollingSelectStatement(session, sql);
-    if (afterDate > 0L) {
+    if (!projectUuids.isEmpty()) {
+      int index = 1;
       for (int i = 1; i <= 4; i++) {
-        stmt.setLong(i, afterDate);
+        for (int uuidIndex = 0; uuidIndex < projectUuids.size(); uuidIndex++) {
+          stmt.setString(index, projectUuids.get(uuidIndex));
+          index++;
+        }
       }
     }
     return stmt;
index e474ca96b1133785b6543131ac903c33993f73bd..614a689bbf570d15b7b95fcbb2affa159e160743 100644 (file)
@@ -22,7 +22,9 @@ package org.sonar.server.permission.index;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableMap;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 import org.elasticsearch.action.index.IndexRequest;
 import org.sonar.db.DbClient;
@@ -31,6 +33,8 @@ import org.sonar.server.es.BaseIndexer;
 import org.sonar.server.es.BulkIndexer;
 import org.sonar.server.es.EsClient;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Arrays.asList;
 import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_AUTHORIZATION_GROUPS;
 import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID;
 import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT;
@@ -57,13 +61,22 @@ public class AuthorizationIndexer extends BaseIndexer {
 
   @Override
   protected long doIndex(long lastUpdatedAt) {
-    try (DbSession dbSession = dbClient.openSession(false)) {
-      // warning - do not enable large mode, else disabling of replicas
-      // will impact the type "issue" which is much bigger than issueAuthorization
-      BulkIndexer bulk = new BulkIndexer(esClient, INDEX);
+    return doIndex(createBulkIndexer(), Collections.<String>emptyList());
+  }
 
+  public void index(String projectUuid) {
+    index(asList(projectUuid));
+  }
+
+  public void index(List<String> projectUuids) {
+    checkArgument(!projectUuids.isEmpty(), "ProjectUuids cannot be empty");
+    super.index(lastUpdatedAt -> doIndex(createBulkIndexer(), projectUuids));
+  }
+
+  private long doIndex(BulkIndexer bulk, List<String> projectUuids) {
+    try (DbSession dbSession = dbClient.openSession(false)) {
       AuthorizationDao dao = new AuthorizationDao();
-      Collection<AuthorizationDao.Dto> authorizations = dao.selectAfterDate(dbClient, dbSession, lastUpdatedAt);
+      Collection<AuthorizationDao.Dto> authorizations = dao.selectAfterDate(dbClient, dbSession, projectUuids);
       return doIndex(bulk, authorizations);
     }
   }
@@ -74,7 +87,7 @@ public class AuthorizationIndexer extends BaseIndexer {
     doIndex(bulk, authorizations);
   }
 
-  private long doIndex(BulkIndexer bulk, Collection<AuthorizationDao.Dto> authorizations) {
+  private static long doIndex(BulkIndexer bulk, Collection<AuthorizationDao.Dto> authorizations) {
     long maxDate = 0L;
     bulk.start();
     for (AuthorizationDao.Dto authorization : authorizations) {
@@ -93,6 +106,12 @@ public class AuthorizationIndexer extends BaseIndexer {
       .get();
   }
 
+  private BulkIndexer createBulkIndexer() {
+    // warning - do not enable large mode, else disabling of replicas
+    // will impact the type "issue" which is much bigger than issueAuthorization
+    return new BulkIndexer(esClient, INDEX);
+  }
+
   private static IndexRequest newIndexRequest(AuthorizationDao.Dto dto) {
     Map<String, Object> doc = ImmutableMap.of(
       FIELD_AUTHORIZATION_PROJECT_UUID, dto.getProjectUuid(),
diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/index/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/permission/index/package-info.java
new file mode 100644 (file)
index 0000000..008124d
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.permission.index;
+
+import javax.annotation.ParametersAreNonnullByDefault;
index 76c227385028144ace866d8db225b44ae7c550ee..d04968bacc15c57d628247576ec40eb69a7342c7 100644 (file)
@@ -107,7 +107,7 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
 
     assertThat(dbClient.componentDao().selectOrFailByKey(dbSession, ROOT_KEY).getAuthorizationUpdatedAt()).isNotNull();
     assertThat(dbClient.roleDao().selectGroupPermissions(dbSession, DefaultGroups.ANYONE, projectDto.getId())).containsOnly(UserRole.USER);
-    authorizationIndexerTester.verifyProjectAuthorization(ROOT_UUID, singletonList(DefaultGroups.ANYONE), emptyList());
+    authorizationIndexerTester.verifyProjectExistsWithAuthorization(ROOT_UUID, singletonList(DefaultGroups.ANYONE), emptyList());
   }
 
   @Test
index e1ae606f0371158879c1778f1b606c8cbef58f09..9428f6070ed46f17cfa55b8ffaa5245b47630a36 100644 (file)
  */
 package org.sonar.server.permission.index;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.utils.System2;
+import org.sonar.core.util.stream.Collectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDbTester;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.permission.GroupPermissionDto;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDbTester;
 import org.sonar.db.user.UserDto;
 
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.api.security.DefaultGroups.ANYONE;
 import static org.sonar.api.web.UserRole.ADMIN;
@@ -48,59 +59,101 @@ public class AuthorizationDaoTest {
   ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
   UserDbTester userDbTester = new UserDbTester(dbTester);
 
+  ComponentDto project1;
+  ComponentDto project2;
+  UserDto user1;
+  UserDto user2;
+  GroupDto group;
+
   AuthorizationDao underTest = new AuthorizationDao();
 
+  @Before
+  public void setUp() throws Exception {
+    project1 = componentDbTester.insertProject();
+    project2 = componentDbTester.insertProject();
+    user1 = userDbTester.insertUser();
+    user2 = userDbTester.insertUser();
+    group = userDbTester.insertGroup();
+  }
+
   @Test
   public void select_all() {
-    ComponentDto project1 = componentDbTester.insertProject();
-    ComponentDto project2 = componentDbTester.insertProject();
+    insertTestDataForProject1And2();
 
-    // user1 can access both projects
-    UserDto user1 = userDbTester.insertUser();
-    userDbTester.insertProjectPermissionOnUser(user1, USER, project1);
-    userDbTester.insertProjectPermissionOnUser(user1, ADMIN, project1);
-    userDbTester.insertProjectPermissionOnUser(user1, USER, project2);
+    Collection<AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, Collections.emptyList());
+    assertThat(dtos).hasSize(2);
 
-    // user2 has user access on project2 only
-    UserDto user2 = userDbTester.insertUser();
-    userDbTester.insertProjectPermissionOnUser(user2, USER, project2);
+    AuthorizationDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos);
+    assertThat(project1Authorization.getGroups()).containsOnly(ANYONE, group.getName());
+    assertThat(project1Authorization.getUsers()).containsOnly(user1.getLogin());
+    assertThat(project1Authorization.getUpdatedAt()).isNotNull();
 
-    // group1 has user access on project1 only
-    GroupDto group = userDbTester.insertGroup();
-    userDbTester.insertProjectPermissionOnGroup(group, USER, project1);
-    userDbTester.insertProjectPermissionOnGroup(group, ADMIN, project1);
+    AuthorizationDao.Dto project2Authorization = getByProjectUuid(project2.uuid(), dtos);
+    assertThat(project2Authorization.getGroups()).containsOnly(ANYONE);
+    assertThat(project2Authorization.getUsers()).containsOnly(user1.getLogin(), user2.getLogin());
+    assertThat(project2Authorization.getUpdatedAt()).isNotNull();
+  }
 
-    // Anyone group has user access on both projects
-    userDbTester.insertProjectPermissionOnAnyone(USER, project1);
-    userDbTester.insertProjectPermissionOnAnyone(ADMIN, project1);
-    userDbTester.insertProjectPermissionOnAnyone(USER, project2);
+  @Test
+  public void select_by_project() throws Exception {
+    insertTestDataForProject1And2();
 
-    Collection<AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, 0L);
+    Collection<AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, singletonList(project1.uuid()));
+    assertThat(dtos).hasSize(1);
+    AuthorizationDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos);
+    assertThat(project1Authorization.getGroups()).containsOnly(ANYONE, group.getName());
+    assertThat(project1Authorization.getUsers()).containsOnly(user1.getLogin());
+    assertThat(project1Authorization.getUpdatedAt()).isNotNull();
+  }
+
+  @Test
+  public void select_by_projects() throws Exception {
+    insertTestDataForProject1And2();
+
+    Map<String, AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, asList(project1.uuid(), project2.uuid()))
+      .stream()
+      .collect(Collectors.uniqueIndex(AuthorizationDao.Dto::getProjectUuid, Function.identity()));
     assertThat(dtos).hasSize(2);
 
-    AuthorizationDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos);
+    AuthorizationDao.Dto project1Authorization = dtos.get(project1.uuid());
     assertThat(project1Authorization.getGroups()).containsOnly(ANYONE, group.getName());
     assertThat(project1Authorization.getUsers()).containsOnly(user1.getLogin());
     assertThat(project1Authorization.getUpdatedAt()).isNotNull();
 
-    AuthorizationDao.Dto project2Authorization = getByProjectUuid(project2.uuid(), dtos);
+    AuthorizationDao.Dto project2Authorization = dtos.get(project2.uuid());
     assertThat(project2Authorization.getGroups()).containsOnly(ANYONE);
     assertThat(project2Authorization.getUsers()).containsOnly(user1.getLogin(), user2.getLogin());
     assertThat(project2Authorization.getUpdatedAt()).isNotNull();
   }
 
   @Test
-  public void no_authorization() {
-    ComponentDto project1 = componentDbTester.insertProject();
-    // no authorizations project1
+  public void select_by_projects_with_high_number_of_projects() throws Exception {
+    List<String> projects = new ArrayList<>();
+    for (int i = 0; i < 350; i++) {
+      ComponentDto project = ComponentTesting.newProjectDto(Integer.toString(i));
+      dbClient.componentDao().insert(dbSession, project);
+      projects.add(project.uuid());
+      GroupPermissionDto dto = new GroupPermissionDto()
+        .setOrganizationUuid(group.getOrganizationUuid())
+        .setGroupId(group.getId())
+        .setRole(USER)
+        .setResourceId(project.getId());
+      dbClient.groupPermissionDao().insert(dbSession, dto);
+    }
+    dbSession.commit();
+
+    Map<String, AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, projects)
+      .stream()
+      .collect(Collectors.uniqueIndex(AuthorizationDao.Dto::getProjectUuid, Function.identity()));
+    assertThat(dtos).hasSize(350);
+  }
 
-    ComponentDto project2 = componentDbTester.insertProject();
-    UserDto user = userDbTester.insertUser();
-    userDbTester.insertProjectPermissionOnUser(user, USER, project2);
-    GroupDto group = userDbTester.insertGroup();
+  @Test
+  public void no_authorization() {
+    userDbTester.insertProjectPermissionOnUser(user1, USER, project2);
     userDbTester.insertProjectPermissionOnGroup(group, USER, project2);
 
-    Collection<AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, 0L);
+    Collection<AuthorizationDao.Dto> dtos = underTest.selectAfterDate(dbClient, dbSession, Collections.emptyList());
 
     assertThat(dtos).hasSize(2);
     AuthorizationDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos);
@@ -113,4 +166,22 @@ public class AuthorizationDaoTest {
     return dtos.stream().filter(dto -> dto.getProjectUuid().equals(projectUuid)).findFirst().orElseThrow(IllegalArgumentException::new);
   }
 
+  private void insertTestDataForProject1And2() {
+    // user1 can access both projects
+    userDbTester.insertProjectPermissionOnUser(user1, USER, project1);
+    userDbTester.insertProjectPermissionOnUser(user1, ADMIN, project1);
+    userDbTester.insertProjectPermissionOnUser(user1, USER, project2);
+
+    // user2 has user access on project2 only
+    userDbTester.insertProjectPermissionOnUser(user2, USER, project2);
+
+    // group1 has user access on project1 only
+    userDbTester.insertProjectPermissionOnGroup(group, USER, project1);
+    userDbTester.insertProjectPermissionOnGroup(group, ADMIN, project1);
+
+    // Anyone group has user access on both projects
+    userDbTester.insertProjectPermissionOnAnyone(USER, project1);
+    userDbTester.insertProjectPermissionOnAnyone(ADMIN, project1);
+    userDbTester.insertProjectPermissionOnAnyone(USER, project2);
+  }
 }
index bf888f56f950f5353b8f807f59d37b359ca845ee..dc67e68442f8ec5ba538353d2908e7d32e9bcf31 100644 (file)
  */
 package org.sonar.server.permission.index;
 
+import java.util.Collections;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
@@ -33,6 +35,7 @@ import org.sonar.server.es.EsTester;
 import org.sonar.server.issue.index.IssueIndexDefinition;
 
 import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
 import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.api.security.DefaultGroups.ANYONE;
@@ -41,6 +44,9 @@ import static org.sonar.api.web.UserRole.USER;
 
 public class AuthorizationIndexerTest {
 
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
@@ -70,9 +76,41 @@ public class AuthorizationIndexerTest {
     userDbTester.insertProjectPermissionOnGroup(group, USER, project);
     userDbTester.insertProjectPermissionOnAnyone(USER, project);
 
-    underTest.doIndex(0L);
+    underTest.index();
 
-    authorizationIndexerTester.verifyProjectAuthorization(project.uuid(), asList(group.getName(), ANYONE), singletonList(user.getLogin()));
+    authorizationIndexerTester.verifyProjectExistsWithAuthorization(project.uuid(), asList(group.getName(), ANYONE), singletonList(user.getLogin()));
+  }
+
+  @Test
+  public void index_one_project() throws Exception {
+    GroupDto group = userDbTester.insertGroup();
+    ComponentDto project1 = componentDbTester.insertProject();
+    userDbTester.insertProjectPermissionOnGroup(group, USER, project1);
+    ComponentDto project2 = componentDbTester.insertProject();
+    userDbTester.insertProjectPermissionOnGroup(group, USER, project2);
+
+    underTest.index(project1.uuid());
+
+    authorizationIndexerTester.verifyProjectExistsWithAuthorization(project1.uuid(), asList(group.getName(), ANYONE), emptyList());
+    authorizationIndexerTester.verifyProjectDoesNotExist(project2.uuid());
+  }
+
+  @Test
+  public void index_projects() throws Exception {
+    GroupDto group = userDbTester.insertGroup();
+    ComponentDto project1 = componentDbTester.insertProject();
+    userDbTester.insertProjectPermissionOnGroup(group, USER, project1);
+    ComponentDto project2 = componentDbTester.insertProject();
+    userDbTester.insertProjectPermissionOnGroup(group, USER, project2);
+    ComponentDto project3 = componentDbTester.insertProject();
+    userDbTester.insertProjectPermissionOnGroup(group, USER, project3);
+
+    // Only index projects 1 and 2
+    underTest.index(asList(project1.uuid(), project2.uuid()));
+
+    authorizationIndexerTester.verifyProjectExistsWithAuthorization(project1.uuid(), asList(group.getName(), ANYONE), emptyList());
+    authorizationIndexerTester.verifyProjectExistsWithAuthorization(project2.uuid(), asList(group.getName(), ANYONE), emptyList());
+    authorizationIndexerTester.verifyProjectDoesNotExist(project3.uuid());
   }
 
   @Test
@@ -98,7 +136,12 @@ public class AuthorizationIndexerTest {
     // remove permissions -> dto has no users nor groups
     underTest.index(singletonList(new AuthorizationDao.Dto("ABC", System.currentTimeMillis())));
 
-    authorizationIndexerTester.verifyProjectAsNoAuthorization("ABC");
+    authorizationIndexerTester.verifyProjectExistsWithoutAuthorization("ABC");
   }
 
+  @Test
+  public void fail_when_trying_to_index_empty_project_uuids() throws Exception {
+    expectedException.expect(IllegalArgumentException.class);
+    underTest.index(Collections.<String>emptyList());
+  }
 }
index 6591022a7215a66ff9db33e7735944fea9c58965..9096bd17b4e565c2a4d8f1cccde8a3a5057c8260 100644 (file)
@@ -59,12 +59,16 @@ public class AuthorizationIndexerTester {
     assertThat(esTester.countDocuments("issues", "authorization")).isZero();
   }
 
-  public void verifyProjectAsNoAuthorization(String projectUuid) {
-    verifyProjectAuthorization(projectUuid, emptyList(), emptyList());
+  public void verifyProjectDoesNotExist(String projectUuid) {
+    assertThat(esTester.getIds("issues", "authorization")).doesNotContain(projectUuid);
   }
 
-  public void verifyProjectAuthorization(String projectUuid, List<String> groupNames, List<String> userLogins) {
-    assertThat(esTester.getIds("issues", "authorization")).containsOnly(projectUuid);
+  public void verifyProjectExistsWithoutAuthorization(String projectUuid) {
+    verifyProjectExistsWithAuthorization(projectUuid, emptyList(), emptyList());
+  }
+
+  public void verifyProjectExistsWithAuthorization(String projectUuid, List<String> groupNames, List<String> userLogins) {
+    assertThat(esTester.getIds("issues", "authorization")).contains(projectUuid);
     BoolQueryBuilder queryBuilder = boolQuery().must(termQuery(FIELD_AUTHORIZATION_PROJECT_UUID, projectUuid));
     if (groupNames.isEmpty()) {
       queryBuilder.mustNot(existsQuery(FIELD_AUTHORIZATION_GROUPS));