From 35de0ed9acb340b5f09281c733951e46ebe40276 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Tue, 17 Jan 2017 18:25:52 +0100 Subject: [PATCH] SONAR-8238 index authorization of views in components index --- .../permission/PermissionTemplateService.java | 4 +- .../server/permission/PermissionUpdater.java | 6 +- .../permission/index/PermissionIndexer.java | 64 +++++++---- .../index/PermissionIndexerDao.java | 30 ++++-- .../index/PermissionIndexerDaoTest.java | 100 ++++++++++++------ .../index/PermissionIndexerTest.java | 17 ++- .../index/PermissionIndexerTester.java | 51 ++++++--- 7 files changed, 185 insertions(+), 87 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java index 491dd0372fd..364ef3d2828 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java @@ -145,8 +145,8 @@ public class PermissionTemplateService { .anyMatch(PermissionTemplateCharacteristicDto::getWithProjectCreator); } - private void indexProjectPermissions(DbSession dbSession, List projectUuids) { - permissionIndexer.index(dbSession, projectUuids); + private void indexProjectPermissions(DbSession dbSession, List projectOrViewUuids) { + permissionIndexer.index(dbSession, projectOrViewUuids); } private void copyPermissions(DbSession dbSession, PermissionTemplateDto template, ComponentDto project, @Nullable Long projectCreatorUserId) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java index 4d90f6c09db..0da2f221d7e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java @@ -51,13 +51,13 @@ public class PermissionUpdater { public void apply(DbSession dbSession, Collection changes) { Set projectIds = new HashSet<>(); - List projectUuids = new ArrayList<>(); + List projectOrViewUuids = new ArrayList<>(); for (PermissionChange change : changes) { boolean changed = doApply(dbSession, change); Optional projectId = change.getProjectId(); if (changed && projectId.isPresent()) { projectIds.add(projectId.get().getId()); - projectUuids.add(projectId.get().getUuid()); + projectOrViewUuids.add(projectId.get().getUuid()); } } for (Long projectId : projectIds) { @@ -66,7 +66,7 @@ public class PermissionUpdater { dbSession.commit(); if (!projectIds.isEmpty()) { - permissionIndexer.index(dbSession, projectUuids); + permissionIndexer.index(dbSession, projectOrViewUuids); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/index/PermissionIndexer.java b/server/sonar-server/src/main/java/org/sonar/server/permission/index/PermissionIndexer.java index 03e390c9285..0d4231cd28e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/index/PermissionIndexer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/index/PermissionIndexer.java @@ -27,6 +27,7 @@ import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; @@ -36,6 +37,7 @@ import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.search.SearchResponse; import org.picocontainer.Startable; +import org.sonar.api.resources.Qualifiers; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.server.component.index.ComponentIndexDefinition; @@ -104,10 +106,10 @@ public class PermissionIndexer implements Startable { BulkIndexer.delete(esClient, index, esClient.prepareSearch(index).setTypes(type).setQuery(matchAllQuery())); } - public void index(DbSession dbSession, List projectUuids) { - checkArgument(!projectUuids.isEmpty(), "ProjectUuids cannot be empty"); + public void index(DbSession dbSession, List viewOrProjectUuids) { + checkArgument(!viewOrProjectUuids.isEmpty(), "viewOrProjectUuids cannot be empty"); PermissionIndexerDao dao = new PermissionIndexerDao(); - index(dao.selectByProjects(dbClient, dbSession, projectUuids)); + index(dao.selectByUuids(dbClient, dbSession, viewOrProjectUuids)); } private void index(Collection authorizations) { @@ -117,9 +119,9 @@ public class PermissionIndexer implements Startable { int count = 0; BulkRequestBuilder bulkRequest = esClient.prepareBulk().setRefresh(false); for (PermissionIndexerDao.Dto dto : authorizations) { - bulkRequest.add(newIssuesAuthorizationIndexRequest(dto)); - bulkRequest.add(newProjectMeasuresAuthorizationIndexRequest(dto)); - bulkRequest.add(newComponentsAuthorizationIndexRequest(dto)); + newIssuesAuthorizationIndexRequest(dto).ifPresent(bulkRequest::add); + newProjectMeasuresAuthorizationIndexRequest(dto).ifPresent(bulkRequest::add); + newComponentsAuthorizationIndexRequest(dto).ifPresent(bulkRequest::add); count++; if (count >= MAX_BATCH_SIZE) { EsUtils.executeBulkRequest(bulkRequest, BULK_ERROR_MESSAGE); @@ -133,9 +135,9 @@ public class PermissionIndexer implements Startable { esClient.prepareRefresh(ComponentIndexDefinition.INDEX_COMPONENTS).get(); } - public void index(DbSession dbSession, String projectUuid) { + public void index(DbSession dbSession, String viewOrProjectUuid) { PermissionIndexerDao dao = new PermissionIndexerDao(); - List dtos = dao.selectByProjects(dbClient, dbSession, singletonList(projectUuid)); + List dtos = dao.selectByUuids(dbClient, dbSession, singletonList(viewOrProjectUuid)); if (dtos.size() == 1) { index(dtos.get(0)); } @@ -143,9 +145,12 @@ public class PermissionIndexer implements Startable { @VisibleForTesting void index(PermissionIndexerDao.Dto dto) { - index(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, newIssuesAuthorizationIndexRequest(dto)); - index(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, newProjectMeasuresAuthorizationIndexRequest(dto)); - index(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION, newComponentsAuthorizationIndexRequest(dto)); + newIssuesAuthorizationIndexRequest(dto) + .ifPresent(rqst -> index(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, rqst)); + newProjectMeasuresAuthorizationIndexRequest(dto) + .ifPresent(rqst -> index(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, rqst)); + newComponentsAuthorizationIndexRequest(dto) + .ifPresent(rqst -> index(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION, rqst)); } private void index(String index, String type, IndexRequest indexRequest) { @@ -157,36 +162,49 @@ public class PermissionIndexer implements Startable { .get(); } - private static IndexRequest newIssuesAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) { + private static Optional newIssuesAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) { + if (!isProject(dto)) { + return Optional.empty(); + } Map doc = ImmutableMap.of( IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, dto.getProjectUuid(), IssueIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(), IssueIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(), IssueIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt())); - return new IndexRequest(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid()) - .routing(dto.getProjectUuid()) - .source(doc); + return Optional.of( + new IndexRequest(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid()) + .routing(dto.getProjectUuid()) + .source(doc)); } - private static IndexRequest newProjectMeasuresAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) { + private static Optional newProjectMeasuresAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) { + if (!isProject(dto)) { + return Optional.empty(); + } Map doc = ImmutableMap.of( ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, dto.getProjectUuid(), ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(), ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(), ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt())); - return new IndexRequest(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid()) - .routing(dto.getProjectUuid()) - .source(doc); + return Optional.of( + new IndexRequest(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid()) + .routing(dto.getProjectUuid()) + .source(doc)); } - private static IndexRequest newComponentsAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) { + private static Optional newComponentsAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) { Map doc = ImmutableMap.of( ComponentIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(), ComponentIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(), ComponentIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt())); - return new IndexRequest(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid()) - .routing(dto.getProjectUuid()) - .source(doc); + return Optional.of( + new IndexRequest(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid()) + .routing(dto.getProjectUuid()) + .source(doc)); + } + + private static boolean isProject(PermissionIndexerDao.Dto dto) { + return dto.getQualifier().equals(Qualifiers.PROJECT); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/index/PermissionIndexerDao.java b/server/sonar-server/src/main/java/org/sonar/server/permission/index/PermissionIndexerDao.java index 292acfd1897..0ccfe3a406e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/index/PermissionIndexerDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/index/PermissionIndexerDao.java @@ -44,12 +44,14 @@ public class PermissionIndexerDao { public static final class Dto { private final String projectUuid; private final long updatedAt; + private final String qualifier; private final List users = Lists.newArrayList(); private final List groups = Lists.newArrayList(); - public Dto(String projectUuid, long updatedAt) { + public Dto(String projectUuid, long updatedAt, String qualifier) { this.projectUuid = projectUuid; this.updatedAt = updatedAt; + this.qualifier = qualifier; } public String getProjectUuid() { @@ -60,6 +62,10 @@ public class PermissionIndexerDao { return updatedAt; } + public String getQualifier() { + return qualifier; + } + public List getUsers() { return users; } @@ -83,18 +89,20 @@ public class PermissionIndexerDao { " project_authorization.project as project, " + " project_authorization.user_id as user_id, " + " project_authorization.permission_group as permission_group, " + - " project_authorization.updated_at as updated_at " + + " project_authorization.updated_at as updated_at, " + + " project_authorization.qualifier as qualifier " + "FROM ( " + // project is returned when no authorization " SELECT " + " projects.uuid AS project, " + " projects.authorization_updated_at AS updated_at, " + + " projects.qualifier AS qualifier, " + " NULL AS user_id, " + " NULL AS permission_group " + " FROM projects " + " WHERE " + - " projects.qualifier = 'TRK' " + + " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " + " AND projects.copy_component_uuid is NULL " + " {projectsCondition} " + " UNION " + @@ -104,12 +112,13 @@ public class PermissionIndexerDao { " SELECT " + " projects.uuid AS project, " + " projects.authorization_updated_at AS updated_at, " + + " projects.qualifier AS qualifier, " + " user_roles.user_id AS user_id, " + " NULL AS permission_group " + " FROM projects " + " INNER JOIN user_roles ON user_roles.resource_id = projects.id AND user_roles.role = 'user' " + " WHERE " + - " projects.qualifier = 'TRK' " + + " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " + " AND projects.copy_component_uuid is NULL " + " {projectsCondition} " + " UNION " + @@ -119,13 +128,14 @@ public class PermissionIndexerDao { " SELECT " + " projects.uuid AS project, " + " projects.authorization_updated_at AS updated_at, " + + " projects.qualifier AS qualifier, " + " NULL AS user_id, " + " 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' " + + " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " + " AND projects.copy_component_uuid is NULL " + " {projectsCondition} " + " AND group_id IS NOT NULL " + @@ -136,12 +146,13 @@ public class PermissionIndexerDao { " SELECT " + " projects.uuid AS project, " + " projects.authorization_updated_at AS updated_at, " + + " projects.qualifier AS qualifier, " + " NULL AS user_id, " + " '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' " + + " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " + " AND projects.copy_component_uuid is NULL " + " {projectsCondition} " + " AND group_roles.group_id IS NULL " + @@ -151,8 +162,8 @@ public class PermissionIndexerDao { return doSelectByProjects(dbClient, session, Collections.emptyList()); } - List selectByProjects(DbClient dbClient, DbSession session, List projectUuids) { - return executeLargeInputs(projectUuids, subProjectUuids -> doSelectByProjects(dbClient, session, subProjectUuids)); + List selectByUuids(DbClient dbClient, DbSession session, List projectOrViewUuids) { + return executeLargeInputs(projectOrViewUuids, subProjectOrViewUuids -> doSelectByProjects(dbClient, session, subProjectOrViewUuids)); } private static List doSelectByProjects(DbClient dbClient, DbSession session, List projectUuids) { @@ -203,7 +214,8 @@ public class PermissionIndexerDao { Dto dto = dtosByProjectUuid.get(projectUuid); if (dto == null) { long updatedAt = rs.getLong(4); - dto = new Dto(projectUuid, updatedAt); + String qualifier = rs.getString(5); + dto = new Dto(projectUuid, updatedAt, qualifier); dtosByProjectUuid.put(projectUuid, dto); } Long userId = rs.getLong(2); diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerDaoTest.java index 1c60a5c0659..6af72e6da70 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerDaoTest.java @@ -41,8 +41,9 @@ 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.resources.Qualifiers.PROJECT; +import static org.sonar.api.resources.Qualifiers.VIEW; import static org.sonar.api.security.DefaultGroups.ANYONE; import static org.sonar.api.web.UserRole.ADMIN; import static org.sonar.api.web.UserRole.USER; @@ -52,24 +53,28 @@ public class PermissionIndexerDaoTest { @Rule public DbTester dbTester = DbTester.create(System2.INSTANCE); - DbClient dbClient = dbTester.getDbClient(); - DbSession dbSession = dbTester.getSession(); + private DbClient dbClient = dbTester.getDbClient(); + private DbSession dbSession = dbTester.getSession(); - ComponentDbTester componentDbTester = new ComponentDbTester(dbTester); - UserDbTester userDbTester = new UserDbTester(dbTester); + private ComponentDbTester componentDbTester = new ComponentDbTester(dbTester); + private UserDbTester userDbTester = new UserDbTester(dbTester); - ComponentDto project1; - ComponentDto project2; - UserDto user1; - UserDto user2; - GroupDto group; + private ComponentDto project1; + private ComponentDto project2; + private ComponentDto view1; + private ComponentDto view2; + private UserDto user1; + private UserDto user2; + private GroupDto group; - PermissionIndexerDao underTest = new PermissionIndexerDao(); + private PermissionIndexerDao underTest = new PermissionIndexerDao(); @Before public void setUp() throws Exception { project1 = componentDbTester.insertProject(); project2 = componentDbTester.insertProject(); + view1 = componentDbTester.insertView(); + view2 = componentDbTester.insertView(); user1 = userDbTester.insertUser(); user2 = userDbTester.insertUser(); group = userDbTester.insertGroup(); @@ -77,52 +82,68 @@ public class PermissionIndexerDaoTest { @Test public void select_all() { - insertTestDataForProject1And2(); + insertTestDataForProjectsAndViews(); Collection dtos = underTest.selectAll(dbClient, dbSession); - assertThat(dtos).hasSize(2); + assertThat(dtos).hasSize(4); PermissionIndexerDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos); assertThat(project1Authorization.getGroups()).containsOnly(ANYONE, group.getName()); assertThat(project1Authorization.getUsers()).containsOnly(user1.getId()); assertThat(project1Authorization.getUpdatedAt()).isNotNull(); + assertThat(project1Authorization.getQualifier()).isEqualTo(PROJECT); + + PermissionIndexerDao.Dto view1Authorization = getByProjectUuid(view1.uuid(), dtos); + assertThat(view1Authorization.getGroups()).containsOnly(ANYONE, group.getName()); + assertThat(view1Authorization.getUsers()).containsOnly(user1.getId()); + assertThat(view1Authorization.getUpdatedAt()).isNotNull(); + assertThat(view1Authorization.getQualifier()).isEqualTo(VIEW); PermissionIndexerDao.Dto project2Authorization = getByProjectUuid(project2.uuid(), dtos); assertThat(project2Authorization.getGroups()).containsOnly(ANYONE); assertThat(project2Authorization.getUsers()).containsOnly(user1.getId(), user2.getId()); assertThat(project2Authorization.getUpdatedAt()).isNotNull(); - } + assertThat(project2Authorization.getQualifier()).isEqualTo(PROJECT); - @Test - public void select_by_project() throws Exception { - insertTestDataForProject1And2(); - - Collection dtos = underTest.selectByProjects(dbClient, dbSession, singletonList(project1.uuid())); - assertThat(dtos).hasSize(1); - PermissionIndexerDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos); - assertThat(project1Authorization.getGroups()).containsOnly(ANYONE, group.getName()); - assertThat(project1Authorization.getUsers()).containsOnly(user1.getId()); - assertThat(project1Authorization.getUpdatedAt()).isNotNull(); + PermissionIndexerDao.Dto view2Authorization = getByProjectUuid(view2.uuid(), dtos); + assertThat(view2Authorization.getGroups()).containsOnly(ANYONE); + assertThat(view2Authorization.getUsers()).containsOnly(user1.getId(), user2.getId()); + assertThat(view2Authorization.getUpdatedAt()).isNotNull(); + assertThat(view2Authorization.getQualifier()).isEqualTo(VIEW); } @Test - public void select_by_projects() throws Exception { - insertTestDataForProject1And2(); + public void selectByUuids() throws Exception { + insertTestDataForProjectsAndViews(); - Map dtos = underTest.selectByProjects(dbClient, dbSession, asList(project1.uuid(), project2.uuid())) + Map dtos = underTest.selectByUuids(dbClient, dbSession, asList(project1.uuid(), project2.uuid(), view1.uuid(), view2.uuid())) .stream() .collect(Collectors.uniqueIndex(PermissionIndexerDao.Dto::getProjectUuid, Function.identity())); - assertThat(dtos).hasSize(2); + assertThat(dtos).hasSize(4); PermissionIndexerDao.Dto project1Authorization = dtos.get(project1.uuid()); assertThat(project1Authorization.getGroups()).containsOnly(ANYONE, group.getName()); assertThat(project1Authorization.getUsers()).containsOnly(user1.getId()); assertThat(project1Authorization.getUpdatedAt()).isNotNull(); + assertThat(project1Authorization.getQualifier()).isEqualTo(PROJECT); + + PermissionIndexerDao.Dto view1Authorization = dtos.get(view1.uuid()); + assertThat(view1Authorization.getGroups()).containsOnly(ANYONE, group.getName()); + assertThat(view1Authorization.getUsers()).containsOnly(user1.getId()); + assertThat(view1Authorization.getUpdatedAt()).isNotNull(); + assertThat(view1Authorization.getQualifier()).isEqualTo(VIEW); PermissionIndexerDao.Dto project2Authorization = dtos.get(project2.uuid()); assertThat(project2Authorization.getGroups()).containsOnly(ANYONE); assertThat(project2Authorization.getUsers()).containsOnly(user1.getId(), user2.getId()); assertThat(project2Authorization.getUpdatedAt()).isNotNull(); + assertThat(project2Authorization.getQualifier()).isEqualTo(PROJECT); + + PermissionIndexerDao.Dto view2Authorization = dtos.get(view2.uuid()); + assertThat(view2Authorization.getGroups()).containsOnly(ANYONE); + assertThat(view2Authorization.getUsers()).containsOnly(user1.getId(), user2.getId()); + assertThat(view2Authorization.getUpdatedAt()).isNotNull(); + assertThat(view2Authorization.getQualifier()).isEqualTo(VIEW); } @Test @@ -141,7 +162,7 @@ public class PermissionIndexerDaoTest { } dbSession.commit(); - Map dtos = underTest.selectByProjects(dbClient, dbSession, projects) + Map dtos = underTest.selectByUuids(dbClient, dbSession, projects) .stream() .collect(Collectors.uniqueIndex(PermissionIndexerDao.Dto::getProjectUuid, Function.identity())); assertThat(dtos).hasSize(350); @@ -151,36 +172,53 @@ public class PermissionIndexerDaoTest { public void no_authorization() { userDbTester.insertProjectPermissionOnUser(user1, USER, project2); userDbTester.insertProjectPermissionOnGroup(group, USER, project2); + userDbTester.insertProjectPermissionOnUser(user1, USER, view2); + userDbTester.insertProjectPermissionOnGroup(group, USER, view2); Collection dtos = underTest.selectAll(dbClient, dbSession); - assertThat(dtos).hasSize(2); + assertThat(dtos).hasSize(4); PermissionIndexerDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos); assertThat(project1Authorization.getGroups()).isEmpty(); assertThat(project1Authorization.getUsers()).isEmpty(); assertThat(project1Authorization.getUpdatedAt()).isNotNull(); + assertThat(project1Authorization.getQualifier()).isEqualTo(PROJECT); + PermissionIndexerDao.Dto view1Authorization = getByProjectUuid(view1.uuid(), dtos); + assertThat(view1Authorization.getGroups()).isEmpty(); + assertThat(view1Authorization.getUsers()).isEmpty(); + assertThat(view1Authorization.getUpdatedAt()).isNotNull(); + assertThat(view1Authorization.getQualifier()).isEqualTo(VIEW); } private static PermissionIndexerDao.Dto getByProjectUuid(String projectUuid, Collection dtos) { return dtos.stream().filter(dto -> dto.getProjectUuid().equals(projectUuid)).findFirst().orElseThrow(IllegalArgumentException::new); } - private void insertTestDataForProject1And2() { + private void insertTestDataForProjectsAndViews() { // user1 can access both projects userDbTester.insertProjectPermissionOnUser(user1, USER, project1); userDbTester.insertProjectPermissionOnUser(user1, ADMIN, project1); userDbTester.insertProjectPermissionOnUser(user1, USER, project2); + userDbTester.insertProjectPermissionOnUser(user1, USER, view1); + userDbTester.insertProjectPermissionOnUser(user1, ADMIN, view1); + userDbTester.insertProjectPermissionOnUser(user1, USER, view2); // user2 has user access on project2 only userDbTester.insertProjectPermissionOnUser(user2, USER, project2); + userDbTester.insertProjectPermissionOnUser(user2, USER, view2); // group1 has user access on project1 only userDbTester.insertProjectPermissionOnGroup(group, USER, project1); userDbTester.insertProjectPermissionOnGroup(group, ADMIN, project1); + userDbTester.insertProjectPermissionOnGroup(group, USER, view1); + userDbTester.insertProjectPermissionOnGroup(group, ADMIN, view1); // Anyone group has user access on both projects userDbTester.insertProjectPermissionOnAnyone(USER, project1); userDbTester.insertProjectPermissionOnAnyone(ADMIN, project1); userDbTester.insertProjectPermissionOnAnyone(USER, project2); + userDbTester.insertProjectPermissionOnAnyone(USER, view1); + userDbTester.insertProjectPermissionOnAnyone(ADMIN, view1); + userDbTester.insertProjectPermissionOnAnyone(USER, view2); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java index 7b40f3bbc60..4efccb44cdd 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerTest.java @@ -25,6 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.config.MapSettings; +import org.sonar.api.resources.Qualifiers; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDbTester; @@ -61,12 +62,12 @@ public class PermissionIndexerTest { new ProjectMeasuresIndexDefinition(new MapSettings()), new ComponentIndexDefinition(new MapSettings())); - ComponentDbTester componentDbTester = new ComponentDbTester(dbTester); - UserDbTester userDbTester = new UserDbTester(dbTester); + private ComponentDbTester componentDbTester = new ComponentDbTester(dbTester); + private UserDbTester userDbTester = new UserDbTester(dbTester); - PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(esTester); + private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(esTester); - PermissionIndexer underTest = new PermissionIndexer(dbTester.getDbClient(), esTester.client()); + private PermissionIndexer underTest = new PermissionIndexer(dbTester.getDbClient(), esTester.client()); @Test public void index_all_does_nothing_when_no_data() { @@ -78,16 +79,22 @@ public class PermissionIndexerTest { @Test public void index_all() { ComponentDto project = componentDbTester.insertProject(); + ComponentDto view = componentDbTester.insertView(); UserDto user = userDbTester.insertUser(); userDbTester.insertProjectPermissionOnUser(user, USER, project); userDbTester.insertProjectPermissionOnUser(user, ADMIN, project); + userDbTester.insertProjectPermissionOnUser(user, USER, view); + userDbTester.insertProjectPermissionOnUser(user, ADMIN, view); GroupDto group = userDbTester.insertGroup(); userDbTester.insertProjectPermissionOnGroup(group, USER, project); userDbTester.insertProjectPermissionOnAnyone(USER, project); + userDbTester.insertProjectPermissionOnGroup(group, USER, view); + userDbTester.insertProjectPermissionOnAnyone(USER, view); underTest.indexAllIfEmpty(); authorizationIndexerTester.verifyProjectExistsWithPermission(project.uuid(), asList(group.getName(), ANYONE), singletonList(user.getId())); + authorizationIndexerTester.verifyViewExistsWithPermissionInRightIndexes(view.uuid(), asList(group.getName(), ANYONE), singletonList(user.getId())); } @Test @@ -168,7 +175,7 @@ public class PermissionIndexerTest { authorizationIndexerTester.indexProjectPermission("ABC", singletonList("dev"), singletonList(10L)); // remove permissions -> dto has no users nor groups - underTest.index(new PermissionIndexerDao.Dto("ABC", System.currentTimeMillis())); + underTest.index(new PermissionIndexerDao.Dto("ABC", System.currentTimeMillis(), Qualifiers.PROJECT)); authorizationIndexerTester.verifyProjectExistsWithoutPermission("ABC"); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerTester.java b/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerTester.java index 2e3a18c3103..693f4a3aff2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerTester.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/index/PermissionIndexerTester.java @@ -23,6 +23,7 @@ package org.sonar.server.permission.index; import java.util.List; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.index.query.BoolQueryBuilder; +import org.sonar.api.resources.Qualifiers; import org.sonar.server.component.index.ComponentIndexDefinition; import org.sonar.server.es.EsTester; import org.sonar.server.issue.index.IssueIndexDefinition; @@ -48,18 +49,12 @@ public class PermissionIndexerTester { } public void indexProjectPermission(String projectUuid, List groupNames, List userLogins) { - PermissionIndexerDao.Dto authorization = new PermissionIndexerDao.Dto(projectUuid, System.currentTimeMillis()); + PermissionIndexerDao.Dto authorization = new PermissionIndexerDao.Dto(projectUuid, System.currentTimeMillis(), Qualifiers.PROJECT); groupNames.forEach(authorization::addGroup); userLogins.forEach(authorization::addUser); permissionIndexer.index(authorization); } - public void verifyEmptyProjectPermission() { - assertThat(esTester.countDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)).isZero(); - assertThat(esTester.countDocuments(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION)).isZero(); - assertThat(esTester.countDocuments(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION)).isZero(); - } - public void verifyProjectDoesNotExist(String projectUuid) { assertThat(esTester.getIds(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)).doesNotContain(projectUuid); assertThat(esTester.getIds(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION)).doesNotContain(projectUuid); @@ -71,21 +66,36 @@ public class PermissionIndexerTester { } public void verifyProjectExistsWithPermission(String projectUuid, List groupNames, List userLogins) { - verifyProjectExistsWithPermissionInIndex(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, + verifyComponentExistsWithPermissionInIndex(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, IssueIndexDefinition.FIELD_AUTHORIZATION_GROUPS, IssueIndexDefinition.FIELD_AUTHORIZATION_USERS, projectUuid, groupNames, userLogins); - verifyProjectExistsWithPermissionInIndex(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, + + verifyComponentExistsWithPermissionInIndex(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_GROUPS, ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_USERS, projectUuid, groupNames, userLogins); - verifyProjectExistsWithPermissionInIndex(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION, + + verifyComponentExistsWithPermissionInIndex(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION, "_id", ComponentIndexDefinition.FIELD_AUTHORIZATION_GROUPS, ComponentIndexDefinition.FIELD_AUTHORIZATION_USERS, projectUuid, groupNames, userLogins); } - private void verifyProjectExistsWithPermissionInIndex(String index, String type, String projectField, String groupField, String userField, String projectUuid, - List groupNames, List userLogins) { - assertThat(esTester.getIds(index, type)).contains(projectUuid); - BoolQueryBuilder queryBuilder = boolQuery().must(termQuery(projectField, projectUuid)); + public void verifyViewExistsWithPermissionInRightIndexes(String viewUuid, List groupNames, List userLogins) { + // index issues + verifyNoAuthorization(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, viewUuid); + + // index project_measures + verifyNoAuthorization(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, viewUuid); + + // index components + verifyComponentExistsWithPermissionInIndex(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION, + "_id", ComponentIndexDefinition.FIELD_AUTHORIZATION_GROUPS, + ComponentIndexDefinition.FIELD_AUTHORIZATION_USERS, viewUuid, groupNames, userLogins); + } + + private void verifyComponentExistsWithPermissionInIndex(String index, String type, String projectField, String groupField, + String userField, String componentUuid, List groupNames, List userLogins) { + assertThat(esTester.getIds(index, type)).contains(componentUuid); + BoolQueryBuilder queryBuilder = boolQuery().must(termQuery(projectField, componentUuid)); if (groupNames.isEmpty()) { queryBuilder.mustNot(existsQuery(groupField)); } else { @@ -102,4 +112,17 @@ public class PermissionIndexerTester { .setQuery(boolQuery().must(matchAllQuery()).filter(queryBuilder)); assertThat(request.get().getHits()).hasSize(1); } + + private void verifyNoAuthorization(String index, String authType, String authId) { + assertThat(esTester.getIds(index, authType)).doesNotContain(authId); + } + + private void verifyDocument(String index, String docType, String componentField, String componentUuid) { + BoolQueryBuilder queryBuilder = boolQuery().must(termQuery(componentField, componentUuid)); + SearchRequestBuilder request = esTester.client() + .prepareSearch(index) + .setTypes(docType) + .setQuery(boolQuery().must(matchAllQuery()).filter(queryBuilder)); + assertThat(request.get().getHits()).isNotEmpty(); + } } -- 2.39.5