Skip to content

Commit

Permalink
fix: revert changes to FLE and exempt from using responseType
Browse files Browse the repository at this point in the history
  • Loading branch information
nbbeeken committed Apr 25, 2024
1 parent 0533414 commit 3ee316d
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 62 deletions.
21 changes: 4 additions & 17 deletions src/client-side-encryption/auto_encrypter.ts
Expand Up @@ -6,11 +6,10 @@ import {

import { deserialize, type Document, serialize } from '../bson';
import { type CommandOptions, type ProxyOptions } from '../cmap/connection';
import { MongoDBResponse, type MongoDBResponseConstructor } from '../cmap/wire_protocol/responses';
import { getMongoDBClientEncryption } from '../deps';
import { MongoRuntimeError } from '../error';
import { MongoClient, type MongoClientOptions } from '../mongo_client';
import { isUint8Array, MongoDBCollectionNamespace } from '../utils';
import { MongoDBCollectionNamespace } from '../utils';
import * as cryptoCallbacks from './crypto_callbacks';
import { MongoCryptInvalidArgumentError } from './errors';
import { MongocryptdManager } from './mongocryptd_manager';
Expand Down Expand Up @@ -474,19 +473,8 @@ export class AutoEncrypter {
/**
* Decrypt a command response
*/
async decrypt(
response: Uint8Array | Document | MongoDBResponse,
options: CommandOptions = {}
): Promise<Document> {
const buffer = MongoDBResponse.is(response)
? response.toBytes()
: isUint8Array(response)
? response
: serialize(response, options);

const responseType = MongoDBResponse.is(response)
? (response.constructor as MongoDBResponseConstructor)
: undefined;
async decrypt(response: Uint8Array | Document, options: CommandOptions = {}): Promise<Document> {
const buffer = Buffer.isBuffer(response) ? response : serialize(response, options);

const context = this._mongocrypt.makeDecryptionContext(buffer);

Expand All @@ -499,11 +487,10 @@ export class AutoEncrypter {
});

const decorateResult = this[kDecorateResult];
const result = await stateMachine.execute(this, context, responseType);
const result = await stateMachine.execute<Document>(this, context);
if (decorateResult) {
decorateDecryptionResult(result, response);
}

return result;
}

Expand Down
31 changes: 4 additions & 27 deletions src/client-side-encryption/state_machine.ts
Expand Up @@ -11,7 +11,6 @@ import {
serialize
} from '../bson';
import { type ProxyOptions } from '../cmap/connection';
import { type MongoDBResponseConstructor } from '../cmap/wire_protocol/responses';
import { getSocks, type SocksLib } from '../deps';
import { type MongoClient, type MongoClientOptions } from '../mongo_client';
import { BufferPool, MongoDBCollectionNamespace, promiseWithResolvers } from '../utils';
Expand Down Expand Up @@ -153,35 +152,18 @@ export class StateMachine {
) {}

/**
* Executes the state machine according to the specification.
* Will construct the result using `responseType`.
*/
async execute<R extends MongoDBResponseConstructor>(
executor: StateMachineExecutable,
context: MongoCryptContext,
responseType?: R
): Promise<InstanceType<R>>;

/**
* Executes the state machine according to the specification.
* Will return a document from the default BSON deserializer.
* Executes the state machine according to the specification
*/
async execute<T extends Document>(
executor: StateMachineExecutable,
context: MongoCryptContext
): Promise<T>;

async execute<T extends Document, R extends MongoDBResponseConstructor>(
executor: StateMachineExecutable,
context: MongoCryptContext,
responseType?: R
): Promise<T | InstanceType<R>> {
): Promise<T> {
const keyVaultNamespace = executor._keyVaultNamespace;
const keyVaultClient = executor._keyVaultClient;
const metaDataClient = executor._metaDataClient;
const mongocryptdClient = executor._mongocryptdClient;
const mongocryptdManager = executor._mongocryptdManager;
let result: any | null = null;
let result: T | null = null;

while (context.state !== MONGOCRYPT_CTX_DONE && context.state !== MONGOCRYPT_CTX_ERROR) {
debug(`[context#${context.id}] ${stateToString.get(context.state) || context.state}`);
Expand Down Expand Up @@ -270,12 +252,7 @@ export class StateMachine {
const message = context.status.message || 'Finalization error';
throw new MongoCryptError(message);
}

result =
responseType != null
? new responseType(finalizedContext)
: (result = deserialize(finalizedContext, this.options) as T);

result = deserialize(finalizedContext, this.options) as T;
break;
}

Expand Down
6 changes: 3 additions & 3 deletions src/cmap/connection.ts
Expand Up @@ -748,7 +748,7 @@ export class CryptoConnection extends Connection {
ns: MongoDBNamespace,
cmd: Document,
options?: CommandOptions,
responseType?: T | undefined
_responseType?: T | undefined
): Promise<Document> {
const { autoEncrypter } = this;
if (!autoEncrypter) {
Expand All @@ -762,7 +762,7 @@ export class CryptoConnection extends Connection {
const serverWireVersion = maxWireVersion(this);
if (serverWireVersion === 0) {
// This means the initial handshake hasn't happened yet
return await super.command<T>(ns, cmd, options, responseType);
return await super.command<T>(ns, cmd, options, undefined);
}

if (serverWireVersion < 8) {
Expand Down Expand Up @@ -796,7 +796,7 @@ export class CryptoConnection extends Connection {
}
}

const response = await super.command<T>(ns, encrypted, options, responseType);
const response = await super.command<T>(ns, encrypted, options, undefined);

return await autoEncrypter.decrypt(response, options);
}
Expand Down
8 changes: 5 additions & 3 deletions src/cursor/find_cursor.ts
Expand Up @@ -70,12 +70,14 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {

/** @internal */
async _initialize(session: ClientSession): Promise<ExecutionResult> {
const findOperation = new FindOperation(undefined, this.namespace, this[kFilter], {
const findOperation = new FindOperation(this.namespace, this[kFilter], {
...this[kBuiltOptions], // NOTE: order matters here, we may need to refine this
...this.cursorOptions,
session
});

findOperation.encryptionEnabled = !!this.client.autoEncrypter;

const response = await executeOperation(this.client, findOperation);

// the response is not a cursor when `explain` is enabled
Expand Down Expand Up @@ -114,7 +116,7 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
}
}

const response = await super.getMore(batchSize, true);
const response = await super.getMore(batchSize, this.client.autoEncrypter ? false : true);
// TODO: wrap this in some logic to prevent it from happening if we don't need this support
if (CursorResponse.is(response)) {
this[kNumReturned] = this[kNumReturned] + response.batchSize;
Expand Down Expand Up @@ -148,7 +150,7 @@ export class FindCursor<TSchema = any> extends AbstractCursor<TSchema> {
async explain(verbosity?: ExplainVerbosityLike): Promise<Document> {
return await executeOperation(
this.client,
new FindOperation(undefined, this.namespace, this[kFilter], {
new FindOperation(this.namespace, this[kFilter], {
...this[kBuiltOptions], // NOTE: order matters here, we may need to refine this
...this.cursorOptions,
explain: verbosity ?? true
Expand Down
13 changes: 5 additions & 8 deletions src/operations/find.ts
Expand Up @@ -78,13 +78,10 @@ export class FindOperation extends CommandOperation<Document> {
override options: FindOptions & { writeConcern?: never };
filter: Document;

constructor(
collection: Collection | undefined,
ns: MongoDBNamespace,
filter: Document = {},
options: FindOptions = {}
) {
super(collection, options);
public encryptionEnabled = false;

constructor(ns: MongoDBNamespace, filter: Document = {}, options: FindOptions = {}) {
super(undefined, options);

this.options = { ...options };
delete this.options.writeConcern;
Expand Down Expand Up @@ -121,7 +118,7 @@ export class FindOperation extends CommandOperation<Document> {
documentsReturnedIn: 'firstBatch',
session
},
this.explain ? undefined : CursorResponse
this.explain || this.encryptionEnabled ? undefined : CursorResponse
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/crud/abstract_operation.test.ts
Expand Up @@ -102,7 +102,7 @@ describe('abstract operation', function () {
correctCommandName: 'count'
},
{
subclassCreator: () => new mongodb.FindOperation(collection, collection.fullNamespace),
subclassCreator: () => new mongodb.FindOperation(undefined, collection.fullNamespace),
subclassType: mongodb.FindOperation,
correctCommandName: 'find'
},
Expand Down
6 changes: 3 additions & 3 deletions test/unit/operations/find.test.ts
Expand Up @@ -18,7 +18,7 @@ describe('FindOperation', function () {
});

describe('#constructor', function () {
const operation = new FindOperation(undefined, namespace, filter, options);
const operation = new FindOperation(namespace, filter, options);

it('sets the namespace', function () {
expect(operation.ns).to.deep.equal(namespace);
Expand All @@ -40,7 +40,7 @@ describe('FindOperation', function () {
const server = new Server(topology, new ServerDescription('a:1'), {} as any);

it('should build basic find command with filter', async () => {
const findOperation = new FindOperation(undefined, namespace, filter);
const findOperation = new FindOperation(namespace, filter);
const stub = sinon.stub(server, 'command').resolves({});
await findOperation.execute(server, undefined);
expect(stub).to.have.been.calledOnceWith(namespace, {
Expand All @@ -53,7 +53,7 @@ describe('FindOperation', function () {
const options = {
oplogReplay: true
};
const findOperation = new FindOperation(undefined, namespace, {}, options);
const findOperation = new FindOperation(namespace, {}, options);
const stub = sinon.stub(server, 'command').resolves({});
await findOperation.execute(server, undefined);
expect(stub).to.have.been.calledOnceWith(
Expand Down

0 comments on commit 3ee316d

Please sign in to comment.