Skip to content

Commit

Permalink
Improve organization user invitation and user sharing
Browse files Browse the repository at this point in the history
  • Loading branch information
ShanChathusanda93 committed Sep 10, 2023
1 parent d2b90cf commit 3cfd8de
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,16 @@ public interface InvitationCoreService {
*/
boolean deleteInvitedUserAssociation(String userId, UserStoreManager userStoreManager)
throws UserInvitationMgtException;

/**
* Checks whether the user claim values can be updated for the user.
*
* @param userID The ID of the user.
* @param profileName The profile name of the user.
* @param userStoreManager The user store manager of the user.
* @return True if the user claim values can be updated.
* @throws UserInvitationMgtException If an error occurs while checking the user claim values can be updated.
*/
boolean isUpdateUserClaimValuesAllowed(String userID, String profileName, UserStoreManager userStoreManager)
throws UserInvitationMgtException;
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,11 @@ public static final class SQLQueries {
public static final String CREATE_USER_ASSOCIATION_TO_ORG = "INSERT INTO IDN_ORG_USER_ASSOCIATION(" +
"SHARED_USER_ID, SUB_ORG_ID, REAL_USER_ID, USER_RESIDENT_ORG_ID) VALUES(?, ?, ?, ?)";
public static final String DELETE_ORG_ASSOCIATION_FOR_SHARED_USER = "DELETE FROM " +
"IDN_ORG_USER_ASSOCIATION WHERE SHARED_USER_ID = ? AND SUB_ORG_ID = ?";
"IDN_ORG_USER_ASSOCIATION WHERE SHARED_USER_ID = ? AND USER_RESIDENT_ORG_ID = ?";
public static final String DELETE_ALL_ORG_ASSOCIATIONS_FOR_SHARED_USER = "DELETE FROM " +
"IDN_ORG_USER_ASSOCIATION WHERE REAL_USER_ID = ? AND USER_RESIDENT_ORG_ID = ?";
public static final String GET_ALL_ORG_ASSOCIATIONS_FOR_SHARED_USER = "SELECT SHARED_USER_ID, SUB_ORG_ID " +
"FROM IDN_ORG_USER_ASSOCIATION WHERE REAL_USER_ID = ? AND USER_RESIDENT_ORG_ID = ?";
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ public enum ErrorMessage {
ERROR_CODE_INVALID_USER("10027",
"Invalid user identification provided.",
"Authenticated user %s is not entitled for the invitation."),
ERROR_CODE_GET_MANAGED_CLAIM("10028",
"Unable to get the claim.",
"Unable to get the managed org claim for user %s."),

// DAO layer errors
ERROR_CODE_STORE_INVITATION("10501",
Expand Down Expand Up @@ -172,7 +175,10 @@ public enum ErrorMessage {
// Event listener errors
ERROR_CODE_DELETE_INVITED_USER_ASSOCIATION("10400",
"Unable to delete invited user association.",
"Could not delete invited user association for user %s.");
"Could not delete invited user association for user %s."),
ERROR_CODE_CHECK_USER_CLAIM_UPDATE_ALLOWED("10401",
"Unable to check whether the update is allowed.",
"Could not check whether the user claim update is allowed for user %s.");

private final String code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.wso2.carbon.identity.organization.user.invitation.management.exception.UserInvitationMgtException;
import org.wso2.carbon.identity.organization.user.invitation.management.exception.UserInvitationMgtServerException;
import org.wso2.carbon.identity.organization.user.invitation.management.models.Invitation;
import org.wso2.carbon.identity.organization.user.invitation.management.models.SharedUserAssociation;

import java.util.List;

Expand Down Expand Up @@ -132,4 +133,15 @@ boolean deleteOrgUserAssociationToSharedOrg(String userId, String organizationId
*/
boolean deleteAllAssociationsOfOrgUserToSharedOrgs(String userId, String organizationId)
throws UserInvitationMgtException;

/**
* Get all the associations for the child organizations when the user is deleting from the parent organization.
*
* @param userId Actual user id of the user in the parent organization.
* @param organizationId The organization id of the parent organization.
* @return True if the associations are deleted successfully.
* @throws UserInvitationMgtException If an error occurs while deleting the associations.
*/
List<SharedUserAssociation> getAllAssociationsOfOrgUserToSharedOrgs(String userId, String organizationId)
throws UserInvitationMgtException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@

import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.organization.user.invitation.management.constant.UserInvitationMgtConstants;
import org.wso2.carbon.identity.organization.user.invitation.management.exception.UserInvitationMgtClientException;
import org.wso2.carbon.identity.organization.user.invitation.management.exception.UserInvitationMgtException;
import org.wso2.carbon.identity.organization.user.invitation.management.exception.UserInvitationMgtServerException;
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.organization.user.invitation.management.models.SharedUserAssociation;

import java.sql.Connection;
import java.sql.PreparedStatement;
Expand Down Expand Up @@ -59,6 +61,7 @@
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.SQLConstants.SQLQueries.DELETE_ORG_ASSOCIATION_FOR_SHARED_USER;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.SQLConstants.SQLQueries.DELETE_ROLE_ASSIGNMENTS_BY_INVITATION_ID;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.SQLConstants.SQLQueries.GET_ACTIVE_INVITATION_BY_USER;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.SQLConstants.SQLQueries.GET_ALL_ORG_ASSOCIATIONS_FOR_SHARED_USER;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.SQLConstants.SQLQueries.GET_INVITATIONS_BY_INVITED_ORG_ID;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.SQLConstants.SQLQueries.GET_INVITATIONS_BY_INVITED_ORG_ID_WITH_STATUS_FILTER_EXPIRED;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.SQLConstants.SQLQueries.GET_INVITATIONS_BY_INVITED_ORG_ID_WITH_STATUS_FILTER_PENDING;
Expand Down Expand Up @@ -124,8 +127,10 @@ public void createInvitation(Invitation invitation) throws UserInvitationMgtExce
Timestamp currentTimestamp = new Timestamp(new Date().getTime());
invitationCreatePrepStat.setTimestamp(9, currentTimestamp,
Calendar.getInstance(TimeZone.getTimeZone(UTC)));
int expiryTime = Integer.parseInt(IdentityUtil.getProperty(
"OrganizationUserInvitation.DefaultExpiryTime"));
Timestamp expiryTimestamp = new Timestamp(
new Timestamp(currentTimestamp.getTime() + TimeUnit.MINUTES.toMillis(1440)).getTime());
new Timestamp(currentTimestamp.getTime() + TimeUnit.MINUTES.toMillis(expiryTime)).getTime());
invitationCreatePrepStat.setTimestamp(10, expiryTimestamp,
Calendar.getInstance(TimeZone.getTimeZone(UTC)));
invitationCreatePrepStat.setString(11, invitation.getUserRedirectUrl());
Expand Down Expand Up @@ -436,6 +441,30 @@ public boolean deleteAllAssociationsOfOrgUserToSharedOrgs(String userId, String
}
}

@Override
public List<SharedUserAssociation> getAllAssociationsOfOrgUserToSharedOrgs(String userId, String organizationId)
throws UserInvitationMgtException {

try (Connection connection = IdentityDatabaseUtil.getDBConnection(false);
PreparedStatement getUserSharedOrgsPrepStat =
connection.prepareStatement(GET_ALL_ORG_ASSOCIATIONS_FOR_SHARED_USER)) {
getUserSharedOrgsPrepStat.setString(1, userId);
getUserSharedOrgsPrepStat.setString(2, organizationId);
List<SharedUserAssociation> sharedUserAssociationList = new ArrayList<>();
try (ResultSet resultSet = getUserSharedOrgsPrepStat.executeQuery()) {
if (resultSet.next()) {
SharedUserAssociation sharedUserAssociation = new SharedUserAssociation();
sharedUserAssociation.setSharedUserId(resultSet.getString("SHARED_USER_ID"));
sharedUserAssociation.setSharedUserOrganizationId(resultSet.getString("SUB_ORG_ID"));
sharedUserAssociationList.add(sharedUserAssociation);
}
}
return sharedUserAssociationList;
} catch (SQLException e) {
throw handleServerException(ERROR_CODE_GET_INVITATION_BY_USER, userId, e);
}
}

private List<RoleAssignments> processRoleAssignments(List<RoleAssignments> roleAssignmentsResultList) {

// Processing the role assignments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
import org.wso2.carbon.user.core.UserStoreException;
import org.wso2.carbon.user.core.UserStoreManager;

import java.util.Map;

import static org.wso2.carbon.identity.organization.user.invitation.management.constant.UserInvitationMgtConstants.ErrorMessage.ERROR_CODE_CHECK_USER_CLAIM_UPDATE_ALLOWED;
import static org.wso2.carbon.identity.organization.user.invitation.management.constant.UserInvitationMgtConstants.ErrorMessage.ERROR_CODE_DELETE_INVITED_USER_ASSOCIATION;

/**
Expand All @@ -35,7 +38,7 @@ public class OrgSharedUserOperationEventListener extends AbstractIdentityUserOpe
@Override
public int getExecutionOrderId() {

return 160;
return 8;
}

@Override
Expand All @@ -55,8 +58,18 @@ public boolean doPreDeleteUserWithID(String userID, UserStoreManager userStoreMa
}

@Override
public boolean isEnable() {
public boolean doPreSetUserClaimValuesWithID(String userID, Map<String, String> claims, String profileName,
UserStoreManager userStoreManager) throws UserStoreException {

return false;
if (!isEnable() || userStoreManager == null) {
return true;
}
InvitationCoreService invitationCoreService = new InvitationCoreServiceImpl();
try {
return invitationCoreService.isUpdateUserClaimValuesAllowed(userID, profileName, userStoreManager);
} catch (UserInvitationMgtException e) {
throw new UserStoreException(String.format(ERROR_CODE_CHECK_USER_CLAIM_UPDATE_ALLOWED.getDescription(),
userID), ERROR_CODE_CHECK_USER_CLAIM_UPDATE_ALLOWED.getCode(), e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.wso2.carbon.identity.organization.user.invitation.management.models;

/**
* Model class to represent the shared user association.
*/
public class SharedUserAssociation {

private String sharedUserId;
private String sharedUserOrganizationId;

public String getSharedUserId() {

return sharedUserId;
}

public void setSharedUserId(String sharedUserId) {

this.sharedUserId = sharedUserId;
}

public String getSharedUserOrganizationId() {

return sharedUserOrganizationId;
}

public void setSharedUserOrganizationId(String sharedUserOrganizationId) {

this.sharedUserOrganizationId = sharedUserOrganizationId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
import org.wso2.carbon.identity.organization.user.invitation.management.dao.UserInvitationDAO;
import org.wso2.carbon.identity.organization.user.invitation.management.dao.UserInvitationDAOImpl;
Expand Down Expand Up @@ -81,7 +82,8 @@
IdentityDatabaseUtil.class,
UserInvitationMgtDataHolder.class,
IdentityTenantUtil.class,
UserInvitationMgtDataHolder.class})
UserInvitationMgtDataHolder.class,
IdentityUtil.class})
public class InvitationCoreServiceImplTest extends PowerMockTestCase {

private final UserInvitationDAO userInvitationDAO = new UserInvitationDAOImpl();
Expand All @@ -96,6 +98,7 @@ public void setUp() throws Exception {
mockCarbonContextForTenant();
mockStatic(IdentityTenantUtil.class);
mockStatic(IdentityDatabaseUtil.class);
mockStatic(IdentityUtil.class);

Connection connection1 = getConnection();
Connection connection2 = getConnection();
Expand Down Expand Up @@ -274,6 +277,7 @@ private static void mockIdentityTenantUtil() {
private void populateH2Base(Connection connection, Invitation invitation) throws Exception {

when(IdentityDatabaseUtil.getDBConnection(anyBoolean())).thenReturn(connection);
when(IdentityUtil.getProperty(anyString())).thenReturn("1440");
userInvitationDAO.createInvitation(invitation);
}

Expand Down

0 comments on commit 3cfd8de

Please sign in to comment.