Skip to content

Commit 274f04e

Browse files
pmereditnbagnard
andauthored
SQL-1937: Add ODBC callback conditionally (#213)
* SQL-1937: Target main for mongodb (and bson) * SQL-1937: Map UserOptions to (Mongo) Client so that we share Clients for OIDC purposes * SQL-1937: Clippy * SQL-1937: Port to using rust driver types * SQL-1937: Oh yea, make sure to also remove any duplicates * SQL-1937: Remove username and password * SQL-1937: Remove username and password * SQL-1937: Some initial feature flag work, checkpointing to switch back to linux * SQL-1937: Add feature flag for garbage collecting * SQL-1937: Abstract client creation, and only use the CLIENT_MAP when we are using OIDC * SQL-1937: Try to load in DLLMain * SQL-1937: Move core back to master, now that oidc is public * SQL-1937: Remove DLLMain because it does not reduce the number of logins in power-bi, since power-bi is actually opening multiple processes * SQL-1937: Move config into shared file * Update core/src/conn.rs * SQL-1937: Move to 3.0.0 GA! * SQL-1937: Appease clippy * SQL-1937: Appease clippy, again * Update core/src/conn.rs Co-authored-by: Natacha Bagnard <[email protected]> * SQL-1937: Remove OIDC-only pooling * SQL-1937: Remove unused import * SQL-1937: Update Cargo.lock * SQL-1937: Fix merge errors * SQL-1937: Fix rustfmt * SQL-1937: Add back in BulkWriteFailure, fix integration_test --------- Co-authored-by: Natacha Bagnard <[email protected]>
1 parent 55ec716 commit 274f04e

31 files changed

+462
-241
lines changed

Cargo.lock

Lines changed: 102 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ cstr = { path = "../cstr" }
2626
fancy-regex = "0.11.0"
2727
shared_sql_utils = { path = "../shared_sql_utils" }
2828
log = "0.4.14"
29-
mongodb = { version = "2.8.2", features = ["aws-auth"] }
30-
# Do NOT change these features without consulting with other team members.
29+
mongodb = { version = "3", features = ["aws-auth", "dns-resolver"] }
30+
# Do NOT change these features without consulting with other team members.
3131
# The features are used to control the behavior of tokio. Tokio is unsafe to use
3232
# across ABI boundaries in any other runtime but current_thread
3333
tokio = { version = "1", features = ["rt", "sync", "io-util", "macros", "net"] }
@@ -46,6 +46,7 @@ windows = { version = "0.44.0", features = [
4646

4747
[features]
4848
bad_host = []
49+
garbage_collect = []
4950

5051
[lib]
5152
name = "mongo_odbc_core"

core/src/bin/test_auth_flow.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
use mongo_odbc_core::oidc_auth::*;
1+
use mongo_odbc_core::{oidc_auth::do_auth_flow, test_config::*};
2+
use mongodb::options::oidc::{CallbackContext, IdpServerInfo};
23

34
#[tokio::main]
45
async fn main() {
5-
let c = CallbackContext {
6-
idp_info: Some(IdpServerInfo {
7-
issuer: "https://mongodb-dev.okta.com/oauth2/ausqrxbcr53xakaRR357".to_string(),
8-
client_id: Some("0oarvap2r7PmNIBsS357".to_string()),
9-
// show that we get a refresh_token even when we don't ask for it here
10-
request_scopes: Some(vec!["openid".to_string()]),
11-
}),
12-
refresh_token: None,
13-
timeout_seconds: None,
14-
version: 1,
15-
};
16-
println!("{:?}", do_auth_flow(c).await.unwrap());
6+
let c = CallbackContext::builder()
7+
.idp_info(
8+
IdpServerInfo::builder()
9+
.issuer(ISSUER_URL.to_string())
10+
.client_id(Some(CLIENT_ID.to_string()))
11+
.request_scopes(Some(vec!["openid".to_string()]))
12+
.build(),
13+
)
14+
.version(1u32)
15+
.build();
16+
let res = do_auth_flow(c).await.unwrap();
17+
println!(
18+
"{:?}, {:?}, {:?}",
19+
res.access_token, res.expires, res.refresh_token
20+
);
1721
}
Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
1-
use mongo_odbc_core::oidc_auth::*;
1+
use mongo_odbc_core::{
2+
oidc_auth::{do_auth_flow, do_refresh},
3+
test_config::*,
4+
};
5+
use mongodb::options::oidc::{CallbackContext, IdpServerInfo};
26

37
#[tokio::main]
48
async fn main() {
5-
let c = CallbackContext {
6-
idp_info: Some(IdpServerInfo {
7-
issuer: "https://mongodb-dev.okta.com/oauth2/ausqrxbcr53xakaRR357".to_string(),
8-
client_id: Some("0oarvap2r7PmNIBsS357".to_string()),
9-
// show that we get a refresh_token even when we don't ask for it here
10-
request_scopes: Some(vec!["openid".to_string()]),
11-
}),
12-
refresh_token: None,
13-
timeout_seconds: None,
14-
version: 1,
15-
};
9+
let c = CallbackContext::builder()
10+
.idp_info(
11+
IdpServerInfo::builder()
12+
.issuer(ISSUER_URL.to_string())
13+
.client_id(Some(CLIENT_ID.to_string()))
14+
.request_scopes(Some(vec!["openid".to_string()]))
15+
.build(),
16+
)
17+
.version(1u32)
18+
.build();
1619
let mut refresh_c = c.clone();
17-
let IdpServerResponse {
18-
access_token: _,
19-
expires: _,
20-
refresh_token,
21-
} = do_auth_flow(c).await.unwrap();
22-
refresh_c.refresh_token = refresh_token;
20+
let res = do_auth_flow(c).await.unwrap();
21+
println!(
22+
"{:?}, {:?}, {:?}",
23+
res.access_token, res.expires, res.refresh_token
24+
);
25+
refresh_c.refresh_token = res.refresh_token;
2326
println!("{:?}", do_refresh(refresh_c).await.unwrap());
2427
}

core/src/bin/test_oidc_call_back.rs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
1-
use mongo_odbc_core::oidc_auth::*;
1+
use mongo_odbc_core::{oidc_auth::oidc_call_back, test_config::*};
2+
use mongodb::options::oidc::{CallbackContext, IdpServerInfo};
23

34
// This shows that the oidc_call_back function works. The second call will use the refresh token,
45
// which will be obvious in that the web browser only opens once.
56
#[tokio::main(flavor = "current_thread")]
67
async fn main() {
7-
let c = CallbackContext {
8-
idp_info: Some(IdpServerInfo {
9-
issuer: "https://mongodb-dev.okta.com/oauth2/ausqrxbcr53xakaRR357".to_string(),
10-
client_id: Some("0oarvap2r7PmNIBsS357".to_string()),
11-
// show that we get a refresh_token even when we don't ask for it here
12-
request_scopes: Some(vec!["openid".to_string()]),
13-
}),
14-
refresh_token: None,
15-
timeout_seconds: None,
16-
version: 1,
17-
};
8+
let c = CallbackContext::builder()
9+
.idp_info(
10+
IdpServerInfo::builder()
11+
.issuer(ISSUER_URL.to_string())
12+
.client_id(Some(CLIENT_ID.to_string()))
13+
.request_scopes(Some(vec!["openid".to_string()]))
14+
.build(),
15+
)
16+
.version(1u32)
17+
.build();
1818
let mut refresh_c = c.clone();
19-
let IdpServerResponse {
20-
access_token: _,
21-
expires: _,
22-
refresh_token,
23-
} = oidc_call_back(c).await.unwrap();
24-
println!("initial refresh token: {refresh_token:?}");
25-
refresh_c.refresh_token = refresh_token;
19+
let res = oidc_call_back(c).await.unwrap();
20+
println!("initial refresh token: {:?}", res.refresh_token);
21+
refresh_c.refresh_token = res.refresh_token;
2622
println!(
2723
"second response: {:?}",
2824
oidc_call_back(refresh_c).await.unwrap()
Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
1-
use mongo_odbc_core::oidc_auth::*;
1+
use mongo_odbc_core::{
2+
oidc_auth::{oidc_call_back, Error},
3+
test_config::*,
4+
};
5+
use mongodb::options::oidc::{CallbackContext, IdpServerInfo};
26

7+
// This shows that the oidc_call_back function works. The second call will use the refresh token,
8+
// which will be obvious in that the web browser only opens once.
39
#[tokio::main(flavor = "current_thread")]
410
async fn main() {
5-
let c = CallbackContext {
6-
idp_info: Some(IdpServerInfo {
7-
issuer: "https://mongodb-dev.okta.com/oauth2/ausqrxbcr53xakaRR357".to_string(),
8-
client_id: Some("0oarvap2r7PmNIBsS357".to_string()),
9-
request_scopes: Some(vec!["openid".to_string()]),
10-
}),
11-
refresh_token: None,
12-
// 2 seconds works well on my laptop. 1 second results in the request dying before the
13-
// server can redirect
14-
timeout_seconds: Some(std::time::Instant::now() + std::time::Duration::from_secs(2)),
15-
version: 1,
16-
};
11+
let c = CallbackContext::builder()
12+
.idp_info(
13+
IdpServerInfo::builder()
14+
.issuer(ISSUER_URL.to_string())
15+
.client_id(Some(CLIENT_ID.to_string()))
16+
.request_scopes(Some(vec!["openid".to_string()]))
17+
.build(),
18+
)
19+
.timeout(std::time::Instant::now() + std::time::Duration::from_secs(2))
20+
.version(1u32)
21+
.build();
1722
println!("This is very timing dependent, but we should see a timeout, if we play with the value: {:?}", oidc_call_back(c).await.unwrap_err().get_custom::<Error>());
18-
// example output from my laptop: `This is very timing dependent, but we should see a timeout, if we play with the value: Some(Timedout)`
1923
}

0 commit comments

Comments
 (0)