diff --git a/components/org.wso2.carbon.identity.organization.management.application/pom.xml b/components/org.wso2.carbon.identity.organization.management.application/pom.xml index 0b3e22590..3c4d01f82 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/pom.xml +++ b/components/org.wso2.carbon.identity.organization.management.application/pom.xml @@ -169,6 +169,7 @@ org.wso2.carbon.identity.event.handler; version="${carbon.identity.package.import.version.range}", org.wso2.carbon.identity.event.event; version="${carbon.identity.package.import.version.range}", org.wso2.carbon.identity.event; version="${carbon.identity.package.import.version.range}", + org.wso2.carbon.identity.event.services; version="${carbon.identity.package.import.version.range}", diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java index 1da42be80..1223147a8 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManager.java @@ -19,6 +19,7 @@ package org.wso2.carbon.identity.organization.management.application; import org.wso2.carbon.identity.application.common.model.ServiceProvider; +import org.wso2.carbon.identity.organization.management.application.model.SharedApplication; import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; import org.wso2.carbon.identity.organization.management.service.model.BasicOrganization; @@ -63,6 +64,17 @@ void deleteSharedApplication(String organizationId, String applicationId, String List getApplicationSharedOrganizations(String ownerOrgId, String mainAppId) throws OrganizationManagementException; + /** + * Returns the shared applications list of a given primary application, along with their organizations. + * + * @param ownerOrgId ID of the organization owning the primary application. + * @param mainAppId UUID of the primary application. + * @return A list of shared applications details. + * @throws OrganizationManagementException on errors occurred while retrieving the list of shared applications. + */ + List getSharedApplications(String ownerOrgId, String mainAppId) + throws OrganizationManagementException; + /** * Resolve the shared application id based on the organization link and the identifier of the main application. * diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java index 2388ae479..865d16830 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java @@ -53,6 +53,8 @@ import org.wso2.carbon.identity.oauth.dto.ScopeDTO; import org.wso2.carbon.identity.organization.management.application.dao.OrgApplicationMgtDAO; import org.wso2.carbon.identity.organization.management.application.internal.OrgApplicationMgtDataHolder; +import org.wso2.carbon.identity.organization.management.application.listener.ApplicationSharingManagerListener; +import org.wso2.carbon.identity.organization.management.application.model.SharedApplication; import org.wso2.carbon.identity.organization.management.application.model.SharedApplicationDO; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; @@ -242,15 +244,21 @@ public void deleteSharedApplication(String organizationId, String applicationId, ServiceProvider serviceProvider = getOrgApplication(applicationId, getTenantDomain()); if (sharedOrganizationId == null) { - + getListener().preDeleteAllSharedApplications(organizationId, applicationId); // Delete share for all shared applications. List sharedApplicationDOList = getOrgApplicationMgtDAO().getSharedApplications(organizationId, applicationId); for (SharedApplicationDO sharedApplicationDO : sharedApplicationDOList) { IdentityUtil.threadLocalProperties.get().put(DELETE_SHARE_FOR_MAIN_APPLICATION, true); - deleteSharedApplication(serviceProvider, organizationId, sharedApplicationDO.getOrganizationId()); + Optional sharedApplicationId = + resolveSharedApp(serviceProvider.getApplicationResourceId(), organizationId, + sharedApplicationDO.getOrganizationId()); + if (sharedApplicationId.isPresent()) { + deleteSharedApplication(sharedApplicationDO.getOrganizationId(), sharedApplicationId.get()); + } IdentityUtil.threadLocalProperties.get().remove(DELETE_SHARE_FOR_MAIN_APPLICATION); } + getListener().postDeleteAllSharedApplications(organizationId, applicationId, sharedApplicationDOList); if (Arrays.stream(serviceProvider.getSpProperties()).anyMatch(p -> SHARE_WITH_ALL_CHILDREN.equals(p.getName()) && Boolean.parseBoolean(p.getValue()))) { setShareWithAllChildrenProperty(serviceProvider, false); @@ -265,41 +273,43 @@ public void deleteSharedApplication(String organizationId, String applicationId, } } } else { + getListener().preDeleteSharedApplication(organizationId, applicationId, sharedOrganizationId); if (Arrays.stream(serviceProvider.getSpProperties()) .anyMatch(p -> SHARE_WITH_ALL_CHILDREN.equals(p.getName()) && Boolean.parseBoolean(p.getValue()))) { throw handleClientException(ERROR_CODE_INVALID_DELETE_SHARE_REQUEST, serviceProvider.getApplicationResourceId(), sharedOrganizationId); } - deleteSharedApplication(serviceProvider, organizationId, sharedOrganizationId); + Optional sharedApplicationId = + resolveSharedApp(serviceProvider.getApplicationResourceId(), organizationId, sharedOrganizationId); + if (sharedApplicationId.isPresent()) { + deleteSharedApplication(sharedOrganizationId, sharedApplicationId.get()); + getListener().postDeleteSharedApplication(organizationId, applicationId, sharedOrganizationId, + sharedApplicationId.get()); + } } } - private void deleteSharedApplication(ServiceProvider serviceProvider, String organizationId, - String sharedOrganizationId) throws OrganizationManagementException { - - Optional fragmentApplicationId = - resolveSharedApp(serviceProvider.getApplicationResourceId(), organizationId, sharedOrganizationId); + private void deleteSharedApplication(String sharedOrganizationId, String sharedApplicationId) + throws OrganizationManagementException { - if (fragmentApplicationId.isPresent()) { - try { - String sharedTenantDomain = getOrganizationManager().resolveTenantDomain(sharedOrganizationId); - ServiceProvider fragmentApplication = - getApplicationManagementService().getApplicationByResourceId(fragmentApplicationId.get(), - sharedTenantDomain); - String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); - - // Setting the thread local property to allow deleting fragment application. Otherwise - // FragmentApplicationMgtListener will reject application deletion. - IdentityUtil.threadLocalProperties.get().put(DELETE_FRAGMENT_APPLICATION, true); - getApplicationManagementService().deleteApplication(fragmentApplication.getApplicationName(), - sharedTenantDomain, username); - } catch (IdentityApplicationManagementException e) { - throw handleServerException(ERROR_CODE_ERROR_REMOVING_FRAGMENT_APP, e, fragmentApplicationId.get(), - sharedOrganizationId); - } finally { - IdentityUtil.threadLocalProperties.get().remove(DELETE_FRAGMENT_APPLICATION); - IdentityUtil.threadLocalProperties.get().remove(DELETE_SHARE_FOR_MAIN_APPLICATION); - } + try { + String sharedTenantDomain = getOrganizationManager().resolveTenantDomain(sharedOrganizationId); + ServiceProvider sharedApplication = + getApplicationManagementService().getApplicationByResourceId(sharedApplicationId, + sharedTenantDomain); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + + // Setting the thread local property to allow deleting fragment application. Otherwise + // FragmentApplicationMgtListener will reject application deletion. + IdentityUtil.threadLocalProperties.get().put(DELETE_FRAGMENT_APPLICATION, true); + getApplicationManagementService().deleteApplication(sharedApplication.getApplicationName(), + sharedTenantDomain, username); + } catch (IdentityApplicationManagementException e) { + throw handleServerException(ERROR_CODE_ERROR_REMOVING_FRAGMENT_APP, e, sharedApplicationId, + sharedOrganizationId); + } finally { + IdentityUtil.threadLocalProperties.get().remove(DELETE_FRAGMENT_APPLICATION); + IdentityUtil.threadLocalProperties.get().remove(DELETE_SHARE_FOR_MAIN_APPLICATION); } } @@ -307,6 +317,7 @@ private void deleteSharedApplication(ServiceProvider serviceProvider, String org public List getApplicationSharedOrganizations(String organizationId, String applicationId) throws OrganizationManagementException { + getListener().preGetApplicationSharedOrganizations(organizationId, applicationId); ServiceProvider application = getOrgApplication(applicationId, getTenantDomain()); List sharedApps = getOrgApplicationMgtDAO().getSharedApplications(organizationId, application.getApplicationResourceId()); @@ -315,9 +326,27 @@ public List getApplicationSharedOrganizations(String organiza Collectors.toList()); List organizations = getOrganizationManager().getChildOrganizations(organizationId, true); + List applicationSharedOrganizationsList = + organizations.stream().filter(o -> sharedOrganizationIds.contains(o.getId())).collect( + Collectors.toList()); + getListener().postGetApplicationSharedOrganizations(organizationId, applicationId, + applicationSharedOrganizationsList); + return applicationSharedOrganizationsList; + } - return organizations.stream().filter(o -> sharedOrganizationIds.contains(o.getId())).collect( - Collectors.toList()); + @Override + public List getSharedApplications(String organizationId, String applicationId) + throws OrganizationManagementException { + + getListener().preGetSharedApplications(organizationId, applicationId); + ServiceProvider application = getOrgApplication(applicationId, getTenantDomain()); + List sharedApplicationDOList = + getOrgApplicationMgtDAO().getSharedApplications(organizationId, application.getApplicationResourceId()); + List sharedApplications = sharedApplicationDOList.stream() + .map(sharedAppDO -> new SharedApplication(sharedAppDO.getFragmentApplicationId(), + sharedAppDO.getOrganizationId())).collect(Collectors.toList()); + getListener().postGetSharedApplications(organizationId, applicationId, sharedApplications); + return sharedApplications; } @Override @@ -501,6 +530,8 @@ public void shareApplication(String ownerOrgId, String sharedOrgId, ServiceProvi boolean shareWithAllChildren) throws OrganizationManagementException { try { + getListener().preShareApplication(ownerOrgId, mainApplication.getApplicationResourceId(), sharedOrgId, + shareWithAllChildren); // Use tenant of the organization to whom the application getting shared. When the consumer application is // loaded, tenant domain will be derived from the user who created the application. String sharedTenantDomain = getOrganizationManager().resolveTenantDomain(sharedOrgId); @@ -543,10 +574,10 @@ public void shareApplication(String ownerOrgId, String sharedOrgId, ServiceProvi throw handleServerException(ERROR_CODE_ERROR_CREATING_OAUTH_APP, e, mainApplication.getApplicationResourceId(), sharedOrgId); } - + String sharedApplicationId; try { ServiceProvider delegatedApplication = prepareSharedApplication(mainApplication, createdOAuthApp); - String sharedApplicationId = getApplicationManagementService().createApplication(delegatedApplication, + sharedApplicationId = getApplicationManagementService().createApplication(delegatedApplication, sharedOrgId, getAuthenticatedUsername()); getOrgApplicationMgtDAO().addSharedApplication(mainApplication.getApplicationResourceId(), ownerOrgId, sharedApplicationId, sharedOrgId, shareWithAllChildren); @@ -555,6 +586,8 @@ public void shareApplication(String ownerOrgId, String sharedOrgId, ServiceProvi throw handleServerException(ERROR_CODE_ERROR_SHARING_APPLICATION, e, mainApplication.getApplicationResourceId(), sharedOrgId); } + getListener().postShareApplication(ownerOrgId, mainApplication.getApplicationResourceId(), sharedOrgId, + sharedApplicationId, shareWithAllChildren); } finally { PrivilegedCarbonContext.endTenantFlow(); } @@ -758,4 +791,9 @@ private ServiceProvider getDefaultServiceProvider() throws OrganizationManagemen throw new OrganizationManagementServerException("Error while retrieving default service provider", null, e); } } + + private ApplicationSharingManagerListener getListener() { + + return OrgApplicationMgtDataHolder.getInstance().getApplicationSharingManagerListener(); + } } diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/OrgApplicationMgtConstants.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/OrgApplicationMgtConstants.java index a979c5994..731d5f1a3 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/OrgApplicationMgtConstants.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/OrgApplicationMgtConstants.java @@ -34,8 +34,28 @@ public class OrgApplicationMgtConstants { public static final String UPDATE_SP_METADATA_SHARE_WITH_ALL_CHILDREN = "updateShareWithAllChildren"; public static final String DELETE_SHARE_FOR_MAIN_APPLICATION = "deleteShareForMainApp"; - public static final String USER_ORGANIZATION_CLAIM_URI = "http://wso2.org/claims/runtime/user_organization"; + public static final String USER_ORGANIZATION_CLAIM_URI = "http://wso2.org/claims/runtime/user_organization"; public static final String USER_ORGANIZATION_CLAIM = "user_organization"; public static final String OIDC_CLAIM_DIALECT_URI = "http://wso2.org/oidc/claim"; + // Event constants related to shared application management. + public static final String EVENT_PROP_PARENT_ORGANIZATION_ID = "PARENT_ORGANIZATION_ID"; + public static final String EVENT_PROP_SHARED_ORGANIZATION_ID = "SHARED_ORGANIZATION_ID"; + public static final String EVENT_PROP_PARENT_APPLICATION_ID = "PARENT_APPLICATION_ID"; + public static final String EVENT_PROP_SHARED_APPLICATION_ID = "SHARED_APPLICATION_ID"; + public static final String EVENT_PROP_SHARED_APPLICATIONS_DATA = "SHARED_APPLICATIONS_DATA"; + public static final String EVENT_PROP_SHARE_WITH_ALL_CHILDREN = "SHARE_WITH_ALL_CHILDREN"; + public static final String EVENT_PROP_SHARED_ORGANIZATIONS = "SHARED_ORGANIZATIONS"; + public static final String EVENT_PRE_SHARE_APPLICATION = "PRE_SHARE_APPLICATION"; + public static final String EVENT_POST_SHARE_APPLICATION = "POST_SHARE_APPLICATION"; + public static final String EVENT_PRE_DELETE_SHARED_APPLICATION = "PRE_DELETE_SHARED_APPLICATION"; + public static final String EVENT_POST_DELETE_SHARED_APPLICATION = "POST_DELETE_SHARED_APPLICATION"; + public static final String EVENT_PRE_DELETE_ALL_SHARED_APPLICATIONS = "PRE_DELETE_ALL_SHARED_APPLICATIONS"; + public static final String EVENT_POST_DELETE_ALL_SHARED_APPLICATIONS = "POST_DELETE_ALL_SHARED_APPLICATIONS"; + public static final String EVENT_PRE_GET_APPLICATION_SHARED_ORGANIZATIONS = + "PRE_GET_APPLICATION_SHARED_ORGANIZATIONS"; + public static final String EVENT_POST_GET_APPLICATION_SHARED_ORGANIZATIONS = + "POST_GET_APPLICATION_SHARED_ORGANIZATIONS"; + public static final String EVENT_PRE_GET_SHARED_APPLICATIONS = "PRE_GET_SHARED_APPLICATIONS"; + public static final String EVENT_POST_GET_SHARED_APPLICATIONS = "POST_GET_SHARED_APPLICATIONS"; } diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/internal/OrgApplicationMgtDataHolder.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/internal/OrgApplicationMgtDataHolder.java index 46516fde0..d4f92bad4 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/internal/OrgApplicationMgtDataHolder.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/internal/OrgApplicationMgtDataHolder.java @@ -20,8 +20,10 @@ import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService; +import org.wso2.carbon.identity.event.services.IdentityEventService; import org.wso2.carbon.identity.oauth.OAuthAdminServiceImpl; import org.wso2.carbon.identity.organization.management.application.dao.OrgApplicationMgtDAO; +import org.wso2.carbon.identity.organization.management.application.listener.ApplicationSharingManagerListener; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; import org.wso2.carbon.identity.organization.management.service.OrganizationUserResidentResolverService; import org.wso2.carbon.idp.mgt.IdpManager; @@ -42,6 +44,8 @@ public class OrgApplicationMgtDataHolder { private OrganizationManager organizationManager; private OrganizationUserResidentResolverService organizationUserResidentResolverService; private IdpManager idpManager; + private ApplicationSharingManagerListener applicationSharingManagerListener; + private IdentityEventService identityEventService; private ClaimMetadataManagementService claimMetadataManagementService; private OrgApplicationMgtDataHolder() { @@ -203,4 +207,45 @@ public void setClaimMetadataManagementService(ClaimMetadataManagementService cla this.claimMetadataManagementService = claimMetadataManagementService; } + + /** + * Get {@link ApplicationSharingManagerListener}. + * + * @return Application sharing manager listener. + */ + public ApplicationSharingManagerListener getApplicationSharingManagerListener() { + + return applicationSharingManagerListener; + } + + /** + * Set {@link ApplicationSharingManagerListener}. + * + * @param applicationSharingManagerListener Instance of {@link ApplicationSharingManagerListener}. + */ + public void setApplicationSharingManagerListener( + ApplicationSharingManagerListener applicationSharingManagerListener) { + + this.applicationSharingManagerListener = applicationSharingManagerListener; + } + + /** + * Get {@link IdentityEventService}. + * + * @return IdentityEventService. + */ + public IdentityEventService getIdentityEventService() { + + return identityEventService; + } + + /** + * Set {@link IdentityEventService}. + * + * @param identityEventService Instance of {@link IdentityEventService}. + */ + public void setIdentityEventService(IdentityEventService identityEventService) { + + this.identityEventService = identityEventService; + } } diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/internal/OrgApplicationMgtServiceComponent.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/internal/OrgApplicationMgtServiceComponent.java index fa06a3ec0..bbe62ce9f 100644 --- a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/internal/OrgApplicationMgtServiceComponent.java +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/internal/OrgApplicationMgtServiceComponent.java @@ -31,10 +31,12 @@ import org.wso2.carbon.identity.application.mgt.listener.ApplicationMgtListener; import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService; import org.wso2.carbon.identity.event.handler.AbstractEventHandler; +import org.wso2.carbon.identity.event.services.IdentityEventService; import org.wso2.carbon.identity.oauth.OAuthAdminServiceImpl; import org.wso2.carbon.identity.organization.management.application.OrgApplicationManager; import org.wso2.carbon.identity.organization.management.application.OrgApplicationManagerImpl; import org.wso2.carbon.identity.organization.management.application.dao.impl.OrgApplicationMgtDAOImpl; +import org.wso2.carbon.identity.organization.management.application.listener.ApplicationSharingManagerListenerImpl; import org.wso2.carbon.identity.organization.management.application.listener.FragmentApplicationMgtListener; import org.wso2.carbon.identity.organization.management.application.listener.OrganizationCreationHandler; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; @@ -64,6 +66,8 @@ protected void activate(ComponentContext componentContext) { try { OrgApplicationMgtDataHolder.getInstance() .setOrgApplicationMgtDAO(new OrgApplicationMgtDAOImpl()); + OrgApplicationMgtDataHolder.getInstance() + .setApplicationSharingManagerListener(new ApplicationSharingManagerListenerImpl()); BundleContext bundleContext = componentContext.getBundleContext(); bundleContext.registerService(OrgApplicationManager.class.getName(), new OrgApplicationManagerImpl(), null); //Fragment application listener. @@ -195,6 +199,25 @@ protected void unsetIdpManager(IdpManager idpManager) { OrgApplicationMgtDataHolder.getInstance().setIdpManager(null); } + @Reference( + name = "identity.event.service", + service = IdentityEventService.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetIdentityEventService" + ) + protected void setIdentityEventService(IdentityEventService identityEventService) { + + log.debug("Set Identity Event Service."); + OrgApplicationMgtDataHolder.getInstance().setIdentityEventService(identityEventService); + } + + protected void unsetIdentityEventService(IdentityEventService identityEventService) { + + log.debug("Unset Identity Event Service."); + OrgApplicationMgtDataHolder.getInstance().setIdentityEventService(null); + } + @Reference( name = "claim.metadata.management.service", service = ClaimMetadataManagementService.class, diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/listener/ApplicationSharingManagerListener.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/listener/ApplicationSharingManagerListener.java new file mode 100644 index 000000000..af1b76c41 --- /dev/null +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/listener/ApplicationSharingManagerListener.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2023, 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.organization.management.application.listener; + +import org.wso2.carbon.identity.organization.management.application.model.SharedApplication; +import org.wso2.carbon.identity.organization.management.application.model.SharedApplicationDO; +import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException; +import org.wso2.carbon.identity.organization.management.service.model.BasicOrganization; + +import java.util.List; + +/** + * Organization application sharing manager listener. + */ +public interface ApplicationSharingManagerListener { + + /** + * Pre listener of sharing an application. + * + * @param parentOrganizationId Parent application residing organization id. + * @param parentApplicationId Parent application id. + * @param sharedOrganizationId Sub-organization id which the application will be shared to. + * @param shareWithAllChildren Whether the application is shared with all children or not. + * @throws OrganizationManagementException When error occurred during pre application sharing actions. + */ + void preShareApplication(String parentOrganizationId, String parentApplicationId, String sharedOrganizationId, + boolean shareWithAllChildren) throws OrganizationManagementException; + + /** + * Post listener of sharing an application. + * + * @param parentOrganizationId Parent application residing organization id. + * @param parentApplicationId Parent application id. + * @param sharedOrganizationId Sub-organization id which the application will be shared to. + * @param sharedApplicationId Shared application id. + * @param shareWithAllChildren Whether the application is shared with all children or not. + * @throws OrganizationManagementException When error occurred during post application sharing actions. + */ + void postShareApplication(String parentOrganizationId, String parentApplicationId, String sharedOrganizationId, + String sharedApplicationId, boolean shareWithAllChildren) + throws OrganizationManagementException; + + /** + * Pre listener of deleting shared application. + * + * @param parentOrganizationId Parent application residing organization id. + * @param parentApplicationId Parent application id. + * @param sharedOrganizationId Sub-organization id which the shared application is deleted from. + * @throws OrganizationManagementException When error occurred during pre shared application deleting actions. + */ + void preDeleteSharedApplication(String parentOrganizationId, String parentApplicationId, + String sharedOrganizationId) throws OrganizationManagementException; + + /** + * Post listener of deleting shared application. + * + * @param parentOrganizationId Parent application residing organization id. + * @param parentApplicationId Parent application id. + * @param sharedOrganizationId Sub-organization id which the shared application is deleted from. + * @param sharedApplicationId Deleted shared application id. + * @throws OrganizationManagementException When error occurred during post shared application deleting actions. + */ + void postDeleteSharedApplication(String parentOrganizationId, String parentApplicationId, + String sharedOrganizationId, String sharedApplicationId) + throws OrganizationManagementException; + + /** + * Pre listener of deleting all shared applications. + * + * @param parentOrganizationId Parent application residing organization id. + * @param parentApplicationId Parent application id. + * @throws OrganizationManagementException When error occurred during pre delete all shared application actions. + */ + void preDeleteAllSharedApplications(String parentOrganizationId, String parentApplicationId) + throws OrganizationManagementException; + + /** + * Post listener of deleting all shared applications. + * + * @param parentOrganizationId Parent application residing organization id. + * @param parentApplicationId Parent application id. + * @param sharedApplicationDOList Deleted shared application app ids and sub-organization ids. + * @throws OrganizationManagementException When error occurred during post delete all shared application actions. + */ + void postDeleteAllSharedApplications(String parentOrganizationId, String parentApplicationId, + List sharedApplicationDOList) + throws OrganizationManagementException; + + /** + * Pre listener of getting shared organizations of an application. + * + * @param parentOrganizationId Parent application residing organization id. + * @param parentApplicationId Parent application id. + * @throws OrganizationManagementException When error occurred during pre actions of + * getting shared organizations of an application. + */ + void preGetApplicationSharedOrganizations(String parentOrganizationId, String parentApplicationId) + throws OrganizationManagementException; + + /** + * Post listener of getting shared organizations of an application. + * + * @param parentOrganizationId Parent application residing organization id. + * @param parentApplicationId Parent application id. + * @param sharedOrganizations The application's shared organization list. + * @throws OrganizationManagementException When error occurred during post actions of + * getting shared organizations of an application. + */ + void postGetApplicationSharedOrganizations(String parentOrganizationId, String parentApplicationId, + List sharedOrganizations) + throws OrganizationManagementException; + + /** + * Pre listener of get shared applications. + * + * @param parentOrganizationId Parent application residing organization id. + * @param parentApplicationId Parent application id. + * @throws OrganizationManagementException When error occurred during pre actions of getting shared applications. + */ + void preGetSharedApplications(String parentOrganizationId, String parentApplicationId) + throws OrganizationManagementException; + + /** + * Post listener of get shared applications. + * + * @param parentOrganizationId Parent application residing organization id. + * @param parentApplicationId Parent application id. + * @param sharedApplications Shared applications list. + * @throws OrganizationManagementException When error occurred during post actions of getting shared applications. + */ + void postGetSharedApplications(String parentOrganizationId, String parentApplicationId, + List sharedApplications) throws OrganizationManagementException; +} diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/listener/ApplicationSharingManagerListenerImpl.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/listener/ApplicationSharingManagerListenerImpl.java new file mode 100644 index 000000000..491aacbb7 --- /dev/null +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/listener/ApplicationSharingManagerListenerImpl.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2023, 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.organization.management.application.listener; + +import org.wso2.carbon.identity.event.IdentityEventClientException; +import org.wso2.carbon.identity.event.IdentityEventException; +import org.wso2.carbon.identity.event.event.Event; +import org.wso2.carbon.identity.event.services.IdentityEventService; +import org.wso2.carbon.identity.organization.management.application.constant.OrgApplicationMgtConstants; +import org.wso2.carbon.identity.organization.management.application.internal.OrgApplicationMgtDataHolder; +import org.wso2.carbon.identity.organization.management.application.model.SharedApplication; +import org.wso2.carbon.identity.organization.management.application.model.SharedApplicationDO; +import org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants; +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.exception.OrganizationManagementServerException; +import org.wso2.carbon.identity.organization.management.service.model.BasicOrganization; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Listener implementation for organization's application sharing operations. + * Class implements {@link ApplicationSharingManagerListener}. + */ +public class ApplicationSharingManagerListenerImpl implements ApplicationSharingManagerListener { + + @Override + public void preShareApplication(String parentOrganizationId, String parentApplicationId, + String sharedOrganizationId, boolean shareWithAllChildren) + throws OrganizationManagementException { + + Map eventProperties = new HashMap<>(); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID, parentOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID, parentApplicationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARED_ORGANIZATION_ID, sharedOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARE_WITH_ALL_CHILDREN, shareWithAllChildren); + fireEvent(OrgApplicationMgtConstants.EVENT_PRE_SHARE_APPLICATION, eventProperties); + } + + @Override + public void postShareApplication(String parentOrganizationId, String parentApplicationId, + String sharedOrganizationId, String sharedApplicationId, + boolean shareWithAllChildren) throws OrganizationManagementException { + + Map eventProperties = new HashMap<>(); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID, parentOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID, parentApplicationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARED_ORGANIZATION_ID, sharedOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARED_APPLICATION_ID, sharedApplicationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARE_WITH_ALL_CHILDREN, shareWithAllChildren); + fireEvent(OrgApplicationMgtConstants.EVENT_POST_SHARE_APPLICATION, eventProperties); + } + + @Override + public void preDeleteSharedApplication(String parentOrganizationId, String parentApplicationId, + String sharedOrganizationId) throws OrganizationManagementException { + + Map eventProperties = new HashMap<>(); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID, parentOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID, parentApplicationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARED_ORGANIZATION_ID, sharedOrganizationId); + fireEvent(OrgApplicationMgtConstants.EVENT_PRE_DELETE_SHARED_APPLICATION, eventProperties); + } + + @Override + public void postDeleteSharedApplication(String parentOrganizationId, String parentApplicationId, + String sharedOrganizationId, String sharedApplicationId) + throws OrganizationManagementException { + + Map eventProperties = new HashMap<>(); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID, parentOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID, parentApplicationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARED_ORGANIZATION_ID, sharedOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARED_APPLICATION_ID, sharedApplicationId); + fireEvent(OrgApplicationMgtConstants.EVENT_POST_DELETE_SHARED_APPLICATION, eventProperties); + } + + @Override + public void preDeleteAllSharedApplications(String parentOrganizationId, String parentApplicationId) + throws OrganizationManagementException { + + Map eventProperties = new HashMap<>(); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID, parentOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID, parentApplicationId); + fireEvent(OrgApplicationMgtConstants.EVENT_PRE_DELETE_ALL_SHARED_APPLICATIONS, eventProperties); + } + + @Override + public void postDeleteAllSharedApplications(String parentOrganizationId, String parentApplicationId, + List sharedApplicationDOList) + throws OrganizationManagementException { + + Map eventProperties = new HashMap<>(); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID, parentOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID, parentApplicationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARED_APPLICATIONS_DATA, sharedApplicationDOList); + fireEvent(OrgApplicationMgtConstants.EVENT_POST_DELETE_ALL_SHARED_APPLICATIONS, eventProperties); + } + + @Override + public void preGetApplicationSharedOrganizations(String parentOrganizationId, String parentApplicationId) + throws OrganizationManagementException { + + Map eventProperties = new HashMap<>(); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID, parentOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID, parentApplicationId); + fireEvent(OrgApplicationMgtConstants.EVENT_PRE_GET_APPLICATION_SHARED_ORGANIZATIONS, eventProperties); + } + + @Override + public void postGetApplicationSharedOrganizations(String parentOrganizationId, String parentApplicationId, + List sharedOrganizations) + throws OrganizationManagementException { + + Map eventProperties = new HashMap<>(); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID, parentOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID, parentApplicationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARED_ORGANIZATIONS, sharedOrganizations); + fireEvent(OrgApplicationMgtConstants.EVENT_POST_GET_APPLICATION_SHARED_ORGANIZATIONS, eventProperties); + } + + @Override + public void preGetSharedApplications(String parentOrganizationId, String parentApplicationId) + throws OrganizationManagementException { + + Map eventProperties = new HashMap<>(); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID, parentOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID, parentApplicationId); + fireEvent(OrgApplicationMgtConstants.EVENT_PRE_GET_SHARED_APPLICATIONS, eventProperties); + } + + @Override + public void postGetSharedApplications(String parentOrganizationId, String parentApplicationId, + List sharedApplications) + throws OrganizationManagementException { + + Map eventProperties = new HashMap<>(); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_ORGANIZATION_ID, parentOrganizationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_PARENT_APPLICATION_ID, parentApplicationId); + eventProperties.put(OrgApplicationMgtConstants.EVENT_PROP_SHARED_APPLICATIONS_DATA, sharedApplications); + fireEvent(OrgApplicationMgtConstants.EVENT_POST_GET_SHARED_APPLICATIONS, eventProperties); + } + + private void fireEvent(String eventName, Map eventProperties) + throws OrganizationManagementException { + + IdentityEventService eventService = OrgApplicationMgtDataHolder.getInstance().getIdentityEventService(); + try { + Event event = new Event(eventName, eventProperties); + eventService.handleEvent(event); + } catch (IdentityEventClientException e) { + throw new OrganizationManagementClientException(e.getMessage(), e.getMessage(), e.getErrorCode(), e); + } catch (IdentityEventException e) { + throw new OrganizationManagementServerException( + OrganizationManagementConstants.ErrorMessages.ERROR_CODE_ERROR_FIRING_EVENTS.getMessage(), + OrganizationManagementConstants.ErrorMessages.ERROR_CODE_ERROR_FIRING_EVENTS.getCode(), e); + } + } +} diff --git a/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/model/SharedApplication.java b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/model/SharedApplication.java new file mode 100644 index 000000000..c2aaa554b --- /dev/null +++ b/components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/model/SharedApplication.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023, 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.organization.management.application.model; + +/** + * Shared application model. + */ +public class SharedApplication { + + String organizationId; + String sharedApplicationId; + + public SharedApplication(String sharedApplicationId, String organizationId) { + + this.sharedApplicationId = sharedApplicationId; + this.organizationId = organizationId; + } + + public String getOrganizationId() { + + return organizationId; + } + + public String getSharedApplicationId() { + + return sharedApplicationId; + } +}