Skip to content

Commit

Permalink
Add channel filtering with configs.
Browse files Browse the repository at this point in the history
  • Loading branch information
Malith-19 committed Nov 7, 2024
1 parent d7d23a0 commit c372371
Showing 1 changed file with 95 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import org.wso2.carbon.identity.recovery.IdentityRecoveryServerException;
import org.wso2.carbon.identity.recovery.RecoveryScenarios;
import org.wso2.carbon.identity.recovery.RecoverySteps;
import org.wso2.carbon.identity.recovery.dto.NotificationChannelDTO;
import org.wso2.carbon.identity.recovery.dto.RecoveryChannelInfoDTO;
import org.wso2.carbon.identity.recovery.dto.RecoveryInformationDTO;
import org.wso2.carbon.identity.recovery.dto.UsernameRecoverDTO;
import org.wso2.carbon.identity.recovery.internal.IdentityRecoveryServiceDataHolder;
Expand All @@ -55,6 +57,7 @@
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants.AUDIT_FAILED;
Expand Down Expand Up @@ -83,9 +86,15 @@ public RecoveryInformationDTO initiate(Map<String, String> claims, String tenant
Map<String, String> properties) throws IdentityRecoveryException {

validateTenantDomain(tenantDomain);
boolean isNotificationBasedRecoveryEnabled = isNotificationBasedRecoveryEnabled(tenantDomain);
validateConfigurations(tenantDomain);
UserAccountRecoveryManager userAccountRecoveryManager = UserAccountRecoveryManager.getInstance();
RecoveryInformationDTO recoveryInformationDTO = new RecoveryInformationDTO();
recoveryInformationDTO.setNotificationBasedRecoveryEnabled(isNotificationBasedRecoveryEnabled);

if (!isNotificationBasedRecoveryEnabled) {
return recoveryInformationDTO;
}

boolean useLegacyAPIApproach = useLegacyAPIApproach(properties);
boolean manageNotificationsInternally = Utils.isNotificationsInternallyManaged(tenantDomain, properties);
Expand Down Expand Up @@ -137,15 +146,33 @@ public RecoveryInformationDTO initiate(Map<String, String> claims, String tenant

boolean nonUniqueUsernameEnabled = Boolean.parseBoolean(IdentityUtil.getProperty(
IdentityRecoveryConstants.ConnectorConfig.USERNAME_RECOVERY_NON_UNIQUE_USERNAME));

RecoveryChannelInfoDTO recoveryChannelInfoDTO;
if (nonUniqueUsernameEnabled) {
recoveryInformationDTO.setRecoveryChannelInfoDTO(userAccountRecoveryManager
.retrieveUsersRecoveryInformationForUsername(claims, tenantDomain, metaProperties));
recoveryChannelInfoDTO = userAccountRecoveryManager
.retrieveUsersRecoveryInformationForUsername(claims, tenantDomain, metaProperties);
} else {
recoveryInformationDTO.setRecoveryChannelInfoDTO(userAccountRecoveryManager
recoveryChannelInfoDTO = userAccountRecoveryManager
.retrieveUserRecoveryInformation(claims, tenantDomain, RecoveryScenarios.USERNAME_RECOVERY,
metaProperties));
metaProperties);
}

// Filtering the notification channel list.
List<NotificationChannelDTO> enabledNotificationChannelDTOs = new ArrayList<>();
for (NotificationChannelDTO notificationChannelDTO : recoveryChannelInfoDTO.getNotificationChannelDTOs()) {
if (isRecoveryChannelEnabled(notificationChannelDTO.getType(), tenantDomain)) {
enabledNotificationChannelDTOs.add(notificationChannelDTO);
}
}
recoveryChannelInfoDTO.setNotificationChannelDTOs(
enabledNotificationChannelDTOs.toArray(new NotificationChannelDTO[0]));
String username = recoveryChannelInfoDTO.getUsername();
String recoveryFlowId = recoveryChannelInfoDTO.getRecoveryFlowId();
recoveryInformationDTO.setUsername(username);
recoveryInformationDTO.setRecoveryFlowId(recoveryFlowId);
// Do not add recovery channel information if Notification based recovery is not enabled.
recoveryInformationDTO.setRecoveryChannelInfoDTO(recoveryChannelInfoDTO);
recoveryInformationDTO.setNotificationBasedRecoveryEnabled(isNotificationBasedRecoveryEnabled);
return recoveryInformationDTO;
}

Expand Down Expand Up @@ -328,6 +355,11 @@ private void triggerNotification(User user, String notificationChannel, String e
Map<String, String> metaProperties)
throws IdentityRecoveryException {

if (!isRecoveryChannelEnabled(notificationChannel, user.getTenantDomain())) {
throw Utils.handleClientException(
IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_INVALID_CHANNEL_ID, null);
}

String combinedUsernames = user.getUserName();
String[] usernames = combinedUsernames.split(",");
for (String username : usernames) {
Expand Down Expand Up @@ -486,4 +518,63 @@ private void auditUserNameRecovery(String action, Map<String, String> claims, St
}
Utils.createAuditMessage(action, target, dataObject, result);
}

private boolean isRecoveryChannelEnabled(String notificationChannelType, String tenantDomain)
throws IdentityRecoveryServerException {

if (NotificationChannels.EMAIL_CHANNEL.getChannelType().equals(notificationChannelType)) {
return isEmailBasedRecoveryEnabled(tenantDomain);
} else if (NotificationChannels.SMS_CHANNEL.getChannelType().equals(notificationChannelType)) {
return isSMSBasedRecoveryEnabled(tenantDomain);
}
return false;
}

private boolean isNotificationBasedRecoveryEnabled(String tenantDomain) throws IdentityRecoveryServerException {

try {
return Boolean.parseBoolean(
Utils.getRecoveryConfigs(
IdentityRecoveryConstants.ConnectorConfig.USERNAME_RECOVERY_ENABLE,
tenantDomain));
} catch (IdentityRecoveryServerException e) {
// Prepend scenario to the thrown exception.
String errorCode = Utils
.prependOperationScenarioToErrorCode(IdentityRecoveryConstants.USER_NAME_RECOVERY,
e.getErrorCode());
throw Utils.handleServerException(errorCode, e.getMessage(), null);
}
}

private boolean isEmailBasedRecoveryEnabled(String tenantDomain) throws IdentityRecoveryServerException {

try {
return Boolean.parseBoolean(
Utils.getRecoveryConfigs(
IdentityRecoveryConstants.ConnectorConfig.USERNAME_RECOVERY_EMAIL_ENABLE,
tenantDomain));
} catch (IdentityRecoveryServerException e) {
// Prepend scenario to the thrown exception.
String errorCode = Utils
.prependOperationScenarioToErrorCode(IdentityRecoveryConstants.USER_NAME_RECOVERY,
e.getErrorCode());
throw Utils.handleServerException(errorCode, e.getMessage(), null);
}
}

private boolean isSMSBasedRecoveryEnabled(String tenantDomain) throws IdentityRecoveryServerException {

try {
return Boolean.parseBoolean(
Utils.getRecoveryConfigs(
IdentityRecoveryConstants.ConnectorConfig.USERNAME_RECOVERY_SMS_ENABLE,
tenantDomain));
} catch (IdentityRecoveryServerException e) {
// Prepend scenario to the thrown exception.
String errorCode = Utils
.prependOperationScenarioToErrorCode(IdentityRecoveryConstants.USER_NAME_RECOVERY,
e.getErrorCode());
throw Utils.handleServerException(errorCode, e.getMessage(), null);
}
}
}

0 comments on commit c372371

Please sign in to comment.