Skip to content

Commit 62d4fc3

Browse files
committed
Add domain-scoped provider filtering to listOauthProvider and centralize domain resolution in OAuth2AuthManager
1 parent 57c837c commit 62d4fc3

4 files changed

Lines changed: 75 additions & 57 deletions

File tree

plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/OAuth2AuthManager.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@
2727
import org.apache.cloudstack.oauth2.vo.OauthProviderVO;
2828

2929
import java.util.List;
30+
import java.util.Map;
3031

3132
public interface OAuth2AuthManager extends PluggableAPIAuthenticator, PluggableService {
33+
String GLOBAL_DOMAIN_FILTER = "-1";
34+
Long GLOBAL_DOMAIN_ID = -1L;
35+
3236
public static ConfigKey<Boolean> OAuth2IsPluginEnabled = new ConfigKey<Boolean>("Advanced", Boolean.class, "oauth2.enabled", "false",
3337
"Indicates whether OAuth plugin is enabled or not. Can be configured at domain level.", true, ConfigKey.Scope.Domain);
3438
public static final ConfigKey<String> OAuth2Plugins = new ConfigKey<String>("Advanced", String.class, "oauth2.plugins", "google,github",
@@ -58,4 +62,6 @@ public interface OAuth2AuthManager extends PluggableAPIAuthenticator, PluggableS
5862
boolean deleteOauthProvider(Long id);
5963

6064
OauthProviderVO updateOauthProvider(UpdateOAuthProviderCmd cmd);
65+
66+
Long resolveDomainId(Map<String, Object[]> params);
6167
}

plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/OAuth2AuthManagerImpl.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818
//
1919
package org.apache.cloudstack.oauth2;
2020

21+
import com.cloud.domain.DomainVO;
22+
import com.cloud.domain.dao.DomainDao;
2123
import com.cloud.user.dao.UserDao;
2224
import com.cloud.utils.component.Manager;
2325
import com.cloud.utils.component.ManagerBase;
2426
import com.cloud.utils.exception.CloudRuntimeException;
27+
import org.apache.cloudstack.api.ApiConstants;
2528
import org.apache.cloudstack.auth.UserOAuth2Authenticator;
2629
import org.apache.cloudstack.framework.config.ConfigKey;
2730
import org.apache.cloudstack.framework.config.Configurable;
@@ -35,12 +38,15 @@
3538
import org.apache.cloudstack.oauth2.vo.OauthProviderVO;
3639
import org.apache.commons.lang3.StringUtils;
3740

41+
import org.apache.commons.lang3.ArrayUtils;
42+
3843
import javax.inject.Inject;
3944
import java.util.ArrayList;
4045
import java.util.Collections;
4146
import java.util.HashMap;
4247
import java.util.List;
4348
import java.util.Map;
49+
import java.util.Objects;
4450

4551
public class OAuth2AuthManagerImpl extends ManagerBase implements OAuth2AuthManager, Manager, Configurable {
4652
@Inject
@@ -49,6 +55,9 @@ public class OAuth2AuthManagerImpl extends ManagerBase implements OAuth2AuthMana
4955
@Inject
5056
protected OauthProviderDao _oauthProviderDao;
5157

58+
@Inject
59+
private DomainDao _domainDao;
60+
5261
protected static Map<String, UserOAuth2Authenticator> userOAuth2AuthenticationProvidersMap = new HashMap<>();
5362

5463
private List<UserOAuth2Authenticator> userOAuth2AuthenticationProviders;
@@ -227,6 +236,38 @@ public boolean deleteOauthProvider(Long id) {
227236
return _oauthProviderDao.remove(id);
228237
}
229238

239+
@Override
240+
public Long resolveDomainId(Map<String, Object[]> params) {
241+
final String[] domainIdArray = (String[])params.get(ApiConstants.DOMAIN_ID);
242+
if (ArrayUtils.isNotEmpty(domainIdArray)) {
243+
String domainUuid = domainIdArray[0];
244+
if (GLOBAL_DOMAIN_FILTER.equals(domainUuid)) {
245+
return GLOBAL_DOMAIN_ID;
246+
}
247+
DomainVO domain = _domainDao.findByUuid(domainUuid);
248+
if (Objects.nonNull(domain)) {
249+
return domain.getId();
250+
}
251+
}
252+
final String[] domainArray = (String[])params.get(ApiConstants.DOMAIN);
253+
if (ArrayUtils.isNotEmpty(domainArray)) {
254+
String path = domainArray[0];
255+
if (StringUtils.isNotEmpty(path)) {
256+
if (!path.startsWith("/")) {
257+
path = "/" + path;
258+
}
259+
if (!path.endsWith("/")) {
260+
path += "/";
261+
}
262+
DomainVO domain = _domainDao.findDomainByPath(path);
263+
if (Objects.nonNull(domain)) {
264+
return domain.getId();
265+
}
266+
}
267+
}
268+
return null;
269+
}
270+
230271
@Override
231272
public String getConfigComponentName() {
232273
return "OAUTH2-PLUGIN";

plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/ListOAuthProvidersCmd.java

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,11 @@
2020
import java.util.ArrayList;
2121
import java.util.List;
2222
import java.util.Map;
23-
import java.util.Objects;
2423

2524
import com.cloud.api.response.ApiResponseSerializer;
2625
import com.cloud.api.ApiDBUtils;
2726
import com.cloud.domain.Domain;
28-
import com.cloud.domain.dao.DomainDao;
2927
import com.cloud.user.Account;
30-
import com.cloud.utils.component.ComponentContext;
3128
import org.apache.cloudstack.acl.RoleType;
3229
import org.apache.cloudstack.api.APICommand;
3330
import org.apache.cloudstack.api.ApiConstants;
@@ -45,7 +42,7 @@
4542
import org.apache.cloudstack.oauth2.OAuth2AuthManager;
4643
import org.apache.cloudstack.oauth2.api.response.OauthProviderResponse;
4744
import org.apache.cloudstack.oauth2.vo.OauthProviderVO;
48-
import org.apache.commons.lang.ArrayUtils;
45+
import org.apache.commons.lang3.ArrayUtils;
4946

5047
import javax.servlet.http.HttpServletRequest;
5148
import javax.servlet.http.HttpServletResponse;
@@ -70,6 +67,10 @@ public class ListOAuthProvidersCmd extends BaseListCmd implements APIAuthenticat
7067
description = "List OAuth providers for a specific domain. Use -1 for global providers only.")
7168
private Long domainId;
7269

70+
@Parameter(name = ApiConstants.DOMAIN, type = CommandType.STRING,
71+
description = "Domain path for domain-specific OAuth provider lookup")
72+
private String domainPath;
73+
7374
/////////////////////////////////////////////////////
7475
/////////////////// Accessors ///////////////////////
7576
/////////////////////////////////////////////////////
@@ -91,8 +92,6 @@ public Long getDomainId() {
9192

9293
OAuth2AuthManager _oauth2mgr;
9394

94-
DomainDao _domainDao;
95-
9695
@Override
9796
public long getEntityOwnerId() {
9897
return Account.Type.NORMAL.ordinal();
@@ -114,20 +113,26 @@ public String authenticate(String command, Map<String, Object[]> params, HttpSes
114113
if (ArrayUtils.isNotEmpty(providerArray)) {
115114
provider = providerArray[0];
116115
}
117-
final String[] domainIdArray = (String[])params.get(ApiConstants.DOMAIN_ID);
118-
if (ArrayUtils.isNotEmpty(domainIdArray)) {
119-
String domainUuid = domainIdArray[0];
120-
if ("-1".equals(domainUuid)) {
121-
domainId = -1L; // Special case for global-only filter
122-
} else {
123-
Domain domain = _domainDao.findByUuid(domainUuid);
124-
if (Objects.nonNull(domain)) {
125-
domainId = domain.getId();
126-
}
127-
}
116+
117+
boolean domainRequested = ArrayUtils.isNotEmpty((String[])params.get(ApiConstants.DOMAIN_ID))
118+
|| ArrayUtils.isNotEmpty((String[])params.get(ApiConstants.DOMAIN));
119+
domainId = resolveDomainId(params);
120+
121+
if (domainRequested && domainId == null) {
122+
ListResponse<OauthProviderResponse> response = new ListResponse<>();
123+
response.setResponses(new ArrayList<>(), 0);
124+
response.setResponseName(getCommandName());
125+
setResponseObject(response);
126+
return ApiResponseSerializer.toSerializedString(response, responseType);
128127
}
129128

130129
List<OauthProviderVO> resultList = _oauth2mgr.listOauthProviders(provider, id, domainId);
130+
if (domainRequested && domainId != null && domainId > 0) {
131+
resultList.removeIf(p -> p.getDomainId() == null);
132+
} else if (!domainRequested) {
133+
resultList.removeIf(p -> p.getDomainId() != null);
134+
}
135+
131136
List<UserOAuth2Authenticator> userOAuth2AuthenticatorPlugins = _oauth2mgr.listUserOAuth2AuthenticationProviders();
132137
List<String> authenticatorPluginNames = new ArrayList<>();
133138
for (UserOAuth2Authenticator authenticator : userOAuth2AuthenticatorPlugins) {
@@ -156,6 +161,10 @@ public String authenticate(String command, Map<String, Object[]> params, HttpSes
156161
return ApiResponseSerializer.toSerializedString(response, responseType);
157162
}
158163

164+
private Long resolveDomainId(Map<String, Object[]> params) {
165+
return _oauth2mgr.resolveDomainId(params);
166+
}
167+
159168
@Override
160169
public APIAuthenticationType getAPIType() {
161170
return null;
@@ -171,9 +180,5 @@ public void setAuthenticators(List<PluggableAPIAuthenticator> authenticators) {
171180
if (_oauth2mgr == null) {
172181
logger.error("No suitable Pluggable Authentication Manager found for listing OAuth providers");
173182
}
174-
_domainDao = (DomainDao) ComponentContext.getComponent(DomainDao.class);
175-
if (Objects.isNull(_domainDao)) {
176-
logger.error("Could not get DomainDao component");
177-
}
178183
}
179184
}

plugins/user-authenticators/oauth2/src/main/java/org/apache/cloudstack/oauth2/api/command/VerifyOAuthCodeAndGetUserCmd.java

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,9 @@
1919
import java.net.InetAddress;
2020
import java.util.List;
2121
import java.util.Map;
22-
import java.util.Objects;
2322

2423
import com.cloud.api.response.ApiResponseSerializer;
25-
import com.cloud.domain.DomainVO;
26-
import com.cloud.domain.dao.DomainDao;
2724
import com.cloud.user.Account;
28-
import com.cloud.utils.component.ComponentContext;
2925

3026
import javax.servlet.http.HttpServletRequest;
3127
import javax.servlet.http.HttpServletResponse;
@@ -45,8 +41,7 @@
4541
import org.apache.cloudstack.api.response.UserResponse;
4642
import org.apache.cloudstack.oauth2.OAuth2AuthManager;
4743
import org.apache.cloudstack.oauth2.api.response.OauthProviderResponse;
48-
import org.apache.commons.lang.ArrayUtils;
49-
import org.apache.commons.lang3.StringUtils;
44+
import org.apache.commons.lang3.ArrayUtils;
5045

5146
@APICommand(name = "verifyOAuthCodeAndGetUser", description = "Verify the OAuth Code and fetch the corresponding user from provider", responseObject = OauthProviderResponse.class, entityType = {},
5247
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
@@ -94,8 +89,6 @@ public Long getDomainId() {
9489

9590
protected OAuth2AuthManager _oauth2mgr;
9691

97-
DomainDao _domainDao;
98-
9992
@Override
10093
public long getEntityOwnerId() {
10194
return Account.Type.NORMAL.ordinal();
@@ -133,30 +126,7 @@ public String authenticate(String command, Map<String, Object[]> params, HttpSes
133126
}
134127

135128
private Long resolveDomainId(Map<String, Object[]> params) {
136-
final String[] domainIdArray = (String[])params.get(ApiConstants.DOMAIN_ID);
137-
if (ArrayUtils.isNotEmpty(domainIdArray)) {
138-
DomainVO domain = _domainDao.findByUuid(domainIdArray[0]);
139-
if (Objects.nonNull(domain)) {
140-
return domain.getId();
141-
}
142-
}
143-
final String[] domainArray = (String[])params.get(ApiConstants.DOMAIN);
144-
if (ArrayUtils.isNotEmpty(domainArray)) {
145-
String path = domainArray[0];
146-
if (StringUtils.isNotEmpty(path)) {
147-
if (!path.startsWith("/")) {
148-
path = "/" + path;
149-
}
150-
if (!path.endsWith("/")) {
151-
path += "/";
152-
}
153-
DomainVO domain = _domainDao.findDomainByPath(path);
154-
if (Objects.nonNull(domain)) {
155-
return domain.getId();
156-
}
157-
}
158-
}
159-
return null;
129+
return _oauth2mgr.resolveDomainId(params);
160130
}
161131

162132
@Override
@@ -174,9 +144,5 @@ public void setAuthenticators(List<PluggableAPIAuthenticator> authenticators) {
174144
if (_oauth2mgr == null) {
175145
logger.error("No suitable Pluggable Authentication Manager found for listing OAuth providers");
176146
}
177-
_domainDao = (DomainDao) ComponentContext.getComponent(DomainDao.class);
178-
if (Objects.isNull(_domainDao)) {
179-
logger.error("Could not get DomainDao component");
180-
}
181147
}
182148
}

0 commit comments

Comments
 (0)