]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8227 Index authorization by projects
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 18 Oct 2016 14:17:20 +0000 (16:17 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 20 Oct 2016 11:12:07 +0000 (13:12 +0200)
server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ApplyPermissionsStep.java
server/sonar-server/src/main/java/org/sonar/server/es/IndexerStartupTask.java
server/sonar-server/src/main/java/org/sonar/server/permission/PermissionService.java
server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java

index 1aae37b7b7459d34cc1c63b48f05ddb67247a835..7ad9b8305e8c7bd75a08cd9cf444160edd196679 100644 (file)
@@ -39,17 +39,17 @@ import org.sonar.server.test.index.TestIndexer;
 public class ComponentCleanerService {
 
   private final DbClient dbClient;
-  private final AuthorizationIndexer issueAuthorizationIndexer;
+  private final AuthorizationIndexer authorizationIndexer;
   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 issueAuthorizationIndexer, IssueIndexer issueIndexer,
+  public ComponentCleanerService(DbClient dbClient, AuthorizationIndexer authorizationIndexer, IssueIndexer issueIndexer,
                                  TestIndexer testIndexer, ProjectMeasuresIndexer projectMeasuresIndexer, ResourceTypes resourceTypes, ComponentFinder componentFinder) {
     this.dbClient = dbClient;
-    this.issueAuthorizationIndexer = issueAuthorizationIndexer;
+    this.authorizationIndexer = authorizationIndexer;
     this.issueIndexer = issueIndexer;
     this.testIndexer = testIndexer;
     this.projectMeasuresIndexer = projectMeasuresIndexer;
@@ -85,7 +85,7 @@ public class ComponentCleanerService {
 
   private void deleteFromIndices(String projectUuid) {
     // optimization : index "issues" is refreshed once at the end
-    issueAuthorizationIndexer.deleteProject(projectUuid, false);
+    authorizationIndexer.deleteProject(projectUuid, false);
     issueIndexer.deleteProject(projectUuid);
     testIndexer.deleteByProject(projectUuid);
     projectMeasuresIndexer.deleteProject(projectUuid);
index ab411e4a5ac7ab950bf999021c64024e96d82378..f6c27656f6570b8f90d8a8a22716739f7c43e10c 100644 (file)
@@ -77,7 +77,7 @@ public class ApplyPermissionsStep implements ComputationStep {
       if (hasNoPermissions(dbSession, projectId)) {
         permissionRepository.applyDefaultPermissionTemplate(dbSession, projectId);
         dbSession.commit();
-        indexer.index();
+        indexer.index(project.getUuid());
       }
     }
   }
index a6e473bbea41f4973782ff29c3e64114cfb28960..aba3ca3c00347b532fce5d4b6badd93fa06bd988 100644 (file)
@@ -34,7 +34,7 @@ public class IndexerStartupTask {
   private static final Logger LOG = Loggers.get(IndexerStartupTask.class);
 
   private final TestIndexer testIndexer;
-  private final AuthorizationIndexer issueAuthorizationIndexer;
+  private final AuthorizationIndexer authorizationIndexer;
   private final IssueIndexer issueIndexer;
   private final UserIndexer userIndexer;
   private final ViewIndexer viewIndexer;
@@ -46,11 +46,11 @@ public class IndexerStartupTask {
    * because we need {@link AuthorizationIndexer} to be executed before
    * {@link org.sonar.server.issue.index.IssueIndexer}
    */
-  public IndexerStartupTask(TestIndexer testIndexer, AuthorizationIndexer issueAuthorizationIndexer, IssueIndexer issueIndexer,
+  public IndexerStartupTask(TestIndexer testIndexer, AuthorizationIndexer authorizationIndexer, IssueIndexer issueIndexer,
                             UserIndexer userIndexer, ViewIndexer viewIndexer, ProjectMeasuresIndexer projectMeasuresIndexer,
                             Settings settings) {
     this.testIndexer = testIndexer;
-    this.issueAuthorizationIndexer = issueAuthorizationIndexer;
+    this.authorizationIndexer = authorizationIndexer;
     this.issueIndexer = issueIndexer;
     this.userIndexer = userIndexer;
     this.viewIndexer = viewIndexer;
@@ -61,8 +61,10 @@ public class IndexerStartupTask {
   public void execute() {
     if (!settings.getBoolean("sonar.internal.es.disableIndexes")) {
 
+      LOG.info("Index authorization");
+      authorizationIndexer.index();
+
       LOG.info("Index issues");
-      issueAuthorizationIndexer.index();
       issueIndexer.index();
 
       LOG.info("Index tests");
index df1d9d3037cc298cc9fdc51a09c3238d2bf5579e..fcda00f76a72fff259a8747428e9172baa3d63c2 100644 (file)
@@ -26,6 +26,7 @@ import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.server.ServerSide;
 import org.sonar.core.component.ComponentKeys;
 import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.util.stream.Collectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
@@ -36,6 +37,7 @@ import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.permission.index.AuthorizationIndexer;
 import org.sonar.server.user.UserSession;
 
+import static java.util.Arrays.asList;
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentKey;
 
 @ServerSide
@@ -43,15 +45,15 @@ public class PermissionService {
 
   private final DbClient dbClient;
   private final PermissionRepository permissionRepository;
-  private final AuthorizationIndexer issueAuthorizationIndexer;
+  private final AuthorizationIndexer authorizationIndexer;
   private final UserSession userSession;
   private final ComponentFinder componentFinder;
 
-  public PermissionService(DbClient dbClient, PermissionRepository permissionRepository, AuthorizationIndexer issueAuthorizationIndexer, UserSession userSession,
-                           ComponentFinder componentFinder) {
+  public PermissionService(DbClient dbClient, PermissionRepository permissionRepository, AuthorizationIndexer authorizationIndexer, UserSession userSession,
+    ComponentFinder componentFinder) {
     this.dbClient = dbClient;
     this.permissionRepository = permissionRepository;
-    this.issueAuthorizationIndexer = issueAuthorizationIndexer;
+    this.authorizationIndexer = authorizationIndexer;
     this.userSession = userSession;
     this.componentFinder = componentFinder;
   }
@@ -85,7 +87,7 @@ public class PermissionService {
     Long userId = Qualifiers.PROJECT.equals(component.qualifier()) && currentUserId != null ? currentUserId.longValue() : null;
     permissionRepository.applyDefaultPermissionTemplate(session, component, userId);
     session.commit();
-    indexProjectPermissions();
+    indexProjectPermissions(asList(component.uuid()));
   }
 
   public boolean wouldCurrentUserHavePermissionWithDefaultTemplate(DbSession dbSession, String permission, @Nullable String branch, String projectKey, String qualifier) {
@@ -108,10 +110,10 @@ public class PermissionService {
       permissionRepository.apply(dbSession, template, project, null);
     }
     dbSession.commit();
-    indexProjectPermissions();
+    indexProjectPermissions(projects.stream().map(ComponentDto::uuid).collect(Collectors.toList()));
   }
 
-  private void indexProjectPermissions() {
-    issueAuthorizationIndexer.index();
+  private void indexProjectPermissions(List<String> projectUuids) {
+    authorizationIndexer.index(projectUuids);
   }
 }
index 07403ad42e08e3a5f173313e16e70c77357b8a34..47a426a2736b9cc83ec9f21e7084c982ada5a2c8 100644 (file)
  */
 package org.sonar.server.permission;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import org.sonar.db.DbClient;
@@ -35,25 +37,27 @@ import org.sonar.server.permission.index.AuthorizationIndexer;
 public class PermissionUpdater {
 
   private final DbClient dbClient;
-  private final AuthorizationIndexer issueAuthorizationIndexer;
+  private final AuthorizationIndexer authorizationIndexer;
   private final UserPermissionChanger userPermissionChanger;
   private final GroupPermissionChanger groupPermissionChanger;
 
-  public PermissionUpdater(DbClient dbClient, AuthorizationIndexer issueAuthorizationIndexer,
-    UserPermissionChanger userPermissionChanger, GroupPermissionChanger groupPermissionChanger) {
+  public PermissionUpdater(DbClient dbClient, AuthorizationIndexer authorizationIndexer,
+                           UserPermissionChanger userPermissionChanger, GroupPermissionChanger groupPermissionChanger) {
     this.dbClient = dbClient;
-    this.issueAuthorizationIndexer = issueAuthorizationIndexer;
+    this.authorizationIndexer = authorizationIndexer;
     this.userPermissionChanger = userPermissionChanger;
     this.groupPermissionChanger = groupPermissionChanger;
   }
 
   public void apply(DbSession dbSession, Collection<PermissionChange> changes) {
     Set<Long> projectIds = new HashSet<>();
+    List<String> projectUuids = new ArrayList<>();
     for (PermissionChange change : changes) {
       boolean changed = doApply(dbSession, change);
       Optional<ProjectId> projectId = change.getProjectId();
       if (changed && projectId.isPresent()) {
         projectIds.add(projectId.get().getId());
+        projectUuids.add(projectId.get().getUuid());
       }
     }
     for (Long projectId : projectIds) {
@@ -62,7 +66,7 @@ public class PermissionUpdater {
     dbSession.commit();
 
     if (!projectIds.isEmpty()) {
-      issueAuthorizationIndexer.index();
+      authorizationIndexer.index(projectUuids);
     }
   }
 
index d9beaf0654d5c8ab95536c4a1b4855a663ea59ae..e90a36aebc5f4d4d971d53899ccd60fcb900a585 100644 (file)
  */
 package org.sonar.server.permission.ws.template;
 
+import java.util.Collections;
 import java.util.List;
 import javax.annotation.Nullable;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.MapSettings;
 import org.sonar.api.web.UserRole;
@@ -34,17 +36,19 @@ import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.es.EsTester;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 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.ws.BasePermissionWsTest;
 import org.sonar.server.ws.WsTester;
 
+import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
 import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.db.component.ComponentTesting.newProjectDto;
 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.CONTROLLER;
@@ -55,6 +59,9 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_T
 
 public class ApplyTemplateActionTest extends BasePermissionWsTest<ApplyTemplateAction> {
 
+  @Rule
+  public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()));
+
   private static final String ACTION = "apply_template";
 
   private UserDto user1;
@@ -64,13 +71,16 @@ public class ApplyTemplateActionTest extends BasePermissionWsTest<ApplyTemplateA
   private ComponentDto project;
   private PermissionTemplateDto template1;
   private PermissionTemplateDto template2;
-  private AuthorizationIndexer issueAuthorizationIndexer = mock(AuthorizationIndexer.class);
+
+  private AuthorizationIndexerTester authorizationIndexerTester = new AuthorizationIndexerTester(esTester);
+
+  private AuthorizationIndexer authorizationIndexer = new AuthorizationIndexer(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, issueAuthorizationIndexer, userSession, componentFinder);
+    PermissionService permissionService = new PermissionService(db.getDbClient(), repository, authorizationIndexer, userSession, componentFinder);
     return new ApplyTemplateAction(db.getDbClient(), userSession, permissionService, newPermissionWsSupport());
   }
 
@@ -109,7 +119,6 @@ public class ApplyTemplateActionTest extends BasePermissionWsTest<ApplyTemplateA
     newRequest(template1.getUuid(), project.uuid(), null);
 
     assertTemplate1AppliedToProject();
-    verify(issueAuthorizationIndexer).index();
   }
 
   @Test
@@ -198,6 +207,8 @@ public class ApplyTemplateActionTest extends BasePermissionWsTest<ApplyTemplateA
     assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty();
     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());
   }
 
   private WsTester.Result newRequest(@Nullable String templateUuid, @Nullable String projectUuid, @Nullable String projectKey) throws Exception {
index 267af21dec1ee1165dc2aa1a989326869ed0b5fc..4b145f9490634c97b880b949768c964871dd47e0 100644 (file)
@@ -51,7 +51,6 @@ import org.sonar.server.tester.UserSessionRule;
 import static com.google.common.collect.Lists.newArrayList;
 import static org.assertj.core.api.Assertions.assertThat;
 
-
 public class ViewIndexerTest {
 
   @Rule
@@ -144,7 +143,7 @@ public class ViewIndexerTest {
   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 issueAuthorizationIndexer = new AuthorizationIndexer(dbClient, esTester.client());
+    AuthorizationIndexer authorizationIndexer = new AuthorizationIndexer(dbClient, esTester.client());
 
     String viewUuid = "ABCD";
 
@@ -152,7 +151,7 @@ public class ViewIndexerTest {
     dbClient.ruleDao().insert(dbSession, rule);
     ComponentDto project1 = addProjectWithIssue(rule);
     issueIndexer.indexAll();
-    issueAuthorizationIndexer.index();
+    authorizationIndexer.index(project1.uuid());
 
     ComponentDto view = ComponentTesting.newView("ABCD");
     ComponentDto techProject1 = ComponentTesting.newProjectCopy("CDEF", project1, view);
@@ -169,7 +168,7 @@ public class ViewIndexerTest {
     // Add a project to the view and index it again
     ComponentDto project2 = addProjectWithIssue(rule);
     issueIndexer.indexAll();
-    issueAuthorizationIndexer.index();
+    authorizationIndexer.index(project2.uuid());
 
     ComponentDto techProject2 = ComponentTesting.newProjectCopy("EFGH", project2, view);
     dbClient.componentDao().insert(dbSession, techProject2);