Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/recovery-api-v2' into recovery-a…
Browse files Browse the repository at this point in the history
…pi-v2
  • Loading branch information
Rashmini committed Sep 15, 2023
2 parents 32a535a + e2fb879 commit d2feb17
Show file tree
Hide file tree
Showing 54 changed files with 659 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<parent>
<artifactId>identity-governance</artifactId>
<groupId>org.wso2.carbon.identity.governance</groupId>
<version>1.8.67-SNAPSHOT</version>
<version>1.8.68-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
<parent>
<groupId>org.wso2.carbon.identity.governance</groupId>
<artifactId>identity-governance</artifactId>
<version>1.8.67-SNAPSHOT</version>
<version>1.8.68-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>

<artifactId>org.wso2.carbon.identity.api.user.governance</artifactId>
<version>1.8.67-SNAPSHOT</version>
<version>1.8.68-SNAPSHOT</version>
<packaging>jar</packaging>
<name>WSO2 Carbon - User Rest Governance API</name>
<description>WSO2 Carbon - User Rest Governance API</description>
Expand Down
4 changes: 2 additions & 2 deletions components/org.wso2.carbon.identity.api.user.recovery/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
<parent>
<groupId>org.wso2.carbon.identity.governance</groupId>
<artifactId>identity-governance</artifactId>
<version>1.8.67-SNAPSHOT</version>
<version>1.8.68-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>

<artifactId>org.wso2.carbon.identity.api.user.recovery</artifactId>
<version>1.8.67-SNAPSHOT</version>
<version>1.8.68-SNAPSHOT</version>
<packaging>jar</packaging>
<name>WSO2 Carbon - Identity Management Recovery Rest API</name>
<description>WSO2 Carbon - Identity Management Recovery Rest API</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@

