Skip to content

Commit 8ddbb51

Browse files
Allow OAuth2 application management through DCR in sub organizations
1 parent b0cd3a9 commit 8ddbb51

File tree

17 files changed

+275
-54
lines changed

17 files changed

+275
-54
lines changed

components/org.wso2.carbon.identity.oauth.dcr/pom.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@
126126
<groupId>org.wso2.carbon.identity.framework</groupId>
127127
<artifactId>org.wso2.carbon.identity.configuration.mgt.core</artifactId>
128128
</dependency>
129-
129+
<dependency>
130+
<groupId>org.wso2.carbon.identity.organization.management.core</groupId>
131+
<artifactId>org.wso2.carbon.identity.organization.management.service</artifactId>
132+
</dependency>
130133
</dependencies>
131134

132135
<build>
@@ -165,6 +168,7 @@
165168
org.wso2.carbon.identity.application.common.model;version="${carbon.identity.framework.imp.pkg.version.range}",
166169
org.wso2.carbon.identity.application.mgt.*;version="${carbon.identity.framework.imp.pkg.version.range}",
167170
org.wso2.carbon.identity.application.authentication.framework.*;version="${carbon.identity.framework.imp.pkg.version.range}",
171+
org.wso2.carbon.identity.organization.management.service.*; version="${carbon.identity.organization.management.core.version.range}",
168172
javax.servlet.http; version="${imp.pkg.version.javax.servlet}",
169173
org.wso2.carbon.user.api; version="${carbon.user.api.imp.pkg.version.range}",
170174
org.wso2.carbon.identity.oauth.*;version="${identity.inbound.auth.oauth.imp.pkg.version.range}",

