From 436ae3ef9d5866654504c7d5bfbf6464197ceee6 Mon Sep 17 00:00:00 2001 From: Sita Lakshmi Sangameswaran Date: Wed, 10 Nov 2021 23:15:12 +0530 Subject: [PATCH] docs(samples): added annotate assessment sample and refactored tests. (#635) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(samples): added annotate assessment sample and refactored tests. * 🦉 Updates from OwlBot See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * docs(samples): refactored variable name. Co-authored-by: Owl Bot --- README.md | 1 + .../java/recaptcha/AnnotateAssessment.java | 68 ++++++++++++++++ .../main/java/recaptcha/CreateAssessment.java | 13 ++- .../main/java/recaptcha/UpdateSiteKey.java | 1 + .../src/test/java/app/SnippetsIT.java | 79 ++++++++++++++----- 5 files changed, 139 insertions(+), 23 deletions(-) create mode 100644 samples/snippets/cloud-client/src/main/java/recaptcha/AnnotateAssessment.java diff --git a/README.md b/README.md index 4da98564..0c5c1bfc 100644 --- a/README.md +++ b/README.md @@ -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) | diff --git a/samples/snippets/cloud-client/src/main/java/recaptcha/AnnotateAssessment.java b/samples/snippets/cloud-client/src/main/java/recaptcha/AnnotateAssessment.java new file mode 100644 index 00000000..8c3e8d53 --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/recaptcha/AnnotateAssessment.java @@ -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. + * + *

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] diff --git a/samples/snippets/cloud-client/src/main/java/recaptcha/CreateAssessment.java b/samples/snippets/cloud-client/src/main/java/recaptcha/CreateAssessment.java index 6159f954..a62bea55 100644 --- a/samples/snippets/cloud-client/src/main/java/recaptcha/CreateAssessment.java +++ b/samples/snippets/cloud-client/src/main/java/recaptcha/CreateAssessment.java @@ -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)); } } } diff --git a/samples/snippets/cloud-client/src/main/java/recaptcha/UpdateSiteKey.java b/samples/snippets/cloud-client/src/main/java/recaptcha/UpdateSiteKey.java index fc2d0253..c0e7d3e1 100644 --- a/samples/snippets/cloud-client/src/main/java/recaptcha/UpdateSiteKey.java +++ b/samples/snippets/cloud-client/src/main/java/recaptcha/UpdateSiteKey.java @@ -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() diff --git a/samples/snippets/cloud-client/src/test/java/app/SnippetsIT.java b/samples/snippets/cloud-client/src/test/java/app/SnippetsIT.java index 9683fd38..e579fc75 100644 --- a/samples/snippets/cloud-client/src/test/java/app/SnippetsIT.java +++ b/samples/snippets/cloud-client/src/test/java/app/SnippetsIT.java @@ -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; @@ -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 @@ -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; @@ -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"); @@ -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() @@ -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. @@ -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(); } }