Skip to content

Commit

Permalink
Support new RoleV2 for parent user invite flow
Browse files Browse the repository at this point in the history
Remove unwanted file addition

Fix minor issue

Add improvement to the implementation
  • Loading branch information
Kanapriya committed Nov 8, 2023
1 parent 2cfdca6 commit f172b11
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.event</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.organization.management</groupId>
<artifactId>org.wso2.carbon.identity.organization.management.role.management.service</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.role.v2.mgt.core</artifactId>
</dependency>
<!--Test Dependencies-->
<dependency>
<groupId>org.testng</groupId>
Expand Down Expand Up @@ -131,12 +139,15 @@
org.wso2.carbon.identity.organization.management.service.constant; version="${org.wso2.identity.organization.mgt.core.imp.pkg.version.range}",
org.wso2.carbon.identity.organization.management.service.util;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}",
org.wso2.carbon.identity.organization.management.service.exception;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}",
org.wso2.carbon.identity.organization.management.role.management.service;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}",
org.wso2.carbon.user.api;version="${carbon.user.api.imp.pkg.version.range}",
org.wso2.carbon.user.core;version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.user.core.common;version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.user.core.listener;version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.user.core.service;version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.user.core.util;version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.identity.role.v2.mgt.core;version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.role.v2.mgt.core.exception;version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.organization.management.organization.user.sharing;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}",
org.wso2.carbon.identity.organization.management.organization.user.sharing.constant;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}",
org.wso2.carbon.identity.organization.management.organization.user.sharing.models;version="${org.wso2.identity.organization.mgt.imp.pkg.version.range}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import org.wso2.carbon.identity.event.IdentityEventException;
import org.wso2.carbon.identity.event.event.Event;
import org.wso2.carbon.identity.organization.management.organization.user.sharing.OrganizationUserSharingService;
import org.wso2.carbon.identity.organization.management.organization.user.sharing.OrganizationUserSharingServiceImpl;
import org.wso2.carbon.identity.organization.management.organization.user.sharing.internal.OrganizationUserSharingDataHolder;
import org.wso2.carbon.identity.organization.management.organization.user.sharing.util.OrganizationSharedUserUtil;
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
Expand All @@ -41,6 +43,8 @@
import org.wso2.carbon.identity.organization.user.invitation.management.internal.UserInvitationMgtDataHolder;
import org.wso2.carbon.identity.organization.user.invitation.management.models.Invitation;
import org.wso2.carbon.identity.organization.user.invitation.management.models.RoleAssignments;
import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService;
import org.wso2.carbon.identity.role.v2.mgt.core.exception.IdentityRoleManagementException;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.core.common.AbstractUserStoreManager;
Expand All @@ -50,7 +54,9 @@
import java.security.SecureRandom;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -78,6 +84,7 @@
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.UserInvitationMgtConstants.ErrorMessage.ERROR_CODE_INVALID_CONFIRMATION_CODE;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.UserInvitationMgtConstants.ErrorMessage.ERROR_CODE_INVALID_FILTER;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.UserInvitationMgtConstants.ErrorMessage.ERROR_CODE_INVALID_INVITATION_ID;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.UserInvitationMgtConstants.ErrorMessage.ERROR_CODE_INVALID_ROLE;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.UserInvitationMgtConstants.ErrorMessage.ERROR_CODE_INVITATION_EXPIRED;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.UserInvitationMgtConstants.ErrorMessage.ERROR_CODE_NO_INVITATION_FOR_USER;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.UserInvitationMgtConstants.ErrorMessage.ERROR_CODE_UNABLE_TO_RESEND_INVITATION;
Expand Down Expand Up @@ -107,6 +114,8 @@ public Invitation createInvitation(Invitation invitation) throws UserInvitationM
String organizationId = Utils.getOrganizationId();
OrganizationManager organizationManager = UserInvitationMgtDataHolder.getInstance()
.getOrganizationManagerService();
RoleManagementService roleManagementService = UserInvitationMgtDataHolder.getInstance()
.getRoleManagementService();
Invitation createdInvitation;
try {
// Checking the parent organization id
Expand All @@ -125,6 +134,7 @@ public Invitation createInvitation(Invitation invitation) throws UserInvitationM
String.format(ERROR_CODE_ACTIVE_INVITATION_EXISTS.getDescription(), invitation.getUsername()));
}
int parentTenantId = IdentityTenantUtil.getTenantId(parentTenantDomain);
String invitedTenantDomain = organizationManager.resolveTenantDomain(organizationId);
AbstractUserStoreManager userStoreManager = getAbstractUserStoreManager(parentTenantId);
String userDomainQualifiedUserName = UserCoreUtil
.addDomainToName(invitation.getUsername(), invitation.getUserDomain());
Expand All @@ -141,16 +151,27 @@ public Invitation createInvitation(Invitation invitation) throws UserInvitationM
invitation.setInvitedOrganizationId(organizationId);
invitation.setStatus(STATUS_PENDING);
if (ArrayUtils.isNotEmpty(invitation.getRoleAssignments())) {
// ToDO : Check the role existence by introducing a role validation service.

for (RoleAssignments roleAssignments : invitation.getRoleAssignments()) {
String[] roles = roleAssignments.getRoles();
for (String roleId : roles) {
if (!roleManagementService.isExistingRole(roleId, invitedTenantDomain)) {
LOG.error("Role: " + roleId + " is not exists in the organization: "
+ organizationId);
throw new UserInvitationMgtClientException(ERROR_CODE_INVALID_ROLE.getCode(),
ERROR_CODE_INVALID_ROLE.getMessage(),
String.format(ERROR_CODE_INVALID_ROLE.getDescription(), roleId));
}
}
}
invitation.setRoleAssignments(invitation.getRoleAssignments());
}
invitation.setInvitationId(UUID.randomUUID().toString());
invitation.setConfirmationCode(UUID.randomUUID().toString());
userInvitationDAO.createInvitation(invitation);
createdInvitation = userInvitationDAO.getInvitationByInvitationId(invitation.getInvitationId());
// Trigger the event for invitation creation
triggerInvitationAddNotification(createdInvitation);
} catch (UserStoreException | OrganizationManagementException e) {
} catch (UserStoreException | OrganizationManagementException | IdentityRoleManagementException e) {
throw new UserInvitationMgtServerException(ERROR_CODE_CREATE_INVITATION.getCode(),
ERROR_CODE_CREATE_INVITATION.getMessage(),
String.format(ERROR_CODE_CREATE_INVITATION.getDescription(), invitation.getUsername()), e);
Expand All @@ -165,8 +186,11 @@ public boolean acceptInvitation(String confirmationCode) throws UserInvitationMg
if (invitation != null) {
if (invitation.getExpiredAt().getTime() > Instant.now().toEpochMilli()) {
try {
OrganizationUserSharingService userSharingService = new OrganizationUserSharingServiceImpl();
OrganizationManager organizationManager = UserInvitationMgtDataHolder.getInstance()
.getOrganizationManagerService();
RoleManagementService roleManagementService = OrganizationUserSharingDataHolder.getInstance()
.getRoleManagementService();
String invitedOrganizationId = invitation.getInvitedOrganizationId();
String invitedTenantDomain = organizationManager.resolveTenantDomain(invitedOrganizationId);
int invitedTenantId = IdentityTenantUtil.getTenantId(invitedTenantDomain);
Expand All @@ -187,13 +211,34 @@ public boolean acceptInvitation(String confirmationCode) throws UserInvitationMg
String userId = getInvitedUserId(invitation);
getOrganizationUserSharingService().shareOrganizationUser(invitedOrganizationId, userId,
invitation.getUserOrganizationId());
String associatedUserId = userSharingService
.getUserAssociationOfAssociatedUserByOrgId(userId, invitedOrganizationId).getUserId();
// Trigger event to add the role assignments if any available in the invitation.
if (ArrayUtils.isNotEmpty(invitation.getRoleAssignments())) {
// Get the available group name for the group in the invited organization.
String availableGroupName = getAvailableGroupName();
userStoreManager.addRole(availableGroupName, new String[]{invitation.getUserDomain()}, null);
triggerRoleAssignmentEvent(invitedOrganizationId, availableGroupName,
Arrays.asList(invitation.getRoleAssignments()));
ArrayList<String> availableRoleNames = new ArrayList<String>();
for (RoleAssignments roleAssignments : invitation.getRoleAssignments()) {
String[] roles = roleAssignments.getRoles();
for (String roleId : roles) {
if (roleManagementService.isExistingRole(roleId, invitedTenantDomain)) {
availableRoleNames.add(roleId);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Role: " + roleId + " is not exist in the invitedTenantDomain : "
+ invitedTenantDomain);
}
}
}
}
availableRoleNames.forEach((role) -> {
try {
roleManagementService.updateUserListOfRole(role,
Collections.singletonList(associatedUserId), Collections.emptyList(),
invitedTenantDomain);
} catch (IdentityRoleManagementException e) {
LOG.error("An error occurred while assigning the role: "
+ role + " to the user: " + associatedUserId);
}
});
}
// Removing the invitation since the user is added to the organization.
if (LOG.isDebugEnabled()) {
Expand All @@ -203,7 +248,7 @@ public boolean acceptInvitation(String confirmationCode) throws UserInvitationMg
}
userInvitationDAO.deleteInvitation(invitation.getInvitationId());
return true;
} catch (UserStoreException | OrganizationManagementException e) {
} catch (UserStoreException | OrganizationManagementException | IdentityRoleManagementException e) {
UserCoreUtil.removeSkipPasswordPatternValidationThreadLocal();
throw new UserInvitationMgtServerException(ERROR_CODE_ACCEPT_INVITATION.getCode(),
ERROR_CODE_ACCEPT_INVITATION.getMessage(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ public enum ErrorMessage {
ERROR_CODE_INVALID_USER("10028",
"Invalid user identification provided.",
"Authenticated user %s is not entitled for the invitation."),
ERROR_CODE_INVALID_ROLE("10029",
"Invalid role identification provided.",
"Could not find a role with given roleId %s."),

// DAO layer errors
ERROR_CODE_STORE_INVITATION("10501",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.wso2.carbon.identity.event.services.IdentityEventService;
import org.wso2.carbon.identity.organization.management.organization.user.sharing.OrganizationUserSharingService;
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService;
import org.wso2.carbon.user.core.service.RealmService;

/**
Expand All @@ -34,6 +35,7 @@ public class UserInvitationMgtDataHolder {
private IdentityEventService identityEventService;
private OrganizationManager organizationManager;
private OrganizationUserSharingService organizationUserSharingService;
private RoleManagementService roleManagementService;

public static UserInvitationMgtDataHolder getInstance() {

Expand Down Expand Up @@ -80,4 +82,24 @@ public void setOrganizationUserSharingService(

this.organizationUserSharingService = organizationUserSharingService;
}

/**
* Get the organization role manager service.
*
* @return Organization role manager service.
*/
public RoleManagementService getRoleManagementService() {

return roleManagementService;
}

/**
* Set the organization role manager service.
*
* @param roleManagementService Organization role manager service.
*/
public void setRoleManagementService(RoleManagementService roleManagementService) {

this.roleManagementService = roleManagementService;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.wso2.carbon.identity.organization.user.invitation.management.InvitationCoreService;
import org.wso2.carbon.identity.organization.user.invitation.management.InvitationCoreServiceImpl;
import org.wso2.carbon.identity.organization.user.invitation.management.handler.UserInvitationEventHandler;
import org.wso2.carbon.identity.role.v2.mgt.core.RoleManagementService;
import org.wso2.carbon.user.core.service.RealmService;

/**
Expand Down Expand Up @@ -137,4 +138,20 @@ protected void unsetOrganizationUserAssociationService(
UserInvitationMgtDataHolder.getInstance().setOrganizationUserSharingService(null);
LOG.debug("Unset organization user association Service.");
}

@Reference(
name = "RoleManagementService",
service = RoleManagementService.class,
cardinality = ReferenceCardinality.MANDATORY,
policy = ReferencePolicy.DYNAMIC,
unbind = "unsetRoleManagementService")
protected void setRoleManagementService(RoleManagementService roleManagementService) {

UserInvitationMgtDataHolder.getInstance().setRoleManagementService(roleManagementService);
}

protected void unsetRoleManagementService(RoleManagementService roleManagementService) {

UserInvitationMgtDataHolder.getInstance().setRoleManagementService(null);
}
}

0 comments on commit f172b11

Please sign in to comment.