components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/DCRMConstants.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ public enum ErrorMessages {
6060
SIGNATURE_VALIDATION_FAILED("Signature validation failed for the software statement"),
6161
MANDATORY_SOFTWARE_STATEMENT("Mandatory software statement is missing"),
6262
FAILED_TO_READ_SSA("Error occurred while reading the software statement"),
63-
ADDITIONAL_ATTRIBUTE_ERROR("Error occurred while handling additional attributes");
63+
ADDITIONAL_ATTRIBUTE_ERROR("Error occurred while handling additional attributes"),
64+
FAILED_TO_RESOLVE_TENANT_DOMAIN("Error while resolving tenant domain from the organization id: %s");
6465

6566
private final String message;
6667
private final String errorCode;

components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/internal/DCRDataHolder.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.wso2.carbon.identity.oauth.dcr.handler.RegistrationHandler;
2424
import org.wso2.carbon.identity.oauth.dcr.handler.UnRegistrationHandler;
2525
import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinder;
26+
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
2627

2728
import java.util.ArrayList;
2829
import java.util.List;
@@ -33,7 +34,6 @@
3334
* This was deprecated as part of deprecating the legacy identity/register DCR endpoint.
3435
* The recommendation is to use /identity/oauth2/dcr/v1.1 instead.
3536
*/
36-
@Deprecated
3737
public class DCRDataHolder {
3838

3939
private static DCRDataHolder thisInstance = new DCRDataHolder();
@@ -42,6 +42,7 @@ public class DCRDataHolder {
4242
private List<UnRegistrationHandler> unRegistrationHandlerList = new ArrayList<>();
4343
private List<TokenBinder> tokenBinders = new ArrayList<>();
4444
private ConfigurationManager configurationManager;
45+
private OrganizationManager organizationManager;
4546

4647
private DCRDataHolder() {
4748

@@ -111,4 +112,14 @@ public void setConfigurationManager(ConfigurationManager configurationManager) {
111112

112113
this.configurationManager = configurationManager;
113114
}
115+
116+
public OrganizationManager getOrganizationManager() {
117+
118+
return organizationManager;
119+
}
120+
121+
public void setOrganizationManager(OrganizationManager organizationManager) {
122+
123+
this.organizationManager = organizationManager;
124+
}
114125
}

components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/internal/DCRServiceComponent.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.wso2.carbon.identity.oauth.dcr.processor.DCRProcessor;
4343
import org.wso2.carbon.identity.oauth.dcr.service.DCRMService;
4444
import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinder;
45+
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
4546

4647
/**
4748
* OAuth DCRM service component.
@@ -52,7 +53,6 @@
5253
name = "identity.oauth.dcr",
5354
immediate = true
5455
)
55-
@Deprecated
5656
public class DCRServiceComponent {
5757

5858
private static final Log log = LogFactory.getLog(DCRServiceComponent.class);
@@ -254,4 +254,23 @@ protected void unregisterConfigurationManager(ConfigurationManager configuration
254254
log.debug("Unregistering the ConfigurationManager in DCR Service Component.");
255255
DCRDataHolder.getInstance().setConfigurationManager(null);
256256
}
257+
258+
@Reference(
259+
name = "organization.service",
260+
service = OrganizationManager.class,
261+
cardinality = ReferenceCardinality.MANDATORY,
262+
policy = ReferencePolicy.DYNAMIC,
263+
unbind = "unsetOrganizationManager"
264+
)
265+
protected void setOrganizationManager(OrganizationManager organizationManager) {
266+
267+
DCRDataHolder.getInstance().setOrganizationManager(organizationManager);
268+
log.debug("Set the organization management service.");
269+
}
270+
271+
protected void unsetOrganizationManager(OrganizationManager organizationManager) {
272+
273+
DCRDataHolder.getInstance().setOrganizationManager(null);
274+
log.debug("Unset organization management service.");
275+
}
257276
}

components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/service/DCRMService.java

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import org.wso2.carbon.identity.oauth2.OAuth2Constants;
6565
import org.wso2.carbon.identity.oauth2.util.JWTSignatureValidationUtils;
6666
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
67+
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
6768
import org.wso2.carbon.user.api.UserStoreException;
6869

6970
import java.lang.reflect.InvocationTargetException;
@@ -105,12 +106,12 @@ public class DCRMService {
105106
*/
106107
public Application getApplication(String clientId) throws DCRMException {
107108

108-
validateRequestTenantDomain(clientId);
109+
String tenantDomain = getTenantDomain();
110+
validateRequestTenantDomain(clientId, tenantDomain);
109111
OAuthConsumerAppDTO consumerAppDTO = getApplicationById(
110-
clientId, DCRMUtils.isApplicationRolePermissionRequired());
112+
clientId, DCRMUtils.isApplicationRolePermissionRequired(), tenantDomain);
111113
// Get the jwksURI from the service provider.
112114
String applicationName = consumerAppDTO.getApplicationName();
113-
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
114115
ServiceProvider serviceProvider = getServiceProvider(applicationName, tenantDomain);
115116
String jwksURI = serviceProvider.getJwksUri();
116117
if (StringUtils.isNotEmpty(jwksURI)) {
@@ -156,7 +157,7 @@ public Application getApplicationByName(String clientName) throws DCRMException
156157
DCRMConstants.ErrorMessages.BAD_REQUEST_INSUFFICIENT_DATA, null);
157158
}
158159

159-
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
160+
String tenantDomain = getTenantDomain();
160161
if (!isServiceProviderExist(clientName, tenantDomain)) {
161162
throw DCRMUtils.generateClientException(
162163
DCRMConstants.ErrorMessages.NOT_FOUND_APPLICATION_WITH_NAME, clientName);
@@ -203,10 +204,10 @@ public Application registerApplication(ApplicationRegistrationRequest registrati
203204
*/
204205
public void deleteApplication(String clientId) throws DCRMException {
205206

206-
validateRequestTenantDomain(clientId);
207-
OAuthConsumerAppDTO appDTO = getApplicationById(clientId);
207+
String tenantDomain = getTenantDomain();
208+
validateRequestTenantDomain(clientId, tenantDomain);
209+
OAuthConsumerAppDTO appDTO = getApplicationById(clientId, tenantDomain);
208210
String applicationOwner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
209-
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
210211
String spName;
211212
try {
212213
spName = DCRDataHolder.getInstance().getApplicationManagementService()
@@ -241,9 +242,9 @@ public void deleteApplication(String clientId) throws DCRMException {
241242
*/
242243
public Application updateApplication(ApplicationUpdateRequest updateRequest, String clientId) throws DCRMException {
243244

244-
validateRequestTenantDomain(clientId);
245-
OAuthConsumerAppDTO appDTO = getApplicationById(clientId);
246-
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
245+
String tenantDomain = getTenantDomain();
246+
validateRequestTenantDomain(clientId, tenantDomain);
247+
OAuthConsumerAppDTO appDTO = getApplicationById(clientId, tenantDomain);
247248
String applicationOwner = StringUtils.isNotBlank(updateRequest.getExtApplicationOwner()) ?
248249
updateRequest.getExtApplicationOwner() :
249250
PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
@@ -426,7 +427,7 @@ public Application updateApplication(ApplicationUpdateRequest updateRequest, Str
426427
throw DCRMUtils.generateServerException(
427428
DCRMConstants.ErrorMessages.FAILED_TO_UPDATE_APPLICATION, clientId, e);
428429
}
429-
OAuthConsumerAppDTO oAuthConsumerAppDTO = getApplicationById(clientId);
430+
OAuthConsumerAppDTO oAuthConsumerAppDTO = getApplicationById(clientId, tenantDomain);
430431
// Setting the jwksURI to be sent in the response.
431432
oAuthConsumerAppDTO.setJwksURI(updateRequest.getJwksURI());
432433
Application application = buildResponse(oAuthConsumerAppDTO, tenantDomain);
@@ -489,12 +490,13 @@ private String getDisplayNameProperty(ServiceProvider serviceProvider) {
489490
return displayNameProperty.map(ServiceProviderProperty::getValue).orElse(null);
490491
}
491492

492-
private OAuthConsumerAppDTO getApplicationById(String clientId) throws DCRMException {
493+
private OAuthConsumerAppDTO getApplicationById(String clientId, String tenantDomain) throws DCRMException {
493494

494-
return getApplicationById(clientId, true);
495+
return getApplicationById(clientId, true, tenantDomain);
495496
}
496497

497-
private OAuthConsumerAppDTO getApplicationById(String clientId, boolean isApplicationRolePermissionRequired)
498+
private OAuthConsumerAppDTO getApplicationById(String clientId, boolean isApplicationRolePermissionRequired,
499+
String tenantDomain)
498500
throws DCRMException {
499501

500502
if (StringUtils.isEmpty(clientId)) {
@@ -504,7 +506,7 @@ private OAuthConsumerAppDTO getApplicationById(String clientId, boolean isApplic
504506
}
505507

506508
try {
507-
OAuthConsumerAppDTO dto = oAuthAdminService.getOAuthApplicationData(clientId);
509+
OAuthConsumerAppDTO dto = oAuthAdminService.getOAuthApplicationData(clientId, tenantDomain);
508510
if (dto == null || StringUtils.isEmpty(dto.getApplicationName())) {
509511
throw DCRMUtils.generateClientException(
510512
DCRMConstants.ErrorMessages.NOT_FOUND_APPLICATION_WITH_ID, clientId);
@@ -529,8 +531,7 @@ private Application createOAuthApplication(ApplicationRegistrationRequest regist
529531
String applicationOwner = StringUtils.isNotBlank(registrationRequest.getExtApplicationOwner()) ?
530532
registrationRequest.getExtApplicationOwner() :
531533
PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
532-
533-
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
534+
String tenantDomain = getTenantDomain();
534535

535536
/*
536537
* ApplicationOwner will be null and a server error is thrown when creating an app, if the api authentication/
@@ -566,7 +567,7 @@ private Application createOAuthApplication(ApplicationRegistrationRequest regist
566567
}
567568

568569
if (StringUtils.isNotEmpty(registrationRequest.getConsumerKey()) && isClientIdExist(
569-
registrationRequest.getConsumerKey())) {
570+
registrationRequest.getConsumerKey(), tenantDomain)) {
570571
throw DCRMUtils.generateClientException(DCRMConstants.ErrorMessages.CONFLICT_EXISTING_CLIENT_ID,
571572
registrationRequest.getConsumerKey());
572573
}
@@ -941,10 +942,10 @@ private boolean isServiceProviderExist(String serviceProviderName, String tenant
941942
* @return true if application exists with the client id.
942943
* @throws DCRMException in case of failure.
943944
*/
944-
private boolean isClientIdExist(String clientId) throws DCRMException {
945+
private boolean isClientIdExist(String clientId, String tenantDomain) throws DCRMException {
945946

946947
try {
947-
OAuthConsumerAppDTO dto = oAuthAdminService.getOAuthApplicationData(clientId);
948+
OAuthConsumerAppDTO dto = oAuthAdminService.getOAuthApplicationData(clientId, tenantDomain);
948949
return dto != null && StringUtils.isNotBlank(dto.getApplicationName());
949950
} catch (IdentityOAuthAdminException e) {
950951
if (e.getCause() instanceof InvalidOAuthClientException) {
@@ -1144,7 +1145,7 @@ private String escapeQueryParamsIfPresent(String redirectURI) {
11441145
private boolean isUserAuthorized(String clientId) throws DCRMServerException {
11451146

11461147
try {
1147-
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
1148+
String tenantDomain = getTenantDomain();
11481149
String spName = DCRDataHolder.getInstance().getApplicationManagementService()
11491150
.getServiceProviderNameByClientId(clientId, DCRMConstants.OAUTH2, tenantDomain);
11501151
String threadLocalUserName = CarbonContext.getThreadLocalCarbonContext().getUsername();
@@ -1176,10 +1177,10 @@ private static boolean clientIdMatchesRegex(String clientId, String clientIdVali
11761177
* @param clientId Consumer key of application.
11771178
* @throws DCRMException DCRMException
11781179
*/
1179-
private void validateRequestTenantDomain(String clientId) throws DCRMException {
1180+
private void validateRequestTenantDomain(String clientId, String tenantDomain) throws DCRMException {
11801181

11811182
try {
1182-
String tenantDomainOfApp = OAuth2Util.getTenantDomainOfOauthApp(clientId);
1183+
String tenantDomainOfApp = OAuth2Util.getTenantDomainOfOauthApp(clientId, tenantDomain);
11831184
OAuth2Util.validateRequestTenantDomain(tenantDomainOfApp);
11841185
} catch (InvalidOAuthClientException e) {
11851186
throw new DCRMClientException(DCRMConstants.ErrorMessages.TENANT_DOMAIN_MISMATCH.getErrorCode(),
@@ -1275,4 +1276,21 @@ private void addSPProperties(Map<String, Object> spProperties, ServiceProvider s
12751276
}
12761277
serviceProvider.setSpProperties(serviceProviderProperties);
12771278
}
1279+
1280+
private static String getTenantDomain() throws DCRMServerException {
1281+
1282+
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
1283+
String applicationResidentOrgId = PrivilegedCarbonContext.getThreadLocalCarbonContext()
1284+
.getApplicationResidentOrganizationId();
1285+
if (StringUtils.isNotEmpty(applicationResidentOrgId)) {
1286+
try {
1287+
tenantDomain = DCRDataHolder.getInstance().getOrganizationManager()
1288+
.resolveTenantDomain(applicationResidentOrgId);
1289+
} catch (OrganizationManagementException e) {
1290+
throw DCRMUtils.generateServerException(
1291+
DCRMConstants.ErrorMessages.FAILED_TO_RESOLVE_TENANT_DOMAIN, applicationResidentOrgId, e);
1292+
}
1293+
}
1294+
return tenantDomain;
1295+
}
12781296
}

components/org.wso2.carbon.identity.oauth.dcr/src/main/java/org/wso2/carbon/identity/oauth/dcr/util/DCRMUtils.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
* This was deprecated as part of deprecating the legacy identity/register DCR endpoint.
3838
* The recommendation is to use /identity/oauth2/dcr/v1.1 instead.
3939
*/
40-
@Deprecated
4140
public class DCRMUtils {
4241

4342
private static final Log log = LogFactory.getLog(DCRMUtils.class);

0 commit comments

Comments
 (0)