Skip to content

Commit

Permalink
Restrict shared apps to only use shared roles when shared apps are ac…
Browse files Browse the repository at this point in the history
…cessed
  • Loading branch information
ShanChathusanda93 committed Feb 3, 2025
1 parent 5938f4d commit 5008aea
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.wso2.carbon.identity.role.v2.mgt.core.model.Permission;
import org.wso2.carbon.identity.role.v2.mgt.core.model.Role;
import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleBasicInfo;
import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleProperty;
import org.wso2.carbon.identity.role.v2.mgt.core.model.UserBasicInfo;

import java.util.ArrayList;
Expand Down Expand Up @@ -447,6 +448,11 @@ public void preGetRoleIdListOfUser(String userId, String tenantDomain) throws Id
public void postGetRoleIdListOfUser(List<String> roleIds, String userId, String tenantDomain)
throws IdentityRoleManagementException {

if (!isFragmentApplication()) {
return;
}

filterAndRemoveNonSharedRoles(roleIds, tenantDomain);
}

@Override
Expand All @@ -459,6 +465,45 @@ public void preGetRoleIdListOfGroups(List<String> groupIds, String tenantDomain)
public void postGetRoleIdListOfGroups(List<String> roleIds, String tenantDomain)
throws IdentityRoleManagementException {

if (!isFragmentApplication()) {
return;
}

filterAndRemoveNonSharedRoles(roleIds, tenantDomain);
}

private static boolean isFragmentApplication() {

boolean isFragmentApp = false;
if (IdentityUtil.threadLocalProperties.get().get(ApplicationConstants.IS_FRAGMENT_APP) != null) {
isFragmentApp = Boolean.parseBoolean(IdentityUtil.threadLocalProperties.get().
get(ApplicationConstants.IS_FRAGMENT_APP).toString());
}

return isFragmentApp;
}

private boolean isSharedRole (List<RoleProperty> roleProperties) {

if (CollectionUtils.isEmpty(roleProperties)) {
return false;
}
return roleProperties.stream().anyMatch(property -> "isSharedRole".equals(property.getName())
&& Boolean.parseBoolean(property.getValue()));
}

private void filterAndRemoveNonSharedRoles(List<String> roleIds, String tenantDomain)
throws IdentityRoleManagementException {

Iterator<String> iterator = roleIds.iterator();
while (iterator.hasNext()) {
String roleId = iterator.next();
Role role = ApplicationManagementServiceComponentHolder.getInstance().getRoleManagementServiceV2()
.getRole(roleId, tenantDomain);
if (role.getRoleProperties() != null && !isSharedRole(role.getRoleProperties())) {
iterator.remove();
}
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@
import org.wso2.carbon.identity.application.common.model.IdPGroup;
import org.wso2.carbon.identity.application.common.model.IdentityProvider;
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.ApplicationConstants;
import org.wso2.carbon.identity.application.mgt.ApplicationManagementService;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService;
import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementException;
Expand Down Expand Up @@ -61,6 +65,7 @@
import static org.wso2.carbon.identity.application.authentication.framework.handler.approles.constant.AppRolesConstants.ErrorMessages.ERROR_CODE_RETRIEVING_LOCAL_USER_GROUPS;
import static org.wso2.carbon.identity.application.authentication.framework.handler.approles.constant.AppRolesConstants.ErrorMessages.ERROR_CODE_USER_NULL;
import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.InternalRoleDomains.APPLICATION_DOMAIN;
import static org.wso2.carbon.identity.role.v2.mgt.core.RoleConstants.Error.INVALID_AUDIENCE;
import static org.wso2.carbon.user.mgt.UserMgtConstants.INTERNAL_ROLE;

/**
Expand Down Expand Up @@ -128,18 +133,43 @@ public String[] getAppAssociatedRolesOfFederatedUser(Map<ClaimMapping, String> f
private String[] getAppAssociatedRolesForLocalUser(AuthenticatedUser authenticatedUser, String applicationId)
throws ApplicationRolesException {

Set<String> userRoleIds = getAllRolesOfLocalUser(authenticatedUser);
List<RoleV2> rolesAssociatedWithApp = getRolesAssociatedWithApplication(applicationId,
authenticatedUser.getTenantDomain());
if (StringUtils.isNotEmpty(authenticatedUser.getSharedUserId())) {
// Add the shared role details to the roles list which are associated with the application.
addSharedRoleAssociations(authenticatedUser, rolesAssociatedWithApp, userRoleIds);
}
ServiceProvider app = null;
try {
app = ApplicationManagementService.getInstance()
.getApplicationByResourceId(applicationId, authenticatedUser.getTenantDomain());

return rolesAssociatedWithApp.stream()
.filter(role -> userRoleIds.contains(role.getId()))
.map(role -> appendInternalDomain(role.getName()))
.toArray(String[]::new);
if (app == null) {
throw new ApplicationRolesException(INVALID_AUDIENCE.getCode(),
"Invalid audience. No application found with application id: " + applicationId +
" and tenant domain : " + authenticatedUser.getTenantDomain());
}
if (IdentityUtil.threadLocalProperties.get().get(ApplicationConstants.IS_FRAGMENT_APP) != null) {
IdentityUtil.threadLocalProperties.get().remove(ApplicationConstants.IS_FRAGMENT_APP);
}
if (app.getSpProperties() != null && Arrays.stream(app.getSpProperties())
.anyMatch(property -> ApplicationConstants.IS_FRAGMENT_APP.equals(property.getName())
&& Boolean.parseBoolean(property.getValue()))) {
IdentityUtil.threadLocalProperties.get().put(ApplicationConstants.IS_FRAGMENT_APP, Boolean.TRUE);
}

Set<String> userRoleIds = getAllRolesOfLocalUser(authenticatedUser);
List<RoleV2> rolesAssociatedWithApp = getRolesAssociatedWithApplication(applicationId,
authenticatedUser.getTenantDomain());
if (StringUtils.isNotEmpty(authenticatedUser.getSharedUserId())) {
// Add the shared role details to the roles list which are associated with the application.
addSharedRoleAssociations(authenticatedUser, rolesAssociatedWithApp, userRoleIds);
}

return rolesAssociatedWithApp.stream()
.filter(role -> userRoleIds.contains(role.getId()))
.map(role -> appendInternalDomain(role.getName()))
.toArray(String[]::new);
} catch (IdentityApplicationManagementException e) {
throw new ApplicationRolesException("Error occurred while extracting the application for application : "
+ applicationId, e.getErrorCode());
} finally {
IdentityUtil.threadLocalProperties.get().remove(ApplicationConstants.IS_FRAGMENT_APP);
}
}

private void addSharedRoleAssociations(AuthenticatedUser authenticatedUser, List<RoleV2> rolesAssociatedWithApp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ public List<String> getRoleIdListOfGroups(List<String> groupIds, String tenantDo
List<String> roles = roleDAO.getRoleIdListOfGroups(groupIds, tenantDomain);
for (RoleManagementListener roleManagementListener : roleManagementListenerList) {
if (roleManagementListener.isEnable()) {
roleManagementListener.postGetRoleIdListOfGroups(groupIds, tenantDomain);
roleManagementListener.postGetRoleIdListOfGroups(roles, tenantDomain);
}
}
return roles;
Expand Down

0 comments on commit 5008aea

Please sign in to comment.