aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-auth-ldap
diff options
context:
space:
mode:
authorWojtek Wajerowicz <115081248+wojciech-wajerowicz-sonarsource@users.noreply.github.com>2022-12-20 14:24:36 +0100
committersonartech <sonartech@sonarsource.com>2022-12-23 20:02:51 +0000
commitd023db004a914ab40a9d7caaaa40d901433a018b (patch)
tree5d6ef66155432dd2579b07ba217dd30476c9c0b0 /server/sonar-auth-ldap
parentba6ee4d6696aa45cdc4b684b7aaa49e71401f3e7 (diff)
downloadsonarqube-d023db004a914ab40a9d7caaaa40d901433a018b.tar.gz
sonarqube-d023db004a914ab40a9d7caaaa40d901433a018b.zip
SONAR-17798 respect sonar.authenticator.ignoreStartupFailure property in LdapCredentialsAuthentication
Diffstat (limited to 'server/sonar-auth-ldap')
-rw-r--r--server/sonar-auth-ldap/build.gradle1
-rw-r--r--server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/LdapRealm.java73
-rw-r--r--server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/KerberosTest.java18
-rw-r--r--server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapRealmTest.java79
4 files changed, 135 insertions, 36 deletions
diff --git a/server/sonar-auth-ldap/build.gradle b/server/sonar-auth-ldap/build.gradle
index 6ef30e47a62..ff21ffe4a90 100644
--- a/server/sonar-auth-ldap/build.gradle
+++ b/server/sonar-auth-ldap/build.gradle
@@ -11,6 +11,7 @@ dependencies {
compileOnlyApi 'com.google.code.findbugs:jsr305'
compileOnlyApi 'javax.servlet:javax.servlet-api'
+ compileOnlyApi project(':server:sonar-process')
compileOnlyApi project(':sonar-core')
testImplementation 'com.tngtech.java:junit-dataprovider'
diff --git a/server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/LdapRealm.java b/server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/LdapRealm.java
index 49dbc11b4c0..7550743cec5 100644
--- a/server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/LdapRealm.java
+++ b/server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/LdapRealm.java
@@ -20,9 +20,15 @@
package org.sonar.auth.ldap;
import java.util.Map;
+import javax.annotation.CheckForNull;
+import org.sonar.api.config.Configuration;
import org.sonar.api.server.ServerSide;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
import static org.sonar.auth.ldap.LdapSettingsManager.DEFAULT_LDAP_SERVER_KEY;
+import static org.sonar.process.ProcessProperties.Property.SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE;
+import static org.sonar.process.ProcessProperties.Property.SONAR_SECURITY_REALM;
/**
* @author Evgeny Mandrikov
@@ -32,44 +38,71 @@ public class LdapRealm {
public static final String LDAP_SECURITY_REALM = "LDAP";
public static final String DEFAULT_LDAP_IDENTITY_PROVIDER_ID = LDAP_SECURITY_REALM + "_" + DEFAULT_LDAP_SERVER_KEY;
- private LdapUsersProvider usersProvider;
- private LdapGroupsProvider groupsProvider;
- private LdapAuthenticator authenticator;
- private final LdapSettingsManager settingsManager;
+ private static final Logger LOG = Loggers.get(LdapRealm.class);
- public LdapRealm(LdapSettingsManager settingsManager) {
- this.settingsManager = settingsManager;
+ private final boolean isLdapAuthActivated;
+ private final LdapUsersProvider usersProvider;
+ private final LdapGroupsProvider groupsProvider;
+ private final LdapAuthenticator authenticator;
+
+ public LdapRealm(LdapSettingsManager settingsManager, Configuration configuration) {
+ String realmName = configuration.get(SONAR_SECURITY_REALM.getKey()).orElse(null);
+ this.isLdapAuthActivated = LDAP_SECURITY_REALM.equals(realmName);
+ boolean ignoreStartupFailure = configuration.getBoolean(SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE.getKey()).orElse(false);
+ if (!isLdapAuthActivated) {
+ this.usersProvider = null;
+ this.groupsProvider = null;
+ this.authenticator = null;
+ } else {
+ Map<String, LdapContextFactory> contextFactories = settingsManager.getContextFactories();
+ Map<String, LdapUserMapping> userMappings = settingsManager.getUserMappings();
+ this.usersProvider = new DefaultLdapUsersProvider(contextFactories, userMappings);
+ this.authenticator = new DefaultLdapAuthenticator(contextFactories, userMappings);
+ this.groupsProvider = createGroupsProvider(contextFactories, userMappings, settingsManager);
+ testConnections(contextFactories, ignoreStartupFailure);
+ }
}
- /**
- * Initializes LDAP realm and tests connection.
- *
- * @throws LdapException if a NamingException was thrown during test
- */
- public void init() {
- Map<String, LdapContextFactory> contextFactories = settingsManager.getContextFactories();
- Map<String, LdapUserMapping> userMappings = settingsManager.getUserMappings();
- usersProvider = new DefaultLdapUsersProvider(contextFactories, userMappings);
- authenticator = new DefaultLdapAuthenticator(contextFactories, userMappings);
+ private static LdapGroupsProvider createGroupsProvider(Map<String, LdapContextFactory> contextFactories, Map<String, LdapUserMapping> userMappings,
+ LdapSettingsManager settingsManager) {
Map<String, LdapGroupMapping> groupMappings = settingsManager.getGroupMappings();
if (!groupMappings.isEmpty()) {
- groupsProvider = new DefaultLdapGroupsProvider(contextFactories, userMappings, groupMappings);
+ return new DefaultLdapGroupsProvider(contextFactories, userMappings, groupMappings);
+ } else {
+ return null;
}
- for (LdapContextFactory contextFactory : contextFactories.values()) {
- contextFactory.testConnection();
+ }
+
+ private static void testConnections(Map<String, LdapContextFactory> contextFactories, boolean ignoreStartupFailure) {
+ try {
+ for (LdapContextFactory contextFactory : contextFactories.values()) {
+ contextFactory.testConnection();
+ }
+ } catch (RuntimeException e) {
+ if (ignoreStartupFailure) {
+ LOG.error("IGNORED - LDAP realm failed to start: " + e.getMessage());
+ } else {
+ throw new LdapException("LDAP realm failed to start: " + e.getMessage(), e);
+ }
}
}
- public LdapAuthenticator doGetAuthenticator() {
+ @CheckForNull
+ public LdapAuthenticator getAuthenticator() {
return authenticator;
}
+ @CheckForNull
public LdapUsersProvider getUsersProvider() {
return usersProvider;
}
+ @CheckForNull
public LdapGroupsProvider getGroupsProvider() {
return groupsProvider;
}
+ public boolean isLdapAuthActivated() {
+ return isLdapAuthActivated;
+ }
}
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/KerberosTest.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/KerberosTest.java
index 7eba029eef5..2de46ca6e26 100644
--- a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/KerberosTest.java
+++ b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/KerberosTest.java
@@ -25,11 +25,13 @@ import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.mockito.Mockito;
+import org.sonar.api.config.Configuration;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.auth.ldap.server.LdapServer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.sonar.process.ProcessProperties.Property.SONAR_SECURITY_REALM;
public class KerberosTest {
@@ -46,10 +48,8 @@ public class KerberosTest {
@Before
public void before() {
MapSettings settings = configure();
- ldapRealm = new LdapRealm(new LdapSettingsManager(settings.asConfig()));
- ldapRealm.init();
-
- authenticator = ldapRealm.doGetAuthenticator();
+ ldapRealm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
+ authenticator = ldapRealm.getAuthenticator();
}
@Test
@@ -86,11 +86,12 @@ public class KerberosTest {
public void wrong_bind_password() {
MapSettings settings = configure()
.setProperty("ldap.bindPassword", "wrong_bind_password");
- LdapRealm wrongPasswordRealm = new LdapRealm(new LdapSettingsManager(settings.asConfig()));
- assertThatThrownBy(wrongPasswordRealm::init)
+ Configuration config = settings.asConfig();
+ LdapSettingsManager settingsManager = new LdapSettingsManager(config);
+ assertThatThrownBy(() -> new LdapRealm(settingsManager, config))
.isInstanceOf(LdapException.class)
- .hasMessage("Unable to open LDAP connection");
+ .hasMessage("LDAP realm failed to start: Unable to open LDAP connection");
}
@@ -102,7 +103,8 @@ public class KerberosTest {
.setProperty("ldap.bindPassword", "bind_password")
.setProperty("ldap.user.baseDn", "ou=users,dc=example,dc=org")
.setProperty("ldap.group.baseDn", "ou=groups,dc=example,dc=org")
- .setProperty("ldap.group.request", "(&(objectClass=groupOfUniqueNames)(uniqueMember={dn}))");
+ .setProperty("ldap.group.request", "(&(objectClass=groupOfUniqueNames)(uniqueMember={dn}))")
+ .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM);
}
}
diff --git a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapRealmTest.java b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapRealmTest.java
index 8ebf44cdb09..8bc3d520637 100644
--- a/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapRealmTest.java
+++ b/server/sonar-auth-ldap/src/test/java/org/sonar/auth/ldap/LdapRealmTest.java
@@ -23,11 +23,14 @@ import javax.servlet.http.HttpServletRequest;
import org.junit.ClassRule;
import org.junit.Test;
import org.mockito.Mockito;
+import org.sonar.api.config.Configuration;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.auth.ldap.server.LdapServer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.sonar.process.ProcessProperties.Property.SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE;
+import static org.sonar.process.ProcessProperties.Property.SONAR_SECURITY_REALM;
public class LdapRealmTest {
@@ -38,10 +41,11 @@ public class LdapRealmTest {
public void normal() {
MapSettings settings = new MapSettings()
.setProperty("ldap.url", server.getUrl())
- .setProperty("ldap.user.baseDn", "cn=users");
- LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()));
- realm.init();
- assertThat(realm.doGetAuthenticator()).isInstanceOf(DefaultLdapAuthenticator.class);
+ .setProperty("ldap.user.baseDn", "cn=users")
+ .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM);
+
+ LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
+ assertThat(realm.getAuthenticator()).isInstanceOf(DefaultLdapAuthenticator.class);
assertThat(realm.getUsersProvider()).isInstanceOf(LdapUsersProvider.class).isInstanceOf(DefaultLdapUsersProvider.class);
assertThat(realm.getGroupsProvider()).isNull();
}
@@ -51,11 +55,61 @@ public class LdapRealmTest {
MapSettings settings = new MapSettings()
.setProperty("ldap.url", "ldap://no-such-host")
.setProperty("ldap.group.baseDn", "cn=groups,dc=example,dc=org")
- .setProperty("ldap.user.baseDn", "cn=users,dc=example,dc=org");
- LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()));
- assertThatThrownBy(realm::init).isInstanceOf(LdapException.class).hasMessage("Unable to open LDAP connection");
+ .setProperty("ldap.user.baseDn", "cn=users,dc=example,dc=org")
+ .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM);
+ Configuration config = settings.asConfig();
+ LdapSettingsManager settingsManager = new LdapSettingsManager(config);
+ assertThatThrownBy(() -> new LdapRealm(settingsManager, config)).isInstanceOf(LdapException.class)
+ .hasMessage("LDAP realm failed to start: Unable to open LDAP connection");
+ }
+
+ @Test
+ public void noConnection_ignore_ignoreStartupFailure_is_false() {
+ MapSettings settings = new MapSettings()
+ .setProperty("ldap.url", "ldap://no-such-host")
+ .setProperty("ldap.group.baseDn", "cn=groups,dc=example,dc=org")
+ .setProperty("ldap.user.baseDn", "cn=users,dc=example,dc=org")
+ .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM)
+ .setProperty(SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE.getKey(), false);
+ ;
+ Configuration config = settings.asConfig();
+ LdapSettingsManager settingsManager = new LdapSettingsManager(config);
+ assertThatThrownBy(() -> new LdapRealm(settingsManager, config)).isInstanceOf(LdapException.class)
+ .hasMessage("LDAP realm failed to start: Unable to open LDAP connection");
+ }
+
+ @Test
+ public void noConnection_ignore_ignoreStartupFailure_is_true() {
+ MapSettings settings = new MapSettings()
+ .setProperty("ldap.url", "ldap://no-such-host")
+ .setProperty("ldap.group.baseDn", "cn=groups,dc=example,dc=org")
+ .setProperty("ldap.user.baseDn", "cn=users,dc=example,dc=org")
+ .setProperty(SONAR_SECURITY_REALM.getKey(), LdapRealm.LDAP_SECURITY_REALM)
+ .setProperty(SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE.getKey(), true);
+
+ LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
+ verifyRealm(realm);
+ }
+
+ @Test
+ public void should_not_activate_ldap_if_realm_is_not_set() {
+ MapSettings settings = new MapSettings();
+
+ LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
+ verifyDeactivatedRealm(realm);
+ }
+
+ @Test
+ public void should_not_activate_ldap_if_realm_is_not_ldap() {
+ MapSettings settings = new MapSettings()
+ .setProperty(SONAR_SECURITY_REALM.getKey(), "not_ldap");
+
+ LdapRealm realm = new LdapRealm(new LdapSettingsManager(settings.asConfig()), settings.asConfig());
+ verifyDeactivatedRealm(realm);
+ }
- assertThat(realm.doGetAuthenticator()).isInstanceOf(DefaultLdapAuthenticator.class);
+ private static void verifyRealm(LdapRealm realm) {
+ assertThat(realm.getAuthenticator()).isInstanceOf(DefaultLdapAuthenticator.class);
LdapUsersProvider usersProvider = realm.getUsersProvider();
assertThat(usersProvider).isInstanceOf(LdapUsersProvider.class).isInstanceOf(DefaultLdapUsersProvider.class);
@@ -73,6 +127,15 @@ public class LdapRealmTest {
.isInstanceOf(LdapException.class)
.hasMessage("Unable to retrieve groups for user tester in server with key <default>");
+ assertThat(realm.isLdapAuthActivated()).isTrue();
+ }
+
+ private static void verifyDeactivatedRealm(LdapRealm realm) {
+ assertThat(realm.getAuthenticator()).isNull();
+ assertThat(realm.getUsersProvider()).isNull();
+ assertThat(realm.getGroupsProvider()).isNull();
+ assertThat(realm.isLdapAuthActivated()).isFalse();
+
}
}