@@ -26,6 +26,16 @@ pub enum Error {
26
26
FailedToCreateLdapEndpointUrl {
27
27
source : stackable_operator:: commons:: authentication:: ldap:: Error ,
28
28
} ,
29
+
30
+ #[ snafu( display( "invalid OIDC endpoint" ) ) ]
31
+ InvalidOidcEndpoint {
32
+ source : stackable_operator:: commons:: authentication:: oidc:: Error ,
33
+ } ,
34
+
35
+ #[ snafu( display( "invalid well-known OIDC configuration URL" ) ) ]
36
+ InvalidWellKnownConfigUrl {
37
+ source : stackable_operator:: commons:: authentication:: oidc:: Error ,
38
+ } ,
29
39
}
30
40
31
41
pub fn add_airflow_config (
@@ -78,7 +88,7 @@ fn append_authentication_config(
78
88
}
79
89
80
90
if !oidc_providers. is_empty ( ) {
81
- append_oidc_config ( config, & oidc_providers) ;
91
+ append_oidc_config ( config, & oidc_providers) ? ;
82
92
}
83
93
84
94
config. insert (
@@ -192,7 +202,7 @@ fn append_oidc_config(
192
202
& oidc:: AuthenticationProvider ,
193
203
& oidc:: ClientAuthenticationOptions < ( ) > ,
194
204
) ] ,
195
- ) {
205
+ ) -> Result < ( ) , Error > {
196
206
// Debatable: AUTH_OAUTH or AUTH_OID
197
207
// Additionally can be set via config
198
208
config. insert (
@@ -217,6 +227,13 @@ fn append_oidc_config(
217
227
218
228
let oauth_providers_config_entry = match oidc_provider {
219
229
oidc:: IdentityProviderHint :: Keycloak => {
230
+ let endpoint_url = oidc. endpoint_url ( ) . context ( InvalidOidcEndpointSnafu ) ?;
231
+ let mut api_base_url = endpoint_url. as_str ( ) . trim_end_matches ( '/' ) . to_owned ( ) ;
232
+ api_base_url. push_str ( "/protocol/" ) ;
233
+ let well_known_config_url = oidc
234
+ . well_known_config_url ( )
235
+ . context ( InvalidWellKnownConfigUrlSnafu ) ?;
236
+
220
237
formatdoc ! (
221
238
"
222
239
{{ 'name': 'keycloak',
@@ -228,11 +245,10 @@ fn append_oidc_config(
228
245
'client_kwargs': {{
229
246
'scope': '{scopes}'
230
247
}},
231
- 'api_base_url': '{url}/protocol/ ',
232
- 'server_metadata_url': '{url}/.well-known/openid-configuration ',
248
+ 'api_base_url': '{api_base_url} ',
249
+ 'server_metadata_url': '{well_known_config_url} ',
233
250
}},
234
251
}}" ,
235
- url = oidc. endpoint_url( ) . unwrap( ) ,
236
252
scopes = scopes. join( " " ) ,
237
253
)
238
254
}
@@ -251,12 +267,15 @@ fn append_oidc_config(
251
267
joined_oauth_providers_config = oauth_providers_config. join( ",\n " )
252
268
) ,
253
269
) ;
270
+
271
+ Ok ( ( ) )
254
272
}
255
273
256
274
#[ cfg( test) ]
257
275
mod tests {
258
276
use crate :: config:: add_airflow_config;
259
- use indoc:: indoc;
277
+ use indoc:: formatdoc;
278
+ use rstest:: rstest;
260
279
use stackable_airflow_crd:: authentication:: {
261
280
default_sync_roles_at, default_user_registration, AirflowAuthenticationClassResolved ,
262
281
AirflowClientAuthenticationDetailsResolved , FlaskRolesSyncMoment ,
@@ -339,12 +358,15 @@ mod tests {
339
358
] ) , result) ;
340
359
}
341
360
342
- #[ test]
343
- fn test_oidc_config ( ) {
344
- let oidc_provider_yaml1 = r#"
345
- hostname: my.keycloak1.server
361
+ #[ rstest]
362
+ #[ case( "/realms/sdp" ) ]
363
+ #[ case( "/realms/sdp/" ) ]
364
+ #[ case( "/realms/sdp/////" ) ]
365
+ fn test_oidc_config ( #[ case] root_path : & str ) {
366
+ let oidc_provider_yaml1 = formatdoc ! (
367
+ "hostname: my.keycloak1.server
346
368
port: 12345
347
- rootPath: my-root-path
369
+ rootPath: {root_path}
348
370
tls:
349
371
verification:
350
372
server:
@@ -356,8 +378,9 @@ mod tests {
356
378
- email
357
379
- profile
358
380
provider_hint: Keycloak
359
- "# ;
360
- let deserializer = serde_yaml:: Deserializer :: from_str ( oidc_provider_yaml1) ;
381
+ "
382
+ ) ;
383
+ let deserializer = serde_yaml:: Deserializer :: from_str ( & oidc_provider_yaml1) ;
361
384
let oidc_provider1: oidc:: AuthenticationProvider =
362
385
serde_yaml:: with:: singleton_map_recursive:: deserialize ( deserializer) . unwrap ( ) ;
363
386
@@ -399,41 +422,47 @@ mod tests {
399
422
let mut result = BTreeMap :: new ( ) ;
400
423
add_airflow_config ( & mut result, & authentication_config) . expect ( "Ok" ) ;
401
424
402
- assert_eq ! ( BTreeMap :: from( [
403
- ( "AUTH_ROLES_SYNC_AT_LOGIN" . into( ) , "false" . into( ) ) ,
404
- ( "AUTH_TYPE" . into( ) , "AUTH_OAUTH" . into( ) ) ,
405
- ( "AUTH_USER_REGISTRATION" . into( ) , "true" . into( ) ) ,
406
- ( "AUTH_USER_REGISTRATION_ROLE" . into( ) , "Admin" . into( ) ) ,
407
- ( "OAUTH_PROVIDERS" . into( ) , indoc!( "
425
+ assert_eq ! (
426
+ BTreeMap :: from( [
427
+ ( "AUTH_ROLES_SYNC_AT_LOGIN" . into( ) , "false" . into( ) ) ,
428
+ ( "AUTH_TYPE" . into( ) , "AUTH_OAUTH" . into( ) ) ,
429
+ ( "AUTH_USER_REGISTRATION" . into( ) , "true" . into( ) ) ,
430
+ ( "AUTH_USER_REGISTRATION_ROLE" . into( ) , "Admin" . into( ) ) ,
431
+ (
432
+ "OAUTH_PROVIDERS" . into( ) ,
433
+ formatdoc! { "
408
434
[
409
- { 'name': 'keycloak',
435
+ {{ 'name': 'keycloak',
410
436
'icon': 'fa-key',
411
437
'token_key': 'access_token',
412
- 'remote_app': {
438
+ 'remote_app': {{
413
439
'client_id': os.environ.get('OIDC_A96BCC4FA49835D2_CLIENT_ID'),
414
440
'client_secret': os.environ.get('OIDC_A96BCC4FA49835D2_CLIENT_SECRET'),
415
- 'client_kwargs': {
441
+ 'client_kwargs': {{
416
442
'scope': 'openid email profile roles'
417
- },
418
- 'api_base_url': 'https://my.keycloak1.server:12345/my-root-path /protocol/',
419
- 'server_metadata_url': 'https://my.keycloak1.server:12345/my-root-path /.well-known/openid-configuration',
420
- },
421
- },
422
- { 'name': 'keycloak',
443
+ }} ,
444
+ 'api_base_url': 'https://my.keycloak1.server:12345/realms/sdp /protocol/',
445
+ 'server_metadata_url': 'https://my.keycloak1.server:12345/realms/sdp /.well-known/openid-configuration',
446
+ }} ,
447
+ }} ,
448
+ {{ 'name': 'keycloak',
423
449
'icon': 'fa-key',
424
450
'token_key': 'access_token',
425
- 'remote_app': {
451
+ 'remote_app': {{
426
452
'client_id': os.environ.get('OIDC_3A305E38C3B561F3_CLIENT_ID'),
427
453
'client_secret': os.environ.get('OIDC_3A305E38C3B561F3_CLIENT_SECRET'),
428
- 'client_kwargs': {
454
+ 'client_kwargs': {{
429
455
'scope': 'openid'
430
- },
431
- 'api_base_url': 'http://my.keycloak2.server// protocol/',
432
- 'server_metadata_url': 'http://my.keycloak2.server// .well-known/openid-configuration',
433
- },
434
- }
456
+ }} ,
457
+ 'api_base_url': 'http://my.keycloak2.server/protocol/',
458
+ 'server_metadata_url': 'http://my.keycloak2.server/.well-known/openid-configuration',
459
+ }} ,
460
+ }}
435
461
]
436
- " ) . into( ) )
437
- ] ) , result) ;
462
+ " }
463
+ )
464
+ ] ) ,
465
+ result
466
+ ) ;
438
467
}
439
468
}
0 commit comments