Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c0af5fa

Browse filesBrowse files
authored
docs(webrisk-samples): init add samples and tests (GoogleCloudPlatform#8810)
* docs(webrisk-samples): init add samples and tests * added pytest to requirements * added test and fixed lint errors * modified acc to review comments * modified acc to review comments * modified acc to review comments * deleted commented out code
1 parent c4441cb commit c0af5fa
Copy full SHA for c0af5fa

File tree

Expand file treeCollapse file tree

9 files changed

+343
-0
lines changed
Filter options
Expand file treeCollapse file tree

9 files changed

+343
-0
lines changed

‎webrisk/snippets/__init__.py

Copy file name to clipboard
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
+81Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START webrisk_compute_threatlist_diff]
16+
from google.cloud import webrisk_v1
17+
18+
19+
def compute_threatlist_diff(
20+
threat_type: webrisk_v1.ThreatType,
21+
version_token: bytes,
22+
max_diff_entries: int,
23+
max_database_entries: int,
24+
compression_type: webrisk_v1.CompressionType,
25+
) -> None:
26+
"""Gets the most recent threat list diffs. These diffs should be applied to a local database of
27+
hashes to keep it up-to-date.
28+
29+
If the local database is empty or excessively out-of-date,
30+
a complete snapshot of the database will be returned. This Method only updates a
31+
single ThreatList at a time. To update multiple ThreatList databases, this method needs to be
32+
called once for each list.
33+
34+
Args:
35+
threat_type: The threat list to update. Only a single ThreatType should be specified per request.
36+
threat_type = webrisk_v1.ThreatType.MALWARE
37+
38+
version_token: The current version token of the client for the requested list. If the
39+
client does not have a version token (this is the first time calling ComputeThreatListDiff),
40+
this may be left empty and a full database snapshot will be returned.
41+
42+
max_diff_entries: The maximum size in number of entries. The diff will not contain more entries
43+
than this value. This should be a power of 2 between 2**10 and 2**20.
44+
If zero, no diff size limit is set.
45+
max_diff_entries = 1024
46+
47+
max_database_entries: Sets the maximum number of entries that the client is willing to have in the local database.
48+
This should be a power of 2 between 2**10 and 2**20. If zero, no database size limit is set.
49+
max_database_entries = 1024
50+
51+
compression_type: The compression type supported by the client.
52+
compression_type = webrisk_v1.CompressionType.RAW
53+
"""
54+
55+
webrisk_client = webrisk_v1.WebRiskServiceClient()
56+
57+
constraints = webrisk_v1.ComputeThreatListDiffRequest.Constraints()
58+
constraints.max_diff_entries = max_diff_entries
59+
constraints.max_database_entries = max_database_entries
60+
constraints.supported_compressions = [compression_type]
61+
62+
request = webrisk_v1.ComputeThreatListDiffRequest()
63+
request.threat_type = threat_type
64+
request.version_token = version_token
65+
request.constraints = constraints
66+
67+
response = webrisk_client.compute_threat_list_diff(request)
68+
69+
# The returned response contains the following information:
70+
# https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#computethreatlistdiffresponse
71+
# Type of response: DIFF/ RESET/ RESPONSE_TYPE_UNSPECIFIED
72+
print(response.response_type)
73+
74+
# New version token to be used the next time when querying.
75+
print(response.new_version_token)
76+
77+
# Recommended next diff timestamp.
78+
print(response.recommended_next_diff)
79+
80+
print("Obtained threat list diff.")
81+
# [END webrisk_compute_threatlist_diff]

‎webrisk/snippets/noxfile_config.py

