Skip to content

Conversation

@sahandilshan
Copy link
Contributor

Purpose

$subject

TODOs:

  • Implementation for Get shared application with hierarchical order
  • Need to test out edge cases
  • Need to add unit tests

@sahandilshan sahandilshan force-pushed the selective-role-sharing branch from 7d1ddeb to 08e73a2 Compare May 28, 2025 05:45
- Provide the support to get application with filtering option.
- Add new error message for application sharing
- Moved application share operations models to a new package
@sahandilshan sahandilshan force-pushed the selective-role-sharing branch from 08e73a2 to 732dfc9 Compare June 1, 2025 13:22
@sahandilshan sahandilshan marked this pull request as ready for review June 1, 2025 15:42
# Conflicts:
#	components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/OrgApplicationManagerImpl.java
#	components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/constant/OrgApplicationMgtConstants.java
#	components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/internal/OrgApplicationMgtDataHolder.java
#	components/org.wso2.carbon.identity.organization.management.application/src/main/java/org/wso2/carbon/identity/organization/management/application/internal/OrgApplicationMgtServiceComponent.java
org.wso2.carbon.identity.role.v2.mgt.core.*;
version="${carbon.identity.package.import.version.range}",
org.wso2.carbon; version="${carbon.kernel.package.import.version.range}",
*;resolution:=optional,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove before merging, by adding all required imports

org.wso2.carbon.identity.role.v2.mgt.core.*;
version="${carbon.identity.package.import.version.range}",
org.wso2.carbon; version="${carbon.kernel.package.import.version.range}",
*;resolution:=optional,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Properly fix the imports

