@@ -8,6 +8,45 @@ use crate::{
8
8
} ;
9
9
use std:: sync:: { Arc , Mutex } ;
10
10
11
+ macro_rules! mongodb_uri {
12
+ ( ) => {
13
+ "mongodb://localhost/"
14
+ } ;
15
+ ( $user: literal ) => {
16
+ concat!( "mongodb://" , $user, "@localhost/" )
17
+ } ;
18
+ }
19
+
20
+ macro_rules! mongodb_uri_single {
21
+ ( ) => {
22
+ concat!( mongodb_uri!( ) , "?authMechanism=MONGODB-OIDC" )
23
+ } ;
24
+ ( $user: literal ) => {
25
+ concat!( mongodb_uri!( $user) , "?authMechanism=MONGODB-OIDC" )
26
+ } ;
27
+ }
28
+
29
+ macro_rules! mongodb_uri_multi {
30
+ ( ) => {
31
+ concat!(
32
+ mongodb_uri!( ) ,
33
+ "?authMechanism=MONGODB-OIDC&directConnection=true"
34
+ )
35
+ } ;
36
+ ( $user: literal ) => {
37
+ concat!(
38
+ mongodb_uri!( $user) ,
39
+ "?authMechanism=MONGODB-OIDC&directConnection=true"
40
+ )
41
+ } ;
42
+ }
43
+
44
+ macro_rules! token_dir {
45
+ ( $path: literal ) => {
46
+ concat!( "/tmp/tokens" , $path)
47
+ } ;
48
+ }
49
+
11
50
// Machine Callback tests
12
51
// Prose test 1.1 Single Principal Implicit Username
13
52
#[ tokio:: test]
@@ -24,15 +63,15 @@ async fn machine_single_principal_implicit_username() -> anyhow::Result<()> {
24
63
let call_count = Arc :: new ( Mutex :: new ( 0 ) ) ;
25
64
let cb_call_count = call_count. clone ( ) ;
26
65
27
- let mut opts = ClientOptions :: parse ( "mongodb://localhost/?authMechanism=MONGODB-OIDC" ) . await ?;
66
+ let mut opts = ClientOptions :: parse ( mongodb_uri_single ! ( ) ) . await ?;
28
67
opts. credential = Credential :: builder ( )
29
68
. mechanism ( AuthMechanism :: MongoDbOidc )
30
69
. oidc_callback ( oidc:: Callback :: machine ( move |_| {
31
70
let call_count = cb_call_count. clone ( ) ;
32
71
* call_count. lock ( ) . unwrap ( ) += 1 ;
33
72
async move {
34
73
Ok ( oidc:: IdpServerResponse {
35
- access_token : tokio:: fs:: read_to_string ( "/tmp/tokens/ test_user1") . await ?,
74
+ access_token : tokio:: fs:: read_to_string ( token_dir ! ( " test_user1") ) . await ?,
36
75
expires : None ,
37
76
refresh_token : None ,
38
77
} )
@@ -75,15 +114,165 @@ async fn human_single_principal_implicit_username() -> anyhow::Result<()> {
75
114
let call_count = Arc :: new ( Mutex :: new ( 0 ) ) ;
76
115
let cb_call_count = call_count. clone ( ) ;
77
116
78
- let mut opts = ClientOptions :: parse ( "mongodb://localhost/?authMechanism=MONGODB-OIDC" ) . await ?;
117
+ let mut opts = ClientOptions :: parse ( mongodb_uri_single ! ( ) ) . await ?;
118
+ opts. credential = Credential :: builder ( )
119
+ . mechanism ( AuthMechanism :: MongoDbOidc )
120
+ . oidc_callback ( oidc:: Callback :: human ( move |_| {
121
+ let call_count = cb_call_count. clone ( ) ;
122
+ * call_count. lock ( ) . unwrap ( ) += 1 ;
123
+ async move {
124
+ Ok ( oidc:: IdpServerResponse {
125
+ access_token : tokio:: fs:: read_to_string ( token_dir ! ( "test_user1" ) ) . await ?,
126
+ expires : None ,
127
+ refresh_token : None ,
128
+ } )
129
+ }
130
+ . boxed ( )
131
+ } ) )
132
+ . build ( )
133
+ . into ( ) ;
134
+ let client = Client :: with_options ( opts) ?;
135
+ client
136
+ . database ( "test" )
137
+ . collection :: < Document > ( "test" )
138
+ . find_one ( None , None )
139
+ . await ?;
140
+ assert_eq ! ( 1 , * ( * call_count) . lock( ) . unwrap( ) ) ;
141
+ Ok ( ( ) )
142
+ }
143
+
144
+ // Prose test 1.2 Single Principal Explicit Username
145
+ #[ tokio:: test]
146
+ async fn human_single_principal_explicit_username ( ) -> anyhow:: Result < ( ) > {
147
+ use crate :: {
148
+ client:: {
149
+ auth:: { oidc, AuthMechanism , Credential } ,
150
+ options:: ClientOptions ,
151
+ } ,
152
+ test:: log_uncaptured,
153
+ Client ,
154
+ } ;
155
+ use bson:: Document ;
156
+ use futures_util:: FutureExt ;
157
+
158
+ if std:: env:: var ( "OIDC_TOKEN_DIR" ) . is_err ( ) {
159
+ log_uncaptured ( "Skipping OIDC test" ) ;
160
+ return Ok ( ( ) ) ;
161
+ }
162
+
163
+ // we need to assert that the callback is only called once
164
+ let call_count = Arc :: new ( Mutex :: new ( 0 ) ) ;
165
+ let cb_call_count = call_count. clone ( ) ;
166
+
167
+ let mut opts = ClientOptions :: parse ( mongodb_uri ! ( "test_user1" ) ) . await ?;
168
+ opts. credential = Credential :: builder ( )
169
+ . mechanism ( AuthMechanism :: MongoDbOidc )
170
+ . oidc_callback ( oidc:: Callback :: human ( move |_| {
171
+ let call_count = cb_call_count. clone ( ) ;
172
+ * call_count. lock ( ) . unwrap ( ) += 1 ;
173
+ async move {
174
+ Ok ( oidc:: IdpServerResponse {
175
+ access_token : tokio:: fs:: read_to_string ( token_dir ! ( "test_user1" ) ) . await ?,
176
+ expires : None ,
177
+ refresh_token : None ,
178
+ } )
179
+ }
180
+ . boxed ( )
181
+ } ) )
182
+ . build ( )
183
+ . into ( ) ;
184
+ let client = Client :: with_options ( opts) ?;
185
+ client
186
+ . database ( "test" )
187
+ . collection :: < Document > ( "test" )
188
+ . find_one ( None , None )
189
+ . await ?;
190
+ assert_eq ! ( 1 , * ( * call_count) . lock( ) . unwrap( ) ) ;
191
+ Ok ( ( ) )
192
+ }
193
+
194
+ // Prose test 1.3 Multiple Principal User1
195
+ #[ tokio:: test]
196
+ async fn human_multiple_principal_user1 ( ) -> anyhow:: Result < ( ) > {
197
+ use crate :: {
198
+ client:: {
199
+ auth:: { oidc, AuthMechanism , Credential } ,
200
+ options:: ClientOptions ,
201
+ } ,
202
+ test:: log_uncaptured,
203
+ Client ,
204
+ } ;
205
+ use bson:: Document ;
206
+ use futures_util:: FutureExt ;
207
+
208
+ if std:: env:: var ( "OIDC_TOKEN_DIR" ) . is_err ( ) {
209
+ log_uncaptured ( "Skipping OIDC test" ) ;
210
+ return Ok ( ( ) ) ;
211
+ }
212
+
213
+ // we need to assert that the callback is only called once
214
+ let call_count = Arc :: new ( Mutex :: new ( 0 ) ) ;
215
+ let cb_call_count = call_count. clone ( ) ;
216
+
217
+ let mut opts = ClientOptions :: parse ( mongodb_uri_multi ! ( "user1" ) ) . await ?;
218
+ opts. credential = Credential :: builder ( )
219
+ . mechanism ( AuthMechanism :: MongoDbOidc )
220
+ . oidc_callback ( oidc:: Callback :: human ( move |_| {
221
+ let call_count = cb_call_count. clone ( ) ;
222
+ * call_count. lock ( ) . unwrap ( ) += 1 ;
223
+ async move {
224
+ Ok ( oidc:: IdpServerResponse {
225
+ access_token : tokio:: fs:: read_to_string ( token_dir ! ( "test_user1" ) ) . await ?,
226
+ expires : None ,
227
+ refresh_token : None ,
228
+ } )
229
+ }
230
+ . boxed ( )
231
+ } ) )
232
+ . build ( )
233
+ . into ( ) ;
234
+ let client = Client :: with_options ( opts) ?;
235
+ client
236
+ . database ( "test" )
237
+ . collection :: < Document > ( "test" )
238
+ . find_one ( None , None )
239
+ . await ?;
240
+ assert_eq ! ( 1 , * ( * call_count) . lock( ) . unwrap( ) ) ;
241
+ Ok ( ( ) )
242
+ }
243
+
244
+ // Prose test 1.4 Multiple Principal User2
245
+ #[ tokio:: test]
246
+ async fn human_multiple_principal_user2 ( ) -> anyhow:: Result < ( ) > {
247
+ use crate :: {
248
+ client:: {
249
+ auth:: { oidc, AuthMechanism , Credential } ,
250
+ options:: ClientOptions ,
251
+ } ,
252
+ test:: log_uncaptured,
253
+ Client ,
254
+ } ;
255
+ use bson:: Document ;
256
+ use futures_util:: FutureExt ;
257
+
258
+ if std:: env:: var ( "OIDC_TOKEN_DIR" ) . is_err ( ) {
259
+ log_uncaptured ( "Skipping OIDC test" ) ;
260
+ return Ok ( ( ) ) ;
261
+ }
262
+
263
+ // we need to assert that the callback is only called once
264
+ let call_count = Arc :: new ( Mutex :: new ( 0 ) ) ;
265
+ let cb_call_count = call_count. clone ( ) ;
266
+
267
+ let mut opts = ClientOptions :: parse ( mongodb_uri_multi ! ( "user2" ) ) . await ?;
79
268
opts. credential = Credential :: builder ( )
80
269
. mechanism ( AuthMechanism :: MongoDbOidc )
81
270
. oidc_callback ( oidc:: Callback :: human ( move |_| {
82
271
let call_count = cb_call_count. clone ( ) ;
83
272
* call_count. lock ( ) . unwrap ( ) += 1 ;
84
273
async move {
85
274
Ok ( oidc:: IdpServerResponse {
86
- access_token : tokio:: fs:: read_to_string ( "/tmp/tokens/test_user1" ) . await ?,
275
+ access_token : tokio:: fs:: read_to_string ( token_dir ! ( "test_user2" ) ) . await ?,
87
276
expires : None ,
88
277
refresh_token : None ,
89
278
} )
0 commit comments