Copy file name to clipboard
+42Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Default TEST_CONFIG_OVERRIDE for python repos.
16+
17+
# You can copy this file into your directory, then it will be imported from
18+
# the noxfile.py.
19+
20+
# The source of truth:
21+
# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/noxfile_config.py
22+
23+
TEST_CONFIG_OVERRIDE = {
24+
# You can opt out from the test for specific Python versions.
25+
"ignored_versions": ["2.7", "3.6"],
26+
# Old samples are opted out of enforcing Python type hints
27+
# All new samples should feature them
28+
"enforce_type_hints": True,
29+
# An envvar key for determining the project id to use. Change it
30+
# to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a
31+
# build specific Cloud project. You can also use your own string
32+
# to use your own Cloud project.
33+
"gcloud_project_env": "GOOGLE_CLOUD_PROJECT",
34+
# 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT',
35+
# If you need to use a specific version of pip,
36+
# change pip_version_override to the string representation
37+
# of the version number, for example, "20.2.4"
38+
"pip_version_override": None,
39+
# A dictionary you want to inject into your test. Don't put any
40+
# secrets here. These values will override predefined values.
41+
"envs": {},
42+
}
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest==7.2.0

‎webrisk/snippets/requirements.txt

Copy file name to clipboard
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
google-cloud-webrisk==1.9.0

‎webrisk/snippets/search_hashes.py

Copy file name to clipboard
+59Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START webrisk_search_hash]
16+
from google.cloud import webrisk_v1
17+
18+
19+
def search_hashes(hash_prefix: bytes, threat_type: webrisk_v1.ThreatType) -> None:
20+
"""Gets the full hashes that match the requested hash prefix.
21+
22+
This is used after a hash prefix is looked up in a threatList and there is a match.
23+
The client side threatList only holds partial hashes so the client must query this method
24+
to determine if there is a full hash match of a threat.
25+
26+
Args:
27+
hash_prefix: A hash prefix, consisting of the most significant 4-32 bytes of a SHA256 hash.
28+
For JSON requests, this field is base64-encoded. Note that if this parameter is provided
29+
by a URI, it must be encoded using the web safe base64 variant (RFC 4648).
30+
Example:
31+
uri = "http://example.com"
32+
sha256 = sha256()
33+
sha256.update(base64.urlsafe_b64encode(bytes(uri, "utf-8")))
34+
hex_string = sha256.digest()
35+
36+
threat_type: The ThreatLists to search in. Multiple ThreatLists may be specified.
37+
For the list on threat types, see:
38+
https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#threattype
39+
threat_type = [webrisk_v1.ThreatType.MALWARE, webrisk_v1.ThreatType.SOCIAL_ENGINEERING]
40+
"""
41+
webrisk_client = webrisk_v1.WebRiskServiceClient()
42+
43+
# Set the hashPrefix and the threat types to search in.
44+
request = webrisk_v1.SearchHashesRequest()
45+
request.hash_prefix = hash_prefix
46+
request.threat_types = [threat_type]
47+
48+
response = webrisk_client.search_hashes(request)
49+
50+
# Get all the hashes that match the prefix. Cache the returned hashes until the time
51+
# specified in threat_hash.expire_time
52+
# For more information on response type, see:
53+
# https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#threathash
54+
for threat_hash in response.threats:
55+
print(threat_hash.hash)
56+
57+
print("Completed searching threat hashes.")
58+
59+
# [END webrisk_search_hash]

‎webrisk/snippets/search_uri.py

Copy file name to clipboard
+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START webrisk_search_uri]
16+
from google.cloud import webrisk_v1
17+
18+
19+
def search_uri(uri: str, threat_type: webrisk_v1.ThreatType.MALWARE) -> None:
20+
"""Checks whether a URI is on a given threatList.
21+
22+
Multiple threatLists may be searched in a single query. The response will list all
23+
requested threatLists the URI was found to match. If the URI is not
24+
found on any of the requested ThreatList an empty response will be returned.
25+
26+
Args:
27+
uri: The URI to be checked for matches
28+
Example: "http://testsafebrowsing.appspot.com/s/malware.html"
29+
30+
threat_type: The ThreatLists to search in. Multiple ThreatLists may be specified.
31+
Example: threat_type = webrisk_v1.ThreatType.MALWARE
32+
"""
33+
webrisk_client = webrisk_v1.WebRiskServiceClient()
34+
35+
request = webrisk_v1.SearchUrisRequest()
36+
request.threat_types = [threat_type]
37+
request.uri = uri
38+
39+
response = webrisk_client.search_uris(request)
40+
if response.threat.threat_types:
41+
print(f"The URI has the following threat: {response}")
42+
return
43+
44+
print("The URL is safe!")
45+
# [END webrisk_search_uri]

