Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve get user authorized organization endpoint #191

Merged
merged 1 commit into from
Jan 17, 2024
Merged
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 @@ -44,5 +44,10 @@
<artifactId>org.wso2.carbon.identity.organization.management.service</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.application.mgt</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package org.wso2.carbon.identity.api.user.organization.common;

import org.wso2.carbon.identity.application.mgt.ApplicationManagementService;
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
import org.wso2.carbon.identity.organization.management.service.OrganizationUserResidentResolverService;

Expand All @@ -29,6 +30,7 @@ public class UserOrganizationServiceHolder {
private static OrganizationUserResidentResolverService organizationUserResidentResolverService;

private static OrganizationManager organizationManagementService;
private static ApplicationManagementService applicationManagementService;

/**
* Method to get the organization user resident resolver OSGi service.
Expand Down Expand Up @@ -71,4 +73,25 @@ public static void setOrganizationManagementService(

UserOrganizationServiceHolder.organizationManagementService = organizationManagementService;
}

/**
* Get application management service.
*
* @return Application management service.
*/
public static ApplicationManagementService getApplicationManagementService() {

return applicationManagementService;
}

/**
* Set application management OSGi service.
*
* @param applicationManagementService Application management service.
*/
public static void setApplicationManagementService(
ApplicationManagementService applicationManagementService) {

UserOrganizationServiceHolder.applicationManagementService = applicationManagementService;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.api.user.organization.common.factory;
ChanikaRuchini marked this conversation as resolved.
Show resolved Hide resolved

import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.application.mgt.ApplicationManagementService;

/**
* Factory Beans serves as a factory for creating other beans within the IOC container. This factory bean is used to
* instantiate the ApplicationManagementService type of object inside the container.
*/
public class ApplicationManagementOSGIServiceFactory extends AbstractFactoryBean<ApplicationManagementService> {

private ApplicationManagementService applicationManagementService;

@Override
public Class<?> getObjectType() {

return Object.class;
}

@Override
protected ApplicationManagementService createInstance() throws Exception {

if (this.applicationManagementService == null) {
ApplicationManagementService service = (ApplicationManagementService) PrivilegedCarbonContext.
getThreadLocalCarbonContext().getOSGiService(ApplicationManagementService.class, null);
if (service != null) {
this.applicationManagementService = service;
} else {
throw new Exception("Unable to retrieve Application Management service.");
}
}
return this.applicationManagementService;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@
<artifactId>org.wso2.carbon.identity.organization.management.service</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.application.mgt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ public class MeApi {
@ApiResponse(code = 500, message = "Internal server error.", response = Error.class),
@ApiResponse(code = 501, message = "Not Implemented.", response = Error.class)
})
public Response rootGet( @Valid@ApiParam(value = "Condition to filter the retrieval of records.") @QueryParam("filter") String filter, @Valid @Min(0)@ApiParam(value = "Maximum number of records to be returned. (Should be greater than 0)") @QueryParam("limit") Integer limit, @Valid@ApiParam(value = "Points to the next range of data to be returned.") @QueryParam("after") String after, @Valid@ApiParam(value = "Points to the previous range of data that can be retrieved.") @QueryParam("before") String before, @Valid@ApiParam(value = "Determines whether a recursive search should happen.", defaultValue="false") @DefaultValue("false") @QueryParam("recursive") Boolean recursive) {
public Response rootGet( @Valid@ApiParam(value = "Condition to filter the retrieval of records.") @QueryParam("filter") String filter, @Valid @Min(0)@ApiParam(value = "Maximum number of records to be returned. (Should be greater than 0)") @QueryParam("limit") Integer limit, @Valid@ApiParam(value = "Points to the next range of data to be returned.") @QueryParam("after") String after, @Valid@ApiParam(value = "Points to the previous range of data that can be retrieved.") @QueryParam("before") String before, @Valid@ApiParam(value = "Determines whether a recursive search should happen.", defaultValue="false") @DefaultValue("false") @QueryParam("recursive") Boolean recursive, @Valid@ApiParam(value = "Retrieves the organizations that are authorized for the user through the role bound to the application.") @QueryParam("authorizedAppName") String authorizedAppName) {

return delegate.rootGet(filter, limit, after, before, recursive );
return delegate.rootGet(filter, limit, after, before, recursive, authorizedAppName );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@

public interface MeApiService {

public Response rootGet(String filter, Integer limit, String after, String before, Boolean recursive);
public Response rootGet(String filter, Integer limit, String after, String before, Boolean recursive, String authorizedAppName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.api.user.organization.common.UserOrganizationServiceHolder;
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
import org.wso2.carbon.identity.application.common.model.ApplicationBasicInfo;
import org.wso2.carbon.identity.application.mgt.ApplicationManagementService;
import org.wso2.carbon.identity.core.ServiceURLBuilder;
import org.wso2.carbon.identity.core.URLBuilderException;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
import org.wso2.carbon.identity.organization.management.service.OrganizationUserResidentResolverService;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementClientException;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
import org.wso2.carbon.identity.organization.management.service.model.BasicOrganization;
import org.wso2.carbon.identity.rest.api.user.organization.v1.exceptions.UserOrganizationManagementEndpointException;
Expand All @@ -51,6 +56,7 @@

import static org.wso2.carbon.identity.api.user.common.Constants.USER_API_PATH_COMPONENT;
import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_ERROR_BUILDING_PAGINATED_RESPONSE_URL;
import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_INVALID_APPLICATION;
import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_USER_ROOT_ORGANIZATION_NOT_FOUND;
import static org.wso2.carbon.identity.organization.management.service.util.Utils.getOrganizationId;
import static org.wso2.carbon.identity.rest.api.user.organization.v1.Constants.ASC_SORT_ORDER;
Expand Down Expand Up @@ -128,14 +134,18 @@ public List<BasicOrganizationObject> getUserOrganizationHierarchyUptoResidentOrg
* @return The root descendants organizations of the authenticated user.
*/
public OrganizationsResponse getAuthorizedOrganizations(String filter, Integer limit, String after, String before,
Boolean recursive) {
Boolean recursive, String applicationName) {

try {
limit = validateLimit(limit);
String sortOrder = StringUtils.isNotBlank(before) ? ASC_SORT_ORDER : DESC_SORT_ORDER;
String applicationAudience = null;
if (applicationName != null) {
applicationAudience = getApplicationAudience(applicationName);
}
List<BasicOrganization> authorizedOrganizations = getOrganizationManagementService()
.getUserAuthorizedOrganizations(limit + 1, after, before, sortOrder, filter,
Boolean.TRUE.equals(recursive));
Boolean.TRUE.equals(recursive), applicationAudience);
return getAuthorizedOrganizationsResponse(limit, after, before, filter,
authorizedOrganizations, Boolean.TRUE.equals(recursive));
} catch (OrganizationManagementException e) {
Expand All @@ -162,6 +172,11 @@ private OrganizationManager getOrganizationManagementService() {
return UserOrganizationServiceHolder.getOrganizationManagementService();
}

private ApplicationManagementService getApplicationManagementService() {

return UserOrganizationServiceHolder.getApplicationManagementService();
}

private int validateLimit(Integer limit) {

if (limit == null) {
Expand Down Expand Up @@ -264,4 +279,21 @@ private String getContext(String url) {
String.format("/o/%s", organizationId) + USER_API_PATH_COMPONENT + endpoint :
USER_API_PATH_COMPONENT + endpoint;
}

private String getApplicationAudience(String applicationName) throws OrganizationManagementException {

try {
ApplicationBasicInfo applicationBasicInfo =
getApplicationManagementService().getApplicationBasicInfoByName(applicationName,
IdentityTenantUtil.resolveTenantDomain());
if (applicationBasicInfo != null) {
return applicationBasicInfo.getApplicationResourceId();
}
throw new OrganizationManagementClientException(ERROR_CODE_INVALID_APPLICATION.getMessage(),
String.format(ERROR_CODE_INVALID_APPLICATION.getDescription(), applicationName),
ERROR_CODE_INVALID_APPLICATION.getCode());
} catch (IdentityApplicationManagementException e) {
throw new OrganizationManagementException(e.getMessage(), e.getErrorCode(), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ public class MeApiServiceImpl implements MeApiService {
UserOrganizationService userOrganizationService;

@Override
public Response rootGet(String filter, Integer limit, String after, String before, Boolean recursive) {
public Response rootGet(String filter, Integer limit, String after, String before, Boolean recursive,
String authorizedAppName) {

return Response.ok(userOrganizationService.getAuthorizedOrganizations(filter, limit, after, before,
recursive)).build();
recursive, authorizedAppName)).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@
class="org.wso2.carbon.identity.api.user.organization.common.factory.OrganizationUserResidentResolverOSGIServiceFactory"/>
<bean id="OrganizationMgtServiceFactoryBean"
class="org.wso2.carbon.identity.api.user.organization.common.factory.OrganizationManagementOSGIServiceFactory"/>
<bean id="ApplicationManagementServiceFactoryBean"
class="org.wso2.carbon.identity.api.user.organization.common.factory.ApplicationManagementOSGIServiceFactory"/>
<bean id="UserOrganizationManagementServiceHolderBean"
class="org.wso2.carbon.identity.api.user.organization.common.UserOrganizationServiceHolder">
<property name="organizationUserResidentResolverService" ref="OrganizationUserResidentResolverServiceFactoryBean"/>
<property name="organizationManagementService" ref="OrganizationMgtServiceFactoryBean"/>
<property name="applicationManagementService" ref="ApplicationManagementServiceFactoryBean"/>
</bean>
</beans>
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ paths:
- $ref: '#/components/parameters/afterQueryParam'
- $ref: '#/components/parameters/beforeQueryParam'
- $ref: '#/components/parameters/recursiveQueryParam'
- $ref: '#/components/parameters/authorizedAppNameQueryParam'
responses:
'200':
description: Successful response
Expand Down Expand Up @@ -163,6 +164,14 @@ components:
schema:
type: boolean
default: false
authorizedAppNameQueryParam:
in: query
name: authorizedAppName
required: false
description:
Retrieves the organizations that are authorized for the user through the role bound to the application.
schema:
type: string
schemas:
RootOrganizationResponse:
type: object
Expand Down
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,12 @@
<version>${carbon.identity.framework.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.application.mgt</artifactId>
<version>${carbon.identity.framework.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.config.mapper</groupId>
<artifactId>config-mapper</artifactId>
Expand Down Expand Up @@ -448,7 +454,7 @@
<carbon.identity.account.association.version>5.3.7</carbon.identity.account.association.version>
<maven.findbugsplugin.version>3.0.5</maven.findbugsplugin.version>
<identity.oauth.version>6.7.71</identity.oauth.version>
<identity.org.mgt.core.version>1.0.85</identity.org.mgt.core.version>
<identity.org.mgt.core.version>1.0.97</identity.org.mgt.core.version>
<testng.version>6.9.10</testng.version>
<fido2.version>5.1.17</fido2.version>
<identity.totp.version>3.3.1</identity.totp.version>
Expand Down
Loading