// This is done to ensure that the sharing is done in a way that respects the organization hierarchy.
List<SelectiveShareApplicationOperation> orgsThatNeedToBeShared = processAndSortOrganizationShares(
filteredChildOrgConfigs, mainOrganizationId);
if (CollectionUtils.isEmpty(orgsThatNeedToBeShared)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the APIs with this change

- Convert logs to debug
- Convert the ShareRoleMgt behaviour to previous behavior
@sahandilshan sahandilshan force-pushed the selective-role-sharing branch from 045e793 to dfdd654 Compare June 11, 2025 11:25
- Improve logging
- Add unit tests
- Reduce using start tenant flows
- Optimize to execute less DB queries
@codecov
Copy link

codecov bot commented Jun 11, 2025

Codecov Report

Attention: Patch coverage is 26.86145% with 776 lines in your changes missing coverage. Please review.

Project coverage is 52.16%. Comparing base (2569253) to head (73f2fca).
Report is 77 commits behind head on main.

Files with missing lines Patch % Lines
...ation/management/handler/SharedRoleMgtHandler.java 37.75% 202 Missing and 42 partials ⚠️
...application/util/OrgApplicationShareProcessor.java 35.10% 106 Missing and 16 partials ⚠️
...lication/listener/OrganizationCreationHandler.java 0.00% 97 Missing ⚠️
...management/application/util/FilterQueriesUtil.java 0.00% 79 Missing ⚠️
...istener/ApplicationSharingManagerListenerImpl.java 0.00% 43 Missing ⚠️
...application/dao/impl/OrgApplicationMgtDAOImpl.java 0.00% 39 Missing ⚠️
...plication/util/OrgApplicationScimFilterParser.java 0.00% 24 Missing ⚠️
...ation/model/SharedApplicationOrganizationNode.java 0.00% 20 Missing ⚠️
...del/operation/ApplicationShareUpdateOperation.java 0.00% 19 Missing ⚠️
.../management/application/OrgApplicationManager.java 0.00% 14 Missing ⚠️
... and 10 more

❌ Your patch status has failed because the patch coverage (26.86%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##               main     #512      +/-   ##
============================================
- Coverage     55.49%   52.16%   -3.34%     
- Complexity     1980     2080     +100     
============================================
  Files           184      196      +12     
  Lines         11213    12840    +1627     
  Branches       1639     1936     +297     
============================================
+ Hits           6223     6698     +475     
- Misses         4460     5519    +1059     
- Partials        530      623      +93     
Flag Coverage Δ
unit 36.06% <26.86%> (-0.37%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines +134 to +139
} else {
// The string does not match the strict pattern.
throw new OrganizationManagementClientException("Invalid filter string format",
ERROR_CODE_INVALID_ORGANIZATION_PATH_FILTER.getDescription(),
ERROR_CODE_INVALID_ORGANIZATION_PATH_FILTER.getCode());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else {
// The string does not match the strict pattern.
throw new OrganizationManagementClientException("Invalid filter string format",
ERROR_CODE_INVALID_ORGANIZATION_PATH_FILTER.getDescription(),
ERROR_CODE_INVALID_ORGANIZATION_PATH_FILTER.getCode());
}
}
// The string does not match the strict pattern.
throw new OrganizationManagementClientException("Invalid filter string format",
ERROR_CODE_INVALID_ORGANIZATION_PATH_FILTER.getDescription(),
ERROR_CODE_INVALID_ORGANIZATION_PATH_FILTER.getCode());

* The class enforces a strict format and provides a method to extract the organization ID
* and an optional path attribute (e.g., ".roles").
*/
public class OrgApplicationScimFilterParser {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change the class name excluding SCIM, it's fine to have in the comment

Comment on lines +273 to +274
error) {
return new OrganizationManagementClientException(error.getMessage(), error.getDescription(), error.getCode());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing new line after method signature

*
* @param error The error enum.
* @param e The error.
* @return OrganizationManagementServerException
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

complete the comment

import org.wso2.carbon.identity.application.common.model.ApplicationBasicInfo;
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.application.model.SharedApplicationOrganizationNodePage;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the year range in copy right header.
Check other classes as well

throws OrganizationManagementException {

throw new NotImplementedException(
"selectiveShareOrganizationApplication method is not implemented in " + this.getClass().getName());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"selectiveShareOrganizationApplication method is not implemented in " + this.getClass().getName());
"shareApplicationWithSelectedOrganizations method is not implemented in " + this.getClass().getName());

throws OrganizationManagementException {

throw new NotImplementedException(
"generalOrganizationApplicationShare method is not implemented in " + this.getClass().getName());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"generalOrganizationApplicationShare method is not implemented in " + this.getClass().getName());
"shareApplicationWithAllOrganizations method is not implemented in " + this.getClass().getName());

if (!parentOrgId.equals(ownerOrgId)) {
Optional<String> parentOrgSharedAppId = resolveSharedApp(
mainApplication.getApplicationResourceId(), ownerOrgId, parentOrgId);
if (!parentOrgSharedAppId.isPresent()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible for an application to be shared with the immediate parent organization, but not with higher-level parent organizations in the hierarchy?

@sahandilshan sahandilshan force-pushed the selective-role-sharing branch from f99fb05 to 73f2fca Compare June 15, 2025 16:10
parentOrgId);
if (!sharedAppIdOptional.isPresent()) {
// No shared application found for the main application.
// TODO: Should we throw an error here and fail org creation?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix this todo

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are few more todos in the code

@AnuradhaSK AnuradhaSK requested a review from Copilot June 19, 2025 16:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request adds support for selective role sharing in application sharing, along with new operations and modifications to the DAO, listener, and manager interfaces to integrate resource sharing policies. Key changes include the introduction of SelectiveShareApplicationOperation, updates to role-sharing configuration classes and events, and enhancements in SQL query building for shared applications.

Reviewed Changes

Copilot reviewed 20 out of 33 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
ApplicationShareRolePolicy.java Added builder and enum changes for role sharing policies.
OrganizationCreationHandler.java Updated event handling to support new resource sharing exceptions and role sharing logic.
OrgApplicationMgtDAOImpl.java Modified DAO methods to support filtering and new shared application retrieval queries.
OrgApplicationManager.java & ApplicationSharingManagerListener*.java Introduced new methods for selective and policy-based application sharing.
Other files (various listener, model, constants, pom.xml) Updated imports and integrated resource sharing policy support across components.

Comment on lines +195 to +200
if (ApplicationShareRolePolicy.Mode.SELECTED.ordinal() == roleSharingMode.ordinal()) {

// That mean the original application is available in the parent org. Not a fragment application.
for (SharedResourceAttribute sharedResourceAttribute : sharedResourceAttributes) {
if (SharedAttributeType.ROLE.ordinal() != sharedResourceAttribute.getSharedAttributeType()
.ordinal()) {
Copy link

Copilot AI Jun 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid using ordinal() for enum comparisons as it can be error-prone if the enum order changes. It is recommended to use equals() for comparing enum values.

Suggested change
if (ApplicationShareRolePolicy.Mode.SELECTED.ordinal() == roleSharingMode.ordinal()) {
// That mean the original application is available in the parent org. Not a fragment application.
for (SharedResourceAttribute sharedResourceAttribute : sharedResourceAttributes) {
if (SharedAttributeType.ROLE.ordinal() != sharedResourceAttribute.getSharedAttributeType()
.ordinal()) {
if (ApplicationShareRolePolicy.Mode.SELECTED == roleSharingMode) {
// That mean the original application is available in the parent org. Not a fragment application.
for (SharedResourceAttribute sharedResourceAttribute : sharedResourceAttributes) {
if (SharedAttributeType.ROLE != sharedResourceAttribute.getSharedAttributeType()) {

Copilot uses AI. Check for mistakes.
String filterQuery = filterQueryBuilder.getFilterQuery();
Map<String, String> filterAttributeValue = filterQueryBuilder.getFilterAttributeValue();
String placeholders = IntStream.range(0, sharedOrgIds.size())
.mapToObj(i -> ":" + SHARED_ORG_ID_PLACEHOLDER_PREFIX + i + ";")
Copy link

Copilot AI Jun 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The placeholder construction appends a semicolon to the parameter name, which may not match with the parameter keys when setting them. Remove the trailing semicolon to ensure the parameter names remain consistent.

Suggested change
.mapToObj(i -> ":" + SHARED_ORG_ID_PLACEHOLDER_PREFIX + i + ";")
.mapToObj(i -> ":" + SHARED_ORG_ID_PLACEHOLDER_PREFIX + i)

Copilot uses AI. Check for mistakes.
Comment on lines +201 to +203



Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove unwanted newlines

// Filter only valid child org configs that exist in the owner's child orgs using the map (O(1) lookups).
List<SelectiveShareApplicationOperation> filteredChildOrgConfigs = selectiveShareApplicationList.stream()
.filter(config -> subOrganizationIdsSet.contains(config.getOrganizationId()))
.collect(Collectors.toList());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better if we can add a debug log for invalid child org IDs sent.

// 3. Collect valid organization IDs and validate complete hierarchy paths.
Set<String> availableOrgIds = new HashSet<>(selectiveShareApplicationList.size());
Map<String, SelectiveShareApplicationOperation> orgIdToConfigMap = new HashMap<>(
selectiveShareApplicationList.size());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using a set for availableOrgIds we can use, orgIdToConfigMap.keySet() which returns the list of available organization IDs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Map.keySet() returns a live view of the map’s keys. It's backed directly by the map — no copying or new allocation.

parentConfig.getPolicy(),
parentConfig.getRoleSharing()
);
effectiveConfigs.put(descendantId, inheritedConfig);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can there be descendantId in the effectiveConfigs if we are iterating the Ids in the bfsOrder?

// Find organizations that are no longer in the share config and need to be unshared.
List<SharedApplicationDO> orgsThatOmitted = sharedApplications.stream()
.filter(sharedApp -> !configOrgIds.contains(sharedApp.getOrganizationId()))
.collect(Collectors.toList());
Copy link
Contributor

@HasiniSama HasiniSama Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will omit all orgs not sent in the request and gets unshared along with it's child orgs. And if it is present in the orgsThatNeedToBeShared list, get reshared again. Can't we remove it from both lists if the config is unchanged? It could reduce the overhead, as a whole subtree would not get unshared/reshared.

// mainApplication.getApplicationResourceId(), sharedOrgId);
// }
// return sharedApplicationId;
// }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there a particular reason this part is commented out?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods can be removed

@HasiniSama HasiniSama merged commit 73f2fca into wso2-extensions:main Jul 22, 2025
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants