diff --git a/src/test/spec/json/auth/mongodb-oidc.md b/src/test/spec/json/auth/mongodb-oidc.md index e95f45e68..7afa3d9ad 100644 --- a/src/test/spec/json/auth/mongodb-oidc.md +++ b/src/test/spec/json/auth/mongodb-oidc.md @@ -232,6 +232,31 @@ source the `secrets-export.sh` file and use the associated env variables in your - Assert there were `SaslStart` commands executed. - Close the client. +#### 4.5 Reauthentication Succeeds when a Session is involved + +- Create an OIDC configured client. +- Set a fail point for `find` commands of the form: + +```javascript +{ + configureFailPoint: "failCommand", + mode: { + times: 1 + }, + data: { + failCommands: [ + "find" + ], + errorCode: 391 // ReauthenticationRequired + } +} +``` + +- Start a new session. +- In the started session perform a `find` operation that succeeds. +- Assert that the callback was called 2 times (once during the connection handshake, and again during reauthentication). +- Close the session and the client. + ## (5) Azure Tests Drivers MUST only run the Azure tests when testing on an Azure VM. See instructions in diff --git a/src/test/spec/oidc.rs b/src/test/spec/oidc.rs index ab832ebdd..e38f72f81 100644 --- a/src/test/spec/oidc.rs +++ b/src/test/spec/oidc.rs @@ -564,6 +564,49 @@ mod basic { Ok(()) } + #[tokio::test(flavor = "multi_thread")] + async fn machine_4_5_reauthentication_when_session_involved() -> anyhow::Result<()> { + let admin_client = Client::with_uri_str(&*MONGODB_URI).await?; + + // Now set a failpoint for find with 391 error code + let fail_point = + FailPoint::fail_command(&["find"], FailPointMode::Times(1)).error_code(391); + let _guard = admin_client.enable_fail_point(fail_point).await.unwrap(); + + // we need to assert the callback count + let call_count: Arc> = Arc::new(Mutex::new(0)); + let cb_call_count = call_count.clone(); + + let mut opts = ClientOptions::parse(&*MONGODB_URI_SINGLE).await?; + opts.credential = Credential::builder() + .mechanism(AuthMechanism::MongoDbOidc) + .oidc_callback(oidc::Callback::machine(move |_| { + let call_count = cb_call_count.clone(); + async move { + *call_count.lock().await += 1; + Ok(oidc::IdpServerResponse { + access_token: get_access_token_test_user_1().await, + expires: None, + refresh_token: None, + }) + } + .boxed() + })) + .build() + .into(); + let client = Client::with_options(opts)?; + let mut session = client.start_session().await.unwrap(); + + client + .database("test") + .collection::("test") + .find_one(doc! {}) + .session(&mut session) + .await?; + assert_eq!(2, *(*call_count).lock().await); + Ok(()) + } + // Human Callback tests #[tokio::test] async fn human_1_1_single_principal_implicit_username() -> anyhow::Result<()> {