]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7482 Return identity providers info in system info
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 29 Apr 2016 15:50:48 +0000 (17:50 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 3 May 2016 12:26:30 +0000 (14:26 +0200)
server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SonarQubeMonitor.java
server/sonar-server/src/test/java/org/sonar/server/platform/monitoring/SonarQubeMonitorTest.java

index ab513629d81cdacb315d7a22b1fd50a17c043e81..4671717239b94cba1ac0a95ff9b58a3c42e82b99 100644 (file)
  */
 package org.sonar.server.platform.monitoring;
 
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
 import java.io.File;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
 import org.sonar.api.platform.Server;
 import org.sonar.api.security.SecurityRealm;
+import org.sonar.api.server.authentication.IdentityProvider;
 import org.sonar.process.ProcessProperties;
+import org.sonar.server.authentication.IdentityProviderRepository;
 import org.sonar.server.platform.ServerLogging;
 import org.sonar.server.user.SecurityRealmFactory;
 
+import static com.google.common.collect.FluentIterable.from;
+
 public class SonarQubeMonitor extends BaseMonitorMBean implements SonarQubeMonitorMBean {
 
+  private static final Joiner COMMA_JOINER = Joiner.on(", ");
+
   static final String BRANDING_FILE_PATH = "web/WEB-INF/classes/com/sonarsource/branding";
 
   private final Settings settings;
   private final SecurityRealmFactory securityRealmFactory;
+  private final IdentityProviderRepository identityProviderRepository;
   private final Server server;
   private final ServerLogging serverLogging;
 
   public SonarQubeMonitor(Settings settings, SecurityRealmFactory securityRealmFactory,
-    Server server, ServerLogging serverLogging) {
+    IdentityProviderRepository identityProviderRepository, Server server, ServerLogging serverLogging) {
     this.settings = settings;
     this.securityRealmFactory = securityRealmFactory;
+    this.identityProviderRepository = identityProviderRepository;
     this.server = server;
     this.serverLogging = serverLogging;
   }
@@ -62,27 +77,40 @@ public class SonarQubeMonitor extends BaseMonitorMBean implements SonarQubeMonit
     return serverLogging.getRootLoggerLevel().name();
   }
 
-  public String getExternalUserAuthentication() {
+  @CheckForNull
+  private String getExternalUserAuthentication() {
     SecurityRealm realm = securityRealmFactory.getRealm();
-    if (realm == null) {
-      return "";
-    }
-    return realm.getName();
+    return realm == null ? null : realm.getName();
+  }
+
+  private List<String> getEnabledIdentityProviders() {
+    return from(identityProviderRepository.getAllEnabledAndSorted())
+      .filter(MatchEnabled.INSTANCE)
+      .transform(IdentityProviderToName.INSTANCE)
+      .toList();
+  }
+
+  private List<String> getAllowsToSignUpEnabledIdentityProviders() {
+    return from(identityProviderRepository.getAllEnabledAndSorted())
+      .filter(MatchEnabled.INSTANCE)
+      .filter(MatchAllowsToSignUp.INSTANCE)
+      .transform(IdentityProviderToName.INSTANCE)
+      .toList();
   }
 
-  public boolean getAutomaticUserCreation() {
+  private boolean getAutomaticUserCreation() {
     return settings.getBoolean(CoreProperties.CORE_AUTHENTICATOR_CREATE_USERS);
   }
 
-  public boolean getAllowUsersToSignUp() {
+  private boolean getAllowUsersToSignUp() {
     return settings.getBoolean(CoreProperties.CORE_ALLOW_USERS_TO_SIGNUP_PROPERTY);
   }
 
-  public boolean getForceAuthentication() {
+  private boolean getForceAuthentication() {
     return settings.getBoolean(CoreProperties.CORE_FORCE_AUTHENTICATION_PROPERTY);
   }
 
-  public boolean isOfficialDistribution() {
+  private boolean isOfficialDistribution() {
     // the dependency com.sonarsource:sonarsource-branding is shaded to webapp
     // during release (see sonar-web pom)
     File brandingFile = new File(server.getRootDir(), BRANDING_FILE_PATH);
@@ -100,7 +128,9 @@ public class SonarQubeMonitor extends BaseMonitorMBean implements SonarQubeMonit
     Map<String, Object> attributes = new LinkedHashMap<>();
     attributes.put("Server ID", getServerId());
     attributes.put("Version", getVersion());
-    attributes.put("External User Authentication", getExternalUserAuthentication());
+    addIfNotNull("External User Authentication", getExternalUserAuthentication(), attributes);
+    addIfNotEmpty("Accepted external identity providers", getEnabledIdentityProviders(), attributes);
+    addIfNotEmpty("External identity providers whose users are allowed to sign themselves up", getAllowsToSignUpEnabledIdentityProviders(), attributes);
     attributes.put("Automatic User Creation", getAutomaticUserCreation());
     attributes.put("Allow Users to Sign Up", getAllowUsersToSignUp());
     attributes.put("Force authentication", getForceAuthentication());
@@ -111,6 +141,44 @@ public class SonarQubeMonitor extends BaseMonitorMBean implements SonarQubeMonit
     attributes.put("Logs Dir", settings.getString(ProcessProperties.PATH_LOGS));
     attributes.put("Logs Level", getLogLevel());
     return attributes;
+  }
+
+  private static void addIfNotNull(String key, @Nullable String value, Map<String, Object> attributes) {
+    if (value != null) {
+      attributes.put(key, value);
+    }
+  }
+
+  private static void addIfNotEmpty(String key, List<String> values, Map<String, Object> attributes) {
+    if (!values.isEmpty()) {
+      attributes.put(key, COMMA_JOINER.join(values));
+    }
+  }
+
+  private enum IdentityProviderToName implements Function<IdentityProvider, String> {
+    INSTANCE;
+
+    @Override
+    public String apply(@Nonnull IdentityProvider input) {
+      return input.getName();
+    }
+  }
 
+  private enum MatchEnabled implements Predicate<IdentityProvider> {
+    INSTANCE;
+
+    @Override
+    public boolean apply(@Nonnull IdentityProvider input) {
+      return input.isEnabled();
+    }
+  }
+
+  private enum MatchAllowsToSignUp implements Predicate<IdentityProvider> {
+    INSTANCE;
+
+    @Override
+    public boolean apply(@Nonnull IdentityProvider input) {
+      return input.allowsUsersToSignUp();
+    }
   }
 }
index a522c1df76737b8dc1ca56a4d0bd5dc18b9ecd1e..2de59d3a6c950596385cc5d0d185873a5ec403c2 100644 (file)
@@ -28,8 +28,11 @@ import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.config.Settings;
 import org.sonar.api.platform.Server;
+import org.sonar.api.security.SecurityRealm;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.log.LoggerLevel;
+import org.sonar.server.authentication.IdentityProviderRepositoryRule;
+import org.sonar.server.authentication.TestIdentityProvider;
 import org.sonar.server.platform.ServerLogging;
 import org.sonar.server.user.SecurityRealmFactory;
 
@@ -42,9 +45,15 @@ public class SonarQubeMonitorTest {
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
 
+  @Rule
+  public IdentityProviderRepositoryRule identityProviderRepository = new IdentityProviderRepositoryRule();
+
   Settings settings = new Settings();
   Server server = mock(Server.class);
   ServerLogging serverLogging = mock(ServerLogging.class);
+  SecurityRealmFactory securityRealmFactory = mock(SecurityRealmFactory.class);
+
+  SonarQubeMonitor underTest = new SonarQubeMonitor(settings, securityRealmFactory, identityProviderRepository, server, serverLogging);
 
   @Before
   public void setUp() throws Exception {
@@ -53,15 +62,14 @@ public class SonarQubeMonitorTest {
 
   @Test
   public void name_is_not_empty() {
-    assertThat(new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server, serverLogging).name()).isNotEmpty();
+    assertThat(underTest.name()).isNotEmpty();
   }
 
   @Test
   public void getServerId() {
     when(server.getStartedAt()).thenReturn(DateUtils.parseDate("2015-01-01"));
-    SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server, serverLogging);
 
-    Map<String, Object> attributes = monitor.attributes();
+    Map<String, Object> attributes = underTest.attributes();
     assertThat(attributes).containsKeys("Server ID", "Version");
   }
 
@@ -71,9 +79,8 @@ public class SonarQubeMonitorTest {
     FileUtils.write(new File(rootDir, SonarQubeMonitor.BRANDING_FILE_PATH), "1.2");
 
     when(server.getRootDir()).thenReturn(rootDir);
-    SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server, serverLogging);
 
-    Map<String, Object> attributes = monitor.attributes();
+    Map<String, Object> attributes = underTest.attributes();
     assertThat(attributes).containsEntry("Official Distribution", Boolean.TRUE);
   }
 
@@ -82,17 +89,73 @@ public class SonarQubeMonitorTest {
     File rootDir = temp.newFolder();
     // branding file is missing
     when(server.getRootDir()).thenReturn(rootDir);
-    SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server, serverLogging);
 
-    Map<String, Object> attributes = monitor.attributes();
+    Map<String, Object> attributes = underTest.attributes();
     assertThat(attributes).containsEntry("Official Distribution", Boolean.FALSE);
   }
 
   @Test
   public void get_log_level() throws Exception {
-    SonarQubeMonitor monitor = new SonarQubeMonitor(settings, new SecurityRealmFactory(settings), server, serverLogging);
-
-    Map<String, Object> attributes = monitor.attributes();
+    Map<String, Object> attributes = underTest.attributes();
     assertThat(attributes).containsEntry("Logs Level", "DEBUG");
   }
+
+  @Test
+  public void get_realm() throws Exception {
+    SecurityRealm realm = mock(SecurityRealm.class);
+    when(realm.getName()).thenReturn("LDAP");
+    when(securityRealmFactory.getRealm()).thenReturn(realm);
+
+    Map<String, Object> attributes = underTest.attributes();
+    assertThat(attributes).containsEntry("External User Authentication", "LDAP");
+  }
+
+  @Test
+  public void no_realm() throws Exception {
+    when(securityRealmFactory.getRealm()).thenReturn(null);
+
+    Map<String, Object> attributes = underTest.attributes();
+    assertThat(attributes).doesNotContainKey("External User Authentication");
+  }
+
+  @Test
+  public void get_enabled_identity_providers() throws Exception {
+    identityProviderRepository.addIdentityProvider(new TestIdentityProvider()
+      .setKey("github")
+      .setName("GitHub")
+      .setEnabled(true));
+    identityProviderRepository.addIdentityProvider(new TestIdentityProvider()
+      .setKey("bitbucket")
+      .setName("Bitbucket")
+      .setEnabled(true));
+    identityProviderRepository.addIdentityProvider(new TestIdentityProvider()
+      .setKey("disabled")
+      .setName("Disabled")
+      .setEnabled(false));
+
+    Map<String, Object> attributes = underTest.attributes();
+    assertThat(attributes).containsEntry("Accepted external identity providers", "Bitbucket, GitHub");
+  }
+
+  @Test
+  public void get_enabled_identity_providers_allowing_users_to_signup() throws Exception {
+    identityProviderRepository.addIdentityProvider(new TestIdentityProvider()
+      .setKey("github")
+      .setName("GitHub")
+      .setEnabled(true)
+      .setAllowsUsersToSignUp(true));
+    identityProviderRepository.addIdentityProvider(new TestIdentityProvider()
+      .setKey("bitbucket")
+      .setName("Bitbucket")
+      .setEnabled(true)
+      .setAllowsUsersToSignUp(false));
+    identityProviderRepository.addIdentityProvider(new TestIdentityProvider()
+      .setKey("disabled")
+      .setName("Disabled")
+      .setEnabled(false)
+      .setAllowsUsersToSignUp(true));
+
+    Map<String, Object> attributes = underTest.attributes();
+    assertThat(attributes).containsEntry("External identity providers whose users are allowed to sign themselves up", "GitHub");
+  }
 }