]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19084 load all GitHub users
authorAurelien Poscia <aurelien.poscia@sonarsource.com>
Fri, 21 Apr 2023 09:16:41 +0000 (11:16 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 11 May 2023 20:03:13 +0000 (20:03 +0000)
server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubManagedInstanceService.java
server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubModule.java
server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java
server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubManagedInstanceServiceTest.java
server/sonar-auth-github/src/test/java/org/sonar/auth/github/GitHubModuleTest.java
server/sonar-db-dao/src/main/java/org/sonar/db/user/UserQuery.java

index 4422d1d3e61067a12bd4c9e180e0783f37de48d2..e88da1259f94c11fab03753ae2e2a7ee8d13e478 100644 (file)
  */
 package org.sonar.auth.github;
 
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Function;
 import org.sonar.api.ce.ComputeEngineSide;
 import org.sonar.api.server.ServerSide;
 import org.sonar.db.DbSession;
+import org.sonar.db.user.UserDao;
+import org.sonar.db.user.UserDto;
+import org.sonar.db.user.UserQuery;
 import org.sonar.server.management.ManagedInstanceService;
 
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
+
 @ServerSide
 @ComputeEngineSide
 public class GitHubManagedInstanceService implements ManagedInstanceService {
 
   private final GitHubSettings gitHubSettings;
+  private final UserDao userDao;
 
-  public GitHubManagedInstanceService(GitHubSettings gitHubSettings) {
+  public GitHubManagedInstanceService(GitHubSettings gitHubSettings, UserDao userDao) {
     this.gitHubSettings = gitHubSettings;
+    this.userDao = userDao;
   }
 
   @Override
@@ -43,7 +53,18 @@ public class GitHubManagedInstanceService implements ManagedInstanceService {
 
   @Override
   public Map<String, Boolean> getUserUuidToManaged(DbSession dbSession, Set<String> userUuids) {
-    throw new IllegalStateException("Not implemented.");
+    UserQuery managedUsersQuery = UserQuery.builder()
+      .userUuids(userUuids)
+      .isManagedClause(getManagedUsersSqlFilter(true))
+      .build();
+
+    List<UserDto> userDtos = userDao.selectUsers(dbSession, managedUsersQuery);
+    Set<String> gitHubUserUuids = userDtos.stream()
+      .map(UserDto::getUuid)
+      .collect(toSet());
+
+    return userUuids.stream()
+      .collect(toMap(Function.identity(), gitHubUserUuids::contains));
   }
 
   @Override
@@ -53,7 +74,8 @@ public class GitHubManagedInstanceService implements ManagedInstanceService {
 
   @Override
   public String getManagedUsersSqlFilter(boolean filterByManaged) {
-    throw new IllegalStateException("Not implemented.");
+    String operator = filterByManaged ? "=" : "<>";
+    return String.format("external_identity_provider %s '%s'", operator, GitHubIdentityProvider.KEY);
   }
 
   @Override
index 5307da164cf6803889216cb7f8778366cbd2227f..12385565b380e1290cdf02ca7fe8394a55a1c661 100644 (file)
@@ -32,6 +32,7 @@ public class GitHubModule extends Module {
     add(
       GitHubIdentityProvider.class,
       GitHubSettings.class,
+      GitHubManagedInstanceService.class,
       GitHubRestClient.class,
       UserIdentityFactoryImpl.class,
       ScribeGitHubApi.class);
index 7469f79749fe2ec7d448ccddff02a8b02c8ba57d..81db6cf05bf80484daa8ba35f4f6ef4781b44f9d 100644 (file)
@@ -44,7 +44,7 @@ public class GitHubSettings {
   public static final String WEB_URL = "sonar.auth.github.webUrl";
   public static final String ORGANIZATIONS = "sonar.auth.github.organizations";
   @VisibleForTesting
-  static final String PROVISIONING = "sonar.provisioning.github.enabled";
+  static final String PROVISIONING = "provisioning.github"; //TODO
 
   private static final String CATEGORY = "authentication";
   private static final String SUBCATEGORY = "github";
index e88ceffe3aaf1bb2a69c04e46e605fbca4d3be7b..7d09ab883c09a771a423e43b7d02b7099b9e1f97 100644 (file)
  */
 package org.sonar.auth.github;
 
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
+import org.sonar.db.DbSession;
+import org.sonar.db.user.UserDao;
+import org.sonar.db.user.UserDto;
+import org.sonar.db.user.UserQuery;
 
+import static java.util.Collections.emptyList;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
@@ -34,6 +46,15 @@ public class GitHubManagedInstanceServiceTest {
   @Mock
   private GitHubSettings gitHubSettings;
 
+  @Mock
+  private UserDao userDao;
+
+  @Mock
+  private DbSession dbSession;
+
+  @Captor
+  private ArgumentCaptor<UserQuery> userQueryCaptor;
+
   @InjectMocks
   private GitHubManagedInstanceService gitHubManagedInstanceService;
 
@@ -48,4 +69,62 @@ public class GitHubManagedInstanceServiceTest {
     when(gitHubSettings.isProvisioningEnabled()).thenReturn(true);
     assertThat(gitHubManagedInstanceService.isInstanceExternallyManaged()).isTrue();
   }
+
+  @Test
+  public void getManagedUsersSqlFilter_whenTrue_returnsFilterByGithub() {
+    String managedUsersSqlFilter = gitHubManagedInstanceService.getManagedUsersSqlFilter(true);
+    assertThat(managedUsersSqlFilter).isEqualTo("external_identity_provider = 'github'");
+  }
+
+  @Test
+  public void getManagedUsersSqlFilter_whenFalse_returnsFilterByNotGithub() {
+    String managedUsersSqlFilter = gitHubManagedInstanceService.getManagedUsersSqlFilter(false);
+    assertThat(managedUsersSqlFilter).isEqualTo("external_identity_provider <> 'github'");
+  }
+
+  @Test
+  public void getUserUuidToManaged_whenNoUsers_returnsFalseForAllInput() {
+    Set<String> uuids = Set.of("uuid1", "uuid2");
+    Map<String, Boolean> userUuidToManaged = gitHubManagedInstanceService.getUserUuidToManaged(dbSession, uuids);
+
+    assertThat(userUuidToManaged)
+      .hasSize(2)
+      .containsEntry("uuid1", false)
+      .containsEntry("uuid2", false);
+  }
+
+  @Test
+  public void getUserUuidToManaged_whenOneUserManaged_returnsTrueForIt() {
+    String managedUserUuid = "managedUserUuid";
+    Set<String> uuids = Set.of("uuid1", managedUserUuid);
+
+    UserDto user2dto = mock(UserDto.class);
+    when(user2dto.getUuid()).thenReturn(managedUserUuid);
+
+    when(userDao.selectUsers(eq(dbSession), userQueryCaptor.capture())).thenReturn(List.of(user2dto));
+
+    Map<String, Boolean> userUuidToManaged = gitHubManagedInstanceService.getUserUuidToManaged(dbSession, uuids);
+
+    assertThat(userUuidToManaged)
+      .hasSize(2)
+      .containsEntry("uuid1", false)
+      .containsEntry(managedUserUuid, true);
+  }
+
+  @Test
+  public void getUserUuidToManaged_sendsTheRightQueryToUserDao() {
+    Set<String> uuids = Set.of("uuid1", "uuid2");
+
+    when(userDao.selectUsers(eq(dbSession), userQueryCaptor.capture())).thenReturn(emptyList());
+
+    gitHubManagedInstanceService.getUserUuidToManaged(dbSession, uuids);
+
+    UserQuery capturedQuery = userQueryCaptor.getValue();
+    UserQuery expectedQuery = UserQuery.builder()
+      .userUuids(uuids)
+      .isManagedClause(gitHubManagedInstanceService.getManagedUsersSqlFilter(true))
+      .build();
+    assertThat(capturedQuery).usingRecursiveComparison().isEqualTo(expectedQuery);
+  }
+
 }
index fa5b385f08fed0eeb342b814a56476ad8595c886..ebb9b1b1f2beb8b66ddf76ffcc1549467c4368c8 100644 (file)
@@ -30,7 +30,7 @@ public class GitHubModuleTest {
   public void verify_count_of_added_components() {
     ListContainer container = new ListContainer();
     new GitHubModule().configure(container);
-    assertThat(container.getAddedObjects()).hasSize(13);
+    assertThat(container.getAddedObjects()).hasSize(14);
   }
 
 }
index 54f8e0945ccdc02d2faeb1ccc809a1c5823cc710..e14d3e72c5f5d60a02200f1467635e31db745175 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.db.user;
 
 import java.time.OffsetDateTime;
 import java.time.temporal.ChronoUnit;
+import java.util.Set;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
@@ -33,10 +34,11 @@ public class UserQuery {
   private final Long lastConnectionDateTo;
   private final Long sonarLintLastConnectionDateFrom;
   private final Long sonarLintLastConnectionDateTo;
+  private final Set<String> userUuids;
 
-  public UserQuery(@Nullable String searchText, @Nullable Boolean isActive, @Nullable String isManagedSqlClause,
+  private UserQuery(@Nullable String searchText, @Nullable Boolean isActive, @Nullable String isManagedSqlClause,
     @Nullable OffsetDateTime lastConnectionDateFrom, @Nullable OffsetDateTime lastConnectionDateTo,
-    @Nullable OffsetDateTime sonarLintLastConnectionDateFrom, @Nullable OffsetDateTime sonarLintLastConnectionDateTo) {
+    @Nullable OffsetDateTime sonarLintLastConnectionDateFrom, @Nullable OffsetDateTime sonarLintLastConnectionDateTo, @Nullable Set<String> userUuids) {
     this.searchText = searchTextToSearchTextSql(searchText);
     this.isActive = isActive;
     this.isManagedSqlClause = isManagedSqlClause;
@@ -44,18 +46,20 @@ public class UserQuery {
     this.lastConnectionDateTo = formatDateToInput(lastConnectionDateTo);
     this.sonarLintLastConnectionDateFrom = parseDateToLong(sonarLintLastConnectionDateFrom);
     this.sonarLintLastConnectionDateTo = formatDateToInput(sonarLintLastConnectionDateTo);
+    this.userUuids = userUuids;
   }
 
   private static Long formatDateToInput(@Nullable OffsetDateTime dateTo) {
-    if(dateTo == null) {
+    if (dateTo == null) {
       return null;
     } else {
       // add 1 second to include all timestamp at the second precision.
       return dateTo.toInstant().plus(1, ChronoUnit.SECONDS).toEpochMilli();
     }
   }
+
   private static Long parseDateToLong(@Nullable OffsetDateTime date) {
-    if(date == null) {
+    if (date == null) {
       return null;
     } else {
       return date.toInstant().toEpochMilli();
@@ -96,15 +100,22 @@ public class UserQuery {
   public Long getLastConnectionDateTo() {
     return lastConnectionDateTo;
   }
+
   @CheckForNull
   public Long getSonarLintLastConnectionDateFrom() {
     return sonarLintLastConnectionDateFrom;
   }
+
   @CheckForNull
   public Long getSonarLintLastConnectionDateTo() {
     return sonarLintLastConnectionDateTo;
   }
 
+  @CheckForNull
+  public Set<String> getUserUuids() {
+    return userUuids;
+  }
+
   public static UserQueryBuilder builder() {
     return new UserQueryBuilder();
   }
@@ -117,7 +128,7 @@ public class UserQuery {
     private OffsetDateTime lastConnectionDateTo = null;
     private OffsetDateTime sonarLintLastConnectionDateFrom = null;
     private OffsetDateTime sonarLintLastConnectionDateTo = null;
-
+    private Set<String> userUuids = null;
 
     private UserQueryBuilder() {
     }
@@ -157,10 +168,15 @@ public class UserQuery {
       return this;
     }
 
+    public UserQueryBuilder userUuids(@Nullable Set<String> userUuids) {
+      this.userUuids = userUuids;
+      return this;
+    }
+
     public UserQuery build() {
       return new UserQuery(
         searchText, isActive, isManagedSqlClause, lastConnectionDateFrom, lastConnectionDateTo,
-        sonarLintLastConnectionDateFrom, sonarLintLastConnectionDateTo);
+        sonarLintLastConnectionDateFrom, sonarLintLastConnectionDateTo, userUuids);
     }
   }
 }