def __init__(self, options, callback): """Abstracts libmongocrypt's mongocrypt_t type. :Parameters: - `options`: A :class:`MongoCryptOptions`. - `callback`: A :class:`MongoCryptCallback`. """ self.__opts = options self.__callback = callback self.__crypt = None if not isinstance(options, MongoCryptOptions): raise TypeError("options must be a MongoCryptOptions") if not isinstance(callback, MongoCryptCallback): raise TypeError("callback must be a MongoCryptCallback") self.__crypt = lib.mongocrypt_new() if self.__crypt == ffi.NULL: raise MongoCryptError("unable to create new mongocrypt object") try: self.__init() except Exception: # Destroy the mongocrypt object on error. self.close() raise
def _write_bytes(mongocrypt_binary, data): """Writes the given data to a mongocrypt_binary_t.""" buf = lib.mongocrypt_binary_data(mongocrypt_binary) if buf == ffi.NULL: raise MongoCryptError('mongocrypt_binary_data returned NULL') ffi.memmove(buf, data, len(data))
def _to_bytes(mongocrypt_binary): """Returns this mongocrypt_binary_t as bytes.""" data = lib.mongocrypt_binary_data(mongocrypt_binary) if data == ffi.NULL: raise MongoCryptError('mongocrypt_binary_data returned NULL') data_len = lib.mongocrypt_binary_len(mongocrypt_binary) return ffi.unpack(ffi.cast("char*", data), data_len)
def __raise_from_status(self): status = lib.mongocrypt_status_new() try: lib.mongocrypt_kms_ctx_status(self.__ctx, status) exc = MongoCryptError.from_status(status) finally: lib.mongocrypt_status_destroy(status) raise exc
def run_state_machine(ctx, callback): """Run the libmongocrypt state machine until completion. :Parameters: - `ctx`: A :class:`MongoCryptContext`. - `callback`: A :class:`MongoCryptCallback`. :Returns: The completed libmongocrypt operation. """ while True: state = ctx.state # Check for terminal states first. if state == lib.MONGOCRYPT_CTX_ERROR: ctx._raise_from_status() elif state == lib.MONGOCRYPT_CTX_READY: return ctx.finish() elif state == lib.MONGOCRYPT_CTX_DONE: return None if state == lib.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO: list_colls_filter = ctx.mongo_operation() coll_info = callback.collection_info(ctx.database, list_colls_filter) if coll_info: ctx.add_mongo_operation_result(coll_info) ctx.complete_mongo_operation() elif state == lib.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS: mongocryptd_cmd = ctx.mongo_operation() result = callback.mark_command(ctx.database, mongocryptd_cmd) ctx.add_mongo_operation_result(result) ctx.complete_mongo_operation() elif state == lib.MONGOCRYPT_CTX_NEED_MONGO_KEYS: key_filter = ctx.mongo_operation() for key in callback.fetch_keys(key_filter): ctx.add_mongo_operation_result(key) ctx.complete_mongo_operation() elif state == lib.MONGOCRYPT_CTX_NEED_KMS: for kms_ctx in ctx.kms_contexts(): with kms_ctx: callback.kms_request(kms_ctx) ctx.complete_kms() else: raise MongoCryptError('unknown state: %r' % (state, ))
def __init__(self, binary): """Wraps a mongocrypt_binary_t.""" if binary == ffi.NULL: raise MongoCryptError( "unable to create new mongocrypt_binary object") self.bin = binary