From 40e4b6daf256aadca8cb8cd1a7782a007dd37bb0 Mon Sep 17 00:00:00 2001 From: Durran Jordan Date: Fri, 24 Jan 2025 12:08:41 +0100 Subject: [PATCH 1/3] test(HELP-69886): run oidc reauth test with mongoose --- src/cmap/auth/mongodb_oidc.ts | 2 +- .../auth/mongodb_oidc.prose.test.ts | 90 +++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/cmap/auth/mongodb_oidc.ts b/src/cmap/auth/mongodb_oidc.ts index 1cd249aac21..4cab886112f 100644 --- a/src/cmap/auth/mongodb_oidc.ts +++ b/src/cmap/auth/mongodb_oidc.ts @@ -143,7 +143,7 @@ export class MongoDBOIDC extends AuthProvider { */ override async auth(authContext: AuthContext): Promise { const { connection, reauthenticating, response } = authContext; - if (response?.speculativeAuthenticate?.done) { + if (response?.speculativeAuthenticate?.done && !reauthenticating) { return; } const credentials = getCredentials(authContext); diff --git a/test/integration/auth/mongodb_oidc.prose.test.ts b/test/integration/auth/mongodb_oidc.prose.test.ts index b2acf89e577..79252526f86 100644 --- a/test/integration/auth/mongodb_oidc.prose.test.ts +++ b/test/integration/auth/mongodb_oidc.prose.test.ts @@ -546,6 +546,96 @@ describe('OIDC Auth Spec Tests', function () { expect(callbackSpy).to.have.been.calledTwice; }); }); + + describe('4.4 Speculative Authentication should be ignored on Reauthentication', function () { + let utilClient: MongoClient; + const callbackSpy = sinon.spy(createCallback()); + const commands = []; + // - Create an OIDC configured client. + // - Populate the *Client Cache* with a valid access token to enforce Speculative Authentication. + // - Perform an `insert` operation that succeeds. + // - Assert that the callback was not called. + // - Assert there were no `SaslStart` commands executed. + // - Set a fail point for `insert` commands of the form: + // ```javascript + // { + // configureFailPoint: "failCommand", + // mode: { + // times: 1 + // }, + // data: { + // failCommands: [ + // "insert" + // ], + // errorCode: 391 // ReauthenticationRequired + // } + // } + // ``` + // - Perform an `insert` operation that succeeds. + // - Assert that the callback was called once. + // - Assert there were `SaslStart` commands executed. + // - Close the client. + beforeEach(async function () { + client = new MongoClient(uriSingle, { + authMechanismProperties: { + OIDC_CALLBACK: callbackSpy + }, + retryReads: false, + monitorCommands: true + }); + client.on('commandStarted', event => { + console.log(event); + if (event.commandName === 'saslStart') { + commands.push(event); + } + }); + const provider = client.s.authProviders.getOrCreateProvider('MONGODB-OIDC', { + OIDC_CALLBACK: callbackSpy + }) as MongoDBOIDC; + const token = await readFile(path.join(process.env.OIDC_TOKEN_DIR, 'test_user1'), { + encoding: 'utf8' + }); + provider.workflow.cache.put({ accessToken: token }); + collection = client.db('test').collection('test'); + await collection.insertOne({ name: 'test' }); + expect(callbackSpy).to.not.have.been.called; + expect(commands).to.be.empty; + + utilClient = new MongoClient(uriSingle, { + authMechanismProperties: { + OIDC_CALLBACK: createCallback() + }, + retryReads: false + }); + await utilClient + .db() + .admin() + .command({ + configureFailPoint: 'failCommand', + mode: { + times: 1 + }, + data: { + failCommands: ['insert'], + errorCode: 391 + } + }); + }); + + afterEach(async function () { + await utilClient.db().admin().command({ + configureFailPoint: 'failCommand', + mode: 'off' + }); + await utilClient.close(); + }); + + it('successfully authenticates', async function () { + await collection.insertOne({ name: 'test' }); + expect(callbackSpy).to.have.been.calledOnce; + expect(commands.length).to.equal(1); + }); + }); }); }); From d789b21e20bcf5e49f8b4b2f613c6d4e80ad8282 Mon Sep 17 00:00:00 2001 From: Warren James Date: Mon, 27 Jan 2025 12:36:32 -0500 Subject: [PATCH 2/3] rename for clarity --- test/integration/auth/mongodb_oidc.prose.test.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/integration/auth/mongodb_oidc.prose.test.ts b/test/integration/auth/mongodb_oidc.prose.test.ts index 79252526f86..a785485d955 100644 --- a/test/integration/auth/mongodb_oidc.prose.test.ts +++ b/test/integration/auth/mongodb_oidc.prose.test.ts @@ -550,7 +550,7 @@ describe('OIDC Auth Spec Tests', function () { describe('4.4 Speculative Authentication should be ignored on Reauthentication', function () { let utilClient: MongoClient; const callbackSpy = sinon.spy(createCallback()); - const commands = []; + const saslStarts = []; // - Create an OIDC configured client. // - Populate the *Client Cache* with a valid access token to enforce Speculative Authentication. // - Perform an `insert` operation that succeeds. @@ -584,9 +584,8 @@ describe('OIDC Auth Spec Tests', function () { monitorCommands: true }); client.on('commandStarted', event => { - console.log(event); if (event.commandName === 'saslStart') { - commands.push(event); + saslStarts.push(event); } }); const provider = client.s.authProviders.getOrCreateProvider('MONGODB-OIDC', { @@ -595,11 +594,13 @@ describe('OIDC Auth Spec Tests', function () { const token = await readFile(path.join(process.env.OIDC_TOKEN_DIR, 'test_user1'), { encoding: 'utf8' }); + provider.workflow.cache.put({ accessToken: token }); collection = client.db('test').collection('test'); + await collection.insertOne({ name: 'test' }); expect(callbackSpy).to.not.have.been.called; - expect(commands).to.be.empty; + expect(saslStarts).to.be.empty; utilClient = new MongoClient(uriSingle, { authMechanismProperties: { @@ -607,6 +608,7 @@ describe('OIDC Auth Spec Tests', function () { }, retryReads: false }); + await utilClient .db() .admin() @@ -633,7 +635,7 @@ describe('OIDC Auth Spec Tests', function () { it('successfully authenticates', async function () { await collection.insertOne({ name: 'test' }); expect(callbackSpy).to.have.been.calledOnce; - expect(commands.length).to.equal(1); + expect(saslStarts.length).to.equal(1); }); }); }); From 8b4b08d7833984e9caea32a4b8bd8b41dcc4f9f6 Mon Sep 17 00:00:00 2001 From: Warren James Date: Mon, 27 Jan 2025 13:39:07 -0500 Subject: [PATCH 3/3] reorganize --- .../auth/mongodb_oidc.prose.test.ts | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/test/integration/auth/mongodb_oidc.prose.test.ts b/test/integration/auth/mongodb_oidc.prose.test.ts index a785485d955..477283ba617 100644 --- a/test/integration/auth/mongodb_oidc.prose.test.ts +++ b/test/integration/auth/mongodb_oidc.prose.test.ts @@ -576,6 +576,13 @@ describe('OIDC Auth Spec Tests', function () { // - Assert there were `SaslStart` commands executed. // - Close the client. beforeEach(async function () { + utilClient = new MongoClient(uriSingle, { + authMechanismProperties: { + OIDC_CALLBACK: createCallback() + }, + retryReads: false + }); + client = new MongoClient(uriSingle, { authMechanismProperties: { OIDC_CALLBACK: callbackSpy @@ -588,6 +595,7 @@ describe('OIDC Auth Spec Tests', function () { saslStarts.push(event); } }); + const provider = client.s.authProviders.getOrCreateProvider('MONGODB-OIDC', { OIDC_CALLBACK: callbackSpy }) as MongoDBOIDC; @@ -597,18 +605,21 @@ describe('OIDC Auth Spec Tests', function () { provider.workflow.cache.put({ accessToken: token }); collection = client.db('test').collection('test'); + }); + afterEach(async function () { + await utilClient.db().admin().command({ + configureFailPoint: 'failCommand', + mode: 'off' + }); + await utilClient.close(); + }); + + it('successfully authenticates', async function () { await collection.insertOne({ name: 'test' }); expect(callbackSpy).to.not.have.been.called; expect(saslStarts).to.be.empty; - utilClient = new MongoClient(uriSingle, { - authMechanismProperties: { - OIDC_CALLBACK: createCallback() - }, - retryReads: false - }); - await utilClient .db() .admin() @@ -622,17 +633,7 @@ describe('OIDC Auth Spec Tests', function () { errorCode: 391 } }); - }); - afterEach(async function () { - await utilClient.db().admin().command({ - configureFailPoint: 'failCommand', - mode: 'off' - }); - await utilClient.close(); - }); - - it('successfully authenticates', async function () { await collection.insertOne({ name: 'test' }); expect(callbackSpy).to.have.been.calledOnce; expect(saslStarts.length).to.equal(1);