Skip to content

Commit ebe1d7d

Browse files
Sita04gcf-owl-bot[bot]eaball35
authored
docs(samples): added account defender samples and tests (#771)
* docs(samples): added sample account defender assessment RPC. * docs(samples): fixed typo * docs(samples): added copyright. * docs(samples): added samples for account defender operations * docs(samples): added comments * docs(samples): lint and comment fix * docs(samples): updated ato samples and added tests * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * docs(samples): update acc to review comments * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * modified var name to match docs * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: Emily Ball <[email protected]>
1 parent edc26d7 commit ebe1d7d

File tree

6 files changed

+483
-12
lines changed

6 files changed

+483
-12
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package account_defender;
18+
19+
// [START recaptcha_enterprise_account_defender_assessment]
20+
21+
import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient;
22+
import com.google.protobuf.ByteString;
23+
import com.google.recaptchaenterprise.v1.AccountDefenderAssessment.AccountDefenderLabel;
24+
import com.google.recaptchaenterprise.v1.Assessment;
25+
import com.google.recaptchaenterprise.v1.CreateAssessmentRequest;
26+
import com.google.recaptchaenterprise.v1.Event;
27+
import com.google.recaptchaenterprise.v1.ProjectName;
28+
import com.google.recaptchaenterprise.v1.RiskAnalysis.ClassificationReason;
29+
import com.google.recaptchaenterprise.v1.TokenProperties;
30+
import java.io.IOException;
31+
import java.nio.charset.StandardCharsets;
32+
import java.security.MessageDigest;
33+
import java.security.NoSuchAlgorithmException;
34+
import java.util.List;
35+
import java.util.UUID;
36+
37+
public class AccountDefenderAssessment {
38+
39+
public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
40+
// TODO(developer): Replace these variables before running the sample.
41+
// projectId: Google Cloud Project ID
42+
String projectId = "project-id";
43+
44+
// recaptchaSiteKey: Site key obtained by registering a domain/app to use recaptcha
45+
// services.
46+
String recaptchaSiteKey = "recaptcha-site-key";
47+
48+
// token: The token obtained from the client on passing the recaptchaSiteKey.
49+
// To get the token, integrate the recaptchaSiteKey with frontend. See,
50+
// https://cloud.google.com/recaptcha-enterprise/docs/instrument-web-pages#frontend_integration_score
51+
String token = "recaptcha-token";
52+
53+
// recaptchaAction: The action name corresponding to the token.
54+
String recaptchaAction = "recaptcha-action";
55+
56+
// Unique ID of the customer, such as email, customer ID, etc.
57+
String userIdentifier = "default" + UUID.randomUUID().toString().split("-")[0];
58+
59+
// Hash the unique customer ID using HMAC SHA-256.
60+
MessageDigest digest = MessageDigest.getInstance("SHA-256");
61+
byte[] hashBytes = digest.digest(userIdentifier.getBytes(StandardCharsets.UTF_8));
62+
ByteString hashedAccountId = ByteString.copyFrom(hashBytes);
63+
64+
accountDefenderAssessment(projectId, recaptchaSiteKey, token, recaptchaAction, hashedAccountId);
65+
}
66+
67+
/**
68+
* This assessment detects account takeovers. See,
69+
* https://cloud.google.com/recaptcha-enterprise/docs/account-takeovers The input is the hashed
70+
* account id. Result tells if the action represents an account takeover. You can optionally
71+
* trigger a Multi-Factor Authentication based on the result.
72+
*/
73+
public static void accountDefenderAssessment(
74+
String projectId,
75+
String recaptchaSiteKey,
76+
String token,
77+
String recaptchaAction,
78+
ByteString hashedAccountId)
79+
throws IOException {
80+
try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {
81+
82+
// Set the properties of the event to be tracked.
83+
Event event =
84+
Event.newBuilder()
85+
.setSiteKey(recaptchaSiteKey)
86+
.setToken(token)
87+
// Set the hashed account id (of the user).
88+
// Recommended approach: HMAC SHA256 along with salt (or secret key).
89+
.setHashedAccountId(hashedAccountId)
90+
.build();
91+
92+
// Build the assessment request.
93+
CreateAssessmentRequest createAssessmentRequest =
94+
CreateAssessmentRequest.newBuilder()
95+
.setParent(ProjectName.of(projectId).toString())
96+
.setAssessment(Assessment.newBuilder().setEvent(event).build())
97+
.build();
98+
99+
Assessment response = client.createAssessment(createAssessmentRequest);
100+
101+
// Check integrity of the response token.
102+
if (!checkTokenIntegrity(response.getTokenProperties(), recaptchaAction)) {
103+
return;
104+
}
105+
106+
// Get the reason(s) and the reCAPTCHA risk score.
107+
// For more information on interpreting the assessment,
108+
// see: https://cloud.google.com/recaptcha-enterprise/docs/interpret-assessment
109+
for (ClassificationReason reason : response.getRiskAnalysis().getReasonsList()) {
110+
System.out.println(reason);
111+
}
112+
float recaptchaScore = response.getRiskAnalysis().getScore();
113+
System.out.println("The reCAPTCHA score is: " + recaptchaScore);
114+
String assessmentName = response.getName();
115+
System.out.println(
116+
"Assessment name: " + assessmentName.substring(assessmentName.lastIndexOf("/") + 1));
117+
118+
// Get the Account Defender result.
119+
com.google.recaptchaenterprise.v1.AccountDefenderAssessment accountDefenderAssessment =
120+
response.getAccountDefenderAssessment();
121+
System.out.println(accountDefenderAssessment);
122+
123+
// Get Account Defender label.
124+
List<AccountDefenderLabel> defenderResult =
125+
response.getAccountDefenderAssessment().getLabelsList();
126+
// Based on the result, can you choose next steps.
127+
// If the 'defenderResult' field is empty, it indicates that Account Defender did not have
128+
// anything to add to the score.
129+
// Few result labels: ACCOUNT_DEFENDER_LABEL_UNSPECIFIED, PROFILE_MATCH,
130+
// SUSPICIOUS_LOGIN_ACTIVITY, SUSPICIOUS_ACCOUNT_CREATION, RELATED_ACCOUNTS_NUMBER_HIGH.
131+
// For more information on interpreting the assessment, see:
132+
// https://cloud.google.com/recaptcha-enterprise/docs/account-defender#interpret-assessment-details
133+
System.out.println("Account Defender Assessment Result: " + defenderResult);
134+
}
135+
}
136+
137+
private static boolean checkTokenIntegrity(
138+
TokenProperties tokenProperties, String recaptchaAction) {
139+
// Check if the token is valid.
140+
if (!tokenProperties.getValid()) {
141+
System.out.println(
142+
"The Account Defender Assessment call failed because the token was: "
143+
+ tokenProperties.getInvalidReason().name());
144+
return false;
145+
}
146+
147+
// Check if the expected action was executed.
148+
if (!tokenProperties.getAction().equals(recaptchaAction)) {
149+
System.out.printf(
150+
"The action attribute in the reCAPTCHA tag '%s' does not match "
151+
+ "the action '%s' you are expecting to score",
152+
tokenProperties.getAction(), recaptchaAction);
153+
return false;
154+
}
155+
return true;
156+
}
157+
}
158+
// [END recaptcha_enterprise_account_defender_assessment]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package account_defender;
18+
19+
// [START recaptcha_enterprise_annotate_account_defender_assessment]
20+
21+
import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient;
22+
import com.google.protobuf.ByteString;
23+
import com.google.recaptchaenterprise.v1.AnnotateAssessmentRequest;
24+
import com.google.recaptchaenterprise.v1.AnnotateAssessmentRequest.Annotation;
25+
import com.google.recaptchaenterprise.v1.AnnotateAssessmentRequest.Reason;
26+
import com.google.recaptchaenterprise.v1.AnnotateAssessmentResponse;
27+
import com.google.recaptchaenterprise.v1.AssessmentName;
28+
import java.io.IOException;
29+
import java.security.NoSuchAlgorithmException;
30+
31+
public class AnnotateAccountDefenderAssessment {
32+
33+
public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
34+
// TODO(developer): Replace these variables before running the sample.
35+
// projectID: GCloud Project id.
36+
String projectID = "project-id";
37+
38+
// assessmentId: Value of the 'name' field returned from the CreateAssessment call.
39+
String assessmentId = "account-defender-assessment-id";
40+
41+
// hashedAccountId: Set the hashedAccountId corresponding to the assessment id.
42+
ByteString hashedAccountId = ByteString.copyFrom(new byte[] {});
43+
44+
annotateAssessment(projectID, assessmentId, hashedAccountId);
45+
}
46+
47+
/**
48+
* Pre-requisite: Create an assessment before annotating. Annotate an assessment to provide
49+
* feedback on the correctness of recaptcha prediction.
50+
*/
51+
public static void annotateAssessment(
52+
String projectID, String assessmentId, ByteString hashedAccountId) throws IOException {
53+
54+
try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {
55+
// Build the annotation request.
56+
// For more info on when/how to annotate, see:
57+
// https://cloud.google.com/recaptcha-enterprise/docs/annotate-assessment#when_to_annotate
58+
AnnotateAssessmentRequest annotateAssessmentRequest =
59+
AnnotateAssessmentRequest.newBuilder()
60+
.setName(AssessmentName.of(projectID, assessmentId).toString())
61+
.setAnnotation(Annotation.LEGITIMATE)
62+
.addReasons(Reason.PASSED_TWO_FACTOR)
63+
.setHashedAccountId(hashedAccountId)
64+
.build();
65+
66+
// Empty response is sent back.
67+
AnnotateAssessmentResponse response = client.annotateAssessment(annotateAssessmentRequest);
68+
System.out.println("Annotated response sent successfully ! " + response);
69+
}
70+
}
71+
}
72+
// [END recaptcha_enterprise_annotate_account_defender_assessment]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package account_defender;
18+
19+
// [START recaptcha_enterprise_list_related_account_group_membership]
20+
21+
import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient;
22+
import com.google.recaptchaenterprise.v1.ListRelatedAccountGroupMembershipsRequest;
23+
import com.google.recaptchaenterprise.v1.RelatedAccountGroupMembership;
24+
import java.io.IOException;
25+
26+
public class ListRelatedAccountGroupMemberships {
27+
28+
public static void main(String[] args) throws IOException {
29+
// TODO(developer): Replace these variables before running the sample.
30+
// projectId: Google Cloud Project Id.
31+
String projectId = "project-id";
32+
33+
// relatedAccountGroup: Name of the account group.
34+
String relatedAccountGroup = "related-account-group-name";
35+
36+
listRelatedAccountGroupMemberships(projectId, relatedAccountGroup);
37+
}
38+
39+
/** Given a group name, list memberships in the group. */
40+
public static void listRelatedAccountGroupMemberships(
41+
String projectId, String relatedAccountGroup) throws IOException {
42+
try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {
43+
44+
// Construct the request.
45+
ListRelatedAccountGroupMembershipsRequest request =
46+
ListRelatedAccountGroupMembershipsRequest.newBuilder()
47+
.setParent(
48+
String.format(
49+
"projects/%s/relatedaccountgroups/%s", projectId, relatedAccountGroup))
50+
.build();
51+
52+
for (RelatedAccountGroupMembership relatedAccountGroupMembership :
53+
client.listRelatedAccountGroupMemberships(request).iterateAll()) {
54+
System.out.println(relatedAccountGroupMembership.getName());
55+
}
56+
System.out.println("Finished listing related account group memberships.");
57+
}
58+
}
59+
}
60+
// [END recaptcha_enterprise_list_related_account_group_membership]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package account_defender;
18+
19+
// [START recaptcha_enterprise_list_related_account_group]
20+
21+
import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient;
22+
import com.google.recaptchaenterprise.v1.ListRelatedAccountGroupsRequest;
23+
import com.google.recaptchaenterprise.v1.RelatedAccountGroup;
24+
import java.io.IOException;
25+
26+
public class ListRelatedAccountGroups {
27+
28+
public static void main(String[] args) throws IOException {
29+
// TODO(developer): Replace these variables before running the sample.
30+
// projectId : Google Cloud Project Id.
31+
String projectId = "project-id";
32+
33+
listRelatedAccountGroups(projectId);
34+
}
35+
36+
// List related account groups in the project.
37+
public static void listRelatedAccountGroups(String projectId) throws IOException {
38+
try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {
39+
40+
ListRelatedAccountGroupsRequest request =
41+
ListRelatedAccountGroupsRequest.newBuilder().setParent("projects/" + projectId).build();
42+
43+
System.out.println("Listing related account groups..");
44+
for (RelatedAccountGroup group : client.listRelatedAccountGroups(request).iterateAll()) {
45+
System.out.println(group.getName());
46+
}
47+
}
48+
}
49+
}
50+
// [END recaptcha_enterprise_list_related_account_group]

0 commit comments

Comments
 (0)