mirror of
https://github.com/SonarSource/sonarqube.git
synced 2024-08-07 15:05:55 +02:00
SONAR-6856 : Add a new API ExternalGroupsProvider.doGetGroups(Context context) to allow plugins to pass groups information to SonarQube
Addition of one more api in ExternalGroupsProvider which will pass Context as parameter . doGetGroups(String username) is marked as deprecated Default implementation is provided in both version of doGetGroups so that authentication plugin relying on previous version ( <5.2) and current version 5.2 do not face compact issue on the SonarQube server 5.2 Testing: 1. Unit test for ExternalGroupsProvider is added. 2. Testing of authentication plugin (e.g. LDAP) targeting SonarQube Plugin apis version < 5.2 working with SonarQube server 5.2 3. Testing of LDAP plugin with SSO changes which are tareting SonarQube plugin api version 5.2 working with SonarQube server 5.2
This commit is contained in:
parent
c769d5e095
commit
271e2cde31
@ -76,7 +76,7 @@ class PluginRealm
|
||||
if @java_authenticator
|
||||
context = org.sonar.api.security.Authenticator::Context.new(username, password, servlet_request)
|
||||
status = @java_authenticator.doAuthenticate(context)
|
||||
status ? synchronize(username, password, details) : nil
|
||||
status ? synchronize(username, password, details, servlet_request) : nil
|
||||
else
|
||||
# No authenticator
|
||||
nil
|
||||
@ -114,7 +114,7 @@ class PluginRealm
|
||||
# Authentication in external system was successful - replicate password, details and groups into Sonar
|
||||
# Return the user.
|
||||
#
|
||||
def synchronize(username, password, details)
|
||||
def synchronize(username, password, details, servlet_request)
|
||||
username=details.getName() if username.blank? && details
|
||||
user = User.find_by_login(username)
|
||||
|
||||
@ -159,7 +159,7 @@ class PluginRealm
|
||||
# Note that validation disabled
|
||||
user.save(false)
|
||||
|
||||
synchronize_groups(user)
|
||||
synchronize_groups(user, servlet_request)
|
||||
# Note that validation disabled
|
||||
user.save(false)
|
||||
end
|
||||
@ -172,10 +172,11 @@ class PluginRealm
|
||||
user
|
||||
end
|
||||
|
||||
def synchronize_groups(user)
|
||||
def synchronize_groups(user, servlet_request)
|
||||
if @java_groups_provider
|
||||
begin
|
||||
groups = @java_groups_provider.doGetGroups(user.login)
|
||||
provider_context = org.sonar.api.security.ExternalGroupsProvider::Context.new(user.login, servlet_request)
|
||||
groups = @java_groups_provider.doGetGroups(provider_context)
|
||||
rescue Exception => e
|
||||
Rails.logger.error("Error from external groups provider: #{e.message}")
|
||||
else
|
||||
|
@ -20,19 +20,52 @@
|
||||
package org.sonar.api.security;
|
||||
|
||||
import java.util.Collection;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* Note that prefix "do" for names of methods is reserved for future enhancements, thus should not be used in subclasses.
|
||||
*
|
||||
* @since 2.14
|
||||
* @see SecurityRealm
|
||||
* @since 2.14
|
||||
*/
|
||||
public abstract class ExternalGroupsProvider {
|
||||
|
||||
/**
|
||||
* @return list of groups associated with specified user, or null if such user doesn't exist
|
||||
* @throws RuntimeException in case of unexpected error such as connection failure
|
||||
* @deprecated replaced by {@link #doGetGroups(org.sonar.api.security.ExternalGroupsProvider.Context)} since v. 5.2
|
||||
*/
|
||||
public abstract Collection<String> doGetGroups(String username);
|
||||
@Deprecated
|
||||
public Collection<String> doGetGroups(String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method in order to load user group information.
|
||||
*
|
||||
* @return list of groups associated with specified user, or null if such user doesn't exist
|
||||
* @throws RuntimeException in case of unexpected error such as connection failure
|
||||
* @since 5.2
|
||||
*/
|
||||
public Collection<String> doGetGroups(Context context) {
|
||||
return doGetGroups(context.getUsername());
|
||||
}
|
||||
|
||||
public static final class Context {
|
||||
private String username;
|
||||
private HttpServletRequest request;
|
||||
|
||||
public Context(String username, HttpServletRequest request) {
|
||||
this.username = username;
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public HttpServletRequest getRequest() {
|
||||
return request;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* SonarQube, open source software quality management tool.
|
||||
* Copyright (C) 2008-2014 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* SonarQube 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.
|
||||
*
|
||||
* SonarQube 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 this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package org.sonar.api.security;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class ExternalGroupsProviderTest {
|
||||
@Test
|
||||
public void doGetGroupsNoOverride() {
|
||||
ExternalGroupsProvider groupsProvider = new ExternalGroupsProvider() {
|
||||
};
|
||||
|
||||
String userName = "foo";
|
||||
assertThat(groupsProvider.doGetGroups(userName)).isNull();
|
||||
assertThat(groupsProvider.doGetGroups(new ExternalGroupsProvider.Context(userName,
|
||||
mock(HttpServletRequest.class)))).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doGetGroupsTests() {
|
||||
final Map<String, Collection<String>> userGroupsMap = getTestUserGroupMapping();
|
||||
|
||||
ExternalGroupsProvider groupsProvider = new ExternalGroupsProvider() {
|
||||
@Override
|
||||
public Collection<String> doGetGroups(Context context) {
|
||||
Preconditions.checkNotNull(context.getUsername());
|
||||
Preconditions.checkNotNull(context.getRequest());
|
||||
|
||||
return userGroupsMap.get(context.getUsername());
|
||||
}
|
||||
};
|
||||
|
||||
runDoGetGroupsTests(groupsProvider, userGroupsMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doGetGroupsDeprecatedApi() {
|
||||
final Map<String, Collection<String>> userGroupsMap = getTestUserGroupMapping();
|
||||
|
||||
ExternalGroupsProvider groupsProvider = new ExternalGroupsProvider() {
|
||||
@Override
|
||||
public Collection<String> doGetGroups(String username) {
|
||||
Preconditions.checkNotNull(username);
|
||||
|
||||
return userGroupsMap.get(username);
|
||||
}
|
||||
};
|
||||
|
||||
runDoGetGroupsTests(groupsProvider, userGroupsMap);
|
||||
}
|
||||
|
||||
private static void runDoGetGroupsTests(ExternalGroupsProvider groupsProvider, Map<String, Collection<String>> userGroupsMap) {
|
||||
for (Map.Entry<String, Collection<String>> userGroupMapEntry : userGroupsMap.entrySet()) {
|
||||
Collection<String> groups = groupsProvider.doGetGroups(new ExternalGroupsProvider.Context(
|
||||
userGroupMapEntry.getKey(), mock(HttpServletRequest.class)));
|
||||
assertThat(groups).isEqualTo(userGroupMapEntry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, Collection<String>> getTestUserGroupMapping() {
|
||||
Map<String, Collection<String>> userGroupsMap = new HashMap<String, Collection<String>>();
|
||||
addUserGroupMapping(userGroupsMap, "userWithOneGroups", new String[] {"group1"});
|
||||
addUserGroupMapping(userGroupsMap, "userWithTwoGroups", new String[] {"group1", "group2"});
|
||||
addUserGroupMapping(userGroupsMap, "userWithNoGroup", new String[] {});
|
||||
addUserGroupMapping(userGroupsMap, "userWithNullGroup", null);
|
||||
|
||||
return userGroupsMap;
|
||||
}
|
||||
|
||||
private static void addUserGroupMapping(Map<String, Collection<String>> userGroupsMap, String user, @Nullable String[] groups) {
|
||||
Collection<String> groupsCollection = null;
|
||||
if (groups != null) {
|
||||
groupsCollection = new ArrayList<String>();
|
||||
groupsCollection.addAll(Arrays.asList(groups));
|
||||
}
|
||||
|
||||
userGroupsMap.put(user, groupsCollection);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user