Skip to content

Commit 1a4a4e8

Browse files
Improve scope validator to resolve the shared apps when switching to organizations
1 parent 23b4539 commit 1a4a4e8

File tree

4 files changed

+92
-13
lines changed

4 files changed

+92
-13
lines changed

components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/dao/SQLQueries.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,6 +1639,9 @@ public class SQLQueries {
16391639
"INSERT INTO IDN_OAUTH2_ACCESS_TOKEN_ATTRIBUTES (TOKEN_ATTR_NAME, TOKEN_ATTR_VALUE, TOKEN_ID) " +
16401640
"VALUES (?, ?, ?)";
16411641

1642+
public static final String GET_SHARED_APP_ID = "SELECT SHARED_APP_ID FROM SP_SHARED_APP WHERE " +
1643+
"OWNER_ORG_ID = ? AND MAIN_APP_ID = ? AND SHARED_ORG_ID = ? ";
1644+
16421645
private SQLQueries() {
16431646

16441647
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
3+
*
4+
* WSO2 LLC. licenses this file to you under the Apache License,
5+
* Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an
13+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
* KIND, either express or implied. See the License for the
15+
* specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
package org.wso2.carbon.identity.oauth2.dao;
20+
21+
import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;
22+
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
23+
24+
import java.sql.Connection;
25+
import java.sql.PreparedStatement;
26+
import java.sql.ResultSet;
27+
import java.sql.SQLException;
28+
29+
import static org.wso2.carbon.identity.oauth2.dao.SQLQueries.GET_SHARED_APP_ID;
30+
import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_ERROR_RESOLVING_SHARED_APPLICATION;
31+
32+
/**
33+
* DAO class to resolve shared application.
34+
*/
35+
public class SharedAppResolveDAO {
36+
37+
public static String resolveSharedApplication(String appResideOrgId, String mainAppId, String orgId)
38+
throws IdentityOAuth2Exception {
39+
40+
try (Connection connection = IdentityDatabaseUtil.getDBConnection(false);
41+
PreparedStatement preparedStatement = connection.prepareStatement(GET_SHARED_APP_ID)) {
42+
preparedStatement.setString(1, appResideOrgId);
43+
preparedStatement.setString(2, mainAppId);
44+
preparedStatement.setString(3, orgId);
45+
46+
try (ResultSet resultSet = preparedStatement.executeQuery()) {
47+
if (resultSet.next()) {
48+
return resultSet.getString(1);
49+
}
50+
return null;
51+
}
52+
} catch (SQLException e) {
53+
throw new IdentityOAuth2Exception(ERROR_CODE_ERROR_RESOLVING_SHARED_APPLICATION.getCode(),
54+
ERROR_CODE_ERROR_RESOLVING_SHARED_APPLICATION.getMessage(), e);
55+
}
56+
}
57+
}

components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/DefaultOAuth2ScopeValidator.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@
3434
import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder;
3535
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
3636
import org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext;
37+
import org.wso2.carbon.identity.oauth2.dao.SharedAppResolveDAO;
3738
import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder;
3839
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
3940
import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationContext;
4041
import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandler;
4142
import org.wso2.carbon.identity.oauth2.validators.validationhandler.ScopeValidationHandlerException;
43+
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
4244

4345
import java.util.ArrayList;
4446
import java.util.Arrays;
@@ -84,6 +86,11 @@ public List<String> validateScope(OAuthAuthzReqMessageContext authzReqMessageCon
8486
String tenantDomain = authzReqMessageContext.getAuthorizationReqDTO().getTenantDomain();
8587
String clientId = authzReqMessageContext.getAuthorizationReqDTO().getConsumerKey();
8688
String appId = getApplicationId(clientId, tenantDomain);
89+
if (isAccessingChildOrganization(authzReqMessageContext.getAuthorizationReqDTO().getUser())) {
90+
String orgId = authzReqMessageContext.getAuthorizationReqDTO().getUser().getAccessingOrganization();
91+
String appResideOrgId = resolveOrgIdByTenantDomain(tenantDomain);
92+
appId = SharedAppResolveDAO.resolveSharedApplication(appResideOrgId, appId, orgId);
93+
}
8794
List<String> authorizedScopes = getAuthorizedScopes(requestedScopes, authzReqMessageContext
8895
.getAuthorizationReqDTO().getUser(), appId, null, tenantDomain);
8996
removeRegisteredScopes(authzReqMessageContext);
@@ -110,6 +117,11 @@ public List<String> validateScope(OAuthTokenReqMessageContext tokenReqMessageCon
110117
String tenantDomain = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getTenantDomain();
111118
String clientId = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getClientId();
112119
String appId = getApplicationId(clientId, tenantDomain);
120+
if (isAccessingChildOrganization(tokenReqMessageContext.getAuthorizedUser())) {
121+
String orgId = tokenReqMessageContext.getAuthorizedUser().getAccessingOrganization();
122+
String appResideOrgId = resolveOrgIdByTenantDomain(tenantDomain);
123+
appId = SharedAppResolveDAO.resolveSharedApplication(appResideOrgId, appId, orgId);
124+
}
113125
String grantType = tokenReqMessageContext.getOauth2AccessTokenReqDTO().getGrantType();
114126
List<String> authorizedScopes = getAuthorizedScopes(requestedScopes, tokenReqMessageContext
115127
.getAuthorizedUser(), appId, grantType, tenantDomain);
@@ -387,4 +399,21 @@ private boolean isScopesEmpty(String[] scopes) {
387399
return ArrayUtils.isEmpty(scopes);
388400
}
389401

402+
private boolean isAccessingChildOrganization(AuthenticatedUser authenticatedUser) {
403+
404+
return authenticatedUser.getAccessingOrganization() != null &&
405+
!authenticatedUser.getAccessingOrganization().equals(authenticatedUser.getUserResidentOrganization());
406+
}
407+
408+
private String resolveOrgIdByTenantDomain(String tenantDomain) throws IdentityOAuth2Exception {
409+
410+
try {
411+
return OAuth2ServiceComponentHolder.getInstance().getOrganizationManager()
412+
.resolveOrganizationId(tenantDomain);
413+
} catch (OrganizationManagementException e) {
414+
throw new IdentityOAuth2Exception("Error occured while resolving organization for tenant domain: "
415+
+ tenantDomain, e);
416+
}
417+
}
418+
390419
}

components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/validators/validationhandler/impl/RoleBasedScopeValidationHandler.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,15 @@ public List<String> validateScopes(List<String> requestedScopes, List<String> ap
6464
}
6565
String tenantDomain = scopeValidationContext.getAuthenticatedUser().getTenantDomain();
6666
String accessingOrganization = scopeValidationContext.getAuthenticatedUser().getAccessingOrganization();
67-
String userResidentOrganization = scopeValidationContext.getAuthenticatedUser()
68-
.getUserResidentOrganization();
6967
if (StringUtils.isNotEmpty(accessingOrganization)) {
7068
tenantDomain = resolveTenantDomainByOrgId(accessingOrganization);
7169
}
72-
73-
List<String> filteredRoleIds;
74-
if (accessingOrganization != null && !accessingOrganization.equals(userResidentOrganization)) {
75-
filteredRoleIds = userRoles;
76-
} else {
77-
filteredRoleIds =
78-
getFilteredRoleIds(userRoles, scopeValidationContext.getAppId(), tenantDomain);
79-
}
80-
70+
List<String> filteredRoleIds = getFilteredRoleIds(userRoles, scopeValidationContext.getAppId(),
71+
tenantDomain);
8172
if (filteredRoleIds.isEmpty()) {
8273
return new ArrayList<>();
8374
}
84-
List<String> associatedScopes = AuthzUtil.getAssociatedScopesForRoles(filteredRoleIds,
85-
tenantDomain);
75+
List<String> associatedScopes = AuthzUtil.getAssociatedScopesForRoles(filteredRoleIds, tenantDomain);
8676
List<String> filteredScopes = appAuthorizedScopes.stream().filter(associatedScopes::contains)
8777
.collect(Collectors.toList());
8878
return requestedScopes.stream().filter(filteredScopes::contains).collect(Collectors.toList());

0 commit comments

Comments
 (0)