This is an automated email from the ASF dual-hosted git repository.
RosiKyu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new 7ccc48ca6d6 OAuthProvider: add param enabled in register API (#13889)
7ccc48ca6d6 is described below
commit 7ccc48ca6d6d78d78607b114443f7fc3179c61ce
Author: René Moser <[email protected]>
AuthorDate: Thu Nov 12 16:42:53 2026 +0100
OAuthProvider: add param enabled in register API (#13889)
* OAuthProvider: add param enable in register API
this allows to created a provider disabled.
* 4.24.0 --> 24.0.0
* default early
* add NPE safeguard
---
.../cloudstack/oauth2/OAuth2AuthManagerImpl.java | 8 ++++--
.../api/command/RegisterOAuthProviderCmd.java | 29 ++++++++++++++++++++
.../oauth2/OAuth2AuthManagerImplTest.java | 24 ++++++++++++++++
.../api/command/RegisterOAuthProviderCmdTest.java | 32 +++++++++++++++++++++-
4 files changed, 89 insertions(+), 4 deletions(-)
diff --git
a/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/OAuth2AuthManagerImpl.java
b/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/OAuth2AuthManagerImpl.java
index c3bad43be40..7fc1df00955 100644
---
a/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/OAuth2AuthManagerImpl.java
+++
b/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/OAuth2AuthManagerImpl.java
@@ -168,6 +168,7 @@ public class OAuth2AuthManagerImpl extends ManagerBase
implements OAuth2AuthMana
Long domainId =
normalizeGlobalScope(resolveDomainIdFromIdOrPath(cmd.getDomainId(),
cmd.getDomainPath()));
String authorizeUrl = StringUtils.trim(cmd.getAuthorizeUrl());
String tokenUrl = StringUtils.trim(cmd.getTokenUrl());
+ Boolean enabled = cmd.getEnabled();
if (!isOAuthPluginEnabled(domainId)) {
throw new CloudRuntimeException("OAuth is not enabled, please
enable to register");
@@ -183,7 +184,7 @@ public class OAuth2AuthManagerImpl extends ManagerBase
implements OAuth2AuthMana
}
}
- return saveOauthProvider(provider, description, clientId, secretKey,
redirectUri, authorizeUrl, tokenUrl, domainId);
+ return saveOauthProvider(provider, description, clientId, secretKey,
redirectUri, authorizeUrl, tokenUrl, domainId, enabled);
}
@Override
@@ -271,7 +272,7 @@ public class OAuth2AuthManagerImpl extends ManagerBase
implements OAuth2AuthMana
return _oauthProviderDao.findById(id);
}
- private OauthProviderVO saveOauthProvider(String provider, String
description, String clientId, String secretKey, String redirectUri, String
authorizeUrl, String tokenUrl, Long domainId) {
+ private OauthProviderVO saveOauthProvider(String provider, String
description, String clientId, String secretKey, String redirectUri, String
authorizeUrl, String tokenUrl, Long domainId, Boolean enabled) {
final OauthProviderVO oauthProviderVO = new OauthProviderVO();
oauthProviderVO.setProvider(provider);
@@ -282,7 +283,8 @@ public class OAuth2AuthManagerImpl extends ManagerBase
implements OAuth2AuthMana
oauthProviderVO.setDomainId(domainId);
oauthProviderVO.setAuthorizeUrl(authorizeUrl);
oauthProviderVO.setTokenUrl(tokenUrl);
- oauthProviderVO.setEnabled(true);
+ // If enabled is null, default to true (enabled), NPE safeguard for
Boolean unboxing
+ oauthProviderVO.setEnabled(enabled == null || enabled);
_oauthProviderDao.persist(oauthProviderVO);
diff --git
a/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmd.java
b/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmd.java
index 956e6fca00a..12d3bc641c5 100644
---
a/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmd.java
+++
b/plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmd.java
@@ -14,7 +14,9 @@
// limitations under the License.
package org.apache.cloudstack.oauth2.api.command;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import javax.inject.Inject;
@@ -28,6 +30,7 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.auth.UserOAuth2Authenticator;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.oauth2.OAuth2AuthManager;
import org.apache.cloudstack.oauth2.api.response.OauthProviderResponse;
@@ -76,6 +79,9 @@ public class RegisterOAuthProviderCmd extends BaseCmd {
@Parameter(name = ApiConstants.TOKEN_URL, type = CommandType.STRING,
description = "Token URL for OAuth finalization (only required for keycloak
provider)", since = "4.23.0")
private String tokenUrl;
+ @Parameter(name = ApiConstants.ENABLED, type = CommandType.BOOLEAN,
description = "OAuth provider will be enabled or disabled based on this value,
defaults to true if not specified", since = "24.0.0")
+ private Boolean enabled;
+
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP,
description = "Any OAuth provider details in key/value pairs using
format details[i].keyname=keyvalue. Example:
details[0].clientsecret=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")
protected Map details;
@@ -121,6 +127,13 @@ public class RegisterOAuthProviderCmd extends BaseCmd {
return tokenUrl;
}
+ public Boolean getEnabled() {
+ if (enabled == null) {
+ enabled = true; // default to enabled if not specified
+ }
+ return enabled;
+ }
+
public Map getDetails() {
if (MapUtils.isEmpty(details)) {
return null;
@@ -151,6 +164,22 @@ public class RegisterOAuthProviderCmd extends BaseCmd {
provider.getAuthorizeUrl(), provider.getTokenUrl(), domain);
response.setResponseName(getCommandName());
response.setObjectName(ApiConstants.OAUTH_PROVIDER);
+
+ List<UserOAuth2Authenticator> userOAuth2AuthenticatorPlugins =
_oauth2mgr.listUserOAuth2AuthenticationProviders();
+ List<String> authenticatorPluginNames = new ArrayList<>();
+
+ for (UserOAuth2Authenticator authenticator :
userOAuth2AuthenticatorPlugins) {
+ String name = authenticator.getName();
+ authenticatorPluginNames.add(name);
+ }
+
+ boolean oauthEnabled =
OAuth2AuthManager.isPluginEnabledForDomain(provider.getDomainId());
+ if (oauthEnabled &&
authenticatorPluginNames.contains(provider.getProvider()) &&
provider.isEnabled()) {
+ response.setEnabled(true);
+ } else {
+ response.setEnabled(false);
+ }
+
setResponseObject(response);
}
}
diff --git
a/plugins/user-authenticators/oauth2/src/test/java/org/apache/cloudstack/oauth2/OAuth2AuthManagerImplTest.java
b/plugins/user-authenticators/oauth2/src/test/java/org/apache/cloudstack/oauth2/OAuth2AuthManagerImplTest.java
index e3e8f7594b3..ffbfa6db621 100644
---
a/plugins/user-authenticators/oauth2/src/test/java/org/apache/cloudstack/oauth2/OAuth2AuthManagerImplTest.java
+++
b/plugins/user-authenticators/oauth2/src/test/java/org/apache/cloudstack/oauth2/OAuth2AuthManagerImplTest.java
@@ -49,6 +49,7 @@ import java.util.List;
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;
@@ -120,6 +121,29 @@ public class OAuth2AuthManagerImplTest {
assertEquals("testSecretKey", result.getSecretKey());
}
+ @Test
+ public void testRegisterOauthProviderDisabledWhenRequested() {
+
when(_authManager.isOAuthPluginEnabled(Mockito.nullable(Long.class))).thenReturn(true);
+
+ RegisterOAuthProviderCmd cmd =
Mockito.mock(RegisterOAuthProviderCmd.class);
+ when(cmd.getDescription()).thenReturn("test description");
+ when(cmd.getProvider()).thenReturn("github");
+ when(cmd.getClientId()).thenReturn("client-id");
+ when(cmd.getSecretKey()).thenReturn("secret-key");
+ when(cmd.getRedirectUri()).thenReturn("http://localhost");
+ when(cmd.getAuthorizeUrl()).thenReturn("https://auth.example.com");
+ when(cmd.getTokenUrl()).thenReturn("https://token.example.com");
+ when(cmd.getDomainId()).thenReturn(null);
+ when(cmd.getDomainPath()).thenReturn(null);
+ when(cmd.getEnabled()).thenReturn(false);
+ when(_authManager._oauthProviderDao.findByProviderAndDomain("github",
null)).thenReturn(null);
+
when(_authManager._oauthProviderDao.persist(Mockito.any(OauthProviderVO.class))).thenAnswer(i
-> i.getArgument(0));
+
+ OauthProviderVO result = _authManager.registerOauthProvider(cmd);
+
+ assertFalse(result.isEnabled());
+ }
+
@Test
public void testUpdateOauthProvider() {
Long id = 1L;
diff --git
a/plugins/user-authenticators/oauth2/src/test/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmdTest.java
b/plugins/user-authenticators/oauth2/src/test/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmdTest.java
index 7e1a96e0c1e..9a98cdf9730 100644
---
a/plugins/user-authenticators/oauth2/src/test/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmdTest.java
+++
b/plugins/user-authenticators/oauth2/src/test/java/org/apache/cloudstack/oauth2/api/command/RegisterOAuthProviderCmdTest.java
@@ -20,12 +20,16 @@
package org.apache.cloudstack.oauth2.api.command;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import java.util.Collections;
+
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.auth.UserOAuth2Authenticator;
import org.apache.cloudstack.oauth2.OAuth2AuthManager;
import org.apache.cloudstack.oauth2.api.response.OauthProviderResponse;
import org.apache.cloudstack.oauth2.vo.OauthProviderVO;
@@ -38,7 +42,7 @@ public class RegisterOAuthProviderCmdTest {
private RegisterOAuthProviderCmd _cmd;
@Before
- public void setUp() throws Exception {
+ public void setUp() {
_oauth2mgr = mock(OAuth2AuthManager.class);
_cmd = new RegisterOAuthProviderCmd();
_cmd._oauth2mgr = _oauth2mgr;
@@ -54,9 +58,35 @@ public class RegisterOAuthProviderCmdTest {
when(provider.getClientId()).thenReturn("client-id");
when(provider.getSecretKey()).thenReturn("secret-key");
when(provider.getRedirectUri()).thenReturn("http://localhost");
+ when(provider.isEnabled()).thenReturn(true);
when(_oauth2mgr.registerOauthProvider(any(RegisterOAuthProviderCmd.class))).thenReturn(provider);
+ UserOAuth2Authenticator authenticator =
mock(UserOAuth2Authenticator.class);
+ when(authenticator.getName()).thenReturn("github");
+
when(_oauth2mgr.listUserOAuth2AuthenticationProviders()).thenReturn(Collections.singletonList(authenticator));
_cmd.execute();
assertEquals(ApiConstants.OAUTH_PROVIDER,
((OauthProviderResponse)_cmd.getResponseObject()).getObjectName());
}
+
+ @Test
+ public void
testExecuteSetsDisabledProviderResponseWhenProviderIsDisabled() throws
ServerApiException {
+ OauthProviderVO provider = mock(OauthProviderVO.class);
+ when(provider.getDomainId()).thenReturn(null);
+ when(provider.getUuid()).thenReturn("test-uuid");
+ when(provider.getProvider()).thenReturn("github");
+ when(provider.getDescription()).thenReturn("test");
+ when(provider.getClientId()).thenReturn("client-id");
+ when(provider.getSecretKey()).thenReturn("secret-key");
+ when(provider.getRedirectUri()).thenReturn("http://localhost");
+ when(provider.isEnabled()).thenReturn(false);
+
when(_oauth2mgr.registerOauthProvider(any(RegisterOAuthProviderCmd.class))).thenReturn(provider);
+ UserOAuth2Authenticator authenticator =
mock(UserOAuth2Authenticator.class);
+ when(authenticator.getName()).thenReturn("github");
+
when(_oauth2mgr.listUserOAuth2AuthenticationProviders()).thenReturn(Collections.singletonList(authenticator));
+
+ _cmd.execute();
+ OauthProviderResponse response =
(OauthProviderResponse)_cmd.getResponseObject();
+ assertEquals(ApiConstants.OAUTH_PROVIDER, response.getObjectName());
+ assertFalse(response.getEnabled());
+ }
}