1
1
import copy
2
+ import os
2
3
import time
4
+ from pathlib import Path
5
+ from urllib .parse import urlencode
3
6
4
7
import django
5
8
from django .conf import settings
8
11
from django .utils .functional import SimpleLazyObject
9
12
from django .utils .text import format_lazy
10
13
from django .utils .version import get_version_tuple
14
+ from pymongo .encryption_options import AutoEncryptionOpts
11
15
from pymongo .uri_parser import parse_uri as pymongo_parse_uri
12
16
13
17
@@ -28,6 +32,62 @@ def check_django_compatability():
28
32
)
29
33
30
34
35
+ # Queryable Encryption-related functions based on helpers from Python Queryable
36
+ # Encryption Tutorial
37
+ # https://github.com/mongodb/docs/tree/master/source/includes/qe-tutorials/python/
38
+ def _get_kms_provider_credentials (kms_provider_name ):
39
+ """
40
+ "A KMS is a remote service that securely stores and manages your encryption keys."
41
+
42
+ Via https://www.mongodb.com/docs/manual/core/queryable-encryption/quick-start/
43
+
44
+ Here we check the provider name and return the appropriate credentials.
45
+ """
46
+ # TODO: Add support for other KMS providers.
47
+ if kms_provider_name == "local" :
48
+ if not Path ("./customer-master-key.txt" ).exists :
49
+ try :
50
+ path = "customer-master-key.txt"
51
+ file_bytes = os .urandom (96 )
52
+ with Path .open (path , "wb" ) as f :
53
+ f .write (file_bytes )
54
+ except Exception as e :
55
+ raise Exception (
56
+ "Unable to write Customer Master Key to file due to the following error: "
57
+ ) from e
58
+
59
+ try :
60
+ path = "./customer-master-key.txt"
61
+ with Path .open (path , "rb" ) as f :
62
+ local_master_key = f .read ()
63
+ if len (local_master_key ) != 96 :
64
+ raise Exception ("Expected the customer master key file to be 96 bytes." )
65
+ return {
66
+ "local" : {"key" : local_master_key },
67
+ }
68
+ except Exception as e :
69
+ raise Exception (
70
+ "Unable to read Customer Master Key from file due to the following error: "
71
+ ) from e
72
+ else :
73
+ raise ValueError (
74
+ "Unrecognized value for kms_provider_name encountered while retrieving KMS credentials."
75
+ )
76
+
77
+
78
+ def get_auto_encryption_options (kms_provider_name ):
79
+ key_vault_database_name = "encryption"
80
+ key_vault_collection_name = "__keyVault"
81
+ key_vault_namespace = f"{ key_vault_database_name } .{ key_vault_collection_name } "
82
+ kms_provider_credentials = _get_kms_provider_credentials (kms_provider_name )
83
+ auto_encryption_opts = AutoEncryptionOpts (
84
+ kms_provider_credentials ,
85
+ key_vault_namespace ,
86
+ crypt_shared_lib_path = os .environ .get ("SHARED_LIB_PATH" ),
87
+ )
88
+ return urlencode (auto_encryption_opts )
89
+
90
+
31
91
def parse_uri (uri , * , db_name = None , test = None ):
32
92
"""
33
93
Convert the given uri into a dictionary suitable for Django's DATABASES
0 commit comments