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

Trigger events on shared application mgt operations and add new service to return shared app data #190

Merged
merged 3 commits into from
Feb 20, 2023
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 @@ -168,6 +168,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}",
</Import-Package>
</instructions>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -63,6 +64,17 @@ void deleteSharedApplication(String organizationId, String applicationId, String
List<BasicOrganization> 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<SharedApplication> getSharedApplications(String ownerOrgId, String mainAppId)
throws OrganizationManagementException;

/**
* Resolve the shared application id based on the organization link and the identifier of the main application.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<SharedApplicationDO> 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<String> sharedApplicationId =
resolveSharedApp(serviceProvider.getApplicationResourceId(), organizationId,
AnuradhaSK marked this conversation as resolved.
Show resolved Hide resolved
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);
Expand All @@ -265,48 +273,51 @@ 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<String> 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<String> 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);
}
}

@Override
public List<BasicOrganization> getApplicationSharedOrganizations(String organizationId, String applicationId)
throws OrganizationManagementException {

getListener().preGetApplicationSharedOrganizations(organizationId, applicationId);
ServiceProvider application = getOrgApplication(applicationId, getTenantDomain());
List<SharedApplicationDO> sharedApps =
getOrgApplicationMgtDAO().getSharedApplications(organizationId, application.getApplicationResourceId());
Expand All @@ -315,9 +326,27 @@ public List<BasicOrganization> getApplicationSharedOrganizations(String organiza
Collectors.toList());

List<BasicOrganization> organizations = getOrganizationManager().getChildOrganizations(organizationId, true);
List<BasicOrganization> 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<SharedApplication> getSharedApplications(String organizationId, String applicationId)
throws OrganizationManagementException {

getListener().preGetSharedApplications(organizationId, applicationId);
ServiceProvider application = getOrgApplication(applicationId, getTenantDomain());
List<SharedApplicationDO> sharedApplicationDOList =
getOrgApplicationMgtDAO().getSharedApplications(organizationId, application.getApplicationResourceId());
AnuradhaSK marked this conversation as resolved.
Show resolved Hide resolved
List<SharedApplication> sharedApplications = sharedApplicationDOList.stream()
.map(sharedAppDO -> new SharedApplication(sharedAppDO.getFragmentApplicationId(),
sharedAppDO.getOrganizationId())).collect(Collectors.toList());
getListener().postGetSharedApplications(organizationId, applicationId, sharedApplications);
return sharedApplications;
}

@Override
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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();
}
Expand Down Expand Up @@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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() {
Expand Down Expand Up @@ -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;
}
}
Loading