From beb8d4cc840962e5581bb8ae3f3ca4717befcd6b Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Mon, 9 Jan 2012 11:22:51 +0400 Subject: [PATCH] SONAR-3137 Add experimental API to retrieve users from external system --- .../api/security/ExternalUsersProvider.java | 34 ++++++++++++ .../org/sonar/api/security/UserDetails.java | 54 +++++++++++++++++++ .../sonar/server/ui/AuthenticatorFactory.java | 21 ++++++++ .../webapp/WEB-INF/lib/need_authentication.rb | 53 ++++++++++++------ 4 files changed, 147 insertions(+), 15 deletions(-) create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/security/ExternalUsersProvider.java create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/security/UserDetails.java diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/security/ExternalUsersProvider.java b/sonar-plugin-api/src/main/java/org/sonar/api/security/ExternalUsersProvider.java new file mode 100644 index 00000000000..8df4d27ea92 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/security/ExternalUsersProvider.java @@ -0,0 +1,34 @@ +/* + * 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.api.security; + +import org.sonar.api.ServerExtension; + +import com.google.common.annotations.Beta; + +/** + * @since 2.14 + */ +@Beta +public interface ExternalUsersProvider extends ServerExtension { + + UserDetails doGetUserDetails(String login); + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/security/UserDetails.java b/sonar-plugin-api/src/main/java/org/sonar/api/security/UserDetails.java new file mode 100644 index 00000000000..f383aafaa4e --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/security/UserDetails.java @@ -0,0 +1,54 @@ +/* + * 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.api.security; + +import com.google.common.annotations.Beta; + +/** + * This class is not intended to be subclassed by clients. + * + * @since 2.14 + */ +@Beta +public class UserDetails { + + private String name; + private String email; + + public UserDetails() { + } + + public void setEmail(String email) { + this.email = email; + } + + public String getEmail() { + return email; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} 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 index 66b000000cb..71b567cd00e 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorFactory.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/AuthenticatorFactory.java @@ -25,7 +25,9 @@ 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 { @@ -89,6 +91,25 @@ public class AuthenticatorFactory implements ServerComponent { 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) { 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 41b86d24bc7..e0abde1c172 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 @@ -82,15 +82,21 @@ end # 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) end @@authenticator end + + def self.users_provider + @@users_provider + end end @@ -122,26 +128,43 @@ module NeedAuthentication login = login.downcase end - return nil if !AuthenticatorFactory.authenticator.authenticate?(login, password) user = User.find_by_login(login) - - # Automatically create a user in the sonar db if authentication has been successfully done - create_user = java_facade.getSettings().getBoolean('sonar.authenticator.createUsers') - if !user && create_user - user=User.new(:login => login, :name => login, :email => '', :password => password, :password_confirmation => password) - user.save! - - default_group_name = java_facade.getSettings().getString('sonar.defaultGroup') - default_group=Group.find_by_name(default_group_name) - if default_group - user.groups< details.getName(), :email => details.getEmail(), :password => password, :password_confirmation => password) + # TODO log if unable to save? 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 + else + # User not found + return nil if !AuthenticatorFactory.authenticator.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) + default_group_name = java_facade.getSettings().getString('sonar.defaultGroup') + default_group=Group.find_by_name(default_group_name) + if default_group + user.groups<