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

Support app audience role deletion on app deletion, Add Listeners for AssociatedRole config retrieval service, and Bug fixes #5047

Merged
merged 3 commits into from
Oct 24, 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 @@ -2683,17 +2683,64 @@ public int getTenantIdByApp(String appId) throws IdentityApplicationManagementSe
public String getAllowedAudienceForRoleAssociation(String applicationUUID, String tenantDomain)
throws IdentityApplicationManagementException {

return ApplicationMgtSystemConfig.getInstance().getApplicationDAO()
// Invoking the pre listeners.
Collection<ApplicationMgtListener> preListeners = getApplicationMgtListeners();
for (ApplicationMgtListener listener : preListeners) {
if (listener.isEnable() &&
!listener.doPreGetAllowedAudienceForRoleAssociation(applicationUUID, tenantDomain)) {
throw buildServerException("Error executing doPreGetAllowedAudienceForRoleAssociation operation of " +
"listener: " + getName(listener) + " for application with id: " + applicationUUID);
}
}

String allowedAudience = ApplicationMgtSystemConfig.getInstance().getApplicationDAO()
.getSPPropertyValueByPropertyKey(applicationUUID,
IdentityApplicationConstants.ALLOWED_ROLE_AUDIENCE_PROPERTY_NAME, tenantDomain);
AssociatedRolesConfig associatedRolesConfigExcludingRoles = new AssociatedRolesConfig();
associatedRolesConfigExcludingRoles.setAllowedAudience(allowedAudience);

// Invoking the post listeners.
Collection<ApplicationMgtListener> postListeners = getApplicationMgtListeners();
for (ApplicationMgtListener listener : postListeners) {
if (listener.isEnable() &&
!listener.doPostGetAllowedAudienceForRoleAssociation(associatedRolesConfigExcludingRoles,
applicationUUID, tenantDomain)) {
throw buildServerException(
"Error executing doPostGetAllowedAudienceForRoleAssociation operation of listener: " +
getName(listener) + " for application with id: " + applicationUUID);
}
}
return associatedRolesConfigExcludingRoles.getAllowedAudience();
}

@Override
public List<RoleV2> getAssociatedRolesOfApplication(String applicationUUID, String tenantDomain)
throws IdentityApplicationManagementException {

return ApplicationMgtSystemConfig.getInstance().getApplicationDAO()
// Invoking the pre listeners.
Collection<ApplicationMgtListener> preListeners = getApplicationMgtListeners();
for (ApplicationMgtListener listener : preListeners) {
if (listener.isEnable() &&
!listener.doPreGetAssociatedRolesOfApplication(applicationUUID, tenantDomain)) {
throw buildServerException("Error executing doPreGetAssociatedRolesOfApplication operation of " +
"listener: " + getName(listener) + " for application with id: " + applicationUUID);
}
}

List<RoleV2> associatedRolesOfApplication = ApplicationMgtSystemConfig.getInstance().getApplicationDAO()
.getAssociatedRolesOfApplication(applicationUUID, tenantDomain);

// Invoking the post listeners.
Collection<ApplicationMgtListener> postListeners = getApplicationMgtListeners();
for (ApplicationMgtListener listener : postListeners) {
if (listener.isEnable() &&
!listener.doPostGetAssociatedRolesOfApplication(associatedRolesOfApplication, applicationUUID,
tenantDomain)) {
throw buildServerException("Error executing doPostGetAssociatedRolesOfApplication operation of " +
"listener: " + getName(listener) + " for application with id: " + applicationUUID);
}
}
return associatedRolesOfApplication;
}

