Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,43 @@ public List<Class<?>> getCommands() {

@Override
public List<UserOAuth2Authenticator> listUserOAuth2AuthenticationProviders() {
return userOAuth2AuthenticationProviders;
if (userOAuth2AuthenticationProviders == null) {
return userOAuth2AuthenticationProviders;
}
List<UserOAuth2Authenticator> allowed = new ArrayList<>();
for (UserOAuth2Authenticator provider : userOAuth2AuthenticationProviders) {
if (isProviderAllowed(provider.getName())) {
allowed.add(provider);
}
}
return allowed;
}

@Override
public UserOAuth2Authenticator getUserOAuth2AuthenticationProvider(String providerName) {
if (StringUtils.isEmpty(providerName)) {
throw new CloudRuntimeException("OAuth2 authentication provider name is empty");
}
if (!userOAuth2AuthenticationProvidersMap.containsKey(providerName.toLowerCase())) {
if (!userOAuth2AuthenticationProvidersMap.containsKey(providerName.toLowerCase()) || !isProviderAllowed(providerName)) {
throw new CloudRuntimeException(String.format("Failed to find OAuth2 authentication provider by the name: %s.", providerName));
}
return userOAuth2AuthenticationProvidersMap.get(providerName.toLowerCase());
}

// oauth2.plugins is an allow-list: a provider must be named in it to be usable at all.
protected boolean isProviderAllowed(String providerName) {
String allowedPlugins = OAuth2AuthManager.OAuth2Plugins.value();
if (StringUtils.isEmpty(allowedPlugins)) {
return true;
}
for (String allowed : allowedPlugins.trim().split("\\s*,\\s*")) {
if (allowed.equalsIgnoreCase(providerName)) {
return true;
}
}
return false;
}

public List<UserOAuth2Authenticator> getUserOAuth2AuthenticationProviders() {
return userOAuth2AuthenticationProviders;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.cloud.user.DomainService;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.auth.UserOAuth2Authenticator;
import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
import org.apache.cloudstack.oauth2.api.command.DeleteOAuthProviderCmd;
Expand All @@ -49,6 +50,7 @@
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doNothing;
Expand Down Expand Up @@ -525,6 +527,50 @@ public void testGetUserOAuth2AuthenticationProviderNotFound() {
}
}

@Test
public void testGetUserOAuth2AuthenticationProviderRejectsProviderNotInPluginsList() {
UserOAuth2Authenticator googleAuthenticator = Mockito.mock(UserOAuth2Authenticator.class);
OAuth2AuthManagerImpl.userOAuth2AuthenticationProvidersMap.put("google", googleAuthenticator);
try {
Mockito.doReturn(false).when(_authManager).isProviderAllowed("google");

try {
_authManager.getUserOAuth2AuthenticationProvider("google");
Assert.fail("Expected CloudRuntimeException was not thrown");
} catch (CloudRuntimeException e) {
assertTrue(e.getMessage().contains("google"));
}
} finally {
OAuth2AuthManagerImpl.userOAuth2AuthenticationProvidersMap.remove("google");
}
}

@Test
public void testListUserOAuth2AuthenticationProvidersFiltersOutDisallowedPlugins() {
UserOAuth2Authenticator googleAuthenticator = Mockito.mock(UserOAuth2Authenticator.class);
when(googleAuthenticator.getName()).thenReturn("google");
UserOAuth2Authenticator keycloakAuthenticator = Mockito.mock(UserOAuth2Authenticator.class);
when(keycloakAuthenticator.getName()).thenReturn("keycloak");
_authManager.setUserOAuth2AuthenticationProviders(Arrays.asList(googleAuthenticator, keycloakAuthenticator));

Mockito.doReturn(true).when(_authManager).isProviderAllowed("google");
Mockito.doReturn(false).when(_authManager).isProviderAllowed("keycloak");

List<UserOAuth2Authenticator> result = _authManager.listUserOAuth2AuthenticationProviders();

assertEquals(1, result.size());
assertEquals("google", result.get(0).getName());
}

@Test
public void testIsProviderAllowedMatchesConfiguredPluginsListCaseInsensitively() {
// no ConfigDepot is wired in this unit test, so OAuth2Plugins.value() falls back to
// its default of "google,github"
assertTrue(_authManager.isProviderAllowed("google"));
assertTrue(_authManager.isProviderAllowed("Google"));
assertFalse(_authManager.isProviderAllowed("keycloak"));
}

// Multiple-domain OAuth tests

@Test
Expand Down
Loading