Skip to content

Commit a1f4616

Browse files
authored
RUST-577 Versioned API implementation (#266)
1 parent 2dbb5bd commit a1f4616

39 files changed

+2935
-118
lines changed

src/client/auth/aws.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@ use sha2::{Digest, Sha256};
55

66
use crate::{
77
bson::{doc, spec::BinarySubtype, Binary, Bson, Document},
8-
client::auth::{
9-
self,
10-
sasl::{SaslContinue, SaslResponse, SaslStart},
11-
AuthMechanism,
12-
Credential,
8+
client::{
9+
auth::{
10+
self,
11+
sasl::{SaslContinue, SaslResponse, SaslStart},
12+
AuthMechanism,
13+
Credential,
14+
},
15+
options::ServerApi,
1316
},
1417
cmap::Connection,
1518
error::{Error, Result},
@@ -24,6 +27,7 @@ const AWS_LONG_DATE_FMT: &str = "%Y%m%dT%H%M%SZ";
2427
pub(super) async fn authenticate_stream(
2528
conn: &mut Connection,
2629
credential: &Credential,
30+
server_api: Option<&ServerApi>,
2731
http_client: &HttpClient,
2832
) -> Result<()> {
2933
let source = match credential.source.as_deref() {
@@ -51,6 +55,7 @@ pub(super) async fn authenticate_stream(
5155
source.into(),
5256
AuthMechanism::MongoDbAws,
5357
client_first_payload_bytes,
58+
server_api.cloned(),
5459
);
5560
let client_first = sasl_start.into_command();
5661

@@ -85,6 +90,7 @@ pub(super) async fn authenticate_stream(
8590
source.into(),
8691
server_first.conversation_id.clone(),
8792
client_second_payload_bytes,
93+
server_api.cloned(),
8894
);
8995

9096
let client_second = sasl_continue.into_command();

src/client/auth/mod.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use typed_builder::TypedBuilder;
2020
use self::scram::ScramVersion;
2121
use crate::{
2222
bson::Document,
23+
client::options::ServerApi,
2324
cmap::{Command, Connection, StreamDescription},
2425
error::{Error, ErrorKind, Result},
2526
runtime::HttpClient,
@@ -227,9 +228,9 @@ impl AuthMechanism {
227228

228229
Ok(Some(ClientFirst::Scram(ScramVersion::Sha256, client_first)))
229230
}
230-
Self::MongoDbX509 => Ok(Some(ClientFirst::X509(x509::build_client_first(
231-
credential,
232-
)))),
231+
Self::MongoDbX509 => Ok(Some(ClientFirst::X509(
232+
x509::build_speculative_client_first(credential),
233+
))),
233234
Self::Plain => Ok(None),
234235
#[cfg(feature = "tokio-runtime")]
235236
AuthMechanism::MongoDbAws => Ok(None),
@@ -250,26 +251,31 @@ impl AuthMechanism {
250251
&self,
251252
stream: &mut Connection,
252253
credential: &Credential,
254+
server_api: Option<&ServerApi>,
253255
#[cfg_attr(not(feature = "tokio-runtime"), allow(unused))] http_client: &HttpClient,
254256
) -> Result<()> {
255257
self.validate_credential(credential)?;
256258

257259
match self {
258260
AuthMechanism::ScramSha1 => {
259261
ScramVersion::Sha1
260-
.authenticate_stream(stream, credential, None)
262+
.authenticate_stream(stream, credential, server_api, None)
261263
.await
262264
}
263265
AuthMechanism::ScramSha256 => {
264266
ScramVersion::Sha256
265-
.authenticate_stream(stream, credential, None)
267+
.authenticate_stream(stream, credential, server_api, None)
266268
.await
267269
}
268-
AuthMechanism::MongoDbX509 => x509::authenticate_stream(stream, credential, None).await,
269-
AuthMechanism::Plain => plain::authenticate_stream(stream, credential).await,
270+
AuthMechanism::MongoDbX509 => {
271+
x509::authenticate_stream(stream, credential, server_api, None).await
272+
}
273+
AuthMechanism::Plain => {
274+
plain::authenticate_stream(stream, credential, server_api).await
275+
}
270276
#[cfg(feature = "tokio-runtime")]
271277
AuthMechanism::MongoDbAws => {
272-
aws::authenticate_stream(stream, credential, http_client).await
278+
aws::authenticate_stream(stream, credential, server_api, http_client).await
273279
}
274280
AuthMechanism::MongoDbCr => Err(ErrorKind::AuthenticationError {
275281
message: "MONGODB-CR is deprecated and not supported by this driver. Use SCRAM \
@@ -393,6 +399,7 @@ impl Credential {
393399
&self,
394400
conn: &mut Connection,
395401
http_client: &HttpClient,
402+
server_api: Option<&ServerApi>,
396403
first_round: Option<FirstRound>,
397404
) -> Result<()> {
398405
let stream_description = conn.stream_description()?;
@@ -407,10 +414,12 @@ impl Credential {
407414
if let Some(first_round) = first_round {
408415
return match first_round {
409416
FirstRound::Scram(version, first_round) => {
410-
version.authenticate_stream(conn, self, first_round).await
417+
version
418+
.authenticate_stream(conn, self, server_api, first_round)
419+
.await
411420
}
412421
FirstRound::X509(server_first) => {
413-
x509::authenticate_stream(conn, self, server_first).await
422+
x509::authenticate_stream(conn, self, server_api, server_first).await
414423
}
415424
};
416425
}
@@ -421,7 +430,9 @@ impl Credential {
421430
};
422431

423432
// Authenticate according to the chosen mechanism.
424-
mechanism.authenticate_stream(conn, self, http_client).await
433+
mechanism
434+
.authenticate_stream(conn, self, server_api, http_client)
435+
.await
425436
}
426437
}
427438

src/client/auth/plain.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use crate::{
2-
client::auth::{
3-
sasl::{SaslResponse, SaslStart},
4-
AuthMechanism,
5-
Credential,
2+
client::{
3+
auth::{
4+
sasl::{SaslResponse, SaslStart},
5+
AuthMechanism,
6+
Credential,
7+
},
8+
options::ServerApi,
69
},
710
cmap::Connection,
811
error::{Error, Result},
@@ -11,6 +14,7 @@ use crate::{
1114
pub(crate) async fn authenticate_stream(
1215
conn: &mut Connection,
1316
credential: &Credential,
17+
server_api: Option<&ServerApi>,
1418
) -> Result<()> {
1519
let source = credential.source.as_deref().unwrap_or("$external");
1620
let username = credential
@@ -27,6 +31,7 @@ pub(crate) async fn authenticate_stream(
2731
source.into(),
2832
AuthMechanism::Plain,
2933
payload_bytes(username, password),
34+
server_api.cloned(),
3035
)
3136
.into_command();
3237

src/client/auth/sasl.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
bson::{doc, spec::BinarySubtype, Binary, Bson, Document},
33
bson_util,
4-
client::auth::AuthMechanism,
4+
client::{auth::AuthMechanism, options::ServerApi},
55
cmap::Command,
66
error::{Error, Result},
77
};
@@ -11,14 +11,21 @@ pub(super) struct SaslStart {
1111
source: String,
1212
mechanism: AuthMechanism,
1313
payload: Vec<u8>,
14+
server_api: Option<ServerApi>,
1415
}
1516

1617
impl SaslStart {
17-
pub(super) fn new(source: String, mechanism: AuthMechanism, payload: Vec<u8>) -> Self {
18+
pub(super) fn new(
19+
source: String,
20+
mechanism: AuthMechanism,
21+
payload: Vec<u8>,
22+
server_api: Option<ServerApi>,
23+
) -> Self {
1824
Self {
1925
source,
2026
mechanism,
2127
payload,
28+
server_api,
2229
}
2330
}
2431

@@ -34,7 +41,12 @@ impl SaslStart {
3441
body.insert("options", doc! { "skipEmptyExchange": true });
3542
}
3643

37-
Command::new("saslStart".into(), self.source, body)
44+
let mut command = Command::new("saslStart".into(), self.source, body);
45+
if let Some(server_api) = self.server_api {
46+
command.set_server_api(&server_api);
47+
}
48+
49+
command
3850
}
3951
}
4052

@@ -43,14 +55,21 @@ pub(super) struct SaslContinue {
4355
source: String,
4456
conversation_id: Bson,
4557
payload: Vec<u8>,
58+
server_api: Option<ServerApi>,
4659
}
4760

4861
impl SaslContinue {
49-
pub(super) fn new(source: String, conversation_id: Bson, payload: Vec<u8>) -> Self {
62+
pub(super) fn new(
63+
source: String,
64+
conversation_id: Bson,
65+
payload: Vec<u8>,
66+
server_api: Option<ServerApi>,
67+
) -> Self {
5068
Self {
5169
source,
5270
conversation_id,
5371
payload,
72+
server_api,
5473
}
5574
}
5675

@@ -61,7 +80,12 @@ impl SaslContinue {
6180
"payload": Binary { subtype: BinarySubtype::Generic, bytes: self.payload },
6281
};
6382

64-
Command::new("saslContinue".into(), self.source, body)
83+
let mut command = Command::new("saslContinue".into(), self.source, body);
84+
if let Some(server_api) = self.server_api {
85+
command.set_server_api(&server_api);
86+
}
87+
88+
command
6589
}
6690
}
6791

0 commit comments

Comments
 (0)