aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-server
diff options
context:
space:
mode:
authorEvgeny Mandrikov <mandrikov@gmail.com>2012-01-09 22:55:59 +0400
committerEvgeny Mandrikov <mandrikov@gmail.com>2012-01-10 02:26:54 +0400
commita3509a17ff32da47721d48c59768dacc2e86b3cd (patch)
treeadfcf555497ad222d5dd93306965be182c3d3537 /sonar-server
parentd9b0b6a9bce879a1831b457e75e529d78889db0c (diff)
downloadsonarqube-a3509a17ff32da47721d48c59768dacc2e86b3cd.tar.gz
sonarqube-a3509a17ff32da47721d48c59768dacc2e86b3cd.zip
SONAR-3137,SONAR-2292 Complete API for external security systems
Diffstat (limited to 'sonar-server')
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java4
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorFactory.java123
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorNotFoundException.java4
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/CompatibilityRealm.java52
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/RealmFactory.java121
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb105
-rw-r--r--sonar-server/src/test/java/org/sonar/server/ui/AuthenticatorFactoryTest.java113
-rw-r--r--sonar-server/src/test/java/org/sonar/server/ui/CompatibilityRealmTest.java42
-rw-r--r--sonar-server/src/test/java/org/sonar/server/ui/RealmFactoryTest.java139
9 files changed, 404 insertions, 299 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
index ba055fec7c9..a22f4f9593b 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
@@ -67,9 +67,9 @@ import org.sonar.server.qualitymodel.DefaultModelManager;
import org.sonar.server.rules.ProfilesConsole;
import org.sonar.server.rules.RulesConsole;
import org.sonar.server.startup.*;
-import org.sonar.server.ui.AuthenticatorFactory;
import org.sonar.server.ui.CodeColorizers;
import org.sonar.server.ui.JRubyI18n;
+import org.sonar.server.ui.RealmFactory;
import org.sonar.server.ui.Views;
import javax.servlet.ServletContext;
@@ -193,7 +193,7 @@ public final class Platform {
servicesContainer.addComponent(DefaultRulesManager.class, false);
servicesContainer.addComponent(ProfilesManager.class, false);
servicesContainer.addComponent(Backup.class, false);
- servicesContainer.addSingleton(AuthenticatorFactory.class);
+ servicesContainer.addSingleton(RealmFactory.class);
servicesContainer.addSingleton(ServerLifecycleNotifier.class);
servicesContainer.addSingleton(AnnotationProfileParser.class);
servicesContainer.addSingleton(XMLProfileParser.class);
diff --git a/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorFactory.java b/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorFactory.java
deleted file mode 100644
index 71b567cd00e..00000000000
--- a/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorFactory.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.server.ui;
-
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.config.Settings;
-import org.sonar.api.security.ExternalUsersProvider;
-import org.sonar.api.security.LoginPasswordAuthenticator;
-import org.sonar.api.security.UserDetails;
-
-public class AuthenticatorFactory implements ServerComponent {
-
- private static final Logger LOG = LoggerFactory.getLogger(AuthenticatorFactory.class);
- private static final Logger INFO = LoggerFactory.getLogger("org.sonar.INFO");
-
- private LoginPasswordAuthenticator authenticator = null;
- private String classname;
- private boolean ignoreStartupFailure;
- private LoginPasswordAuthenticator[] authenticators;
-
- public AuthenticatorFactory(Settings settings, LoginPasswordAuthenticator[] authenticators) {
- classname = settings.getString(CoreProperties.CORE_AUTHENTICATOR_CLASS);
- ignoreStartupFailure = settings.getBoolean(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE);
- this.authenticators = authenticators;
- }
-
- /**
- * This constructor is used when there aren't any authentication plugins.
- */
- public AuthenticatorFactory(Settings settings) {
- this(settings, null);
- }
-
- /**
- * Start the authenticator selected in sonar configuration. If no authentication plugin is selected, then
- * the default authentication mechanism is used and null is returned.
- *
- * @throws AuthenticatorNotFoundException if authenticator can not be found
- * @throws RuntimeException if authenticator can not be started
- */
- public void start() {
- // check authentication plugin at startup
- if (StringUtils.isEmpty(classname)) {
- // use sonar internal authenticator
- return;
- }
-
- authenticator = searchAuthenticator();
- if (authenticator == null) {
- LOG.error("Authentication plugin not found. Please check the property '" + CoreProperties.CORE_AUTHENTICATOR_CLASS + "' in conf/sonar.properties");
- throw new AuthenticatorNotFoundException(classname);
- }
-
- try {
- INFO.info("Authentication plugin: class " + classname);
- authenticator.init();
- INFO.info("Authentication plugin started");
-
- } catch (RuntimeException e) {
- if (ignoreStartupFailure) {
- LOG.error("IGNORED - Authentication plugin fails to start: " + e.getMessage());
- } else {
- LOG.error("Authentication plugin fails to start: " + e.getMessage());
- throw e;
- }
- }
- }
-
- public LoginPasswordAuthenticator getAuthenticator() {
- return authenticator;
- }
-
- public ExternalUsersProvider getUsersProvider() {
- if (authenticator != null) {
- if (authenticator instanceof ExternalUsersProvider) {
- return (ExternalUsersProvider) authenticator;
- }
- return new DefaultUsersProvider();
- }
- return null;
- }
-
- private static class DefaultUsersProvider implements ExternalUsersProvider {
- public UserDetails doGetUserDetails(String login) {
- UserDetails result = new UserDetails();
- result.setName(login);
- result.setEmail("");
- return result;
- }
- }
-
- private LoginPasswordAuthenticator searchAuthenticator() {
- if (authenticators != null) {
- for (LoginPasswordAuthenticator lpa : authenticators) {
- if (lpa.getClass().getName().equals(classname)) {
- return lpa;
- }
- }
- }
- return null;
- }
-}
diff --git a/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorNotFoundException.java b/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorNotFoundException.java
index 0e57e6bbfc5..5e22a0b2ad0 100644
--- a/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorNotFoundException.java
+++ b/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorNotFoundException.java
@@ -19,6 +19,10 @@
*/
package org.sonar.server.ui;
+/**
+ * @deprecated in 2.14 and should be removed
+ */
+@Deprecated
public class AuthenticatorNotFoundException extends RuntimeException {
public AuthenticatorNotFoundException(String classname) {
diff --git a/sonar-server/src/main/java/org/sonar/server/ui/CompatibilityRealm.java b/sonar-server/src/main/java/org/sonar/server/ui/CompatibilityRealm.java
new file mode 100644
index 00000000000..0e669791878
--- /dev/null
+++ b/sonar-server/src/main/java/org/sonar/server/ui/CompatibilityRealm.java
@@ -0,0 +1,52 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.server.ui;
+
+import org.sonar.api.CoreProperties;
+import org.sonar.api.security.LoginPasswordAuthenticator;
+import org.sonar.api.security.Realm;
+
+/**
+ * Provides backward compatibility for {@link CoreProperties#CORE_AUTHENTICATOR_CLASS}.
+ *
+ * @since 2.14
+ */
+class CompatibilityRealm extends Realm {
+ private final LoginPasswordAuthenticator authenticator;
+
+ public CompatibilityRealm(LoginPasswordAuthenticator authenticator) {
+ this.authenticator = authenticator;
+ }
+
+ @Override
+ public void init() {
+ authenticator.init();
+ }
+
+ @Override
+ public String getName() {
+ return "CompatibilityRealm[" + authenticator.getClass().getName() + "]";
+ }
+
+ @Override
+ public LoginPasswordAuthenticator getAuthenticator() {
+ return authenticator;
+ }
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/ui/RealmFactory.java b/sonar-server/src/main/java/org/sonar/server/ui/RealmFactory.java
new file mode 100644
index 00000000000..db3614281b3
--- /dev/null
+++ b/sonar-server/src/main/java/org/sonar/server/ui/RealmFactory.java
@@ -0,0 +1,121 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.server.ui;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.config.Settings;
+import org.sonar.api.security.LoginPasswordAuthenticator;
+import org.sonar.api.security.Realm;
+
+/**
+ * @since 2.14
+ */
+public class RealmFactory implements ServerComponent {
+
+ private static final Logger INFO = LoggerFactory.getLogger("org.sonar.INFO");
+ private static final Logger LOG = LoggerFactory.getLogger(RealmFactory.class);
+
+ private final boolean ignoreStartupFailure;
+ private final Realm realm;
+
+ static final String REALM_PROPERTY = "sonar.security.realm";
+
+ public RealmFactory(Settings settings, Realm[] realms, LoginPasswordAuthenticator[] authenticators) {
+ ignoreStartupFailure = settings.getBoolean(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE);
+ String realmName = settings.getString(REALM_PROPERTY);
+ String className = settings.getString(CoreProperties.CORE_AUTHENTICATOR_CLASS);
+ Realm selectedRealm = null;
+ if (!StringUtils.isEmpty(realmName)) {
+ selectedRealm = selectRealm(realms, realmName);
+ if (selectedRealm == null) {
+ LOG.error("Realm not found. Please check the property '" + REALM_PROPERTY + "' in conf/sonar.properties");
+ throw new AuthenticatorNotFoundException(realmName);
+ }
+ }
+ if (selectedRealm == null && !StringUtils.isEmpty(className)) {
+ LoginPasswordAuthenticator authenticator = selectAuthenticator(authenticators, className);
+ if (authenticator == null) {
+ LOG.error("Authenticator plugin not found. Please check the property '" + CoreProperties.CORE_AUTHENTICATOR_CLASS
+ + "' in conf/sonar.properties");
+ throw new AuthenticatorNotFoundException(className);
+ }
+ selectedRealm = new CompatibilityRealm(authenticator);
+ }
+ realm = selectedRealm;
+ }
+
+ public RealmFactory(Settings settings, LoginPasswordAuthenticator[] authenticators) {
+ this(settings, null, authenticators);
+ }
+
+ public RealmFactory(Settings settings, Realm[] realms) {
+ this(settings, realms, null);
+ }
+
+ public RealmFactory(Settings settings) {
+ this(settings, null, null);
+ }
+
+ public void start() {
+ try {
+ INFO.info("Security realm: " + realm.getName());
+ realm.init();
+ INFO.info("Security realm started");
+ } catch (RuntimeException e) {
+ if (ignoreStartupFailure) {
+ LOG.error("IGNORED - Realm fails to start: " + e.getMessage());
+ } else {
+ LOG.error("Realm fails to start: " + e.getMessage());
+ throw e;
+ }
+ }
+ }
+
+ public Realm getRealm() {
+ return realm;
+ }
+
+ private static Realm selectRealm(Realm[] realms, String realmName) {
+ if (realms != null) {
+ for (Realm realm : realms) {
+ if (StringUtils.equals(realmName, realm.getName())) {
+ return realm;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static LoginPasswordAuthenticator selectAuthenticator(LoginPasswordAuthenticator[] authenticators, String className) {
+ if (authenticators != null) {
+ for (LoginPasswordAuthenticator lpa : authenticators) {
+ if (lpa.getClass().getName().equals(className)) {
+ return lpa;
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb b/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb
index e0abde1c172..a24eb6bf9ac 100644
--- a/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/lib/need_authentication.rb
@@ -21,81 +21,70 @@
#
# Use Sonar database (table USERS) to authenticate users.
#
-class DefaultAuthenticator
+class DefaultRealm
def authenticate?(login, password)
return false if login.blank? || password.blank?
- user=User.find_by_login(login)
+ user = User.find_by_login(login)
user && user.authenticated?(password)
end
- def editable_password?
- true
- end
-end
-
-
-#
-# Use an external system to authenticate users, for example LDAP. See the Java extension point org.sonar.api.security.LoginPasswordAuthenticator.
-#
-class PluginAuthenticator
- def initialize(java_authenticator)
- @java_authenticator=java_authenticator
- end
-
- def authenticate?(login, password)
- login.present? && password.present? && @java_authenticator.authenticate(login, password)
+ def synchronize(user, password)
+ # nothing to do
end
def editable_password?
- false
+ true
end
end
#
-# Since 2.14
-# Experimental
-#
-# Use an external system to authenticate users with fallback to Sonar database.
+# Use an external security system with fallback to Sonar database.
+# See the Java extension point org.sonar.api.security.Realm
#
-class FallbackAuthenticator
- def initialize(java_authenticator)
- @java_authenticator = java_authenticator
+class PluginRealm
+ def initialize(java_realm)
+ @java_authenticator = java_realm.getAuthenticator()
+ @java_users_provider = java_realm.getUsersProvider()
end
def authenticate?(login, password)
return false if login.blank? || password.blank?
+ # TODO handle exceptions
if @java_authenticator.authenticate(login, password)
return true
end
- # Fallback to password in Sonar Database
+ # Fallback to password from Sonar Database
user = User.find_by_login(login)
return user && user.authenticated?(password)
end
+ def synchronize(user, password)
+ if @java_users_provider
+ # TODO handle exceptions
+ details = @java_users_provider.doGetUserDetails(user.login)
+ user.update_attributes(:name => details.getName(), :email => details.getEmail(), :password => password, :password_confirmation => password)
+ user.save
+ end
+ end
+
def editable_password?
- true
+ false
end
end
#
-# Load the authentication system to use. The server must be restarted when configuration is changed.
+# Load the realm to use. The server must be restarted when configuration is changed.
#
-class AuthenticatorFactory
- @@authenticator = nil
- @@users_provider = nil
-
- def self.authenticator
- if @@authenticator.nil?
- authenticator_factory=Java::OrgSonarServerUi::JRubyFacade.new.getCoreComponentByClassname('org.sonar.server.ui.AuthenticatorFactory')
- component=authenticator_factory.getAuthenticator()
- @@authenticator=(component ? FallbackAuthenticator.new(component) : DefaultAuthenticator.new)
- @@users_provider = (component ? authenticator_factory.getUsersProvider() : nil)
+class RealmFactory
+ @@realm = nil
+
+ def self.realm
+ if @@realm.nil?
+ realm_factory = Java::OrgSonarServerUi::JRubyFacade.new.getCoreComponentByClassname('org.sonar.server.ui.RealmFactory')
+ component = realm_factory.getRealm()
+ @@realm = component ? PluginRealm.new(component) : DefaultRealm.new
end
- @@authenticator
- end
-
- def self.users_provider
- @@users_provider
+ @@realm
end
end
@@ -131,44 +120,38 @@ module NeedAuthentication
user = User.find_by_login(login)
if user
# User exists
- return nil if !AuthenticatorFactory.authenticator.authenticate?(login, password)
+ return nil if !RealmFactory.realm.authenticate?(login, password)
# Password correct
- users_provider = AuthenticatorFactory.users_provider
- if users_provider
- # Sync details
- details = AuthenticatorFactory.users_provider.doGetUserDetails(login)
- user.update_attributes(:name => details.getName(), :email => details.getEmail(), :password => password, :password_confirmation => password)
- # TODO log if unable to save?
- user.save
- end
+ # Synchronize details
+ RealmFactory.realm.synchronize(user, password)
else
# User not found
- return nil if !AuthenticatorFactory.authenticator.authenticate?(login, password)
+ return nil if !RealmFactory.realm.authenticate?(login, password)
# Password correct
# Automatically create a user in the sonar db if authentication has been successfully done
create_user = java_facade.getSettings().getBoolean('sonar.authenticator.createUsers')
- users_provider = AuthenticatorFactory.users_provider
- if create_user && users_provider
- details = users_provider.doGetUserDetails(login)
- user = User.new(:login => login, :name => details.getName(), :email => details.getEmail(), :password => password, :password_confirmation => password)
+ if create_user
+ user = User.new(:login => login, :name => login, :email => '', :password => password, :password_confirmation => password)
default_group_name = java_facade.getSettings().getString('sonar.defaultGroup')
- default_group=Group.find_by_name(default_group_name)
+ default_group = Group.find_by_name(default_group_name)
if default_group
user.groups<<default_group
user.save
else
logger.error("The default user group does not exist: #{default_group_name}. Please check the parameter 'Default user group' in general settings.")
end
+
+ # Synchronize details
+ RealmFactory.realm.synchronize(user, password)
end
end
-
return user
end
def editable_password?
- AuthenticatorFactory.authenticator.editable_password?
+ RealmFactory.realm.editable_password?
end
end
end
diff --git a/sonar-server/src/test/java/org/sonar/server/ui/AuthenticatorFactoryTest.java b/sonar-server/src/test/java/org/sonar/server/ui/AuthenticatorFactoryTest.java
deleted file mode 100644
index c36aa0f3ddb..00000000000
--- a/sonar-server/src/test/java/org/sonar/server/ui/AuthenticatorFactoryTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.server.ui;
-
-import org.junit.Test;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.api.security.LoginPasswordAuthenticator;
-
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.core.IsNull.nullValue;
-import static org.junit.Assert.assertThat;
-
-public class AuthenticatorFactoryTest {
-
- @Test
- public void doNotFailIfNoAuthenticationPlugins() {
- AuthenticatorFactory factory = new AuthenticatorFactory(new Settings());
- assertThat(factory.getAuthenticator(), nullValue());
- factory.start();
- }
-
- @Test
- public void startSelectedAuthenticator() {
- Settings settings = new Settings();
- settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FakeAuthenticator.class.getName());
-
- LoginPasswordAuthenticator authenticator = new FakeAuthenticator();
- AuthenticatorFactory factory = new AuthenticatorFactory(settings, new LoginPasswordAuthenticator[]{authenticator});
- factory.start();
- assertThat(factory.getAuthenticator(), is(authenticator));
- }
-
- @Test(expected = ConnectionException.class)
- public void authenticatorDoesNotStart() {
- Settings settings = new Settings();
- settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FailAuthenticator.class.getName());
-
- AuthenticatorFactory factory = new AuthenticatorFactory(settings, new LoginPasswordAuthenticator[]{new FakeAuthenticator(), new FailAuthenticator()});
- factory.start();
- factory.getAuthenticator();
- }
-
- @Test(expected = AuthenticatorNotFoundException.class)
- public void authenticatorNotFound() {
- Settings settings = new Settings();
- settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, "foo");
-
- AuthenticatorFactory factory = new AuthenticatorFactory(settings, new LoginPasswordAuthenticator[]{new FakeAuthenticator(), new FailAuthenticator()});
- factory.start();
- factory.getAuthenticator();
- }
-
- @Test(expected = AuthenticatorNotFoundException.class)
- public void noAuthenticators() {
- Settings settings = new Settings();
- settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, "foo");
-
- AuthenticatorFactory factory = new AuthenticatorFactory(settings, null);
- factory.start();
- }
-
- @Test
- public void ignoreStartupFailure() {
- Settings settings = new Settings();
- settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FailAuthenticator.class.getName());
- settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE, Boolean.TRUE);
-
- AuthenticatorFactory factory = new AuthenticatorFactory(settings, new LoginPasswordAuthenticator[]{new FakeAuthenticator(), new FailAuthenticator()});
- factory.start();
- assertThat(factory.getAuthenticator(), not(nullValue()));
- }
-
- static class FakeAuthenticator implements LoginPasswordAuthenticator {
- public void init() {
- }
-
- public boolean authenticate(String login, String password) {
- return false;
- }
- }
-
- static class ConnectionException extends RuntimeException {
- }
-
- static class FailAuthenticator implements LoginPasswordAuthenticator {
- public void init() {
- throw new ConnectionException();
- }
-
- public boolean authenticate(String login, String password) {
- return false;
- }
- }
-}
diff --git a/sonar-server/src/test/java/org/sonar/server/ui/CompatibilityRealmTest.java b/sonar-server/src/test/java/org/sonar/server/ui/CompatibilityRealmTest.java
new file mode 100644
index 00000000000..46c8aa6213b
--- /dev/null
+++ b/sonar-server/src/test/java/org/sonar/server/ui/CompatibilityRealmTest.java
@@ -0,0 +1,42 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.server.ui;
+
+import org.junit.Test;
+import org.sonar.api.security.LoginPasswordAuthenticator;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class CompatibilityRealmTest {
+
+ @Test
+ public void shouldDelegate() {
+ LoginPasswordAuthenticator authenticator = mock(LoginPasswordAuthenticator.class);
+ CompatibilityRealm realm = new CompatibilityRealm(authenticator);
+ realm.init();
+ verify(authenticator).init();
+ assertThat(realm.getAuthenticator(), is(authenticator));
+ assertThat(realm.getName(), is("CompatibilityRealm[" + authenticator.getClass().getName() + "]"));
+ }
+
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/ui/RealmFactoryTest.java b/sonar-server/src/test/java/org/sonar/server/ui/RealmFactoryTest.java
new file mode 100644
index 00000000000..a0436ac9120
--- /dev/null
+++ b/sonar-server/src/test/java/org/sonar/server/ui/RealmFactoryTest.java
@@ -0,0 +1,139 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.server.ui;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.config.Settings;
+import org.sonar.api.security.LoginPasswordAuthenticator;
+import org.sonar.api.security.Realm;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+public class RealmFactoryTest {
+
+ private Settings settings;
+
+ @Before
+ public void setUp() {
+ settings = new Settings();
+ }
+
+ /**
+ * Typical usage.
+ */
+ @Test
+ public void shouldSelectRealmAndStart() {
+ Realm realm = spy(new FakeRealm());
+ settings.setProperty(RealmFactory.REALM_PROPERTY, realm.getName());
+
+ RealmFactory factory = new RealmFactory(settings, new Realm[] {realm});
+ factory.start();
+ assertThat(factory.getRealm(), is(realm));
+ verify(realm).init();
+ }
+
+ @Test
+ public void doNotFailIfNoRealms() {
+ RealmFactory factory = new RealmFactory(settings);
+ assertThat(factory.getRealm(), nullValue());
+ }
+
+ @Test(expected = AuthenticatorNotFoundException.class)
+ public void realmNotFound() {
+ settings.setProperty(RealmFactory.REALM_PROPERTY, "Fake");
+
+ new RealmFactory(settings);
+ }
+
+ @Test
+ public void shouldProvideCompatibilityForAuthenticator() {
+ settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FakeAuthenticator.class.getName());
+ LoginPasswordAuthenticator authenticator = new FakeAuthenticator();
+
+ RealmFactory factory = new RealmFactory(settings, new LoginPasswordAuthenticator[] {authenticator});
+ Realm realm = factory.getRealm();
+ assertThat(realm, instanceOf(CompatibilityRealm.class));
+ }
+
+ @Test
+ public void shouldTakePrecedenceOverAuthenticator() {
+ Realm realm = new FakeRealm();
+ settings.setProperty(RealmFactory.REALM_PROPERTY, realm.getName());
+ LoginPasswordAuthenticator authenticator = new FakeAuthenticator();
+ settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FakeAuthenticator.class.getName());
+
+ RealmFactory factory = new RealmFactory(settings, new Realm[] {realm}, new LoginPasswordAuthenticator[] {authenticator});
+ assertThat(factory.getRealm(), is(realm));
+ }
+
+ @Test(expected = AuthenticatorNotFoundException.class)
+ public void authenticatorNotFound() {
+ settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, "Fake");
+
+ new RealmFactory(settings);
+ }
+
+ @Test
+ public void ignoreStartupFailure() {
+ Realm realm = spy(new AlwaysFailsRealm());
+ settings.setProperty(RealmFactory.REALM_PROPERTY, realm.getName());
+ settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE, true);
+
+ new RealmFactory(settings, new Realm[] {realm}).start();
+ verify(realm).init();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void shouldFail() {
+ Realm realm = spy(new AlwaysFailsRealm());
+ settings.setProperty(RealmFactory.REALM_PROPERTY, realm.getName());
+
+ new RealmFactory(settings, new Realm[] {realm}).start();
+ }
+
+ private static class AlwaysFailsRealm extends FakeRealm {
+ @Override
+ public void init() {
+ throw new IllegalStateException();
+ }
+ }
+
+ private static class FakeRealm extends Realm {
+ @Override
+ public LoginPasswordAuthenticator getAuthenticator() {
+ return null;
+ }
+ }
+
+ private static class FakeAuthenticator implements LoginPasswordAuthenticator {
+ public void init() {
+ }
+
+ public boolean authenticate(String login, String password) {
+ return false;
+ }
+ }
+
+}