Skip to content

Commit 3619a31

Browse files
authored
feat: use cryptographically secure random for new document ids (#1162)
1 parent bda9865 commit 3619a31

2 files changed

Lines changed: 22 additions & 3 deletions

File tree

‎packages/google-cloud-firestore/google/cloud/firestore_v1/base_collection.py‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
importdatetime
6161

6262
_AUTO_ID_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
63+
system_random=random.SystemRandom()
6364

6465

6566
classBaseCollectionReference(Generic[QueryType]):
@@ -623,8 +624,11 @@ def _auto_id() -> str:
623624
str: A 20 character string composed of digits, uppercase and
624625
lowercase and letters.
625626
"""
626-
627-
return"".join(random.choice(_AUTO_ID_CHARS) for_inrange(20))
627+
try:
628+
return"".join(system_random.choice(_AUTO_ID_CHARS) for_inrange(20))
629+
# Very old Unix systems don't have os.urandom (/dev/urandom), in which case use random.choice
630+
exceptNotImplementedError:
631+
return"".join(random.choice(_AUTO_ID_CHARS) for_inrange(20))
628632

629633

630634
def_item_to_document_ref(collection_reference, item):

‎packages/google-cloud-firestore/tests/unit/v1/test_base_collection.py‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ def test_basecollectionreference_pipeline(mock_query):
437437
assertpipeline==mock_query._build_pipeline.return_value
438438

439439

440-
@mock.patch("random.choice")
440+
@mock.patch("random.SystemRandom.choice")
441441
deftest__auto_id(mock_rand_choice):
442442
fromgoogle.cloud.firestore_v1.base_collectionimport_AUTO_ID_CHARS, _auto_id
443443

@@ -450,6 +450,21 @@ def test__auto_id(mock_rand_choice):
450450
assertmock_rand_choice.mock_calls==mock_calls
451451

452452

453+
@mock.patch("random.choice")
454+
@mock.patch("random.SystemRandom.choice")
455+
deftest__auto_id_fallback_to_random(mock_system_rand_choice, mock_rand_choice):
456+
fromgoogle.cloud.firestore_v1.base_collectionimport_AUTO_ID_CHARS, _auto_id
457+
458+
mock_system_rand_choice.side_effect=NotImplementedError
459+
mock_result="0123456789abcdefghij"
460+
mock_rand_choice.side_effect=list(mock_result)
461+
result=_auto_id()
462+
assertresult==mock_result
463+
464+
mock_calls= [mock.call(_AUTO_ID_CHARS)] *20
465+
assertmock_rand_choice.mock_calls==mock_calls
466+
467+
453468
def_make_credentials():
454469
importgoogle.auth.credentials
455470

0 commit comments

Comments
 (0)