@@ -42,6 +42,7 @@ describe('Kerberos', function () {
42
42
}
43
43
let krb5Uri = process . env . MONGODB_URI ;
44
44
const parts = krb5Uri . split ( '@' , 2 ) ;
45
+ const host = parts [ 1 ] . split ( '/' ) [ 0 ] ;
45
46
46
47
if ( ! process . env . KRB5_PRINCIPAL ) {
47
48
console . error ( 'skipping Kerberos tests, KRB5_PRINCIPAL environment variable is not defined' ) ;
@@ -74,24 +75,185 @@ describe('Kerberos', function () {
74
75
) ;
75
76
client . connect ( function ( err , client ) {
76
77
if ( err ) return done ( err ) ;
77
- expect ( dns . resolveCname ) . to . be . calledOnce ;
78
+ expect ( dns . resolveCname ) . to . be . calledOnceWith ( host ) ;
78
79
verifyKerberosAuthentication ( client , done ) ;
79
80
} ) ;
80
81
} ) ;
81
82
82
- it ( 'validate that CANONICALIZE_HOST_NAME can be passed in' , function ( done ) {
83
- if ( process . platform === 'darwin' ) {
84
- this . test . skipReason = 'DNS does not resolve with proper CNAME record on evergreen MacOS' ;
85
- this . skip ( ) ;
86
- }
87
- const client = new MongoClient (
88
- `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:true&maxPoolSize=1`
89
- ) ;
90
- client . connect ( function ( err , client ) {
91
- if ( err ) return done ( err ) ;
92
- expect ( dns . resolveCname ) . to . be . calledOnce ;
93
- verifyKerberosAuthentication ( client , done ) ;
83
+ context ( 'when passing in CANONICALIZE_HOST_NAME' , function ( ) {
84
+ beforeEach ( function ( ) {
85
+ if ( process . platform === 'darwin' ) {
86
+ this . currentTest . skipReason =
87
+ 'DNS does not resolve with proper CNAME record on evergreen MacOS' ;
88
+ this . skip ( ) ;
89
+ }
90
+ } ) ;
91
+
92
+ context ( 'when the value is forward' , function ( ) {
93
+ it ( 'authenticates with a forward cname lookup' , function ( done ) {
94
+ const client = new MongoClient (
95
+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:forward&maxPoolSize=1`
96
+ ) ;
97
+ client . connect ( function ( err , client ) {
98
+ if ( err ) return done ( err ) ;
99
+ expect ( dns . resolveCname ) . to . be . calledOnceWith ( host ) ;
100
+ verifyKerberosAuthentication ( client , done ) ;
101
+ } ) ;
102
+ } ) ;
94
103
} ) ;
104
+
105
+ for ( const option of [ false , 'none' ] ) {
106
+ context ( `when the value is ${ option } ` , function ( ) {
107
+ it ( 'authenticates with no dns lookups' , function ( done ) {
108
+ const client = new MongoClient (
109
+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
110
+ ) ;
111
+ client . connect ( function ( err , client ) {
112
+ if ( err ) return done ( err ) ;
113
+ expect ( dns . resolveCname ) . to . not . be . called ;
114
+ // 2 calls when establishing connection - expect no third call.
115
+ expect ( dns . lookup ) . to . be . calledTwice ;
116
+ verifyKerberosAuthentication ( client , done ) ;
117
+ } ) ;
118
+ } ) ;
119
+ } ) ;
120
+ }
121
+
122
+ for ( const option of [ true , 'forwardAndReverse' ] ) {
123
+ context ( `when the value is ${ option } ` , function ( ) {
124
+ context ( 'when the reverse lookup succeeds' , function ( ) {
125
+ const resolveStub = ( address , callback ) => {
126
+ callback ( null , [ host ] ) ;
127
+ } ;
128
+
129
+ beforeEach ( function ( ) {
130
+ dns . resolvePtr . restore ( ) ;
131
+ sinon . stub ( dns , 'resolvePtr' ) . callsFake ( resolveStub ) ;
132
+ } ) ;
133
+
134
+ it ( 'authenticates with a forward dns lookup and a reverse ptr lookup' , function ( done ) {
135
+ const client = new MongoClient (
136
+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
137
+ ) ;
138
+ client . connect ( function ( err , client ) {
139
+ if ( err ) return done ( err ) ;
140
+ // 2 calls to establish connection, 1 call in canonicalization.
141
+ expect ( dns . lookup ) . to . be . calledThrice ;
142
+ expect ( dns . resolvePtr ) . to . be . calledOnce ;
143
+ verifyKerberosAuthentication ( client , done ) ;
144
+ } ) ;
145
+ } ) ;
146
+ } ) ;
147
+
148
+ context ( 'when the reverse lookup is empty' , function ( ) {
149
+ const resolveStub = ( address , callback ) => {
150
+ callback ( null , [ ] ) ;
151
+ } ;
152
+
153
+ beforeEach ( function ( ) {
154
+ dns . resolvePtr . restore ( ) ;
155
+ sinon . stub ( dns , 'resolvePtr' ) . callsFake ( resolveStub ) ;
156
+ } ) ;
157
+
158
+ it ( 'authenticates with a fallback cname lookup' , function ( done ) {
159
+ const client = new MongoClient (
160
+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
161
+ ) ;
162
+ client . connect ( function ( err , client ) {
163
+ if ( err ) return done ( err ) ;
164
+ // 2 calls to establish connection, 1 call in canonicalization.
165
+ expect ( dns . lookup ) . to . be . calledThrice ;
166
+ // This fails.
167
+ expect ( dns . resolvePtr ) . to . be . calledOnce ;
168
+ // Expect the fallback to the host name.
169
+ expect ( dns . resolveCname ) . to . not . be . called ;
170
+ verifyKerberosAuthentication ( client , done ) ;
171
+ } ) ;
172
+ } ) ;
173
+ } ) ;
174
+
175
+ context ( 'when the reverse lookup fails' , function ( ) {
176
+ const resolveStub = ( address , callback ) => {
177
+ callback ( new Error ( 'not found' ) , null ) ;
178
+ } ;
179
+
180
+ beforeEach ( function ( ) {
181
+ dns . resolvePtr . restore ( ) ;
182
+ sinon . stub ( dns , 'resolvePtr' ) . callsFake ( resolveStub ) ;
183
+ } ) ;
184
+
185
+ it ( 'authenticates with a fallback cname lookup' , function ( done ) {
186
+ const client = new MongoClient (
187
+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
188
+ ) ;
189
+ client . connect ( function ( err , client ) {
190
+ if ( err ) return done ( err ) ;
191
+ // 2 calls to establish connection, 1 call in canonicalization.
192
+ expect ( dns . lookup ) . to . be . calledThrice ;
193
+ // This fails.
194
+ expect ( dns . resolvePtr ) . to . be . calledOnce ;
195
+ // Expect the fallback to be called.
196
+ expect ( dns . resolveCname ) . to . be . calledOnceWith ( host ) ;
197
+ verifyKerberosAuthentication ( client , done ) ;
198
+ } ) ;
199
+ } ) ;
200
+ } ) ;
201
+
202
+ context ( 'when the cname lookup fails' , function ( ) {
203
+ const resolveStub = ( address , callback ) => {
204
+ callback ( new Error ( 'not found' ) , null ) ;
205
+ } ;
206
+
207
+ beforeEach ( function ( ) {
208
+ dns . resolveCname . restore ( ) ;
209
+ sinon . stub ( dns , 'resolveCname' ) . callsFake ( resolveStub ) ;
210
+ } ) ;
211
+
212
+ it ( 'authenticates with a fallback host name' , function ( done ) {
213
+ const client = new MongoClient (
214
+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
215
+ ) ;
216
+ client . connect ( function ( err , client ) {
217
+ if ( err ) return done ( err ) ;
218
+ // 2 calls to establish connection, 1 call in canonicalization.
219
+ expect ( dns . lookup ) . to . be . calledThrice ;
220
+ // This fails.
221
+ expect ( dns . resolvePtr ) . to . be . calledOnce ;
222
+ // Expect the fallback to be called.
223
+ expect ( dns . resolveCname ) . to . be . calledOnceWith ( host ) ;
224
+ verifyKerberosAuthentication ( client , done ) ;
225
+ } ) ;
226
+ } ) ;
227
+ } ) ;
228
+
229
+ context ( 'when the cname lookup is empty' , function ( ) {
230
+ const resolveStub = ( address , callback ) => {
231
+ callback ( null , [ ] ) ;
232
+ } ;
233
+
234
+ beforeEach ( function ( ) {
235
+ dns . resolveCname . restore ( ) ;
236
+ sinon . stub ( dns , 'resolveCname' ) . callsFake ( resolveStub ) ;
237
+ } ) ;
238
+
239
+ it ( 'authenticates with a fallback host name' , function ( done ) {
240
+ const client = new MongoClient (
241
+ `${ krb5Uri } &authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${ option } &maxPoolSize=1`
242
+ ) ;
243
+ client . connect ( function ( err , client ) {
244
+ if ( err ) return done ( err ) ;
245
+ // 2 calls to establish connection, 1 call in canonicalization.
246
+ expect ( dns . lookup ) . to . be . calledThrice ;
247
+ // This fails.
248
+ expect ( dns . resolvePtr ) . to . be . calledOnce ;
249
+ // Expect the fallback to be called.
250
+ expect ( dns . resolveCname ) . to . be . calledOnceWith ( host ) ;
251
+ verifyKerberosAuthentication ( client , done ) ;
252
+ } ) ;
253
+ } ) ;
254
+ } ) ;
255
+ } ) ;
256
+ }
95
257
} ) ;
96
258
97
259
// Unskip this test when a proper setup is available - see NODE-3060
0 commit comments