import org.sonar.server.component.ComponentCleanerService;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.component.ComponentService;
+import org.sonar.server.component.es.ProjectMeasuresIndexer;
import org.sonar.server.computation.queue.PurgeCeActivities;
import org.sonar.server.computation.task.projectanalysis.ProjectAnalysisTaskModule;
import org.sonar.server.computation.taskprocessor.CeTaskProcessorModule;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChanger;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.platform.DatabaseServerCompatibility;
import org.sonar.server.platform.DefaultServerUpgradeStatus;
import org.sonar.server.platform.ServerFileSystemImpl;
import org.sonar.server.plugins.ServerExtensionInstaller;
import org.sonar.server.plugins.privileged.PrivilegedPluginsBootstraper;
import org.sonar.server.plugins.privileged.PrivilegedPluginsStopper;
-import org.sonar.server.component.es.ProjectMeasuresIndexer;
import org.sonar.server.property.InternalPropertiesImpl;
import org.sonar.server.qualityprofile.QProfileLookup;
import org.sonar.server.qualityprofile.QProfileProjectOperations;
// issues
IssueIndexer.class,
- AuthorizationIndexer.class,
+ PermissionIndexer.class,
IssueUpdater.class, // used in Web Services and CE's DebtCalculator
FunctionExecutor.class, // used by IssueWorkflow
IssueWorkflow.class, // used in Web Services and CE's DebtCalculator
import org.sonar.db.component.ComponentDto;
import org.sonar.server.component.es.ProjectMeasuresIndexer;
import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.test.index.TestIndexer;
@ServerSide
public class ComponentCleanerService {
private final DbClient dbClient;
- private final AuthorizationIndexer authorizationIndexer;
+ private final PermissionIndexer permissionIndexer;
private final IssueIndexer issueIndexer;
private final TestIndexer testIndexer;
private final ProjectMeasuresIndexer projectMeasuresIndexer;
private final ResourceTypes resourceTypes;
private final ComponentFinder componentFinder;
- public ComponentCleanerService(DbClient dbClient, AuthorizationIndexer authorizationIndexer, IssueIndexer issueIndexer,
+ public ComponentCleanerService(DbClient dbClient, PermissionIndexer permissionIndexer, IssueIndexer issueIndexer,
TestIndexer testIndexer, ProjectMeasuresIndexer projectMeasuresIndexer, ResourceTypes resourceTypes, ComponentFinder componentFinder) {
this.dbClient = dbClient;
- this.authorizationIndexer = authorizationIndexer;
+ this.permissionIndexer = permissionIndexer;
this.issueIndexer = issueIndexer;
this.testIndexer = testIndexer;
this.projectMeasuresIndexer = projectMeasuresIndexer;
+++ /dev/null
-/*
- * 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.
- */
-package org.sonar.server.component.es;
-
-import com.google.common.collect.Maps;
-import org.sonar.server.es.BaseDoc;
-
-import static org.sonar.server.component.es.ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID;
-
-public class ProjectMeasuresAuthorizationDoc extends BaseDoc {
-
- public ProjectMeasuresAuthorizationDoc() {
- super(Maps.newHashMap());
- }
-
- @Override
- public String getId() {
- return projectUuid();
- }
-
- @Override
- public String getRouting() {
- return projectUuid();
- }
-
- @Override
- public String getParent() {
- return null;
- }
-
- public String projectUuid() {
- return getField(FIELD_AUTHORIZATION_PROJECT_UUID);
- }
-
- public ProjectMeasuresAuthorizationDoc setProjectUuid(String s) {
- setField(FIELD_AUTHORIZATION_PROJECT_UUID, s);
- return this;
- }
-}
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;
import org.sonar.server.computation.task.projectanalysis.component.TypeAwareVisitorAdapter;
import org.sonar.server.computation.task.step.ComputationStep;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT;
import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.VIEW;
private final DbClient dbClient;
private final DbIdsRepository dbIdsRepository;
- private final AuthorizationIndexer indexer;
+ private final PermissionIndexer indexer;
private final PermissionRepository permissionRepository;
private final TreeRootHolder treeRootHolder;
- public ApplyPermissionsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, AuthorizationIndexer indexer, PermissionRepository permissionRepository,
- TreeRootHolder treeRootHolder) {
+ public ApplyPermissionsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, PermissionIndexer indexer, PermissionRepository permissionRepository,
+ TreeRootHolder treeRootHolder) {
this.dbClient = dbClient;
this.dbIdsRepository = dbIdsRepository;
this.indexer = indexer;
import org.sonar.api.utils.log.Loggers;
import org.sonar.server.component.es.ProjectMeasuresIndexer;
import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.test.index.TestIndexer;
import org.sonar.server.user.index.UserIndexer;
import org.sonar.server.view.index.ViewIndexer;
private static final Logger LOG = Loggers.get(IndexerStartupTask.class);
private final TestIndexer testIndexer;
- private final AuthorizationIndexer authorizationIndexer;
+ private final PermissionIndexer permissionIndexer;
private final IssueIndexer issueIndexer;
private final UserIndexer userIndexer;
private final ViewIndexer viewIndexer;
/**
* Limitation - {@link org.sonar.server.es.BaseIndexer} are not injected through an array or a collection
- * because we need {@link AuthorizationIndexer} to be executed before
+ * because we need {@link PermissionIndexer} to be executed before
* {@link org.sonar.server.issue.index.IssueIndexer}
*/
- public IndexerStartupTask(TestIndexer testIndexer, AuthorizationIndexer authorizationIndexer, IssueIndexer issueIndexer,
- UserIndexer userIndexer, ViewIndexer viewIndexer, ProjectMeasuresIndexer projectMeasuresIndexer,
- Settings settings) {
+ public IndexerStartupTask(TestIndexer testIndexer, PermissionIndexer permissionIndexer, IssueIndexer issueIndexer,
+ UserIndexer userIndexer, ViewIndexer viewIndexer, ProjectMeasuresIndexer projectMeasuresIndexer,
+ Settings settings) {
this.testIndexer = testIndexer;
- this.authorizationIndexer = authorizationIndexer;
+ this.permissionIndexer = permissionIndexer;
this.issueIndexer = issueIndexer;
this.userIndexer = userIndexer;
this.viewIndexer = viewIndexer;
if (!settings.getBoolean("sonar.internal.es.disableIndexes")) {
LOG.info("Index authorization");
- authorizationIndexer.indexAllIfEmpty();
+ permissionIndexer.indexAllIfEmpty();
LOG.info("Index issues");
issueIndexer.index();
import org.sonar.db.permission.PermissionRepository;
import org.sonar.db.permission.template.PermissionTemplateDto;
import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.user.UserSession;
import static java.util.Arrays.asList;
private final DbClient dbClient;
private final PermissionRepository permissionRepository;
- private final AuthorizationIndexer authorizationIndexer;
+ private final PermissionIndexer permissionIndexer;
private final UserSession userSession;
private final ComponentFinder componentFinder;
- public PermissionService(DbClient dbClient, PermissionRepository permissionRepository, AuthorizationIndexer authorizationIndexer, UserSession userSession,
- ComponentFinder componentFinder) {
+ public PermissionService(DbClient dbClient, PermissionRepository permissionRepository, PermissionIndexer permissionIndexer, UserSession userSession,
+ ComponentFinder componentFinder) {
this.dbClient = dbClient;
this.permissionRepository = permissionRepository;
- this.authorizationIndexer = authorizationIndexer;
+ this.permissionIndexer = permissionIndexer;
this.userSession = userSession;
this.componentFinder = componentFinder;
}
}
private void indexProjectPermissions(DbSession dbSession, List<String> projectUuids) {
- authorizationIndexer.index(dbSession, projectUuids);
+ permissionIndexer.index(dbSession, projectUuids);
}
}
import java.util.Set;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
/**
* Add or remove global/project permissions to a group. This class
public class PermissionUpdater {
private final DbClient dbClient;
- private final AuthorizationIndexer authorizationIndexer;
+ private final PermissionIndexer permissionIndexer;
private final UserPermissionChanger userPermissionChanger;
private final GroupPermissionChanger groupPermissionChanger;
- public PermissionUpdater(DbClient dbClient, AuthorizationIndexer authorizationIndexer,
+ public PermissionUpdater(DbClient dbClient, PermissionIndexer permissionIndexer,
UserPermissionChanger userPermissionChanger, GroupPermissionChanger groupPermissionChanger) {
this.dbClient = dbClient;
- this.authorizationIndexer = authorizationIndexer;
+ this.permissionIndexer = permissionIndexer;
this.userPermissionChanger = userPermissionChanger;
this.groupPermissionChanger = groupPermissionChanger;
}
dbSession.commit();
if (!projectIds.isEmpty()) {
- authorizationIndexer.index(dbSession, projectUuids);
+ permissionIndexer.index(dbSession, projectUuids);
}
}
+++ /dev/null
-/*
- * 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.
- */
-package org.sonar.server.permission.index;
-
-import com.google.common.collect.Lists;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-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;
-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
- */
-public class AuthorizationDao {
-
- public static final class Dto {
- private final String projectUuid;
- private final long updatedAt;
- private final List<Long> users = Lists.newArrayList();
- private final List<String> groups = Lists.newArrayList();
-
- public Dto(String projectUuid, long updatedAt) {
- this.projectUuid = projectUuid;
- this.updatedAt = updatedAt;
- }
-
- public String getProjectUuid() {
- return projectUuid;
- }
-
- public long getUpdatedAt() {
- return updatedAt;
- }
-
- public List<Long> getUsers() {
- return users;
- }
-
- public Dto addUser(Long s) {
- users.add(s);
- return this;
- }
-
- public Dto addGroup(String s) {
- groups.add(s);
- return this;
- }
-
- public List<String> getGroups() {
- return groups;
- }
- }
-
- private static final String SQL_TEMPLATE = "SELECT " +
- " 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 " +
- "FROM ( " +
-
- // project is returned when no authorization
- " SELECT " +
- " projects.uuid AS project, " +
- " projects.authorization_updated_at AS updated_at, " +
- " NULL AS user_id, " +
- " 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, " +
- " 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' " +
- " 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 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' " +
- " 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 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' " +
- " AND projects.copy_component_uuid is NULL " +
- " {projectsCondition} " +
- " AND group_roles.group_id IS NULL " +
- " ) project_authorization";
-
- List<Dto> selectAll(DbClient dbClient, DbSession session) {
- return doSelectByProjects(dbClient, session, Collections.emptyList());
- }
-
- List<Dto> selectByProjects(DbClient dbClient, DbSession session, List<String> projectUuids) {
- return executeLargeInputs(projectUuids, subProjectUuids -> doSelectByProjects(dbClient, session, subProjectUuids));
- }
-
- private static List<Dto> doSelectByProjects(DbClient dbClient, DbSession session, List<String> projectUuids) {
- try {
- Map<String, Dto> dtosByProjectUuid = new HashMap<>();
- PreparedStatement stmt = null;
- ResultSet rs = null;
- try {
- stmt = createStatement(dbClient, session, projectUuids);
- rs = stmt.executeQuery();
- while (rs.next()) {
- processRow(rs, dtosByProjectUuid);
- }
- return new ArrayList<>(dtosByProjectUuid.values());
- } finally {
- DbUtils.closeQuietly(rs);
- DbUtils.closeQuietly(stmt);
- }
- } catch (SQLException e) {
- throw new IllegalStateException("Fail to select authorizations", e);
- }
- }
-
- private static PreparedStatement createStatement(DbClient dbClient, DbSession session, List<String> projectUuids) throws SQLException {
- String sql;
- if (!projectUuids.isEmpty()) {
- sql = StringUtils.replace(SQL_TEMPLATE, "{projectsCondition}", " AND (" + repeatCondition("projects.uuid = ?", projectUuids.size(), "OR") + ")");
- } else {
- sql = StringUtils.replace(SQL_TEMPLATE, "{projectsCondition}", "");
- }
- PreparedStatement stmt = dbClient.getMyBatis().newScrollingSelectStatement(session, sql);
- if (!projectUuids.isEmpty()) {
- int index = 1;
- for (int i = 1; i <= 4; i++) {
- for (int uuidIndex = 0; uuidIndex < projectUuids.size(); uuidIndex++) {
- stmt.setString(index, projectUuids.get(uuidIndex));
- index++;
- }
- }
- }
- return stmt;
- }
-
- private static void processRow(ResultSet rs, Map<String, Dto> dtosByProjectUuid) throws SQLException {
- String projectUuid = rs.getString(1);
- String group = rs.getString(3);
-
- Dto dto = dtosByProjectUuid.get(projectUuid);
- if (dto == null) {
- long updatedAt = rs.getLong(4);
- dto = new Dto(projectUuid, updatedAt);
- dtosByProjectUuid.put(projectUuid, dto);
- }
- Long userId = rs.getLong(2);
- if (!rs.wasNull()) {
- dto.addUser(userId);
- }
- if (StringUtils.isNotBlank(group)) {
- dto.addGroup(group);
- }
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-package org.sonar.server.permission.index;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.Uninterruptibles;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-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.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.server.component.es.ProjectMeasuresIndexDefinition;
-import org.sonar.server.es.BulkIndexer;
-import org.sonar.server.es.EsClient;
-import org.sonar.server.es.EsUtils;
-import org.sonar.server.issue.index.IssueIndexDefinition;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Collections.singletonList;
-import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
-
-/**
- * Manages the synchronization of index issues/authorization with authorization settings defined in database :
- * <ul>
- * <li>index the projects with recent permission changes</li>
- * <li>delete project orphans from index</li>
- * </ul>
- */
-public class AuthorizationIndexer implements Startable {
-
- private static final int MAX_BATCH_SIZE = 1000;
-
- private static final String BULK_ERROR_MESSAGE = "Fail to index authorization";
-
- private final ThreadPoolExecutor executor;
- private final DbClient dbClient;
- private final EsClient esClient;
-
- public AuthorizationIndexer(DbClient dbClient, EsClient esClient) {
- this.executor = new ThreadPoolExecutor(0, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
- this.dbClient = dbClient;
- this.esClient = esClient;
- }
-
- /**
- * Index issues authorization and project measures authorization indexes only when they are empty
- */
- public void indexAllIfEmpty() {
- Future submit = executor.submit(() -> {
- if (isIndexEmpty(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION) ||
- isIndexEmpty(ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION)) {
- truncate(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION);
- truncate(ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION);
- try (DbSession dbSession = dbClient.openSession(false)) {
- index(new AuthorizationDao().selectAll(dbClient, dbSession));
- }
- }
- });
- try {
- Uninterruptibles.getUninterruptibly(submit);
- } catch (ExecutionException e) {
- Throwables.propagate(e);
- }
- }
-
- private boolean isIndexEmpty(String index, String type) {
- SearchResponse issuesAuthorizationResponse = esClient.prepareSearch(index).setTypes(type).setSize(0).get();
- return issuesAuthorizationResponse.getHits().getTotalHits() == 0;
- }
-
- private void truncate(String index, String type) {
- BulkIndexer.delete(esClient, index, esClient.prepareSearch(index).setTypes(type).setQuery(matchAllQuery()));
- }
-
- public void index(DbSession dbSession, List<String> projectUuids) {
- checkArgument(!projectUuids.isEmpty(), "ProjectUuids cannot be empty");
- AuthorizationDao dao = new AuthorizationDao();
- index(dao.selectByProjects(dbClient, dbSession, projectUuids));
- }
-
- private void index(Collection<AuthorizationDao.Dto> authorizations) {
- if (authorizations.isEmpty()) {
- return;
- }
- int count = 0;
- BulkRequestBuilder bulkRequest = esClient.prepareBulk().setRefresh(false);
- for (AuthorizationDao.Dto dto : authorizations) {
- bulkRequest.add(newIssuesAuthorizationIndexRequest(dto));
- bulkRequest.add(newProjectMeasuresAuthorizationIndexRequest(dto));
- count++;
- if (count >= MAX_BATCH_SIZE) {
- EsUtils.executeBulkRequest(bulkRequest, BULK_ERROR_MESSAGE);
- bulkRequest = esClient.prepareBulk().setRefresh(false);
- count = 0;
- }
- }
- EsUtils.executeBulkRequest(bulkRequest, BULK_ERROR_MESSAGE);
- esClient.prepareRefresh(IssueIndexDefinition.INDEX).get();
- esClient.prepareRefresh(ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES).get();
- }
-
- public void index(DbSession dbSession, String projectUuid) {
- AuthorizationDao dao = new AuthorizationDao();
- List<AuthorizationDao.Dto> dtos = dao.selectByProjects(dbClient, dbSession, singletonList(projectUuid));
- if (dtos.size() == 1) {
- index(dtos.get(0));
- }
- }
-
- @VisibleForTesting
- void index(AuthorizationDao.Dto dto) {
- index(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, newIssuesAuthorizationIndexRequest(dto));
- index(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, newProjectMeasuresAuthorizationIndexRequest(dto));
- }
-
- private void index(String index, String type, IndexRequest indexRequest) {
- esClient.prepareIndex(index, type)
- .setId(indexRequest.id())
- .setRouting(indexRequest.routing())
- .setSource(indexRequest.source())
- .setRefresh(true)
- .get();
- }
-
- private static IndexRequest newIssuesAuthorizationIndexRequest(AuthorizationDao.Dto dto) {
- Map<String, Object> 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);
- }
-
- private static IndexRequest newProjectMeasuresAuthorizationIndexRequest(AuthorizationDao.Dto dto) {
- Map<String, Object> 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);
- }
-
- @Override
- public void start() {
- // nothing to do at startup
- }
-
- @Override
- public void stop() {
- executor.shutdown();
- }
-}
--- /dev/null
+/*
+ * 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.
+ */
+package org.sonar.server.permission.index;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.Uninterruptibles;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+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.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.server.component.es.ProjectMeasuresIndexDefinition;
+import org.sonar.server.es.BulkIndexer;
+import org.sonar.server.es.EsClient;
+import org.sonar.server.es.EsUtils;
+import org.sonar.server.issue.index.IssueIndexDefinition;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Collections.singletonList;
+import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
+
+/**
+ * Manages the synchronization of index issues/authorization with authorization settings defined in database :
+ * <ul>
+ * <li>index the projects with recent permission changes</li>
+ * <li>delete project orphans from index</li>
+ * </ul>
+ */
+public class PermissionIndexer implements Startable {
+
+ private static final int MAX_BATCH_SIZE = 1000;
+
+ private static final String BULK_ERROR_MESSAGE = "Fail to index authorization";
+
+ private final ThreadPoolExecutor executor;
+ private final DbClient dbClient;
+ private final EsClient esClient;
+
+ public PermissionIndexer(DbClient dbClient, EsClient esClient) {
+ this.executor = new ThreadPoolExecutor(0, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
+ this.dbClient = dbClient;
+ this.esClient = esClient;
+ }
+
+ /**
+ * Index issues authorization and project measures authorization indexes only when they are empty
+ */
+ public void indexAllIfEmpty() {
+ Future submit = executor.submit(() -> {
+ if (isIndexEmpty(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION) ||
+ isIndexEmpty(ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION)) {
+ truncate(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION);
+ truncate(ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION);
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ index(new PermissionIndexerDao().selectAll(dbClient, dbSession));
+ }
+ }
+ });
+ try {
+ Uninterruptibles.getUninterruptibly(submit);
+ } catch (ExecutionException e) {
+ Throwables.propagate(e);
+ }
+ }
+
+ private boolean isIndexEmpty(String index, String type) {
+ SearchResponse issuesAuthorizationResponse = esClient.prepareSearch(index).setTypes(type).setSize(0).get();
+ return issuesAuthorizationResponse.getHits().getTotalHits() == 0;
+ }
+
+ private void truncate(String index, String type) {
+ BulkIndexer.delete(esClient, index, esClient.prepareSearch(index).setTypes(type).setQuery(matchAllQuery()));
+ }
+
+ public void index(DbSession dbSession, List<String> projectUuids) {
+ checkArgument(!projectUuids.isEmpty(), "ProjectUuids cannot be empty");
+ PermissionIndexerDao dao = new PermissionIndexerDao();
+ index(dao.selectByProjects(dbClient, dbSession, projectUuids));
+ }
+
+ private void index(Collection<PermissionIndexerDao.Dto> authorizations) {
+ if (authorizations.isEmpty()) {
+ return;
+ }
+ int count = 0;
+ BulkRequestBuilder bulkRequest = esClient.prepareBulk().setRefresh(false);
+ for (PermissionIndexerDao.Dto dto : authorizations) {
+ bulkRequest.add(newIssuesAuthorizationIndexRequest(dto));
+ bulkRequest.add(newProjectMeasuresAuthorizationIndexRequest(dto));
+ count++;
+ if (count >= MAX_BATCH_SIZE) {
+ EsUtils.executeBulkRequest(bulkRequest, BULK_ERROR_MESSAGE);
+ bulkRequest = esClient.prepareBulk().setRefresh(false);
+ count = 0;
+ }
+ }
+ EsUtils.executeBulkRequest(bulkRequest, BULK_ERROR_MESSAGE);
+ esClient.prepareRefresh(IssueIndexDefinition.INDEX).get();
+ esClient.prepareRefresh(ProjectMeasuresIndexDefinition.TYPE_PROJECT_MEASURES).get();
+ }
+
+ public void index(DbSession dbSession, String projectUuid) {
+ PermissionIndexerDao dao = new PermissionIndexerDao();
+ List<PermissionIndexerDao.Dto> dtos = dao.selectByProjects(dbClient, dbSession, singletonList(projectUuid));
+ if (dtos.size() == 1) {
+ index(dtos.get(0));
+ }
+ }
+
+ @VisibleForTesting
+ void index(PermissionIndexerDao.Dto dto) {
+ index(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION, newIssuesAuthorizationIndexRequest(dto));
+ index(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION, newProjectMeasuresAuthorizationIndexRequest(dto));
+ }
+
+ private void index(String index, String type, IndexRequest indexRequest) {
+ esClient.prepareIndex(index, type)
+ .setId(indexRequest.id())
+ .setRouting(indexRequest.routing())
+ .setSource(indexRequest.source())
+ .setRefresh(true)
+ .get();
+ }
+
+ private static IndexRequest newIssuesAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) {
+ Map<String, Object> 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);
+ }
+
+ private static IndexRequest newProjectMeasuresAuthorizationIndexRequest(PermissionIndexerDao.Dto dto) {
+ Map<String, Object> 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);
+ }
+
+ @Override
+ public void start() {
+ // nothing to do at startup
+ }
+
+ @Override
+ public void stop() {
+ executor.shutdown();
+ }
+}
--- /dev/null
+/*
+ * 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.
+ */
+package org.sonar.server.permission.index;
+
+import com.google.common.collect.Lists;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+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;
+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
+ */
+public class PermissionIndexerDao {
+
+ public static final class Dto {
+ private final String projectUuid;
+ private final long updatedAt;
+ private final List<Long> users = Lists.newArrayList();
+ private final List<String> groups = Lists.newArrayList();
+
+ public Dto(String projectUuid, long updatedAt) {
+ this.projectUuid = projectUuid;
+ this.updatedAt = updatedAt;
+ }
+
+ public String getProjectUuid() {
+ return projectUuid;
+ }
+
+ public long getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public List<Long> getUsers() {
+ return users;
+ }
+
+ public Dto addUser(Long s) {
+ users.add(s);
+ return this;
+ }
+
+ public Dto addGroup(String s) {
+ groups.add(s);
+ return this;
+ }
+
+ public List<String> getGroups() {
+ return groups;
+ }
+ }
+
+ private static final String SQL_TEMPLATE = "SELECT " +
+ " 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 " +
+ "FROM ( " +
+
+ // project is returned when no authorization
+ " SELECT " +
+ " projects.uuid AS project, " +
+ " projects.authorization_updated_at AS updated_at, " +
+ " NULL AS user_id, " +
+ " 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, " +
+ " 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' " +
+ " 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 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' " +
+ " 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 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' " +
+ " AND projects.copy_component_uuid is NULL " +
+ " {projectsCondition} " +
+ " AND group_roles.group_id IS NULL " +
+ " ) project_authorization";
+
+ List<Dto> selectAll(DbClient dbClient, DbSession session) {
+ return doSelectByProjects(dbClient, session, Collections.emptyList());
+ }
+
+ List<Dto> selectByProjects(DbClient dbClient, DbSession session, List<String> projectUuids) {
+ return executeLargeInputs(projectUuids, subProjectUuids -> doSelectByProjects(dbClient, session, subProjectUuids));
+ }
+
+ private static List<Dto> doSelectByProjects(DbClient dbClient, DbSession session, List<String> projectUuids) {
+ try {
+ Map<String, Dto> dtosByProjectUuid = new HashMap<>();
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try {
+ stmt = createStatement(dbClient, session, projectUuids);
+ rs = stmt.executeQuery();
+ while (rs.next()) {
+ processRow(rs, dtosByProjectUuid);
+ }
+ return new ArrayList<>(dtosByProjectUuid.values());
+ } finally {
+ DbUtils.closeQuietly(rs);
+ DbUtils.closeQuietly(stmt);
+ }
+ } catch (SQLException e) {
+ throw new IllegalStateException("Fail to select authorizations", e);
+ }
+ }
+
+ private static PreparedStatement createStatement(DbClient dbClient, DbSession session, List<String> projectUuids) throws SQLException {
+ String sql;
+ if (!projectUuids.isEmpty()) {
+ sql = StringUtils.replace(SQL_TEMPLATE, "{projectsCondition}", " AND (" + repeatCondition("projects.uuid = ?", projectUuids.size(), "OR") + ")");
+ } else {
+ sql = StringUtils.replace(SQL_TEMPLATE, "{projectsCondition}", "");
+ }
+ PreparedStatement stmt = dbClient.getMyBatis().newScrollingSelectStatement(session, sql);
+ if (!projectUuids.isEmpty()) {
+ int index = 1;
+ for (int i = 1; i <= 4; i++) {
+ for (int uuidIndex = 0; uuidIndex < projectUuids.size(); uuidIndex++) {
+ stmt.setString(index, projectUuids.get(uuidIndex));
+ index++;
+ }
+ }
+ }
+ return stmt;
+ }
+
+ private static void processRow(ResultSet rs, Map<String, Dto> dtosByProjectUuid) throws SQLException {
+ String projectUuid = rs.getString(1);
+ String group = rs.getString(3);
+
+ Dto dto = dtosByProjectUuid.get(projectUuid);
+ if (dto == null) {
+ long updatedAt = rs.getLong(4);
+ dto = new Dto(projectUuid, updatedAt);
+ dtosByProjectUuid.put(projectUuid, dto);
+ }
+ Long userId = rs.getLong(2);
+ if (!rs.wasNull()) {
+ dto.addUser(userId);
+ }
+ if (StringUtils.isNotBlank(group)) {
+ dto.addGroup(group);
+ }
+ }
+}
import org.sonar.server.component.ComponentService;
import org.sonar.server.component.DefaultComponentFinder;
import org.sonar.server.component.DefaultRubyComponentService;
+import org.sonar.server.component.es.ProjectsEsModule;
import org.sonar.server.component.ws.ComponentsWsModule;
import org.sonar.server.config.ws.PropertiesWs;
import org.sonar.server.dashboard.template.GlobalDefaultDashboard;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChanger;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.permission.ws.PermissionsWsModule;
import org.sonar.server.platform.BackendCleanup;
import org.sonar.server.platform.PersistentSettings;
import org.sonar.server.plugins.ws.PluginsWs;
import org.sonar.server.plugins.ws.UninstallAction;
import org.sonar.server.plugins.ws.UpdatesAction;
-import org.sonar.server.component.es.ProjectsEsModule;
import org.sonar.server.project.ws.ProjectsWsModule;
import org.sonar.server.projectlink.ws.ProjectLinksModule;
import org.sonar.server.property.InternalPropertiesImpl;
// issues
IssueIndexDefinition.class,
IssueIndexer.class,
- AuthorizationIndexer.class,
+ PermissionIndexer.class,
ServerIssueStorage.class,
IssueUpdater.class,
FunctionExecutor.class,
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.index.IssueIndexDefinition;
import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.permission.index.AuthorizationIndexerTester;
+import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.platform.ServerFileSystem;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsTester;
private IssueIndex issueIndex;
private IssueIndexer issueIndexer;
- private AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(es);
+ private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es);
private ServerFileSystem fs = mock(ServerFileSystem.class);
WsTester tester;
}
private void addIssueAuthorization(String projectUuid, @Nullable String group, @Nullable Long user) {
- authorizationIndexerTester.insertProjectAuthorization(projectUuid, singletonList(group), singletonList(user));
+ authorizationIndexerTester.indexProjectPermission(projectUuid, singletonList(group), singletonList(user));
}
private void addBrowsePermissionOnComponent(String componentKey) {
import org.sonar.server.issue.IssueTesting;
import org.sonar.server.issue.index.IssueIndexDefinition;
import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.test.index.TestDoc;
import org.sonar.server.test.index.TestIndexDefinition;
import org.sonar.server.test.index.TestIndexer;
DbClient dbClient = db.getDbClient();
DbSession dbSession = db.getSession();
- AuthorizationIndexer authorizationIndexer = new AuthorizationIndexer(dbClient, es.client());
+ PermissionIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client());
IssueIndexer issueIndexer = new IssueIndexer(dbClient, es.client());
TestIndexer testIndexer = new TestIndexer(dbClient, es.client());
ProjectMeasuresIndexer projectMeasuresIndexer = new ProjectMeasuresIndexer(dbClient, es.client());
ResourceTypes mockResourceTypes = mock(ResourceTypes.class);
ComponentCleanerService underTest = new ComponentCleanerService(dbClient,
- authorizationIndexer, issueIndexer, testIndexer, projectMeasuresIndexer,
+ permissionIndexer, issueIndexer, testIndexer, projectMeasuresIndexer,
mockResourceTypes,
new ComponentFinder(dbClient));
dbClient.componentDao().insert(dbSession, project);
dbSession.commit();
projectMeasuresIndexer.index();
- authorizationIndexer.index(dbSession, project.uuid());
+ permissionIndexer.index(dbSession, project.uuid());
String issueKey = "issue-key-" + suffix;
es.putDocuments(IssueIndexDefinition.INDEX, TYPE_ISSUE, IssueTesting.newDoc(issueKey, project));
import org.sonar.server.es.EsTester;
import org.sonar.server.es.SearchIdResult;
import org.sonar.server.es.SearchOptions;
-import org.sonar.server.permission.index.AuthorizationIndexerTester;
+import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.tester.UserSessionRule;
import static com.google.common.collect.Lists.newArrayList;
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
- private AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(es);
+ private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es);
private ProjectMeasuresIndex underTest = new ProjectMeasuresIndex(es.client(), userSession);
try {
es.putDocuments(INDEX_PROJECT_MEASURES, TYPE_PROJECT_MEASURES, docs);
for (ProjectMeasuresDoc doc : docs) {
- authorizationIndexerTester.insertProjectAuthorization(doc.getId(),
+ authorizationIndexerTester.indexProjectPermission(doc.getId(),
authorizedGroup != null ? singletonList(authorizedGroup) : Collections.emptyList(),
authorizeUser != null ? singletonList(authorizeUser) : Collections.emptyList());
}
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.server.es.EsTester;
-import org.sonar.server.permission.index.AuthorizationIndexerTester;
+import org.sonar.server.permission.index.PermissionIndexerTester;
import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
public DbTester dbTester = DbTester.create(System2.INSTANCE);
ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
- AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(esTester);
+ PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(esTester);
ProjectMeasuresIndexer underTest = new ProjectMeasuresIndexer(dbTester.getDbClient(), esTester.client());
ComponentDto project3 = newProjectDto();
componentDbTester.insertProjectAndSnapshot(project3);
underTest.index();
- authorizationIndexerTester.insertProjectAuthorization(project1.uuid(), emptyList(), emptyList());
- authorizationIndexerTester.insertProjectAuthorization(project2.uuid(), emptyList(), emptyList());
- authorizationIndexerTester.insertProjectAuthorization(project3.uuid(), emptyList(), emptyList());
+ authorizationIndexerTester.indexProjectPermission(project1.uuid(), emptyList(), emptyList());
+ authorizationIndexerTester.indexProjectPermission(project2.uuid(), emptyList(), emptyList());
+ authorizationIndexerTester.indexProjectPermission(project3.uuid(), emptyList(), emptyList());
underTest.deleteProject(project1.uuid());
ComponentDto project = newProjectDto();
componentDbTester.insertProjectAndSnapshot(project);
underTest.index();
- authorizationIndexerTester.insertProjectAuthorization(project.uuid(), emptyList(), emptyList());
+ authorizationIndexerTester.indexProjectPermission(project.uuid(), emptyList(), emptyList());
underTest.deleteProject("UNKNOWN");
import org.sonar.server.component.es.ProjectMeasuresIndex;
import org.sonar.server.component.es.ProjectMeasuresIndexDefinition;
import org.sonar.server.es.EsTester;
-import org.sonar.server.permission.index.AuthorizationIndexerTester;
+import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.KeyExamples;
import org.sonar.server.ws.TestRequest;
private DbClient dbClient = db.getDbClient();
private DbSession dbSession = db.getSession();
- private AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(es);
+ private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es);
private WsActionTester ws = new WsActionTester(
new SearchProjectsAction(dbClient, new ProjectMeasuresIndex(es.client(), userSession), new ProjectMeasuresQueryValidator(dbClient)));
try {
es.putDocuments(INDEX_PROJECT_MEASURES, TYPE_PROJECT_MEASURES,
new ProjectMeasuresDoc().setId(project.uuid()).setKey(project.key()).setName(project.name()).setMeasures(measures));
- authorizationIndexerTester.insertProjectAuthorization(project.uuid(), singletonList(DefaultGroups.ANYONE), Collections.emptyList());
+ authorizationIndexerTester.indexProjectPermission(project.uuid(), singletonList(DefaultGroups.ANYONE), Collections.emptyList());
} catch (Exception e) {
Throwables.propagate(e);
}
import org.sonar.server.computation.task.step.ComputationStep;
import org.sonar.server.es.EsTester;
import org.sonar.server.issue.index.IssueIndexDefinition;
-import org.sonar.server.permission.index.AuthorizationIndexer;
-import org.sonar.server.permission.index.AuthorizationIndexerTester;
+import org.sonar.server.permission.index.PermissionIndexer;
+import org.sonar.server.permission.index.PermissionIndexerTester;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
@Rule
public MutableDbIdsRepositoryRule dbIdsRepository = MutableDbIdsRepositoryRule.create(treeRootHolder);
- private AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(esTester);
+ private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(esTester);
private DbSession dbSession;
private DbClient dbClient = dbTester.getDbClient();
@Before
public void setUp() {
dbSession = dbClient.openSession(false);
- step = new ApplyPermissionsStep(dbClient, dbIdsRepository, new AuthorizationIndexer(dbClient, esTester.client()), new PermissionRepository(dbClient, settings), treeRootHolder);
+ step = new ApplyPermissionsStep(dbClient, dbIdsRepository, new PermissionIndexer(dbClient, esTester.client()), new PermissionRepository(dbClient, settings), treeRootHolder);
}
@After
assertThat(dbClient.componentDao().selectOrFailByKey(dbSession, ROOT_KEY).getAuthorizationUpdatedAt()).isNotNull();
assertThat(dbClient.roleDao().selectGroupPermissions(dbSession, DefaultGroups.ANYONE, projectDto.getId())).containsOnly(UserRole.USER);
- authorizationIndexerTester.verifyProjectExistsWithAuthorization(ROOT_UUID, singletonList(DefaultGroups.ANYONE), emptyList());
+ authorizationIndexerTester.verifyProjectExistsWithPermission(ROOT_UUID, singletonList(DefaultGroups.ANYONE), emptyList());
}
@Test
import org.sonar.server.issue.IssueQuery;
import org.sonar.server.issue.IssueQuery.Builder;
import org.sonar.server.issue.IssueTesting;
-import org.sonar.server.permission.index.AuthorizationIndexerTester;
+import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.view.index.ViewIndexDefinition;
import org.sonar.server.view.index.ViewIndexer;
IssueIndex index;
IssueIndexer issueIndexer;
- AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(tester);
+ PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(tester);
ViewIndexer viewIndexer;
@Before
}
private void addIssueAuthorization(String projectUuid, @Nullable String group, @Nullable Long user) {
- authorizationIndexerTester.insertProjectAuthorization(projectUuid, singletonList(group), singletonList(user));
+ authorizationIndexerTester.indexProjectPermission(projectUuid, singletonList(group), singletonList(user));
}
private Builder newQueryBuilder() {
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.issue.IssueQuery;
import org.sonar.server.issue.IssueTesting;
-import org.sonar.server.permission.index.AuthorizationIndexerTester;
+import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.view.index.ViewDoc;
import org.sonar.server.view.index.ViewIndexDefinition;
IssueIndex underTest;
IssueIndexer issueIndexer;
- AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(tester);
+ PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(tester);
ViewIndexer viewIndexer;
@Before
}
private void addIssueAuthorization(String projectUuid, @Nullable String group, @Nullable Long user) {
- authorizationIndexerTester.insertProjectAuthorization(projectUuid, singletonList(group), singletonList(user));
+ authorizationIndexerTester.indexProjectPermission(projectUuid, singletonList(group), singletonList(user));
}
private void indexView(String viewUuid, List<String> projects) {
+++ /dev/null
-/*
- * 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.
- */
-package org.sonar.server.permission.index;
-
-import java.util.ArrayList;
-import java.util.Collection;
-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;
-import static org.sonar.api.web.UserRole.USER;
-
-public class AuthorizationDaoTest {
-
- @Rule
- public DbTester dbTester = DbTester.create(System2.INSTANCE);
-
- DbClient dbClient = dbTester.getDbClient();
- DbSession dbSession = dbTester.getSession();
-
- 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() {
- insertTestDataForProject1And2();
-
- Collection<AuthorizationDao.Dto> dtos = underTest.selectAll(dbClient, dbSession);
- assertThat(dtos).hasSize(2);
-
- AuthorizationDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos);
- assertThat(project1Authorization.getGroups()).containsOnly(ANYONE, group.getName());
- assertThat(project1Authorization.getUsers()).containsOnly(user1.getId());
- assertThat(project1Authorization.getUpdatedAt()).isNotNull();
-
- AuthorizationDao.Dto project2Authorization = getByProjectUuid(project2.uuid(), dtos);
- assertThat(project2Authorization.getGroups()).containsOnly(ANYONE);
- assertThat(project2Authorization.getUsers()).containsOnly(user1.getId(), user2.getId());
- assertThat(project2Authorization.getUpdatedAt()).isNotNull();
- }
-
- @Test
- public void select_by_project() throws Exception {
- insertTestDataForProject1And2();
-
- Collection<AuthorizationDao.Dto> dtos = underTest.selectByProjects(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.getId());
- assertThat(project1Authorization.getUpdatedAt()).isNotNull();
- }
-
- @Test
- public void select_by_projects() throws Exception {
- insertTestDataForProject1And2();
-
- Map<String, AuthorizationDao.Dto> dtos = underTest.selectByProjects(dbClient, dbSession, asList(project1.uuid(), project2.uuid()))
- .stream()
- .collect(Collectors.uniqueIndex(AuthorizationDao.Dto::getProjectUuid, Function.identity()));
- assertThat(dtos).hasSize(2);
-
- AuthorizationDao.Dto project1Authorization = dtos.get(project1.uuid());
- assertThat(project1Authorization.getGroups()).containsOnly(ANYONE, group.getName());
- assertThat(project1Authorization.getUsers()).containsOnly(user1.getId());
- assertThat(project1Authorization.getUpdatedAt()).isNotNull();
-
- AuthorizationDao.Dto project2Authorization = dtos.get(project2.uuid());
- assertThat(project2Authorization.getGroups()).containsOnly(ANYONE);
- assertThat(project2Authorization.getUsers()).containsOnly(user1.getId(), user2.getId());
- assertThat(project2Authorization.getUpdatedAt()).isNotNull();
- }
-
- @Test
- 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.selectByProjects(dbClient, dbSession, projects)
- .stream()
- .collect(Collectors.uniqueIndex(AuthorizationDao.Dto::getProjectUuid, Function.identity()));
- assertThat(dtos).hasSize(350);
- }
-
- @Test
- public void no_authorization() {
- userDbTester.insertProjectPermissionOnUser(user1, USER, project2);
- userDbTester.insertProjectPermissionOnGroup(group, USER, project2);
-
- Collection<AuthorizationDao.Dto> dtos = underTest.selectAll(dbClient, dbSession);
-
- assertThat(dtos).hasSize(2);
- AuthorizationDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos);
- assertThat(project1Authorization.getGroups()).isEmpty();
- assertThat(project1Authorization.getUsers()).isEmpty();
- assertThat(project1Authorization.getUpdatedAt()).isNotNull();
- }
-
- private static AuthorizationDao.Dto getByProjectUuid(String projectUuid, Collection<AuthorizationDao.Dto> dtos) {
- 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);
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-package org.sonar.server.permission.index;
-
-import com.google.common.collect.ImmutableMap;
-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;
-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 org.sonar.server.component.es.ProjectMeasuresIndexDefinition;
-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;
-import static org.sonar.api.web.UserRole.ADMIN;
-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);
-
- @Rule
- public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()), new ProjectMeasuresIndexDefinition(new MapSettings()));
-
- ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
- UserDbTester userDbTester = new UserDbTester(dbTester);
- AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(esTester);
-
- AuthorizationIndexer underTest = new AuthorizationIndexer(dbTester.getDbClient(), esTester.client());
-
- @Test
- public void index_all_does_nothing_when_no_data() {
- underTest.indexAllIfEmpty();
-
- assertThat(esTester.countDocuments("issues", "authorization")).isZero();
- }
-
- @Test
- public void index_all() {
- ComponentDto project = componentDbTester.insertProject();
- UserDto user = userDbTester.insertUser();
- userDbTester.insertProjectPermissionOnUser(user, USER, project);
- userDbTester.insertProjectPermissionOnUser(user, ADMIN, project);
- GroupDto group = userDbTester.insertGroup();
- userDbTester.insertProjectPermissionOnGroup(group, USER, project);
- userDbTester.insertProjectPermissionOnAnyone(USER, project);
-
- underTest.indexAllIfEmpty();
-
- authorizationIndexerTester.verifyProjectExistsWithAuthorization(project.uuid(), asList(group.getName(), ANYONE), singletonList(user.getId()));
- }
-
- @Test
- public void index_all_with_huge_number_of_projects() throws Exception {
- GroupDto group = userDbTester.insertGroup();
- for (int i = 0; i < 1100; i++) {
- ComponentDto project = ComponentTesting.newProjectDto();
- dbTester.getDbClient().componentDao().insert(dbTester.getSession(), project);
- GroupPermissionDto dto = new GroupPermissionDto()
- .setOrganizationUuid(group.getOrganizationUuid())
- .setGroupId(group.getId())
- .setRole(USER)
- .setResourceId(project.getId());
- dbTester.getDbClient().groupPermissionDao().insert(dbTester.getSession(), dto);
- }
- dbTester.getSession().commit();
-
- underTest.indexAllIfEmpty();
-
- assertThat(esTester.countDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)).isEqualTo(1100);
- assertThat(esTester.countDocuments(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION)).isEqualTo(1100);
- }
-
- @Test
- public void index_all_is_first_truncating_indexes() throws Exception {
- // Insert only one document in issues authorization => only one index is empty
- esTester.client().prepareIndex(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)
- .setId("ABC")
- .setRouting("ABC")
- .setSource(ImmutableMap.of(IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, "ABC"))
- .setRefresh(true)
- .get();
- GroupDto group = userDbTester.insertGroup();
- ComponentDto project = componentDbTester.insertProject();
- userDbTester.insertProjectPermissionOnGroup(group, USER, project);
-
- underTest.indexAllIfEmpty();
-
- authorizationIndexerTester.verifyProjectExistsWithAuthorization(project.uuid(), asList(group.getName(), ANYONE), emptyList());
- authorizationIndexerTester.verifyProjectDoesNotExist("ABC");
- }
-
- @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(dbTester.getSession(), 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(dbTester.getSession(), 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
- public void update_existing_permissions() {
- authorizationIndexerTester.insertProjectAuthorization("ABC", singletonList("dev"), singletonList(10L));
-
- // remove permissions -> dto has no users nor groups
- underTest.index(new AuthorizationDao.Dto("ABC", System.currentTimeMillis()));
-
- authorizationIndexerTester.verifyProjectExistsWithoutAuthorization("ABC");
- }
-
- @Test
- public void fail_when_trying_to_index_empty_project_uuids() throws Exception {
- expectedException.expect(IllegalArgumentException.class);
- underTest.index(dbTester.getSession(), Collections.emptyList());
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-
-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.server.component.es.ProjectMeasuresIndexDefinition;
-import org.sonar.server.es.EsTester;
-import org.sonar.server.issue.index.IssueIndexDefinition;
-
-import static java.util.Collections.emptyList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
-import static org.elasticsearch.index.query.QueryBuilders.existsQuery;
-import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
-import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
-
-public class AuthorizationIndexerTester {
-
- private final EsTester esTester;
-
- private final AuthorizationIndexer authorizationIndexer;
-
- public AuthorizationIndexerTester(EsTester esTester) {
- this.esTester = esTester;
- this.authorizationIndexer = new AuthorizationIndexer(null, esTester.client());
- }
-
- public void insertProjectAuthorization(String projectUuid, List<String> groupNames, List<Long> userLogins) {
- AuthorizationDao.Dto authorization = new AuthorizationDao.Dto(projectUuid, System.currentTimeMillis());
- groupNames.forEach(authorization::addGroup);
- userLogins.forEach(authorization::addUser);
- authorizationIndexer.index(authorization);
- }
-
- public void verifyEmptyProjectAuthorization() {
- assertThat(esTester.countDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)).isZero();
- assertThat(esTester.countDocuments(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.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);
- }
-
- public void verifyProjectExistsWithoutAuthorization(String projectUuid) {
- verifyProjectExistsWithAuthorization(projectUuid, emptyList(), emptyList());
- }
-
- public void verifyProjectExistsWithAuthorization(String projectUuid, List<String> groupNames, List<Long> userLogins) {
- verifyProjectExistsWithAuthorizationInIndex(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION,
- IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, IssueIndexDefinition.FIELD_AUTHORIZATION_GROUPS, IssueIndexDefinition.FIELD_AUTHORIZATION_USERS,
- projectUuid, groupNames, userLogins);
- verifyProjectExistsWithAuthorizationInIndex(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION,
- ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_GROUPS,
- ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_USERS, projectUuid, groupNames, userLogins);
- }
-
- private void verifyProjectExistsWithAuthorizationInIndex(String index, String type, String projectField, String groupField, String userField, String projectUuid,
- List<String> groupNames, List<Long> userLogins) {
- assertThat(esTester.getIds(index, type)).contains(projectUuid);
- BoolQueryBuilder queryBuilder = boolQuery().must(termQuery(projectField, projectUuid));
- if (groupNames.isEmpty()) {
- queryBuilder.mustNot(existsQuery(groupField));
- } else {
- queryBuilder.must(termsQuery(groupField, groupNames));
- }
- if (userLogins.isEmpty()) {
- queryBuilder.mustNot(existsQuery(userField));
- } else {
- queryBuilder.must(termsQuery(userField, userLogins));
- }
- SearchRequestBuilder request = esTester.client()
- .prepareSearch(index)
- .setTypes(type)
- .setQuery(boolQuery().must(matchAllQuery()).filter(queryBuilder));
- assertThat(request.get().getHits()).hasSize(1);
- }
-}
--- /dev/null
+/*
+ * 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.
+ */
+package org.sonar.server.permission.index;
+
+import java.util.ArrayList;
+import java.util.Collection;
+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;
+import static org.sonar.api.web.UserRole.USER;
+
+public class PermissionIndexerDaoTest {
+
+ @Rule
+ public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+ DbClient dbClient = dbTester.getDbClient();
+ DbSession dbSession = dbTester.getSession();
+
+ ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
+ UserDbTester userDbTester = new UserDbTester(dbTester);
+
+ ComponentDto project1;
+ ComponentDto project2;
+ UserDto user1;
+ UserDto user2;
+ GroupDto group;
+
+ PermissionIndexerDao underTest = new PermissionIndexerDao();
+
+ @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() {
+ insertTestDataForProject1And2();
+
+ Collection<PermissionIndexerDao.Dto> dtos = underTest.selectAll(dbClient, dbSession);
+ assertThat(dtos).hasSize(2);
+
+ 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 project2Authorization = getByProjectUuid(project2.uuid(), dtos);
+ assertThat(project2Authorization.getGroups()).containsOnly(ANYONE);
+ assertThat(project2Authorization.getUsers()).containsOnly(user1.getId(), user2.getId());
+ assertThat(project2Authorization.getUpdatedAt()).isNotNull();
+ }
+
+ @Test
+ public void select_by_project() throws Exception {
+ insertTestDataForProject1And2();
+
+ Collection<PermissionIndexerDao.Dto> 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();
+ }
+
+ @Test
+ public void select_by_projects() throws Exception {
+ insertTestDataForProject1And2();
+
+ Map<String, PermissionIndexerDao.Dto> dtos = underTest.selectByProjects(dbClient, dbSession, asList(project1.uuid(), project2.uuid()))
+ .stream()
+ .collect(Collectors.uniqueIndex(PermissionIndexerDao.Dto::getProjectUuid, Function.identity()));
+ assertThat(dtos).hasSize(2);
+
+ PermissionIndexerDao.Dto project1Authorization = dtos.get(project1.uuid());
+ assertThat(project1Authorization.getGroups()).containsOnly(ANYONE, group.getName());
+ assertThat(project1Authorization.getUsers()).containsOnly(user1.getId());
+ assertThat(project1Authorization.getUpdatedAt()).isNotNull();
+
+ PermissionIndexerDao.Dto project2Authorization = dtos.get(project2.uuid());
+ assertThat(project2Authorization.getGroups()).containsOnly(ANYONE);
+ assertThat(project2Authorization.getUsers()).containsOnly(user1.getId(), user2.getId());
+ assertThat(project2Authorization.getUpdatedAt()).isNotNull();
+ }
+
+ @Test
+ 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, PermissionIndexerDao.Dto> dtos = underTest.selectByProjects(dbClient, dbSession, projects)
+ .stream()
+ .collect(Collectors.uniqueIndex(PermissionIndexerDao.Dto::getProjectUuid, Function.identity()));
+ assertThat(dtos).hasSize(350);
+ }
+
+ @Test
+ public void no_authorization() {
+ userDbTester.insertProjectPermissionOnUser(user1, USER, project2);
+ userDbTester.insertProjectPermissionOnGroup(group, USER, project2);
+
+ Collection<PermissionIndexerDao.Dto> dtos = underTest.selectAll(dbClient, dbSession);
+
+ assertThat(dtos).hasSize(2);
+ PermissionIndexerDao.Dto project1Authorization = getByProjectUuid(project1.uuid(), dtos);
+ assertThat(project1Authorization.getGroups()).isEmpty();
+ assertThat(project1Authorization.getUsers()).isEmpty();
+ assertThat(project1Authorization.getUpdatedAt()).isNotNull();
+ }
+
+ private static PermissionIndexerDao.Dto getByProjectUuid(String projectUuid, Collection<PermissionIndexerDao.Dto> dtos) {
+ 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);
+ }
+}
--- /dev/null
+/*
+ * 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.
+ */
+package org.sonar.server.permission.index;
+
+import com.google.common.collect.ImmutableMap;
+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;
+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 org.sonar.server.component.es.ProjectMeasuresIndexDefinition;
+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;
+import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.api.web.UserRole.USER;
+
+public class PermissionIndexerTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+ @Rule
+ public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()), new ProjectMeasuresIndexDefinition(new MapSettings()));
+
+ ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
+ UserDbTester userDbTester = new UserDbTester(dbTester);
+
+ PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(esTester);
+
+ PermissionIndexer underTest = new PermissionIndexer(dbTester.getDbClient(), esTester.client());
+
+ @Test
+ public void index_all_does_nothing_when_no_data() {
+ underTest.indexAllIfEmpty();
+
+ assertThat(esTester.countDocuments("issues", "authorization")).isZero();
+ }
+
+ @Test
+ public void index_all() {
+ ComponentDto project = componentDbTester.insertProject();
+ UserDto user = userDbTester.insertUser();
+ userDbTester.insertProjectPermissionOnUser(user, USER, project);
+ userDbTester.insertProjectPermissionOnUser(user, ADMIN, project);
+ GroupDto group = userDbTester.insertGroup();
+ userDbTester.insertProjectPermissionOnGroup(group, USER, project);
+ userDbTester.insertProjectPermissionOnAnyone(USER, project);
+
+ underTest.indexAllIfEmpty();
+
+ authorizationIndexerTester.verifyProjectExistsWithPermission(project.uuid(), asList(group.getName(), ANYONE), singletonList(user.getId()));
+ }
+
+ @Test
+ public void index_all_with_huge_number_of_projects() throws Exception {
+ GroupDto group = userDbTester.insertGroup();
+ for (int i = 0; i < 1100; i++) {
+ ComponentDto project = ComponentTesting.newProjectDto();
+ dbTester.getDbClient().componentDao().insert(dbTester.getSession(), project);
+ GroupPermissionDto dto = new GroupPermissionDto()
+ .setOrganizationUuid(group.getOrganizationUuid())
+ .setGroupId(group.getId())
+ .setRole(USER)
+ .setResourceId(project.getId());
+ dbTester.getDbClient().groupPermissionDao().insert(dbTester.getSession(), dto);
+ }
+ dbTester.getSession().commit();
+
+ underTest.indexAllIfEmpty();
+
+ assertThat(esTester.countDocuments(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)).isEqualTo(1100);
+ assertThat(esTester.countDocuments(ProjectMeasuresIndexDefinition.INDEX_PROJECT_MEASURES, ProjectMeasuresIndexDefinition.TYPE_AUTHORIZATION)).isEqualTo(1100);
+ }
+
+ @Test
+ public void index_all_is_first_truncating_indexes() throws Exception {
+ // Insert only one document in issues authorization => only one index is empty
+ esTester.client().prepareIndex(IssueIndexDefinition.INDEX, IssueIndexDefinition.TYPE_AUTHORIZATION)
+ .setId("ABC")
+ .setRouting("ABC")
+ .setSource(ImmutableMap.of(IssueIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, "ABC"))
+ .setRefresh(true)
+ .get();
+ GroupDto group = userDbTester.insertGroup();
+ ComponentDto project = componentDbTester.insertProject();
+ userDbTester.insertProjectPermissionOnGroup(group, USER, project);
+
+ underTest.indexAllIfEmpty();
+
+ authorizationIndexerTester.verifyProjectExistsWithPermission(project.uuid(), asList(group.getName(), ANYONE), emptyList());
+ authorizationIndexerTester.verifyProjectDoesNotExist("ABC");
+ }
+
+ @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(dbTester.getSession(), project1.uuid());
+
+ authorizationIndexerTester.verifyProjectExistsWithPermission(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(dbTester.getSession(), asList(project1.uuid(), project2.uuid()));
+
+ authorizationIndexerTester.verifyProjectExistsWithPermission(project1.uuid(), asList(group.getName(), ANYONE), emptyList());
+ authorizationIndexerTester.verifyProjectExistsWithPermission(project2.uuid(), asList(group.getName(), ANYONE), emptyList());
+ authorizationIndexerTester.verifyProjectDoesNotExist(project3.uuid());
+ }
+
+ @Test
+ public void update_existing_permissions() {
+ authorizationIndexerTester.indexProjectPermission("ABC", singletonList("dev"), singletonList(10L));
+
+ // remove permissions -> dto has no users nor groups
+ underTest.index(new PermissionIndexerDao.Dto("ABC", System.currentTimeMillis()));
+
+ authorizationIndexerTester.verifyProjectExistsWithoutPermission("ABC");
+ }
+
+ @Test
+ public void fail_when_trying_to_index_empty_project_uuids() throws Exception {
+ expectedException.expect(IllegalArgumentException.class);
+ underTest.index(dbTester.getSession(), Collections.emptyList());
+ }
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+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.server.component.es.ProjectMeasuresIndexDefinition;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.issue.index.IssueIndexDefinition;
+
+import static java.util.Collections.emptyList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
+import static org.elasticsearch.index.query.QueryBuilders.existsQuery;
+import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
+import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
+
+public class PermissionIndexerTester {
+
+ private final EsTester esTester;
+
+ private final PermissionIndexer permissionIndexer;
+
+ public PermissionIndexerTester(EsTester esTester) {
+ this.esTester = esTester;
+ this.permissionIndexer = new PermissionIndexer(null, esTester.client());
+ }
+
+ public void indexProjectPermission(String projectUuid, List<String> groupNames, List<Long> userLogins) {
+ PermissionIndexerDao.Dto authorization = new PermissionIndexerDao.Dto(projectUuid, System.currentTimeMillis());
+ 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();
+ }
+
+ 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);
+ }
+
+ public void verifyProjectExistsWithoutPermission(String projectUuid) {
+ verifyProjectExistsWithPermission(projectUuid, emptyList(), emptyList());
+ }
+
+ public void verifyProjectExistsWithPermission(String projectUuid, List<String> groupNames, List<Long> userLogins) {
+ verifyProjectExistsWithPermissionInIndex(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,
+ ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_PROJECT_UUID, ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_GROUPS,
+ ProjectMeasuresIndexDefinition.FIELD_AUTHORIZATION_USERS, projectUuid, groupNames, userLogins);
+ }
+
+ private void verifyProjectExistsWithPermissionInIndex(String index, String type, String projectField, String groupField, String userField, String projectUuid,
+ List<String> groupNames, List<Long> userLogins) {
+ assertThat(esTester.getIds(index, type)).contains(projectUuid);
+ BoolQueryBuilder queryBuilder = boolQuery().must(termQuery(projectField, projectUuid));
+ if (groupNames.isEmpty()) {
+ queryBuilder.mustNot(existsQuery(groupField));
+ } else {
+ queryBuilder.must(termsQuery(groupField, groupNames));
+ }
+ if (userLogins.isEmpty()) {
+ queryBuilder.mustNot(existsQuery(userField));
+ } else {
+ queryBuilder.must(termsQuery(userField, userLogins));
+ }
+ SearchRequestBuilder request = esTester.client()
+ .prepareSearch(index)
+ .setTypes(type)
+ .setQuery(boolQuery().must(matchAllQuery()).filter(queryBuilder));
+ assertThat(request.get().getHits()).hasSize(1);
+ }
+}
import org.sonar.server.permission.GroupPermissionChanger;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChanger;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.usergroups.ws.GroupWsSupport;
import org.sonar.server.ws.WsTester;
protected PermissionUpdater newPermissionUpdater() {
return new PermissionUpdater(db.getDbClient(),
- mock(AuthorizationIndexer.class),
+ mock(PermissionIndexer.class),
new UserPermissionChanger(db.getDbClient(), defaultOrganizationProvider),
new GroupPermissionChanger(db.getDbClient(), defaultOrganizationProvider));
}
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.issue.index.IssueIndexDefinition;
import org.sonar.server.permission.PermissionService;
-import org.sonar.server.permission.index.AuthorizationIndexer;
-import org.sonar.server.permission.index.AuthorizationIndexerTester;
+import org.sonar.server.permission.index.PermissionIndexer;
+import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.permission.ws.BasePermissionWsTest;
import org.sonar.server.ws.WsTester;
private PermissionTemplateDto template1;
private PermissionTemplateDto template2;
- private AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(esTester);
+ private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(esTester);
- private AuthorizationIndexer authorizationIndexer = new AuthorizationIndexer(db.getDbClient(), esTester.client());
+ private PermissionIndexer permissionIndexer = new PermissionIndexer(db.getDbClient(), esTester.client());
@Override
protected ApplyTemplateAction buildWsAction() {
PermissionRepository repository = new PermissionRepository(db.getDbClient(), new MapSettings());
ComponentFinder componentFinder = new ComponentFinder(db.getDbClient());
- PermissionService permissionService = new PermissionService(db.getDbClient(), repository, authorizationIndexer, userSession, componentFinder);
+ PermissionService permissionService = new PermissionService(db.getDbClient(), repository, permissionIndexer, userSession, componentFinder);
return new ApplyTemplateAction(db.getDbClient(), userSession, permissionService, newPermissionWsSupport());
}
assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).containsExactly(user1.getLogin());
assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).containsExactly(user2.getLogin());
- authorizationIndexerTester.verifyProjectExistsWithAuthorization(project.uuid(), singletonList(group2.getName()), Collections.emptyList());
+ authorizationIndexerTester.verifyProjectExistsWithPermission(project.uuid(), singletonList(group2.getName()), Collections.emptyList());
}
private WsTester.Result newRequest(@Nullable String templateUuid, @Nullable String projectUuid, @Nullable String projectKey) throws Exception {
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.i18n.I18nRule;
import org.sonar.server.permission.PermissionService;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.permission.ws.BasePermissionWsTest;
import org.sonar.server.ws.WsTester;
private GroupDto group2;
private PermissionTemplateDto template1;
private PermissionTemplateDto template2;
- private AuthorizationIndexer issueAuthorizationIndexer = mock(AuthorizationIndexer.class);
+ private PermissionIndexer issuePermissionIndexer = mock(PermissionIndexer.class);
@Override
protected BulkApplyTemplateAction buildWsAction() {
PermissionRepository repository = new PermissionRepository(db.getDbClient(), new MapSettings());
ComponentFinder componentFinder = new ComponentFinder(db.getDbClient());
- PermissionService permissionService = new PermissionService(db.getDbClient(), repository, issueAuthorizationIndexer, userSession, componentFinder);
+ PermissionService permissionService = new PermissionService(db.getDbClient(), repository, issuePermissionIndexer, userSession, componentFinder);
return new BulkApplyTemplateAction(db.getDbClient(), userSession, permissionService, newPermissionWsSupport(), new I18nRule(), newRootResourceTypes());
}
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.component.ComponentCleanerService;
import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.component.es.ProjectMeasuresIndexer;
import org.sonar.server.es.EsTester;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.issue.IssueTesting;
import org.sonar.server.issue.index.IssueAuthorizationDoc;
import org.sonar.server.issue.index.IssueIndexDefinition;
import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.permission.index.AuthorizationIndexer;
-import org.sonar.server.component.es.ProjectMeasuresIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.test.index.TestDoc;
import org.sonar.server.test.index.TestIndexDefinition;
import org.sonar.server.test.index.TestIndexer;
ws = new WsTester(new ProjectsWs(
new BulkDeleteAction(
new ComponentCleanerService(dbClient,
- new AuthorizationIndexer(dbClient, es.client()),
+ new PermissionIndexer(dbClient, es.client()),
new IssueIndexer(dbClient, es.client()),
new TestIndexer(dbClient, es.client()),
new ProjectMeasuresIndexer(dbClient, es.client()),
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.component.ComponentCleanerService;
import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.component.es.ProjectMeasuresIndexer;
import org.sonar.server.es.EsTester;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.issue.IssueTesting;
import org.sonar.server.issue.index.IssueAuthorizationDoc;
import org.sonar.server.issue.index.IssueIndexDefinition;
import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.permission.index.AuthorizationIndexer;
-import org.sonar.server.component.es.ProjectMeasuresIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.test.index.TestDoc;
import org.sonar.server.test.index.TestIndexDefinition;
import org.sonar.server.test.index.TestIndexer;
new DeleteAction(
new ComponentCleanerService(
dbClient,
- new AuthorizationIndexer(dbClient, es.client()),
+ new PermissionIndexer(dbClient, es.client()),
new IssueIndexer(dbClient, es.client()),
new TestIndexer(dbClient, es.client()),
new ProjectMeasuresIndexer(dbClient, es.client()),
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.index.IssueIndexDefinition;
import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.permission.index.AuthorizationIndexer;
+import org.sonar.server.permission.index.PermissionIndexer;
import org.sonar.server.tester.UserSessionRule;
import static com.google.common.collect.Lists.newArrayList;
public void clear_views_lookup_cache_on_index_view_uuid() {
IssueIndex issueIndex = new IssueIndex(esTester.client(), System2.INSTANCE, userSessionRule);
IssueIndexer issueIndexer = new IssueIndexer(dbClient, esTester.client());
- AuthorizationIndexer authorizationIndexer = new AuthorizationIndexer(dbClient, esTester.client());
+ PermissionIndexer permissionIndexer = new PermissionIndexer(dbClient, esTester.client());
String viewUuid = "ABCD";
dbClient.ruleDao().insert(dbSession, rule);
ComponentDto project1 = addProjectWithIssue(rule);
issueIndexer.indexAll();
- authorizationIndexer.index(dbSession, project1.uuid());
+ permissionIndexer.index(dbSession, project1.uuid());
ComponentDto view = ComponentTesting.newView("ABCD");
ComponentDto techProject1 = ComponentTesting.newProjectCopy("CDEF", project1, view);
// Add a project to the view and index it again
ComponentDto project2 = addProjectWithIssue(rule);
issueIndexer.indexAll();
- authorizationIndexer.index(dbSession, project2.uuid());
+ permissionIndexer.index(dbSession, project2.uuid());
ComponentDto techProject2 = ComponentTesting.newProjectCopy("EFGH", project2, view);
dbClient.componentDao().insert(dbSession, techProject2);