Skip to content

Commit

Permalink
SONAR-8238 index authorization of views in components index
Browse files Browse the repository at this point in the history
  • Loading branch information
sns-seb committed Jan 17, 2017
1 parent 5de879e commit 35de0ed
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 87 deletions.
Expand Up @@ -145,8 +145,8 @@ private boolean hasProjectCreatorPermission(DbSession dbSession, @Nullable Permi
.anyMatch(PermissionTemplateCharacteristicDto::getWithProjectCreator); .anyMatch(PermissionTemplateCharacteristicDto::getWithProjectCreator);
} }


private void indexProjectPermissions(DbSession dbSession, List<String> projectUuids) { private void indexProjectPermissions(DbSession dbSession, List<String> projectOrViewUuids) {
permissionIndexer.index(dbSession, projectUuids); permissionIndexer.index(dbSession, projectOrViewUuids);
} }


private void copyPermissions(DbSession dbSession, PermissionTemplateDto template, ComponentDto project, @Nullable Long projectCreatorUserId) { private void copyPermissions(DbSession dbSession, PermissionTemplateDto template, ComponentDto project, @Nullable Long projectCreatorUserId) {
Expand Down
Expand Up @@ -51,13 +51,13 @@ public PermissionUpdater(DbClient dbClient, PermissionIndexer permissionIndexer,


public void apply(DbSession dbSession, Collection<PermissionChange> changes) { public void apply(DbSession dbSession, Collection<PermissionChange> changes) {
Set<Long> projectIds = new HashSet<>(); Set<Long> projectIds = new HashSet<>();
List<String> projectUuids = new ArrayList<>(); List<String> projectOrViewUuids = new ArrayList<>();
for (PermissionChange change : changes) { for (PermissionChange change : changes) {
boolean changed = doApply(dbSession, change); boolean changed = doApply(dbSession, change);
Optional<ProjectId> projectId = change.getProjectId(); Optional<ProjectId> projectId = change.getProjectId();
if (changed && projectId.isPresent()) { if (changed && projectId.isPresent()) {
projectIds.add(projectId.get().getId()); projectIds.add(projectId.get().getId());
projectUuids.add(projectId.get().getUuid()); projectOrViewUuids.add(projectId.get().getUuid());
} }
} }
for (Long projectId : projectIds) { for (Long projectId : projectIds) {
Expand All @@ -66,7 +66,7 @@ public void apply(DbSession dbSession, Collection<PermissionChange> changes) {
dbSession.commit(); dbSession.commit();


if (!projectIds.isEmpty()) { if (!projectIds.isEmpty()) {
permissionIndexer.index(dbSession, projectUuids); permissionIndexer.index(dbSession, projectOrViewUuids);
} }
} }


Expand Down
Expand Up @@ -27,6 +27,7 @@
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
Expand All @@ -36,6 +37,7 @@
import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.picocontainer.Startable; import org.picocontainer.Startable;
import org.sonar.api.resources.Qualifiers;
import org.sonar.db.DbClient; import org.sonar.db.DbClient;
import org.sonar.db.DbSession; import org.sonar.db.DbSession;
import org.sonar.server.component.index.ComponentIndexDefinition; import org.sonar.server.component.index.ComponentIndexDefinition;
Expand Down Expand Up @@ -104,10 +106,10 @@ private void truncate(String index, String type) {
BulkIndexer.delete(esClient, index, esClient.prepareSearch(index).setTypes(type).setQuery(matchAllQuery())); BulkIndexer.delete(esClient, index, esClient.prepareSearch(index).setTypes(type).setQuery(matchAllQuery()));
} }


public void index(DbSession dbSession, List<String> projectUuids) { public void index(DbSession dbSession, List<String> viewOrProjectUuids) {
checkArgument(!projectUuids.isEmpty(), "ProjectUuids cannot be empty"); checkArgument(!viewOrProjectUuids.isEmpty(), "viewOrProjectUuids cannot be empty");
PermissionIndexerDao dao = new PermissionIndexerDao(); PermissionIndexerDao dao = new PermissionIndexerDao();
index(dao.selectByProjects(dbClient, dbSession, projectUuids)); index(dao.selectByUuids(dbClient, dbSession, viewOrProjectUuids));
} }


private void index(Collection<PermissionIndexerDao.Dto> authorizations) { private void index(Collection<PermissionIndexerDao.Dto> authorizations) {
Expand All @@ -117,9 +119,9 @@ private void index(Collection<PermissionIndexerDao.Dto> authorizations) {
int count = 0; int count = 0;
BulkRequestBuilder bulkRequest = esClient.prepareBulk().setRefresh(false); BulkRequestBuilder bulkRequest = esClient.prepareBulk().setRefresh(false);
for (PermissionIndexerDao.Dto dto : authorizations) { for (PermissionIndexerDao.Dto dto : authorizations) {
bulkRequest.add(newIssuesAuthorizationIndexRequest(dto)); newIssuesAuthorizationIndexRequest(dto).ifPresent(bulkRequest::add);
bulkRequest.add(newProjectMeasuresAuthorizationIndexRequest(dto)); newProjectMeasuresAuthorizationIndexRequest(dto).ifPresent(bulkRequest::add);
bulkRequest.add(newComponentsAuthorizationIndexRequest(dto)); newComponentsAuthorizationIndexRequest(dto).ifPresent(bulkRequest::add);
count++; count++;
if (count >= MAX_BATCH_SIZE) { if (count >= MAX_BATCH_SIZE) {
EsUtils.executeBulkRequest(bulkRequest, BULK_ERROR_MESSAGE); EsUtils.executeBulkRequest(bulkRequest, BULK_ERROR_MESSAGE);
Expand All @@ -133,19 +135,22 @@ private void index(Collection<PermissionIndexerDao.Dto> authorizations) {
esClient.prepareRefresh(ComponentIndexDefinition.INDEX_COMPONENTS).get(); esClient.prepareRefresh(ComponentIndexDefinition.INDEX_COMPONENTS).get();
} }


public void index(DbSession dbSession, String projectUuid) { public void index(DbSession dbSession, String viewOrProjectUuid) {
PermissionIndexerDao dao = new PermissionIndexerDao(); PermissionIndexerDao dao = new PermissionIndexerDao();
List<PermissionIndexerDao.Dto> dtos = dao.selectByProjects(dbClient, dbSession, singletonList(projectUuid)); List<PermissionIndexerDao.Dto> dtos = dao.selectByUuids(dbClient, dbSession, singletonList(viewOrProjectUuid));
if (dtos.size() == 1) { if (dtos.size() == 1) {
index(dtos.get(0)); index(dtos.get(0));
} }
} }


@VisibleForTesting @VisibleForTesting
void index(PermissionIndexerDao.Dto dto) { void index(PermissionIndexerDao.Dto dto) {
index(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, newIssuesAuthorizationIndexRequest(dto)); newIssuesAuthorizationIndexRequest(dto)
index(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, newProjectMeasuresAuthorizationIndexRequest(dto)); .ifPresent(rqst -> index(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, rqst));
index(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION, newComponentsAuthorizationIndexRequest(dto)); 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) { private void index(String index, String type, IndexRequest indexRequest) {
Expand All @@ -157,36 +162,49 @@ private void index(String index, String type, IndexRequest indexRequest) {
.get(); .get();
} }


private static IndexRequest newIssuesAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) { private static Optional<IndexRequest> newIssuesAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) {
if (!isProject(dto)) {
return Optional.empty();
}
Map<String, Object> doc = ImmutableMap.of( Map<String, Object> doc = ImmutableMap.of(
IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, dto.getProjectUuid(), IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, dto.getProjectUuid(),
IssueIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(), IssueIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(),
IssueIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(), IssueIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(),
IssueIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt())); IssueIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt()));
return new IndexRequest(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid()) return Optional.of(
.routing(dto.getProjectUuid()) new IndexRequest(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid())
.source(doc); .routing(dto.getProjectUuid())
.source(doc));
} }


private static IndexRequest newProjectMeasuresAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) { private static Optional<IndexRequest> newProjectMeasuresAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) {
if (!isProject(dto)) {
return Optional.empty();
}
Map<String, Object> doc = ImmutableMap.of( Map<String, Object> doc = ImmutableMap.of(
ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, dto.getProjectUuid(), ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, dto.getProjectUuid(),
ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(), ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(),
ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(), ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(),
ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt())); ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt()));
return new IndexRequest(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid()) return Optional.of(
.routing(dto.getProjectUuid()) new IndexRequest(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid())
.source(doc); .routing(dto.getProjectUuid())
.source(doc));
} }


private static IndexRequest newComponentsAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) { private static Optional<IndexRequest> newComponentsAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) {
Map<String, Object> doc = ImmutableMap.of( Map<String, Object> doc = ImmutableMap.of(
ComponentIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(), ComponentIndexDefinition.FIELD_AUTHORIZATION_GROUPS, dto.getGroups(),
ComponentIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(), ComponentIndexDefinition.FIELD_AUTHORIZATION_USERS, dto.getUsers(),
ComponentIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt())); ComponentIndexDefinition.FIELD_AUTHORIZATION_UPDATED_AT, new Date(dto.getUpdatedAt()));
return new IndexRequest(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid()) return Optional.of(
.routing(dto.getProjectUuid()) new IndexRequest(ComponentIndexDefinition.INDEX_COMPONENTS, ComponentIndexDefinition.TYPE_AUTHORIZATION, dto.getProjectUuid())
.source(doc); .routing(dto.getProjectUuid())
.source(doc));
}

private static boolean isProject(PermissionIndexerDao.Dto dto) {
return dto.getQualifier().equals(Qualifiers.PROJECT);
} }


@Override @Override
Expand Down
Expand Up @@ -44,12 +44,14 @@ public class PermissionIndexerDao {
public static final class Dto { public static final class Dto {
private final String projectUuid; private final String projectUuid;
private final long updatedAt; private final long updatedAt;
private final String qualifier;
private final List<Long> users = Lists.newArrayList(); private final List<Long> users = Lists.newArrayList();
private final List<String> groups = Lists.newArrayList(); private final List<String> groups = Lists.newArrayList();


public Dto(String projectUuid, long updatedAt) { public Dto(String projectUuid, long updatedAt, String qualifier) {
this.projectUuid = projectUuid; this.projectUuid = projectUuid;
this.updatedAt = updatedAt; this.updatedAt = updatedAt;
this.qualifier = qualifier;
} }


public String getProjectUuid() { public String getProjectUuid() {
Expand All @@ -60,6 +62,10 @@ public long getUpdatedAt() {
return updatedAt; return updatedAt;
} }


public String getQualifier() {
return qualifier;
}

public List<Long> getUsers() { public List<Long> getUsers() {
return users; return users;
} }
Expand All @@ -83,18 +89,20 @@ public List<String> getGroups() {
" project_authorization.project as project, " + " project_authorization.project as project, " +
" project_authorization.user_id as user_id, " + " project_authorization.user_id as user_id, " +
" project_authorization.permission_group as permission_group, " + " 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 ( " + "FROM ( " +


// project is returned when no authorization // project is returned when no authorization
" SELECT " + " SELECT " +
" projects.uuid AS project, " + " projects.uuid AS project, " +
" projects.authorization_updated_at AS updated_at, " + " projects.authorization_updated_at AS updated_at, " +
" projects.qualifier AS qualifier, " +
" NULL AS user_id, " + " NULL AS user_id, " +
" NULL AS permission_group " + " NULL AS permission_group " +
" FROM projects " + " FROM projects " +
" WHERE " + " WHERE " +
" projects.qualifier = 'TRK' " + " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " +
" AND projects.copy_component_uuid is NULL " + " AND projects.copy_component_uuid is NULL " +
" {projectsCondition} " + " {projectsCondition} " +
" UNION " + " UNION " +
Expand All @@ -104,12 +112,13 @@ public List<String> getGroups() {
" SELECT " + " SELECT " +
" projects.uuid AS project, " + " projects.uuid AS project, " +
" projects.authorization_updated_at AS updated_at, " + " projects.authorization_updated_at AS updated_at, " +
" projects.qualifier AS qualifier, " +
" user_roles.user_id AS user_id, " + " user_roles.user_id AS user_id, " +
" NULL AS permission_group " + " NULL AS permission_group " +
" FROM projects " + " FROM projects " +
" INNER JOIN user_roles ON user_roles.resource_id = projects.id AND user_roles.role = 'user' " + " INNER JOIN user_roles ON user_roles.resource_id = projects.id AND user_roles.role = 'user' " +
" WHERE " + " WHERE " +
" projects.qualifier = 'TRK' " + " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " +
" AND projects.copy_component_uuid is NULL " + " AND projects.copy_component_uuid is NULL " +
" {projectsCondition} " + " {projectsCondition} " +
" UNION " + " UNION " +
Expand All @@ -119,13 +128,14 @@ public List<String> getGroups() {
" SELECT " + " SELECT " +
" projects.uuid AS project, " + " projects.uuid AS project, " +
" projects.authorization_updated_at AS updated_at, " + " projects.authorization_updated_at AS updated_at, " +
" projects.qualifier AS qualifier, " +
" NULL AS user_id, " + " NULL AS user_id, " +
" groups.name AS permission_group " + " groups.name AS permission_group " +
" FROM projects " + " FROM projects " +
" INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role = 'user' " + " 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 " + " INNER JOIN groups ON groups.id = group_roles.group_id " +
" WHERE " + " WHERE " +
" projects.qualifier = 'TRK' " + " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " +
" AND projects.copy_component_uuid is NULL " + " AND projects.copy_component_uuid is NULL " +
" {projectsCondition} " + " {projectsCondition} " +
" AND group_id IS NOT NULL " + " AND group_id IS NOT NULL " +
Expand All @@ -136,12 +146,13 @@ public List<String> getGroups() {
" SELECT " + " SELECT " +
" projects.uuid AS project, " + " projects.uuid AS project, " +
" projects.authorization_updated_at AS updated_at, " + " projects.authorization_updated_at AS updated_at, " +
" projects.qualifier AS qualifier, " +
" NULL AS user_id, " + " NULL AS user_id, " +
" 'Anyone' AS permission_group " + " 'Anyone' AS permission_group " +
" FROM projects " + " FROM projects " +
" INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role='user' " + " INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role='user' " +
" WHERE " + " WHERE " +
" projects.qualifier = 'TRK' " + " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " +
" AND projects.copy_component_uuid is NULL " + " AND projects.copy_component_uuid is NULL " +
" {projectsCondition} " + " {projectsCondition} " +
" AND group_roles.group_id IS NULL " + " AND group_roles.group_id IS NULL " +
Expand All @@ -151,8 +162,8 @@ List<Dto> selectAll(DbClient dbClient, DbSession session) {
return doSelectByProjects(dbClient, session, Collections.emptyList()); return doSelectByProjects(dbClient, session, Collections.emptyList());
} }


List<Dto> selectByProjects(DbClient dbClient, DbSession session, List<String> projectUuids) { List<Dto> selectByUuids(DbClient dbClient, DbSession session, List<String> projectOrViewUuids) {
return executeLargeInputs(projectUuids, subProjectUuids -> doSelectByProjects(dbClient, session, subProjectUuids)); return executeLargeInputs(projectOrViewUuids, subProjectOrViewUuids -> doSelectByProjects(dbClient, session, subProjectOrViewUuids));
} }


private static List<Dto> doSelectByProjects(DbClient dbClient, DbSession session, List<String> projectUuids) { private static List<Dto> doSelectByProjects(DbClient dbClient, DbSession session, List<String> projectUuids) {
Expand Down Expand Up @@ -203,7 +214,8 @@ private static void processRow(ResultSet rs, Map<String, Dto> dtosByProjectUuid)
Dto dto = dtosByProjectUuid.get(projectUuid); Dto dto = dtosByProjectUuid.get(projectUuid);
if (dto == null) { if (dto == null) {
long updatedAt = rs.getLong(4); 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); dtosByProjectUuid.put(projectUuid, dto);
} }
Long userId = rs.getLong(2); Long userId = rs.getLong(2);
Expand Down

0 comments on commit 35de0ed

Please sign in to comment.