Skip to content
This repository has been archived by the owner on Sep 16, 2023. It is now read-only.

docs(samples): added annotate assessment sample and refactored tests. #635

Merged
merged 3 commits into from Nov 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -109,6 +109,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-recaptchaente
| --------------------------- | --------------------------------- | ------ |
| Main | [source code](https://github.com/googleapis/java-recaptchaenterprise/blob/main/samples/snippets/cloud-client/src/main/java/app/Main.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-recaptchaenterprise&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/app/Main.java) |
| Main Controller | [source code](https://github.com/googleapis/java-recaptchaenterprise/blob/main/samples/snippets/cloud-client/src/main/java/app/MainController.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-recaptchaenterprise&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/app/MainController.java) |
| Annotate Assessment | [source code](https://github.com/googleapis/java-recaptchaenterprise/blob/main/samples/snippets/cloud-client/src/main/java/recaptcha/AnnotateAssessment.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-recaptchaenterprise&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/recaptcha/AnnotateAssessment.java) |
| Create Assessment | [source code](https://github.com/googleapis/java-recaptchaenterprise/blob/main/samples/snippets/cloud-client/src/main/java/recaptcha/CreateAssessment.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-recaptchaenterprise&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/recaptcha/CreateAssessment.java) |
| Create Site Key | [source code](https://github.com/googleapis/java-recaptchaenterprise/blob/main/samples/snippets/cloud-client/src/main/java/recaptcha/CreateSiteKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-recaptchaenterprise&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/recaptcha/CreateSiteKey.java) |
| Delete Site Key | [source code](https://github.com/googleapis/java-recaptchaenterprise/blob/main/samples/snippets/cloud-client/src/main/java/recaptcha/DeleteSiteKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-recaptchaenterprise&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/recaptcha/DeleteSiteKey.java) |
Expand Down
@@ -0,0 +1,68 @@
/*
* Copyright 2021 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package recaptcha;

// [START recaptcha_enterprise_annotate_assessment]

import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient;
import com.google.recaptchaenterprise.v1.AnnotateAssessmentRequest;
import com.google.recaptchaenterprise.v1.AnnotateAssessmentRequest.Annotation;
import com.google.recaptchaenterprise.v1.AnnotateAssessmentRequest.Reason;
import com.google.recaptchaenterprise.v1.AnnotateAssessmentResponse;
import com.google.recaptchaenterprise.v1.AssessmentName;
import java.io.IOException;

public class AnnotateAssessment {

public static void main(String[] args) throws IOException {
// TODO(developer): Replace these variables before running the sample.
String projectID = "project-id";
String assessmentId = "assessment-id";
annotateAssessment(projectID, assessmentId);
}

/**
* Pre-requisite: Create an assessment before annotating.
*
* <p>Annotate an assessment to provide feedback on the correctness of recaptcha prediction.
*
* @param projectID: GCloud Project id
* @param assessmentId: Value of the 'name' field returned from the CreateAssessment call.
*/
public static void annotateAssessment(String projectID, String assessmentId) throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the `client.close()` method on the client to safely
// clean up any remaining background resources.
try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {
// Build the annotation request.
// For more info on when/how to annotate, see:
// https://cloud.google.com/recaptcha-enterprise/docs/annotate-assessment#when_to_annotate
AnnotateAssessmentRequest annotateAssessmentRequest =
AnnotateAssessmentRequest.newBuilder()
.setName(AssessmentName.of(projectID, assessmentId).toString())
.setAnnotation(Annotation.FRAUDULENT)
.addReasons(Reason.FAILED_TWO_FACTOR)
.build();

// Empty response is sent back.
AnnotateAssessmentResponse response = client.annotateAssessment(annotateAssessmentRequest);
System.out.println("Annotated response sent successfully ! " + response);
}
}
}
// [END recaptcha_enterprise_annotate_assessment]
Expand Up @@ -89,15 +89,20 @@ public static void createAssessment(
return;
}

// Get the risk score and the reason(s).
// Get the reason(s) and the risk score.
// For more information on interpreting the assessment,
// see: https://cloud.google.com/recaptcha-enterprise/docs/interpret-assessment
float recaptchaScore = response.getRiskAnalysis().getScore();
System.out.println("The reCAPTCHA score is: " + recaptchaScore);

for (ClassificationReason reason : response.getRiskAnalysis().getReasonsList()) {
System.out.println(reason);
}

float recaptchaScore = response.getRiskAnalysis().getScore();
System.out.println("The reCAPTCHA score is: " + recaptchaScore);

// Get the assessment name (id). Use this to annotate the assessment.
String assessmentName = response.getName();
System.out.println(
"Assessment name: " + assessmentName.substring(assessmentName.lastIndexOf("/") + 1));
}
}
}
Expand Down
Expand Up @@ -60,6 +60,7 @@ public static void updateSiteKey(String projectID, String recaptchaSiteKeyID, St
UpdateKeyRequest.newBuilder()
.setKey(
Key.newBuilder()
.setDisplayName("any descriptive name for the key")
.setName(KeyName.of(projectID, recaptchaSiteKeyID).toString())
.setWebSettings(
WebKeySettings.newBuilder()
Expand Down
79 changes: 60 additions & 19 deletions samples/snippets/cloud-client/src/test/java/app/SnippetsIT.java
Expand Up @@ -24,10 +24,12 @@
import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;
import java.time.Duration;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
Expand All @@ -47,6 +49,7 @@
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.util.UriComponentsBuilder;
import recaptcha.AnnotateAssessment;

@RunWith(SpringJUnit4ClassRunner.class)
@EnableAutoConfiguration
Expand All @@ -55,6 +58,7 @@ public class SnippetsIT {

private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT");
private static final String DOMAIN_NAME = "localhost";
private static String ASSESSMENT_NAME = "";
private static String RECAPTCHA_SITE_KEY_1 = "recaptcha-site-key1";
private static String RECAPTCHA_SITE_KEY_2 = "recaptcha-site-key2";
private static WebDriver browser;
Expand All @@ -69,7 +73,7 @@ public static void requireEnvVar(String envVarName) {
}

@BeforeClass
public static void setUp() throws IOException, InterruptedException {
public static void setUp() throws IOException, InterruptedException, JSONException {
requireEnvVar("GOOGLE_APPLICATION_CREDENTIALS");
requireEnvVar("GOOGLE_CLOUD_PROJECT");

Expand Down Expand Up @@ -144,11 +148,59 @@ public void testDeleteSiteKey()
}

@Test
public void testCreateAssessment() throws IOException, JSONException, InterruptedException {
public void testCreateAnnotateAssessment()
throws JSONException, IOException, InterruptedException {
// Create an assessment.
String testURL = "http://localhost:" + randomServerPort + "/";
JSONObject createAssessmentResult = createAssessment(testURL);
ASSESSMENT_NAME = createAssessmentResult.getString("assessmentName");
// Verify that the assessment name has been modified post the assessment creation.
assertThat(ASSESSMENT_NAME).isNotEmpty();

// Annotate the assessment.
AnnotateAssessment.annotateAssessment(PROJECT_ID, ASSESSMENT_NAME);
assertThat(stdOut.toString()).contains("Annotated response sent successfully ! ");
}

public JSONObject createAssessment(String testURL)
throws IOException, JSONException, InterruptedException {

// Setup the automated browser test and retrieve the token and action.
JSONObject tokenActionPair = initiateBrowserTest(testURL);

// Send the token for analysis. The analysis score ranges from 0.0 to 1.0
recaptcha.CreateAssessment.createAssessment(
PROJECT_ID,
RECAPTCHA_SITE_KEY_1,
tokenActionPair.getString("token"),
tokenActionPair.getString("action"));

// Analyse the response.
String response = stdOut.toString();
assertThat(response).contains("Assessment name: ");
assertThat(response).contains("The reCAPTCHA score is: ");
float recaptchaScore = 0;
String assessmentName = "";
for (String line : response.split("\n")) {
if (line.contains("The reCAPTCHA score is: ")) {
recaptchaScore = Float.parseFloat(substr(line));
} else if (line.contains("Assessment name: ")) {
assessmentName = substr(line);
}
}

// Set the score.
browser.findElement(By.cssSelector("#assessment")).sendKeys(String.valueOf(recaptchaScore));
return new JSONObject()
.put("recaptchaScore", recaptchaScore)
.put("assessmentName", assessmentName);
}

public JSONObject initiateBrowserTest(String testURL)
throws IOException, JSONException, InterruptedException {
// Construct the URL to call for validating the assessment.
String assessURL = "http://localhost:" + randomServerPort + "/";
URI url =
UriComponentsBuilder.fromUriString(assessURL)
UriComponentsBuilder.fromUriString(testURL)
.queryParam("recaptchaSiteKey", RECAPTCHA_SITE_KEY_1)
.build()
.encode()
Expand All @@ -158,7 +210,7 @@ public void testCreateAssessment() throws IOException, JSONException, Interrupte

// Wait until the page is loaded.
JavascriptExecutor js = (JavascriptExecutor) browser;
new WebDriverWait(browser, 10)
new WebDriverWait(browser, Duration.ofSeconds(10))
.until(webDriver -> js.executeScript("return document.readyState").equals("complete"));

// Pass the values to be entered.
Expand All @@ -175,21 +227,10 @@ public void testCreateAssessment() throws IOException, JSONException, Interrupte
String token = element.getAttribute("data-token");
String action = element.getAttribute("data-action");

// The obtained token must be further analyzed to get the score.
float recaptchaScore = assessToken(token, action);

// Set the score.
browser.findElement(By.cssSelector("#assessment")).sendKeys(String.valueOf(recaptchaScore));
return;
return new JSONObject().put("token", token).put("action", action);
}

public float assessToken(String token, String action) throws IOException {
// Send the token for analysis. The analysis score ranges from 0.0 to 1.0
recaptcha.CreateAssessment.createAssessment(PROJECT_ID, RECAPTCHA_SITE_KEY_1, token, action);
String response = stdOut.toString();
assertThat(response).contains("The reCAPTCHA score is: ");
float recaptchaScore =
Float.parseFloat(response.substring(response.lastIndexOf(":") + 1).trim());
return recaptchaScore;
public String substr(String line) {
return line.substring((line.lastIndexOf(":") + 1)).trim();
}
}