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 new RoleV2 for parent user invite flow #287

Merged
merged 4 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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 @@ -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>
Kanapriya marked this conversation as resolved.
Show resolved Hide resolved
</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,16 @@
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}",
Kanapriya marked this conversation as resolved.
Show resolved Hide resolved
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.role.v2.mgt.core.model;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 @@ -41,6 +41,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 @@ -51,6 +53,7 @@
import java.sql.Timestamp;
import java.time.Instant;
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 +81,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 +111,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 +131,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 +148,23 @@ 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 roleAssignment : invitation.getRoleAssignments()) {
if (!roleManagementService.isExistingRole(roleAssignment.getRole(), invitedTenantDomain)) {
LOG.error("Role: " + roleAssignment.getRole() + " is not exists in the organization: "
+ organizationId);
Kanapriya marked this conversation as resolved.
Show resolved Hide resolved
throw new UserInvitationMgtClientException(ERROR_CODE_INVALID_ROLE.getCode(),
ERROR_CODE_INVALID_ROLE.getMessage(),
String.format(ERROR_CODE_INVALID_ROLE.getDescription(), roleAssignment.getRole()));
}
}
}
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 @@ -167,6 +181,8 @@ public boolean acceptInvitation(String confirmationCode) throws UserInvitationMg
try {
OrganizationManager organizationManager = UserInvitationMgtDataHolder.getInstance()
.getOrganizationManagerService();
RoleManagementService roleManagementService = UserInvitationMgtDataHolder.getInstance()
.getRoleManagementService();
String invitedOrganizationId = invitation.getInvitedOrganizationId();
String invitedTenantDomain = organizationManager.resolveTenantDomain(invitedOrganizationId);
int invitedTenantId = IdentityTenantUtil.getTenantId(invitedTenantDomain);
Expand All @@ -189,11 +205,22 @@ public boolean acceptInvitation(String confirmationCode) throws UserInvitationMg
invitation.getUserOrganizationId());
// 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()));
for (RoleAssignments roleAssignments : invitation.getRoleAssignments()) {
Kanapriya marked this conversation as resolved.
Show resolved Hide resolved
if (roleManagementService.isExistingRole(roleAssignments.getRoleId(),
invitedTenantDomain)) {
String associatedUserId = getOrganizationUserSharingService()
Kanapriya marked this conversation as resolved.
Show resolved Hide resolved
.getUserAssociationOfAssociatedUserByOrgId(userId,
invitedOrganizationId).getUserId();
roleManagementService.updateUserListOfRole(roleAssignments.getRoleId(),
Collections.singletonList(associatedUserId), Collections.emptyList(),
invitedTenantDomain);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Role: " + roleAssignments.getRoleId()
+ " is not exist in the invitedTenantDomain : " + invitedTenantDomain);
}
}
}
}
// Removing the invitation since the user is added to the organization.
if (LOG.isDebugEnabled()) {
Expand All @@ -203,7 +230,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 @@ -62,6 +62,12 @@ public static final class SQLQueries {
"USER_NAME, DOMAIN_NAME, EMAIL, USER_ORG_ID, INVITED_ORG_ID, STATUS, CREATED_AT, EXPIRED_AT, " +
"USER_REDIRECT_URL FROM IDN_ORG_USER_INVITATION WHERE USER_NAME = ? AND DOMAIN_NAME = ? AND " +
"USER_ORG_ID = ? AND INVITED_ORG_ID = ? AND EXPIRED_AT > CURRENT_TIMESTAMP";
public static final String GET_APP_ID_BY_ROLE_ID = "SELECT APP_ID FROM APP_ROLE_ASSOCIATION WHERE ROLE_ID = ?";
public static final String GET_ROLE_ASSIGNMENTS_BY_ROLE_ID = "SELECT UM_AUDIENCE, " +
"UM_AUDIENCE_ID, UM_ROLE_NAME, APP_NAME FROM UM_HYBRID_ROLE INNER JOIN UM_HYBRID_ROLE_AUDIENCE ON " +
"UM_HYBRID_ROLE.UM_AUDIENCE_REF_ID = UM_HYBRID_ROLE_AUDIENCE.UM_ID " +
"INNER JOIN SP_APP ON UM_HYBRID_ROLE_AUDIENCE.UM_AUDIENCE_ID = SP_APP.UUID " +
"WHERE UM_HYBRID_ROLE.UM_UUID = ?";
}

/**
Expand All @@ -82,5 +88,9 @@ public static final class SQLPlaceholders {
public static final String COLUMN_NAME_REDIRECT_URL = "USER_REDIRECT_URL";
public static final String COLUMN_NAME_APP_ID = "APPLICATION_ID";
public static final String COLUMN_NAME_ROLE_ID = "ROLE_ID";
public static final String COLUMN_UM_ROLE_NAME = "UM_ROLE_NAME";
public static final String COLUMN_UM_AUDIENCE = "UM_AUDIENCE";
public static final String COLUMN_UM_AUDIENCE_ID = "UM_AUDIENCE_ID";
public static final String COLUMN_APP_NAME = "APP_NAME";
}
}
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 Expand Up @@ -178,7 +181,16 @@ public enum ErrorMessage {
"Unable to get the organization associations for the user %s."),
ERROR_CODE_GET_ORG_ASSOCIATION_FOR_USER("10519",
"Unable to get the organization association.",
"Unable to get the organization association for the user %s.");
"Unable to get the organization association for the user %s."),
ERROR_CODE_GET_APP_ID("10520",
"Unable to retrieve the application id.",
"Could not retrieve the applicationId for the roleId %s."),
ERROR_CODE_GET_APPLICATION_ID("10522",
"Unable to retrieve the application id.",
"Could not retrieve the applicationId for the roleId %s."),
ERROR_CODE_GET_ROLE_ASSOCIATIONS("10523",
"Unable to retrieve the role assignments.",
"Could not retrieve the role assignments for the roleId %s.");

private final String code;
private final String message;
Expand Down
Loading
Loading