@ApiModel(description = "")
public class ReCaptchaPropertiesDTO {



private Boolean reCaptchaEnabled = null;




private String reCaptchaType = null;


private String reCaptchaKey = null;


private String reCaptchaAPI = null;


/**
**/
@ApiModelProperty(value = "")
Expand All @@ -33,7 +36,19 @@ public void setReCaptchaEnabled(Boolean reCaptchaEnabled) {
this.reCaptchaEnabled = reCaptchaEnabled;
}



/**
**/
@ApiModelProperty(value = "")
@JsonProperty("reCaptchaType")
public String getReCaptchaType() {
return reCaptchaType;
}
public void setReCaptchaType(String reCaptchaType) {
this.reCaptchaType = reCaptchaType;
}


/**
**/
@ApiModelProperty(value = "")
Expand All @@ -45,7 +60,7 @@ public void setReCaptchaKey(String reCaptchaKey) {
this.reCaptchaKey = reCaptchaKey;
}


/**
**/
@ApiModelProperty(value = "")
Expand All @@ -57,14 +72,15 @@ public void setReCaptchaAPI(String reCaptchaAPI) {
this.reCaptchaAPI = reCaptchaAPI;
}



@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class ReCaptchaPropertiesDTO {\n");

sb.append(" reCaptchaEnabled: ").append(reCaptchaEnabled).append("\n");
sb.append(" reCaptchaType: ").append(reCaptchaType).append("\n");
sb.append(" reCaptchaKey: ").append(reCaptchaKey).append("\n");
sb.append(" reCaptchaAPI: ").append(reCaptchaAPI).append("\n");
sb.append("}\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ public static Properties getValidatedCaptchaConfigs() {
private static Properties validateCaptchaConfigs(Properties properties) {

boolean reCaptchaEnabled = Boolean.valueOf(properties.getProperty(CaptchaConstants.RE_CAPTCHA_ENABLED));
String reCaptchaType = properties.getProperty(CaptchaConstants.RE_CAPTCHA_TYPE);

if (reCaptchaEnabled && StringUtils.isBlank(properties.getProperty(CaptchaConstants.RE_CAPTCHA_SITE_KEY))) {
RecoveryUtil.handleBadRequest(String.format("%s is not found ", CaptchaConstants.RE_CAPTCHA_SITE_KEY),
Expand All @@ -469,6 +470,12 @@ private static Properties validateCaptchaConfigs(Properties properties) {
RecoveryUtil.handleBadRequest(String.format("%s is not found ", CaptchaConstants.RE_CAPTCHA_VERIFY_URL),
Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT);
}
// Check if project id is available for reCaptcha Enterprise.
if (CaptchaConstants.RE_CAPTCHA_TYPE_ENTERPRISE.equals(reCaptchaType) &&
StringUtils.isBlank(properties.getProperty(CaptchaConstants.RE_CAPTCHA_PROJECT_ID))) {
RecoveryUtil.handleBadRequest(String.format("%s is not found ", CaptchaConstants
.RE_CAPTCHA_PROJECT_ID), Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT);
}
return properties;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
*/
public class CaptchaApiServiceImpl extends CaptchaApiService {

private static final String SUCCESS = "success";
private static final Log log = LogFactory.getLog(CaptchaApiServiceImpl.class);
private final String RECAPTCHA = "ReCaptcha";

Expand All @@ -64,11 +63,11 @@ public Response getCaptcha(String captchaType, String recoveryType, String tenan
reCaptchaPropertiesDTO.setReCaptchaEnabled(true);
reCaptchaPropertiesDTO.setReCaptchaKey(properties.getProperty(CaptchaConstants.RE_CAPTCHA_SITE_KEY));
reCaptchaPropertiesDTO.setReCaptchaAPI(properties.getProperty(CaptchaConstants.RE_CAPTCHA_API_URL));
return Response.ok(reCaptchaPropertiesDTO).build();
reCaptchaPropertiesDTO.setReCaptchaType(properties.getProperty(CaptchaConstants.RE_CAPTCHA_TYPE));
} else {
reCaptchaPropertiesDTO.setReCaptchaEnabled(false);
return Response.ok(reCaptchaPropertiesDTO).build();
}
return Response.ok(reCaptchaPropertiesDTO).build();
}

@Override
Expand All @@ -80,6 +79,7 @@ public Response verifyCaptcha(ReCaptchaResponseTokenDTO reCaptchaResponse, Strin

Properties properties = RecoveryUtil.getValidatedCaptchaConfigs();
boolean reCaptchaEnabled = Boolean.valueOf(properties.getProperty(CaptchaConstants.RE_CAPTCHA_ENABLED));
String reCaptchaType = properties.getProperty(CaptchaConstants.RE_CAPTCHA_TYPE);

if (!reCaptchaEnabled) {
RecoveryUtil.handleBadRequest("ReCaptcha is disabled", Constants.INVALID);
Expand All @@ -89,21 +89,30 @@ public Response verifyCaptcha(ReCaptchaResponseTokenDTO reCaptchaResponse, Strin
HttpEntity entity = response.getEntity();
ReCaptchaVerificationResponseDTO reCaptchaVerificationResponseDTO = new ReCaptchaVerificationResponseDTO();

try {
if (entity == null) {
RecoveryUtil.handleBadRequest("ReCaptcha verification response is not received.",
Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT);
if (entity == null) {
RecoveryUtil.handleBadRequest("ReCaptcha verification response is not received.",
Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT);
}
try (InputStream in = entity.getContent()) {
JsonObject verificationResponse = new JsonParser().parse(IOUtils.toString(in)).getAsJsonObject();

if (CaptchaConstants.RE_CAPTCHA_TYPE_ENTERPRISE.equals(reCaptchaType)) {
// For Recaptcha Enterprise.
JsonObject tokenProperties = verificationResponse.get(CaptchaConstants.CAPTCHA_TOKEN_PROPERTIES)
.getAsJsonObject();
boolean success = tokenProperties.get(CaptchaConstants.CAPTCHA_VALID).getAsBoolean();
reCaptchaVerificationResponseDTO.setSuccess(success);
} else {
try (InputStream in = entity.getContent()) {
JsonObject verificationResponse = new JsonParser().parse(IOUtils.toString(in)).getAsJsonObject();
reCaptchaVerificationResponseDTO.setSuccess(verificationResponse.get(SUCCESS).getAsBoolean());
}
// For ReCaptcha v2 and v3.
reCaptchaVerificationResponseDTO.setSuccess(verificationResponse.get(
CaptchaConstants.CAPTCHA_SUCCESS).getAsBoolean());
}
} catch (IOException e) {
log.error("Unable to read the verification response.", e);
RecoveryUtil.handleBadRequest("Unable to read the verification response.",
Constants.STATUS_INTERNAL_SERVER_ERROR_MESSAGE_DEFAULT);
}

return Response.ok(reCaptchaVerificationResponseDTO).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,8 @@ definitions:
properties:
reCaptchaEnabled:
type: boolean
reCaptchaType:
type: string
reCaptchaKey:
type: string
reCaptchaAPI:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@

package org.wso2.carbon.identity.recovery.endpoint.impl;

import org.apache.commons.lang.StringUtils;
import org.mockito.InjectMocks;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.wso2.carbon.identity.captcha.util.CaptchaConstants;
import org.wso2.carbon.identity.recovery.endpoint.Utils.RecoveryUtil;

import org.wso2.carbon.identity.recovery.endpoint.dto.ReCaptchaPropertiesDTO;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
Expand All @@ -35,8 +37,9 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;

import javax.ws.rs.core.Response;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;

/**
* Unit tests for CaptchaApiServiceImpl.java
Expand All @@ -61,8 +64,51 @@ public void tearDown() {
mockedRecoveryUtil.close();
}

@Test(description = "This method test, getReCaptcha method for username recovery")
public void testGetCaptcha() throws IOException {
@DataProvider(name = "captchaTestDataProvider")
public static Object[][] getCaptchaTestDataProvider() {

String reCaptchaEnterprise = CaptchaConstants.RE_CAPTCHA_TYPE_ENTERPRISE;

return new Object[][]{
{false, "", ""},
{true, "", "https://www.google.com/recaptcha/api.js"},
{true, reCaptchaEnterprise, "https://www.google.com/recaptcha/enterprise.js"}
};
}

@Test(description = "This method test, getReCaptcha method for username recovery",
dataProvider = "captchaTestDataProvider")
public void testGetCaptcha(boolean reCaptchaEnabled, String reCaptchaType,
String reCaptchaAPI) throws IOException {

Properties sampleProperties = getSampleConfigFile();

sampleProperties.setProperty(CaptchaConstants.RE_CAPTCHA_ENABLED, String.valueOf(reCaptchaEnabled));
sampleProperties.setProperty(CaptchaConstants.RE_CAPTCHA_TYPE, reCaptchaType);
sampleProperties.setProperty(CaptchaConstants.RE_CAPTCHA_API_URL, reCaptchaAPI);

mockedRecoveryUtil.when(RecoveryUtil::getValidatedCaptchaConfigs).thenReturn(sampleProperties);
mockedRecoveryUtil.when(() -> RecoveryUtil.checkCaptchaEnabledResidentIdpConfiguration(Mockito.anyString(),
Mockito.anyString())).thenReturn(true);
Response response = captchaApiService.getCaptcha("ReCaptcha", "username-recovery",
"test.org");

ReCaptchaPropertiesDTO reCaptchaPropertiesDTO = response.readEntity(ReCaptchaPropertiesDTO.class);

assertEquals(reCaptchaPropertiesDTO.getReCaptchaEnabled().booleanValue(), reCaptchaEnabled);
if (reCaptchaPropertiesDTO.getReCaptchaType() == null) {
assertNull(reCaptchaPropertiesDTO.getReCaptchaType());
} else {
assertEquals(reCaptchaPropertiesDTO.getReCaptchaType(), reCaptchaType);
}
if (StringUtils.isBlank(reCaptchaAPI)) {
assertNull(reCaptchaPropertiesDTO.getReCaptchaAPI());
} else {
assertEquals(reCaptchaPropertiesDTO.getReCaptchaAPI(), reCaptchaAPI);
}
}

public Properties getSampleConfigFile() throws IOException {

Path path = Paths.get("src/test/resources", "repository", "conf", "identity",
CaptchaConstants.CAPTCHA_CONFIG_FILE_NAME);
Expand All @@ -74,11 +120,6 @@ public void testGetCaptcha() throws IOException {
throw new IOException("Unable to read the captcha configuration file.", e);
}
}

mockedRecoveryUtil.when(RecoveryUtil::getValidatedCaptchaConfigs).thenReturn(sampleProperties);
mockedRecoveryUtil.when(() -> RecoveryUtil.checkCaptchaEnabledResidentIdpConfiguration(Mockito.anyString(),
Mockito.anyString())).thenReturn(true);
assertEquals(captchaApiService.getCaptcha("ReCaptcha", "username-recovery",
null).getStatus(), 200);
return sampleProperties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.identity.governance</groupId>
<artifactId>identity-governance</artifactId>
<version>1.8.67-SNAPSHOT</version>
<version>1.8.68-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand Down
28 changes: 27 additions & 1 deletion components/org.wso2.carbon.identity.captcha/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.identity.governance</groupId>
<artifactId>identity-governance</artifactId>
<version>1.8.67-SNAPSHOT</version>
<version>1.8.68-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand Down Expand Up @@ -114,6 +114,22 @@
<groupId>org.wso2.securevault</groupId>
<artifactId>org.wso2.securevault</artifactId>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<classifier>runtime</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -185,6 +201,16 @@
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
Expand Down
Loading

0 comments on commit d2feb17

Please sign in to comment.