67
67
68
68
69
69
@contextlib .contextmanager
70
- def _wrap_encryption_errors_ctx ():
70
+ def _wrap_encryption_errors ():
71
71
"""Context manager to wrap encryption related errors."""
72
72
try :
73
73
yield
@@ -79,19 +79,6 @@ def _wrap_encryption_errors_ctx():
79
79
raise EncryptionError (exc )
80
80
81
81
82
- def _wrap_encryption_errors (encryption_func = None ):
83
- """Decorator or context manager to wrap encryption related errors."""
84
- if encryption_func :
85
- @functools .wraps (encryption_func )
86
- def wrap_encryption_errors (* args , ** kwargs ):
87
- with _wrap_encryption_errors_ctx ():
88
- return encryption_func (* args , ** kwargs )
89
-
90
- return wrap_encryption_errors
91
- else :
92
- return _wrap_encryption_errors_ctx ()
93
-
94
-
95
82
class _EncryptionIO (MongoCryptCallback ):
96
83
def __init__ (self , client , key_vault_coll , mongocryptd_client , opts ):
97
84
"""Internal class to perform I/O on behalf of pymongocrypt."""
@@ -260,8 +247,8 @@ def __init__(self, io_callbacks, opts):
260
247
self ._auto_encrypter = AutoEncrypter (io_callbacks , MongoCryptOptions (
261
248
opts ._kms_providers , schema_map ))
262
249
self ._bypass_auto_encryption = opts ._bypass_auto_encryption
250
+ self ._closed = False
263
251
264
- @_wrap_encryption_errors
265
252
def encrypt (self , database , cmd , check_keys , codec_options ):
266
253
"""Encrypt a MongoDB command.
267
254
@@ -274,17 +261,20 @@ def encrypt(self, database, cmd, check_keys, codec_options):
274
261
:Returns:
275
262
The encrypted command to execute.
276
263
"""
277
- # Workaround for $clusterTime which is incompatible with check_keys.
278
- cluster_time = check_keys and cmd .pop ('$clusterTime' , None )
279
- encoded_cmd = _dict_to_bson (cmd , check_keys , codec_options )
280
- encrypted_cmd = self ._auto_encrypter .encrypt (database , encoded_cmd )
281
- # TODO: PYTHON-1922 avoid decoding the encrypted_cmd.
282
- encrypt_cmd = _inflate_bson (encrypted_cmd , DEFAULT_RAW_BSON_OPTIONS )
283
- if cluster_time :
284
- encrypt_cmd ['$clusterTime' ] = cluster_time
285
- return encrypt_cmd
286
-
287
- @_wrap_encryption_errors
264
+ self ._check_closed ()
265
+ with _wrap_encryption_errors ():
266
+ # Workaround for $clusterTime which is incompatible with
267
+ # check_keys.
268
+ cluster_time = check_keys and cmd .pop ('$clusterTime' , None )
269
+ encoded_cmd = _dict_to_bson (cmd , check_keys , codec_options )
270
+ encrypted_cmd = self ._auto_encrypter .encrypt (database , encoded_cmd )
271
+ # TODO: PYTHON-1922 avoid decoding the encrypted_cmd.
272
+ encrypt_cmd = _inflate_bson (
273
+ encrypted_cmd , DEFAULT_RAW_BSON_OPTIONS )
274
+ if cluster_time :
275
+ encrypt_cmd ['$clusterTime' ] = cluster_time
276
+ return encrypt_cmd
277
+
288
278
def decrypt (self , response ):
289
279
"""Decrypt a MongoDB command response.
290
280
@@ -294,10 +284,17 @@ def decrypt(self, response):
294
284
:Returns:
295
285
The decrypted command response.
296
286
"""
297
- return self ._auto_encrypter .decrypt (response )
287
+ self ._check_closed ()
288
+ with _wrap_encryption_errors ():
289
+ return self ._auto_encrypter .decrypt (response )
290
+
291
+ def _check_closed (self ):
292
+ if self ._closed :
293
+ raise InvalidOperation ("Cannot use MongoClient after close" )
298
294
299
295
def close (self ):
300
296
"""Cleanup resources."""
297
+ self ._closed = True
301
298
self ._auto_encrypter .close ()
302
299
303
300
@staticmethod
@@ -430,7 +427,7 @@ def create_data_key(self, kms_provider, master_key=None,
430
427
The ``_id`` of the created data key document.
431
428
"""
432
429
self ._check_closed ()
433
- with _wrap_encryption_errors_ctx ():
430
+ with _wrap_encryption_errors ():
434
431
return self ._encryption .create_data_key (
435
432
kms_provider , master_key = master_key ,
436
433
key_alt_names = key_alt_names )
@@ -461,7 +458,7 @@ def encrypt(self, value, algorithm, key_id=None, key_alt_name=None):
461
458
'key_id must be a bson.binary.Binary with subtype 4' )
462
459
463
460
doc = encode ({'v' : value }, codec_options = self ._codec_options )
464
- with _wrap_encryption_errors_ctx ():
461
+ with _wrap_encryption_errors ():
465
462
encrypted_doc = self ._encryption .encrypt (
466
463
doc , algorithm , key_id = key_id , key_alt_name = key_alt_name )
467
464
return decode (encrypted_doc )['v' ]
@@ -481,7 +478,7 @@ def decrypt(self, value):
481
478
raise TypeError (
482
479
'value to decrypt must be a bson.binary.Binary with subtype 6' )
483
480
484
- with _wrap_encryption_errors_ctx ():
481
+ with _wrap_encryption_errors ():
485
482
doc = encode ({'v' : value })
486
483
decrypted_doc = self ._encryption .decrypt (doc )
487
484
return decode (decrypted_doc ,
0 commit comments