Skip to content

Commit

Permalink
Merge pull request #5744 from RushanNanayakkara/sms_otp_pw_recovery_e…
Browse files Browse the repository at this point in the history
…nhance_recovery_api_v2

Add API client functions for RecoveryAPI V2 and on demand migration for new configs.
  • Loading branch information
RushanNanayakkara authored Jun 25, 2024
2 parents 7f16bb6 + 3e8b0d1 commit 0db8132
Show file tree
Hide file tree
Showing 18 changed files with 1,293 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public static final class ServiceEndpoints {

public static final class PasswordRecoveryOptions {
public static final String EMAIL = "EMAIL";
public static final String SMSOTP = "SMSOTP";
public static final String SECURITY_QUESTIONS = "SECURITY_QUESTIONS";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.json.JSONTokener;
import org.wso2.carbon.identity.mgt.endpoint.util.IdentityManagementEndpointUtil;
import org.wso2.carbon.identity.mgt.endpoint.util.IdentityManagementServiceUtil;
import org.wso2.carbon.idp.mgt.util.IdPManagementConstants;
import org.wso2.carbon.utils.HTTPClientUtils;

import java.io.IOException;
Expand All @@ -58,7 +59,6 @@ public class PreferenceRetrievalClient {
private static final String GOVERNANCE_API_RELATIVE_PATH = "/api/server/v1/identity-governance";
private static final String SELF_REGISTRATION_PROPERTY = "SelfRegistration.Enable";
private static final String USERNAME_RECOVERY_PROPERTY = "Recovery.Notification.Username.Enable";
private static final String NOTIFICATION_PASSWORD_RECOVERY_PROPERTY = "Recovery.Notification.Password.Enable";
private static final String QUESTION_PASSWORD_RECOVERY_PROPERTY = "Recovery.Question.Password.Enable";
private static final String SELF_SIGN_UP_LOCK_ON_CREATION_PROPERTY = "SelfRegistration.LockOnCreation";
private static final String MULTI_ATTRIBUTE_LOGIN_PROPERTY = "account.multiattributelogin.handler.enable";
Expand Down Expand Up @@ -141,7 +141,33 @@ public boolean checkUsernameRecovery(String tenant) throws PreferenceRetrievalCl
*/
public boolean checkNotificationBasedPasswordRecovery(String tenant) throws PreferenceRetrievalClientException {

return checkPreference(tenant, RECOVERY_CONNECTOR, NOTIFICATION_PASSWORD_RECOVERY_PROPERTY);
return checkPreference(tenant, RECOVERY_CONNECTOR,
IdPManagementConstants.NOTIFICATION_PASSWORD_ENABLE_PROPERTY);
}

/**
* Check email link based password recovery is enabled or not.
*
* @param tenant Tenant domain name.
* @return Returns true if email link based password recovery enabled.
* @throws PreferenceRetrievalClientException PreferenceRetrievalClientException.
*/
public boolean checkEmailLinkBasedPasswordRecovery(String tenant) throws PreferenceRetrievalClientException {

return checkPreference(tenant, RECOVERY_CONNECTOR,
IdPManagementConstants.EMAIL_LINK_PASSWORD_RECOVERY_PROPERTY);
}

/**
* Check SMS OTP based password recovery is enabled or not.
*
* @param tenant Tenant domain name.
* @return Returns true if SMS OTP based password recovery enabled.
* @throws PreferenceRetrievalClientException PreferenceRetrievalClientException.
*/
public boolean checkSMSOTPBasedPasswordRecovery(String tenant) throws PreferenceRetrievalClientException {

return checkPreference(tenant, RECOVERY_CONNECTOR, IdPManagementConstants.SMS_OTP_PASSWORD_RECOVERY_PROPERTY);
}

/**
Expand All @@ -166,7 +192,7 @@ public boolean checkQuestionBasedPasswordRecovery(String tenant) throws Preferen
public boolean checkPasswordRecovery(String tenant) throws PreferenceRetrievalClientException {

List<String> propertyNameList = new ArrayList<String>();
propertyNameList.add(NOTIFICATION_PASSWORD_RECOVERY_PROPERTY);
propertyNameList.add(IdPManagementConstants.NOTIFICATION_PASSWORD_ENABLE_PROPERTY);
propertyNameList.add(QUESTION_PASSWORD_RECOVERY_PROPERTY);
return checkMultiplePreference(tenant, RECOVERY_CONNECTOR, propertyNameList);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,25 @@
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants;
import org.wso2.carbon.identity.mgt.endpoint.util.IdentityManagementEndpointConstants;
import org.wso2.carbon.identity.mgt.endpoint.util.IdentityManagementEndpointUtil;
import org.wso2.carbon.identity.mgt.endpoint.util.client.ApiClient;
import org.wso2.carbon.identity.mgt.endpoint.util.client.ApiException;
import org.wso2.carbon.identity.mgt.endpoint.util.client.Configuration;
import org.wso2.carbon.identity.mgt.endpoint.util.client.Pair;
import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.AccountRecoveryType;
import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ConfirmRequest;
import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ConfirmResponse;
import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.RecoveryInitRequest;
import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.RecoveryRequest;
import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.RecoveryResponse;
import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ResendRequest;
import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ResendResponse;
import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ResetRequest;
import org.wso2.carbon.identity.mgt.endpoint.util.client.model.recovery.v2.ResetResponse;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand All @@ -43,6 +51,11 @@
*/
public class RecoveryApiV2 {

private static final String PATH_PASSWORD_RECOVERY_INIT = "/password/init";
private static final String PATH_PASSWORD_RECOVERY_RECOVER = "/password/recover";
private static final String PATH_PASSWORD_RECOVERY_RESEND = "/password/resend";
private static final String PATH_PASSWORD_RECOVERY_CONFIRM = "/password/confirm";
private static final String PATH_PASSWORD_RECOVERY_RESET = "/password/reset";
String basePath = IdentityManagementEndpointUtil.buildEndpointUrl(IdentityManagementEndpointConstants
.UserInfoRecovery.RECOVERY_API_V2_RELATIVE_PATH);
private ApiClient apiClient;
Expand Down Expand Up @@ -80,8 +93,7 @@ public List<AccountRecoveryType> initiatePasswordRecovery(RecoveryInitRequest re
String tenantDomain, Map<String, String> headers)
throws ApiException {

String localVarPath = "/password/init".replaceAll("\\{format\\}", "json");
return initiateRecovery(recoveryInitRequest, tenantDomain, headers, localVarPath);
return initiateRecovery(recoveryInitRequest, tenantDomain, headers, PATH_PASSWORD_RECOVERY_INIT);
}

/**
Expand All @@ -96,8 +108,52 @@ public List<AccountRecoveryType> initiatePasswordRecovery(RecoveryInitRequest re
public RecoveryResponse recoverPassword(RecoveryRequest recoveryRequest, String tenantDomain,
Map<String, String> headers) throws ApiException {

String localVarPath = "/password/recover".replaceAll("\\{format\\}", "json");
return recover(recoveryRequest, tenantDomain, headers, localVarPath);
return recover(recoveryRequest, tenantDomain, headers, PATH_PASSWORD_RECOVERY_RECOVER);
}

/**
* Resend password recovery confirmation details.
*
* @param resendRequest Resend request. (required)
* @param tenantDomain Tenant Domain which user belongs. Default "carbon.super". (optional)
* @param headers Any additional headers to be embedded. (optional)
* @return Resend response.
* @throws ApiException If fails to make API call.
*/
public ResendResponse resendPasswordNotification(ResendRequest resendRequest, String tenantDomain,
Map<String, String> headers) throws ApiException {

return resend(resendRequest, tenantDomain, headers, PATH_PASSWORD_RECOVERY_RESEND);
}

/**
* Confirm password recovery.
*
* @param confirmRequest Password recovery confirm request. (required)
* @param tenantDomain Tenant Domain which user belongs. Default "carbon.super". (optional)
* @param headers Any additional headers to be embedded. (optional)
* @return Confirm response.
* @throws ApiException If fails to make API call.
*/
public ConfirmResponse confirmPasswordRecovery(ConfirmRequest confirmRequest, String tenantDomain,
Map<String, String> headers) throws ApiException {

return confirm(confirmRequest, tenantDomain, headers, PATH_PASSWORD_RECOVERY_CONFIRM);
}

/**
* Reset user password.
*
* @param resetRequest Password reset request. (required)
* @param tenantDomain Tenant Domain which user belongs. Default "carbon.super". (optional)
* @param headers Any additional headers to be embedded. (optional)
* @return reset response.
* @throws ApiException If fails to make API call.
*/
public ResetResponse resetUserPassword(ResetRequest resetRequest, String tenantDomain,
Map<String, String> headers) throws ApiException {

return reset(resetRequest, tenantDomain, headers, PATH_PASSWORD_RECOVERY_RESET);
}

/**
Expand All @@ -117,8 +173,8 @@ private List<AccountRecoveryType> initiateRecovery(RecoveryInitRequest recoveryI
Object localVarPostBody = recoveryInitRequest;
// Verify the required parameter 'recoveryInitRequest' is set.
if (recoveryInitRequest == null) {
throw new ApiException(400, "Missing the required parameter 'recoveryInitRequest' when calling " +
"initializeRecovery");
throw new ApiException(HttpServletResponse.SC_BAD_REQUEST,
"Missing the required parameter 'recoveryInitRequest' when calling initializeRecovery");
}
if (StringUtils.isBlank(tenantDomain)) {
tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
Expand All @@ -133,11 +189,11 @@ private List<AccountRecoveryType> initiateRecovery(RecoveryInitRequest recoveryI
}
Map<String, Object> localVarFormParams = new HashMap<String, Object>();
final String[] localVarAccepts = {
"application/json"
FrameworkConstants.ContentTypes.TYPE_APPLICATION_JSON
};
final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
final String[] localVarContentTypes = {
"application/json"
FrameworkConstants.ContentTypes.TYPE_APPLICATION_JSON
};
final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
String[] localVarAuthNames = new String[]{};
Expand All @@ -164,7 +220,8 @@ private RecoveryResponse recover(RecoveryRequest recoveryRequest, String tenantD
Object localVarPostBody = recoveryRequest;
// Verify if the required parameter 'recoveryRequest' is set.
if (recoveryRequest == null) {
throw new ApiException(400, "Missing the required parameter 'recoveryRequest' when requesting recovery");
throw new ApiException(HttpServletResponse.SC_BAD_REQUEST,
"Missing the required parameter 'recoveryRequest' when requesting recovery");
}
if (StringUtils.isBlank(tenantDomain)) {
tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
Expand All @@ -179,11 +236,11 @@ private RecoveryResponse recover(RecoveryRequest recoveryRequest, String tenantD
}
Map<String, Object> localVarFormParams = new HashMap<String, Object>();
final String[] localVarAccepts = {
"application/json"
FrameworkConstants.ContentTypes.TYPE_APPLICATION_JSON
};
final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
final String[] localVarContentTypes = {
"application/json"
FrameworkConstants.ContentTypes.TYPE_APPLICATION_JSON
};
final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
String[] localVarAuthNames = new String[]{};
Expand All @@ -193,4 +250,85 @@ private RecoveryResponse recover(RecoveryRequest recoveryRequest, String tenantD
localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames,
localVarReturnType);
}

private ResendResponse resend(ResendRequest resendRequest, String tenantDomain, Map<String, String> headers,
String localVarPath) throws ApiException {

// Verify if the required parameter 'recoveryRequest' is set.
if (resendRequest == null) {
throw new ApiException(HttpServletResponse.SC_BAD_REQUEST,
"Missing the required parameter 'resendRequest' when requesting recovery");
}
if (StringUtils.isBlank(tenantDomain)) {
tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
}
basePath = IdentityManagementEndpointUtil.getBasePath(tenantDomain,
IdentityManagementEndpointConstants.UserInfoRecovery.RECOVERY_API_V2_RELATIVE_PATH);
apiClient.setBasePath(basePath);
Map<String, String> localVarHeaderParams = new HashMap<>();
if (MapUtils.isNotEmpty(headers)) {
localVarHeaderParams.putAll(headers);
}
final String localVarAccept = apiClient.selectHeaderAccept(
new String[]{FrameworkConstants.ContentTypes.TYPE_APPLICATION_JSON});
final String localVarContentType = apiClient.selectHeaderContentType(
new String[]{FrameworkConstants.ContentTypes.TYPE_APPLICATION_JSON});
return apiClient.invokeAPI(localVarPath, "POST", new ArrayList<>(), resendRequest,
localVarHeaderParams, new HashMap<>(), localVarAccept, localVarContentType, new String[]{},
new GenericType<ResendResponse>(){});
}

private ConfirmResponse confirm(ConfirmRequest confirmRequest, String tenantDomain, Map<String, String> headers,
String localVarPath) throws ApiException {

// Verify if the required parameter 'recoveryRequest' is set.
if (confirmRequest == null) {
throw new ApiException(HttpServletResponse.SC_BAD_REQUEST,
"Missing the required parameter 'confirmRequest' when requesting recovery");
}
if (StringUtils.isBlank(tenantDomain)) {
tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
}
basePath = IdentityManagementEndpointUtil.getBasePath(tenantDomain,
IdentityManagementEndpointConstants.UserInfoRecovery.RECOVERY_API_V2_RELATIVE_PATH);
apiClient.setBasePath(basePath);
Map<String, String> localVarHeaderParams = new HashMap<>();
if (MapUtils.isNotEmpty(headers)) {
localVarHeaderParams.putAll(headers);
}
final String localVarAccept = apiClient.selectHeaderAccept(
new String[]{FrameworkConstants.ContentTypes.TYPE_APPLICATION_JSON});
final String localVarContentType = apiClient.selectHeaderContentType(
new String[]{FrameworkConstants.ContentTypes.TYPE_APPLICATION_JSON});
return apiClient.invokeAPI(localVarPath, "POST", new ArrayList<>(), confirmRequest,
localVarHeaderParams, new HashMap<>(), localVarAccept, localVarContentType, new String[]{},
new GenericType<ConfirmResponse>(){});
}

private ResetResponse reset(ResetRequest resetRequest, String tenantDomain, Map<String, String> headers,
String localVarPath) throws ApiException {

// Verify if the required parameter 'recoveryRequest' is set.
if (resetRequest == null) {
throw new ApiException(HttpServletResponse.SC_BAD_REQUEST,
"Missing the required parameter 'resetRequest' when requesting recovery");
}
if (StringUtils.isBlank(tenantDomain)) {
tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
}
basePath = IdentityManagementEndpointUtil.getBasePath(tenantDomain,
IdentityManagementEndpointConstants.UserInfoRecovery.RECOVERY_API_V2_RELATIVE_PATH);
apiClient.setBasePath(basePath);
Map<String, String> localVarHeaderParams = new HashMap<>();
if (MapUtils.isNotEmpty(headers)) {
localVarHeaderParams.putAll(headers);
}
final String localVarAccept = apiClient.selectHeaderAccept(
new String[]{FrameworkConstants.ContentTypes.TYPE_APPLICATION_JSON});
final String localVarContentType = apiClient.selectHeaderContentType(
new String[]{FrameworkConstants.ContentTypes.TYPE_APPLICATION_JSON});
return apiClient.invokeAPI(localVarPath, "POST", new ArrayList<>(), resetRequest,
localVarHeaderParams, new HashMap<>(), localVarAccept, localVarContentType, new String[]{},
new GenericType<ResetResponse>(){});
}
}
Loading

0 comments on commit 0db8132

Please sign in to comment.