private void doPreUpdateChecks(String storedAppName, ServiceProvider updatedApp, String tenantDomain,
Expand Down Expand Up @@ -3040,8 +3087,8 @@ private boolean isAssociatedRolesConfigValid(ServiceProvider serviceProvider, St
return true;
}
String allowedAudienceType =
StringUtils.isNotBlank(associatedRolesConfig.getAllowedAudience()) ? RoleConstants.ORGANIZATION :
associatedRolesConfig.getAllowedAudience();
StringUtils.isBlank(associatedRolesConfig.getAllowedAudience()) ? RoleConstants.ORGANIZATION :
associatedRolesConfig.getAllowedAudience().toLowerCase();
String allowedAudienceId;
switch (allowedAudienceType) {
case RoleConstants.APPLICATION:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2150,7 +2150,7 @@ private AssociatedRolesConfig getAssociatedRoles(String applicationId, Connectio
String allowedAudience =
getSPPropertyValueByPropertyKey(applicationId, ALLOWED_ROLE_AUDIENCE_PROPERTY_NAME, tenantDomain);
associatedRolesConfig.setAllowedAudience(
StringUtils.isNotBlank(allowedAudience) ? allowedAudience : RoleConstants.ORGANIZATION);
StringUtils.isNotBlank(allowedAudience) ? allowedAudience.toLowerCase() : RoleConstants.ORGANIZATION);
return associatedRolesConfig;
}

Expand Down Expand Up @@ -4870,7 +4870,7 @@ private ServiceProviderProperty buildAllowedRoleAudienceProperty(ServiceProvider
return allowedRoleAudienceProperty;
}
String allowedAudience = StringUtils.isNotBlank(associatedRolesConfig.getAllowedAudience()) ?
associatedRolesConfig.getAllowedAudience() : RoleConstants.ORGANIZATION;
associatedRolesConfig.getAllowedAudience().toLowerCase() : RoleConstants.ORGANIZATION;
allowedRoleAudienceProperty.setValue(allowedAudience);
return allowedRoleAudienceProperty;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ protected void activate(ComponentContext context) {
new AuthorizedAPIManagementServiceImpl(), null);

bundleContext.registerService(RoleManagementListener.class, new DefaultRoleManagementListener(), null);
bundleContext.registerService(ApplicationMgtListener.class, new DefaultRoleManagementListener(), null);

// Register the ApplicationValidator.
context.getBundleContext().registerService(ApplicationValidator.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@
package org.wso2.carbon.identity.application.mgt.listener;

import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
import org.wso2.carbon.identity.application.common.model.AssociatedRolesConfig;
import org.wso2.carbon.identity.application.common.model.RoleV2;
import org.wso2.carbon.identity.application.common.model.ServiceProvider;
import org.wso2.carbon.identity.application.mgt.dao.ApplicationDAO;

import java.util.List;

/**
* Definition for the listeners which listens to Application/Service Provider CRUD events.
*/
Expand Down Expand Up @@ -390,4 +394,64 @@ default boolean doPreUpdateApplicationTemplate(ServiceProvider serviceProvider,

return true;
}

/**
* Define any additional action before retrieving the allowed audiences for role association.
*
* @param applicationUUID Application UUID.
* @param tenantDomain Tenant domain.
* @return True if the preprocessing is successful.
* @throws IdentityApplicationManagementException Error occurred while preprocessing actions.
*/
default boolean doPreGetAllowedAudienceForRoleAssociation(String applicationUUID, String tenantDomain)
throws IdentityApplicationManagementException {

return true;
}

/**
* Define any additional action after retrieving the allowed audiences for role association.
*
* @param allowedAudienceForRoleAssociation Allowed audiences for role association.
* @param applicationUUID Application UUID.
* @param tenantDomain Tenant domain.
* @return True if the postprocessing is successful.
* @throws IdentityApplicationManagementException Error occurred while postprocessing actions.
*/
default boolean doPostGetAllowedAudienceForRoleAssociation(AssociatedRolesConfig allowedAudienceForRoleAssociation,
String applicationUUID, String tenantDomain)
throws IdentityApplicationManagementException {

return true;
}

/**
* Define any additional action before retrieving the associated roles of an application.
*
* @param applicationUUID Application UUID.
* @param tenantDomain Tenant domain.
* @return True if the preprocessing is successful.
* @throws IdentityApplicationManagementException Error occurred while preprocessing actions.
*/
default boolean doPreGetAssociatedRolesOfApplication(String applicationUUID, String tenantDomain)
throws IdentityApplicationManagementException {

return true;
}

/**
* Define any additional action after retrieving the associated roles of an application.
*
* @param associatedRolesOfApplication Associated roles of an application.
* @param applicationUUID Application UUID.
* @param tenantDomain Tenant domain.
* @return True if the postprocessing is successful.
* @throws IdentityApplicationManagementException Error occurred while postprocessing actions.
*/
default boolean doPostGetAssociatedRolesOfApplication(List<RoleV2> associatedRolesOfApplication,
String applicationUUID, String tenantDomain)
throws IdentityApplicationManagementException {

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
import org.wso2.carbon.identity.application.common.model.AuthorizedScopes;
import org.wso2.carbon.identity.application.common.model.ServiceProvider;
import org.wso2.carbon.identity.application.common.model.ServiceProviderProperty;
import org.wso2.carbon.identity.application.mgt.ApplicationManagementService;
import org.wso2.carbon.identity.application.mgt.AuthorizedAPIManagementService;
import org.wso2.carbon.identity.application.mgt.AuthorizedAPIManagementServiceImpl;
import org.wso2.carbon.identity.application.mgt.internal.ApplicationManagementServiceComponentHolder;
import org.wso2.carbon.identity.application.mgt.internal.cache.ServiceProviderByResourceIdCache;
import org.wso2.carbon.identity.application.mgt.internal.cache.ServiceProviderResourceIdCacheKey;
import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementClientException;
Expand All @@ -41,16 +41,16 @@
import java.util.ArrayList;
import java.util.List;

import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.ALLOWED_ROLE_AUDIENCE_PROPERTY_NAME;
import static org.wso2.carbon.identity.role.v2.mgt.core.RoleConstants.APPLICATION;
import static org.wso2.carbon.identity.role.v2.mgt.core.RoleConstants.Error.INVALID_AUDIENCE;
import static org.wso2.carbon.identity.role.v2.mgt.core.RoleConstants.Error.INVALID_PERMISSION;
import static org.wso2.carbon.identity.role.v2.mgt.core.RoleConstants.Error.UNEXPECTED_SERVER_ERROR;

/**
* Default Role Management Listener implementation of Role Management V2 Listener.
* Default Role Management Listener implementation of Role Management V2 Listener,
* and application based role management.
*/
public class DefaultRoleManagementListener implements RoleManagementListener {
public class DefaultRoleManagementListener extends AbstractApplicationMgtListener implements RoleManagementListener {

private static final AuthorizedAPIManagementService authorizedAPIManagementService =
new AuthorizedAPIManagementServiceImpl();
Expand Down Expand Up @@ -456,15 +456,9 @@ private void validateApplicationRoleAudience(String applicationId, String tenant
"Invalid audience. No application found with application id: " + applicationId +
" and tenant domain : " + tenantDomain);
}
boolean valid = false;
for (ServiceProviderProperty property : app.getSpProperties()) {
// TODO : use osgi service to get this
if (ALLOWED_ROLE_AUDIENCE_PROPERTY_NAME.equals(property.getName()) &&
APPLICATION.equalsIgnoreCase(property.getValue())) {
valid = true;
}
}
if (!valid) {
String allowedAudienceForRoleAssociation = ApplicationManagementService.getInstance()
.getAllowedAudienceForRoleAssociation(app.getApplicationResourceId(), tenantDomain);
if (!APPLICATION.equalsIgnoreCase(allowedAudienceForRoleAssociation.toLowerCase())) {
throw new IdentityRoleManagementClientException(INVALID_AUDIENCE.getCode(),
"Application: " + applicationId + " does not have Application role audience type");
}
Expand Down Expand Up @@ -543,4 +537,19 @@ private String getApplicationName(String applicationID, String tenantDomain)
throw new IdentityRoleManagementServerException(UNEXPECTED_SERVER_ERROR.getCode(), errorMessage, e);
}
}

@Override
public boolean doPostDeleteApplication(ServiceProvider serviceProvider, String tenantDomain, String userName)
throws IdentityApplicationManagementException {

try {
ApplicationManagementServiceComponentHolder.getInstance().getRoleManagementServiceV2()
.deleteRolesByApplication(serviceProvider.getApplicationResourceId(), tenantDomain);
} catch (IdentityRoleManagementException e) {
throw new IdentityApplicationManagementException(
String.format("Error occurred while deleting roles created for the application: %s.",
serviceProvider.getApplicationName()), e);
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ private void validateOrganizationRoleAudience(String audienceId, String roleCrea
OrganizationManager organizationManager = RoleManagementServiceComponentHolder.getInstance()
.getOrganizationManager();
String orgIdOfTenantDomain = organizationManager.resolveOrganizationId(roleCreationTenantDomain);
if (orgIdOfTenantDomain == null || orgIdOfTenantDomain.equalsIgnoreCase(audienceId)) {
if (orgIdOfTenantDomain == null || !orgIdOfTenantDomain.equalsIgnoreCase(audienceId)) {
throw new IdentityRoleManagementClientException(INVALID_AUDIENCE.getCode(),
"Invalid audience. Given Organization id: " + audienceId + " is invalid");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,7 @@ private List<RoleDTO> getHybridRolesByApplication(String applicationId, String t
throws IdentityRoleManagementException {

List<RoleDTO> hybridRoles = new ArrayList<>();
try (Connection connection = IdentityDatabaseUtil.getDBConnection(false);
try (Connection connection = IdentityDatabaseUtil.getUserDBConnection(false);
NamedPreparedStatement statement = new NamedPreparedStatement(connection, GET_ROLES_BY_APP_ID_SQL)) {

statement.setInt(RoleConstants.RoleTableColumns.UM_TENANT_ID, IdentityTenantUtil.getTenantId(tenantDomain));
Expand Down
Loading