‎webrisk/snippets/submit_uri.py

Copy file name to clipboard
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START webrisk_submit_uri]
16+
from google.cloud import webrisk_v1
17+
18+
19+
def submit_uri(project_id: str, uri: str) -> None:
20+
"""Submits a URI suspected of containing malicious content to be reviewed.
21+
22+
Returns a google.longrunning.Operation which, once the review is complete, is updated with its result.
23+
If the result verifies the existence of malicious content, the site will be added to the
24+
Google's Social Engineering lists in order to protect users that could get exposed to this
25+
threat in the future. Only allow-listed projects can use this method during Early Access.
26+
27+
Args:
28+
project_id: The name of the project that is making the submission.
29+
uri: The URI that is being reported for malicious content to be analyzed.
30+
uri = "http://testsafebrowsing.appspot.com/s/malware.html"
31+
"""
32+
webrisk_client = webrisk_v1.WebRiskServiceClient()
33+
34+
submission = webrisk_v1.Submission()
35+
submission.uri = uri
36+
37+
request = webrisk_v1.CreateSubmissionRequest()
38+
request.parent = f"projects/{project_id}"
39+
request.submission = submission
40+
41+
response = webrisk_client.create_submission(request)
42+
print(f"Submission response: {response}")
43+
44+
# [END webrisk_submit_uri]
+57Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import base64
15+
import hashlib
16+
import re
17+
18+
from _pytest.capture import CaptureFixture
19+
import google
20+
from google.cloud import webrisk_v1
21+
22+
from .compute_threatlist_diff import compute_threatlist_diff
23+
from .search_hashes import search_hashes
24+
from .search_uri import search_uri
25+
from .submit_uri import submit_uri
26+
27+
PROJECT = google.auth.default()[1]
28+
29+
30+
def test_search_uri_with_threat(capsys: CaptureFixture) -> None:
31+
search_uri("http://testsafebrowsing.appspot.com/s/malware.html", webrisk_v1.ThreatType.MALWARE)
32+
assert re.search("The URI has the following threat: ", capsys.readouterr().out)
33+
34+
35+
def test_search_uri_without_threat(capsys: CaptureFixture) -> None:
36+
search_uri("http://testsafebrowsing.appspot.com/malware.html", webrisk_v1.ThreatType.MALWARE)
37+
assert re.search("The URL is safe!", capsys.readouterr().out)
38+
39+
40+
def test_submit_uri(capsys: CaptureFixture) -> None:
41+
submit_uri(PROJECT, "http://testsafebrowsing.appspot.com/s/malware.html")
42+
assert re.search("Submission response: ", capsys.readouterr().out)
43+
44+
45+
def test_search_hashes(capsys: CaptureFixture) -> None:
46+
uri = "http://example.com"
47+
sha256 = hashlib.sha256()
48+
sha256.update(base64.urlsafe_b64encode(bytes(uri, "utf-8")))
49+
hex_string = sha256.digest()
50+
51+
search_hashes(hex_string, webrisk_v1.ThreatType.MALWARE)
52+
assert re.search("Completed searching threat hashes.", capsys.readouterr().out)
53+
54+
55+
def test_compute_threatdiff_list(capsys: CaptureFixture) -> None:
56+
compute_threatlist_diff(webrisk_v1.ThreatType.MALWARE, b'', 1024, 1024, webrisk_v1.CompressionType.RAW)
57+
assert re.search("Obtained threat list diff.", capsys.readouterr().out)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.