diff --git a/samples/snippets/cloud-client/src/main/java/app/Main.java b/samples/snippets/cloud-client/src/main/java/app/Main.java new file mode 100644 index 00000000..1c398cbf --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/app/Main.java @@ -0,0 +1,29 @@ +/* + * 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 app; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + SpringApplication.run(Main.class, args); + } + +} diff --git a/samples/snippets/cloud-client/src/main/java/app/MainController.java b/samples/snippets/cloud-client/src/main/java/app/MainController.java new file mode 100644 index 00000000..6b53b8f0 --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/app/MainController.java @@ -0,0 +1,38 @@ +/* + * 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 app; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.ModelAndView; + + +@Controller +@RequestMapping +public class MainController { + + @GetMapping(value = "/") + public static ModelAndView landingPage( + @RequestParam("recaptchaSiteKey") String recaptchaSiteKey) { + ModelMap map = new ModelAndView().getModelMap(); + map.put("siteKey", recaptchaSiteKey); + return new ModelAndView("index", map); + } +} diff --git a/samples/snippets/cloud-client/src/main/java/recaptcha/CreateAssessment.java b/samples/snippets/cloud-client/src/main/java/recaptcha/CreateAssessment.java new file mode 100644 index 00000000..8c73bd5c --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/recaptcha/CreateAssessment.java @@ -0,0 +1,105 @@ +/* + * 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_create_assessment] + +import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient; +import com.google.recaptchaenterprise.v1.Assessment; +import com.google.recaptchaenterprise.v1.CreateAssessmentRequest; +import com.google.recaptchaenterprise.v1.Event; +import com.google.recaptchaenterprise.v1.ProjectName; +import com.google.recaptchaenterprise.v1.RiskAnalysis.ClassificationReason; +import java.io.IOException; + +public class CreateAssessment { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectID = "project-id"; + String recaptchaSiteKey = "recaptcha-site-key"; + String token = "action-token"; + String recaptchaAction = "action-name"; + + createAssessment(projectID, recaptchaSiteKey, token, recaptchaAction); + } + + + /** + * Create an assessment to analyze the risk of an UI action. + * + * @param projectID : GCloud Project ID + * @param recaptchaSiteKey : Site key obtained by registering a domain/app to use recaptcha + * services. + * @param token : The token obtained from the client on passing the recaptchaSiteKey. + * @param recaptchaAction : Action name corresponding to the token. + */ + public static void createAssessment(String projectID, String recaptchaSiteKey, String token, + String recaptchaAction) + 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()) { + + // Specify a name for this assessment. + String assessmentName = "assessment-name"; + // Set the properties of the event to be tracked. + Event event = Event.newBuilder() + .setSiteKey(recaptchaSiteKey) + .setToken(token) + .build(); + + // Build the assessment request. + CreateAssessmentRequest createAssessmentRequest = CreateAssessmentRequest.newBuilder() + .setParent(ProjectName.of(projectID).toString()) + .setAssessment(Assessment.newBuilder().setEvent(event).setName(assessmentName).build()) + .build(); + + Assessment response = client.createAssessment(createAssessmentRequest); + + // Check if the token is valid. + if (!response.getTokenProperties().getValid()) { + System.out.println("The CreateAssessment call failed because the token was: " + + response.getTokenProperties().getInvalidReason().name()); + return; + } + + // Check if the expected action was executed. + if (!response.getTokenProperties().getAction().equals(recaptchaAction)) { + System.out.println( + "The action attribute in reCAPTCHA tag is: " + response.getTokenProperties() + .getAction()); + System.out.println("The action attribute in the reCAPTCHA tag " + + "does not match the action (" + recaptchaAction + ") you are expecting to score"); + return; + } + + // Get the risk score and the reason(s). + // 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); + } + } + } +} +// [END recaptcha_enterprise_create_assessment] \ No newline at end of file diff --git a/samples/snippets/cloud-client/src/main/java/recaptcha/CreateSiteKey.java b/samples/snippets/cloud-client/src/main/java/recaptcha/CreateSiteKey.java new file mode 100644 index 00000000..c2eff222 --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/recaptcha/CreateSiteKey.java @@ -0,0 +1,78 @@ +/* + * 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_create_site_key] + +import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient; +import com.google.recaptchaenterprise.v1.CreateKeyRequest; +import com.google.recaptchaenterprise.v1.Key; +import com.google.recaptchaenterprise.v1.ProjectName; +import com.google.recaptchaenterprise.v1.WebKeySettings; +import com.google.recaptchaenterprise.v1.WebKeySettings.IntegrationType; +import java.io.IOException; + + +public class CreateSiteKey { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectID = "your-project-id"; + String domainName = "domain-name"; + + createSiteKey(projectID, domainName); + } + + /** + * Create reCAPTCHA Site key which binds a domain name to a unique key. + * + * @param projectID : GCloud Project ID. + * @param domainName : Specify the domain name in which the reCAPTCHA should be activated. + */ + public static String createSiteKey(String projectID, String domainName) 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()) { + + // Set the type of reCAPTCHA to be displayed. + // For different types, see: https://cloud.google.com/recaptcha-enterprise/docs/keys + Key scoreKey = Key.newBuilder() + .setDisplayName("any_descriptive_name_for_the_key") + .setWebSettings(WebKeySettings.newBuilder() + .addAllowedDomains(domainName) + .setAllowAmpTraffic(false) + .setIntegrationType(IntegrationType.SCORE).build()) + .build(); + + CreateKeyRequest createKeyRequest = CreateKeyRequest.newBuilder() + .setParent(ProjectName.of(projectID).toString()) + .setKey(scoreKey) + .build(); + + // Get the name of the created reCAPTCHA site key. + Key response = client.createKey(createKeyRequest); + String keyName = response.getName(); + String recaptchaSiteKey = keyName.substring(keyName.lastIndexOf("/") + 1); + System.out.println("reCAPTCHA Site key created successfully. Site Key: " + recaptchaSiteKey); + return recaptchaSiteKey; + } + } +} +// [END recaptcha_enterprise_create_site_key] + diff --git a/samples/snippets/cloud-client/src/main/java/recaptcha/DeleteSiteKey.java b/samples/snippets/cloud-client/src/main/java/recaptcha/DeleteSiteKey.java new file mode 100644 index 00000000..80809eff --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/recaptcha/DeleteSiteKey.java @@ -0,0 +1,64 @@ +/* + * 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_delete_site_key] + +import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient; +import com.google.recaptchaenterprise.v1.DeleteKeyRequest; +import com.google.recaptchaenterprise.v1.KeyName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class DeleteSiteKey { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + // TODO(developer): Replace these variables before running the sample. + String projectID = "your-project-id"; + String recaptchaSiteKey = "recaptcha-site-key"; + + deleteSiteKey(projectID, recaptchaSiteKey); + } + + /** + * Delete the given reCAPTCHA site key present under the project ID. + * + * @param projectID: GCloud Project ID. + * @param recaptchaSiteKey: Specify the site key to be deleted. + */ + public static void deleteSiteKey(String projectID, String recaptchaSiteKey) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + // 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()) { + + // Set the project ID and reCAPTCHA site key. + DeleteKeyRequest deleteKeyRequest = DeleteKeyRequest.newBuilder() + .setName(KeyName.of(projectID, recaptchaSiteKey).toString()) + .build(); + + client.deleteKeyCallable().futureCall(deleteKeyRequest).get(5, TimeUnit.SECONDS); + System.out.println("reCAPTCHA Site key successfully deleted !"); + } + } +} +// [END recaptcha_enterprise_delete_site_key] \ No newline at end of file diff --git a/samples/snippets/cloud-client/src/main/java/recaptcha/GetSiteKey.java b/samples/snippets/cloud-client/src/main/java/recaptcha/GetSiteKey.java new file mode 100644 index 00000000..b77f72d8 --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/recaptcha/GetSiteKey.java @@ -0,0 +1,70 @@ +/* + * 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_get_site_key] + +import com.google.api.core.ApiFuture; +import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient; +import com.google.recaptchaenterprise.v1.GetKeyRequest; +import com.google.recaptchaenterprise.v1.Key; +import com.google.recaptchaenterprise.v1.KeyName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class GetSiteKey { + + public static void main(String[] args) + throws IOException, InterruptedException, ExecutionException, TimeoutException { + // TODO(developer): Replace these variables before running the sample. + String projectID = "your-project-id"; + String recaptchaSiteKey = "recaptcha-site-key"; + + getSiteKey(projectID, recaptchaSiteKey); + } + + + /** + * Get the reCAPTCHA site key present under the project ID. + * + * @param projectID: GCloud Project ID. + * @param recaptchaSiteKey: Specify the site key to get the details. + */ + public static void getSiteKey(String projectID, String recaptchaSiteKey) + throws IOException, InterruptedException, ExecutionException, TimeoutException { + // 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()) { + + // Construct the "GetSiteKey" request. + GetKeyRequest getKeyRequest = GetKeyRequest.newBuilder() + .setName(KeyName.of(projectID, recaptchaSiteKey).toString()) + .build(); + + // Wait for the operation to complete. + ApiFuture futureCall = client.getKeyCallable().futureCall(getKeyRequest); + Key key = futureCall.get(5, TimeUnit.SECONDS); + + System.out.println("Successfully obtained the key !" + key.getName()); + } + } +} +// [END recaptcha_enterprise_get_site_key] \ No newline at end of file diff --git a/samples/snippets/cloud-client/src/main/java/recaptcha/ListSiteKeys.java b/samples/snippets/cloud-client/src/main/java/recaptcha/ListSiteKeys.java new file mode 100644 index 00000000..41e7e8b1 --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/recaptcha/ListSiteKeys.java @@ -0,0 +1,59 @@ +/* + * 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_list_site_keys] + +import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient; +import com.google.recaptchaenterprise.v1.Key; +import com.google.recaptchaenterprise.v1.ListKeysRequest; +import com.google.recaptchaenterprise.v1.ProjectName; +import java.io.IOException; + +public class ListSiteKeys { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectID = "your-project-id"; + + listSiteKeys(projectID); + } + + /** + * List all keys present under the given project ID. + * + * @param projectID: GCloud Project ID. + */ + public static void listSiteKeys(String projectID) 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()) { + // Set the project ID to list the keys present in it. + ListKeysRequest listKeysRequest = ListKeysRequest.newBuilder() + .setParent(ProjectName.of(projectID).toString()) + .build(); + + System.out.println("Listing reCAPTCHA site keys: "); + for (Key key : client.listKeys(listKeysRequest).iterateAll()) { + System.out.println(key.getName()); + } + } + } +} +// [END recaptcha_enterprise_list_site_keys] \ No newline at end of file diff --git a/samples/snippets/cloud-client/src/main/java/recaptcha/UpdateSiteKey.java b/samples/snippets/cloud-client/src/main/java/recaptcha/UpdateSiteKey.java new file mode 100644 index 00000000..ef2d5acd --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/recaptcha/UpdateSiteKey.java @@ -0,0 +1,86 @@ +/* + * 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_update_site_key] + +import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient; +import com.google.recaptchaenterprise.v1.GetKeyRequest; +import com.google.recaptchaenterprise.v1.Key; +import com.google.recaptchaenterprise.v1.KeyName; +import com.google.recaptchaenterprise.v1.UpdateKeyRequest; +import com.google.recaptchaenterprise.v1.WebKeySettings; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +public class UpdateSiteKey { + + public static void main(String[] args) + throws IOException, InterruptedException, ExecutionException, TimeoutException { + // TODO(developer): Replace these variables before running the sample. + String projectID = "your-project-id"; + String recaptchaSiteKeyID = "recaptcha-site-key-id"; + String domainName = "domain-name"; + + updateSiteKey(projectID, recaptchaSiteKeyID, domainName); + } + + /** + * Update the properties of the given site key present under the project id. + * + * @param projectID: GCloud Project ID. + * @param recaptchaSiteKeyID: Specify the site key. + * @param domainName: Specify the domain name for which the settings should be updated. + */ + public static void updateSiteKey(String projectID, String recaptchaSiteKeyID, String domainName) + throws IOException, InterruptedException, ExecutionException, TimeoutException { + // 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()) { + + // Set the name and the new settings for the key. + UpdateKeyRequest updateKeyRequest = UpdateKeyRequest.newBuilder() + .setKey(Key.newBuilder() + .setName(KeyName.of(projectID, recaptchaSiteKeyID).toString()) + .setWebSettings(WebKeySettings.newBuilder() + .setAllowAmpTraffic(true) + .addAllowedDomains(domainName).build()) + .build()) + .build(); + + client.updateKeyCallable().futureCall(updateKeyRequest).get(); + + // Check if the key has been updated. + GetKeyRequest getKeyRequest = GetKeyRequest.newBuilder() + .setName(KeyName.of(projectID, recaptchaSiteKeyID).toString()).build(); + Key response = client.getKey(getKeyRequest); + + // Get the changed property. + boolean allowedAmpTraffic = response.getWebSettings().getAllowAmpTraffic(); + if (!allowedAmpTraffic) { + System.out + .println("Error! reCAPTCHA Site key property hasn't been updated. Please try again !"); + return; + } + System.out.println("reCAPTCHA Site key successfully updated !"); + } + } +} +// [END recaptcha_enterprise_update_site_key] \ No newline at end of file diff --git a/samples/snippets/cloud-client/src/pom.xml b/samples/snippets/cloud-client/src/pom.xml new file mode 100644 index 00000000..da25891a --- /dev/null +++ b/samples/snippets/cloud-client/src/pom.xml @@ -0,0 +1,129 @@ + + + 4.0.0 + com.google.cloud + recaptcha-enterprise-snippets + jar + Google reCAPTCHA Enterprise Snippets + https://github.com/googleapis/java-recaptchaenterprise + + + + com.google.cloud.samples + shared-configuration + 1.0.23 + + + + 11 + 11 + UTF-8 + + + + + + + com.google.cloud + libraries-bom + 20.8.0 + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + + com.google.cloud + google-cloud-recaptchaenterprise + + + + + + org.seleniumhq.selenium + selenium-java + 3.9.0 + + + org.seleniumhq.selenium + selenium-chrome-driver + 3.9.0 + + + com.google.guava + guava + 23.6-jre + + + + io.github.bonigarcia + webdrivermanager + 4.0.0 + + + + + + + + junit + junit + 4.13.2 + test + + + com.google.truth + truth + 1.1.3 + test + + + + + + + + org.springframework.boot + spring-boot-starter-web + 2.5.2 + + + org.springframework.boot + spring-boot-starter-test + 2.5.2 + test + + + org.springframework.boot + spring-boot-starter-thymeleaf + 2.5.2 + + + net.bytebuddy + byte-buddy + 1.10.20 + + + com.google.api + api-common + + + + + + diff --git a/samples/snippets/cloud-client/src/resources/templates/index.html b/samples/snippets/cloud-client/src/resources/templates/index.html new file mode 100644 index 00000000..77e1ed6f --- /dev/null +++ b/samples/snippets/cloud-client/src/resources/templates/index.html @@ -0,0 +1,79 @@ + + + + + reCAPTCHA-Enterprise + + + + + +
+ + + + + + + +
+
+ +
+ + \ No newline at end of file diff --git a/samples/snippets/cloud-client/src/test/java/app/SnippetsIT.java b/samples/snippets/cloud-client/src/test/java/app/SnippetsIT.java new file mode 100644 index 00000000..e769afbb --- /dev/null +++ b/samples/snippets/cloud-client/src/test/java/app/SnippetsIT.java @@ -0,0 +1,193 @@ +/* + * 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 app; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import io.github.bonigarcia.wdm.WebDriverManager; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.net.URI; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.json.JSONException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.util.UriComponentsBuilder; + +@RunWith(SpringJUnit4ClassRunner.class) +@EnableAutoConfiguration +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class SnippetsIT { + + private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static final String DOMAIN_NAME = "localhost"; + private static String RECAPTCHA_SITE_KEY_1 = "recaptcha-site-key1"; + private static String RECAPTCHA_SITE_KEY_2 = "recaptcha-site-key2"; + private static WebDriver browser; + @LocalServerPort + private int randomServerPort; + private ByteArrayOutputStream stdOut; + + + // Check if the required environment variables are set. + public static void requireEnvVar(String envVarName) { + assertWithMessage(String.format("Missing environment variable '%s' ", envVarName)) + .that(System.getenv(envVarName)).isNotEmpty(); + } + + @BeforeClass + public static void setUp() throws IOException, InterruptedException { + requireEnvVar("GOOGLE_APPLICATION_CREDENTIALS"); + requireEnvVar("GOOGLE_CLOUD_PROJECT"); + + // Create reCAPTCHA Site key and associate the given domain. + RECAPTCHA_SITE_KEY_1 = recaptcha.CreateSiteKey.createSiteKey(PROJECT_ID, DOMAIN_NAME); + RECAPTCHA_SITE_KEY_2 = recaptcha.CreateSiteKey.createSiteKey(PROJECT_ID, DOMAIN_NAME); + TimeUnit.SECONDS.sleep(5); + + // Set Selenium Driver to Chrome. + WebDriverManager.chromedriver().setup(); + browser = new ChromeDriver(); + } + + @AfterClass + public static void cleanUp() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(stdOut)); + + recaptcha.DeleteSiteKey.deleteSiteKey(PROJECT_ID, RECAPTCHA_SITE_KEY_1); + assertThat(stdOut.toString()).contains("reCAPTCHA Site key successfully deleted !"); + + browser.quit(); + + stdOut.close(); + System.setOut(null); + } + + @Before + public void beforeEach() { + stdOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(stdOut)); + } + + @After + public void afterEach() { + stdOut = null; + System.setOut(null); + } + + @Test + public void testCreateSiteKey() { + // Test if the recaptcha site key has already been successfully created, as part of the setup. + Assert.assertFalse(RECAPTCHA_SITE_KEY_1.isEmpty()); + } + + @Test + public void testGetKey() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + recaptcha.GetSiteKey.getSiteKey(PROJECT_ID, RECAPTCHA_SITE_KEY_1); + assertThat(stdOut.toString()).contains(RECAPTCHA_SITE_KEY_1); + } + + @Test + public void testListSiteKeys() throws IOException { + recaptcha.ListSiteKeys.listSiteKeys(PROJECT_ID); + assertThat(stdOut.toString()).contains(RECAPTCHA_SITE_KEY_1); + } + + @Test + public void testUpdateSiteKey() + throws IOException, InterruptedException, ExecutionException, TimeoutException { + recaptcha.UpdateSiteKey.updateSiteKey(PROJECT_ID, RECAPTCHA_SITE_KEY_1, DOMAIN_NAME); + assertThat(stdOut.toString()).contains("reCAPTCHA Site key successfully updated !"); + } + + @Test + public void testDeleteSiteKey() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + recaptcha.DeleteSiteKey.deleteSiteKey(PROJECT_ID, RECAPTCHA_SITE_KEY_2); + assertThat(stdOut.toString()).contains("reCAPTCHA Site key successfully deleted !"); + } + + @Test + public void testCreateAssessment() throws IOException, JSONException, InterruptedException { + // Construct the URL to call for validating the assessment. + String assessURL = "http://localhost:" + randomServerPort + "/"; + URI url = UriComponentsBuilder.fromUriString(assessURL) + .queryParam("recaptchaSiteKey", RECAPTCHA_SITE_KEY_1) + .build().encode().toUri(); + + browser.get(url.toURL().toString()); + + // Wait until the page is loaded. + JavascriptExecutor js = (JavascriptExecutor) browser; + new WebDriverWait(browser, 10).until( + webDriver -> js.executeScript("return document.readyState").equals("complete")); + + // Pass the values to be entered. + browser.findElement(By.id("username")).sendKeys("username"); + browser.findElement(By.id("password")).sendKeys("password"); + + // On clicking the button, the request params will be sent to reCAPTCHA. + browser.findElement(By.id("recaptchabutton")).click(); + + TimeUnit.SECONDS.sleep(1); + + // Retrieve the reCAPTCHA token response. + WebElement element = browser.findElement(By.cssSelector("#assessment")); + 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; + } + + 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; + } +}