88from django .utils .functional import SimpleLazyObject
99from django .utils .text import format_lazy
1010from django .utils .version import get_version_tuple
11+ from pymongo .encryption_options import AutoEncryptionOpts
1112from pymongo .uri_parser import parse_uri as pymongo_parse_uri
1213
1314
@@ -28,7 +29,52 @@ def check_django_compatability():
2829 )
2930
3031
31- def parse_uri (uri , * , db_name = None , test = None ):
32+ def get_auto_encryption_opts (crypt_shared_lib_path = None , kms_providers = None ):
33+ key_vault_database_name = "encryption"
34+ key_vault_collection_name = "__keyVault"
35+ key_vault_namespace = f"{ key_vault_database_name } .{ key_vault_collection_name } "
36+ return AutoEncryptionOpts (
37+ key_vault_namespace = key_vault_namespace ,
38+ kms_providers = kms_providers ,
39+ crypt_shared_lib_path = crypt_shared_lib_path ,
40+ )
41+
42+
43+ # This file is intended for local testing only.
44+ # The returned key is hard-coded and should NOT be used in production.
45+
46+
47+ def get_customer_master_key ():
48+ """
49+ Returns a 96-byte local master key for use with MongoDB Client-Side Field Level Encryption.
50+
51+ For local testing purposes only. In production, use a secure KMS like AWS, Azure, GCP, or KMIP.
52+
53+ Returns:
54+ bytes: A 96-byte key.
55+ """
56+ # WARNING: This is a static key for testing only.
57+ # Generate with: os.urandom(96)
58+ return bytes .fromhex (
59+ "000102030405060708090a0b0c0d0e0f"
60+ "101112131415161718191a1b1c1d1e1f"
61+ "202122232425262728292a2b2c2d2e2f"
62+ "303132333435363738393a3b3c3d3e3f"
63+ "404142434445464748494a4b4c4d4e4f"
64+ "505152535455565758595a5b5c5d5e5f"
65+ )
66+
67+
68+ def get_kms_providers ():
69+ """
70+ Return the KMS providers for the MongoDB client.
71+ """
72+ if not settings .KMS_PROVIDERS :
73+ raise ImproperlyConfigured ("You must set KMS_PROVIDERS in your Django settings." )
74+ return settings .KMS_PROVIDERS
75+
76+
77+ def parse_uri (uri , * , db_name = None , test = None , options = None ):
3278 """
3379 Convert the given uri into a dictionary suitable for Django's DATABASES
3480 setting.
@@ -48,14 +94,17 @@ def parse_uri(uri, *, db_name=None, test=None):
4894 db_name = db_name or uri ["database" ]
4995 if not db_name :
5096 raise ImproperlyConfigured ("You must provide the db_name parameter." )
97+ opts = uri .get ("options" )
98+ if options :
99+ opts = {** opts , ** options }
51100 settings_dict = {
52101 "ENGINE" : "django_mongodb_backend" ,
53102 "NAME" : db_name ,
54103 "HOST" : host ,
55104 "PORT" : port ,
56105 "USER" : uri .get ("username" ),
57106 "PASSWORD" : uri .get ("password" ),
58- "OPTIONS" : uri . get ( "options" ) ,
107+ "OPTIONS" : opts ,
59108 }
60109 if "authSource" not in settings_dict ["OPTIONS" ] and uri ["database" ]:
61110 settings_dict ["OPTIONS" ]["authSource" ] = uri ["database" ]
0 commit comments