@@ -28,6 +28,7 @@ impl Builder<Schemas, ()> {
28
28
( "internal" , "Internal" ) ,
29
29
( "ldap" , "LDAP Directory" ) ,
30
30
( "sql" , "SQL Database" ) ,
31
+ ( "oidc" , "OpenID Connect" ) ,
31
32
( "lmtp" , "LMTP Server" ) ,
32
33
( "smtp" , "SMTP Server" ) ,
33
34
( "imap" , "IMAP4 Server" ) ,
@@ -210,7 +211,7 @@ impl Builder<Schemas, ()> {
210
211
. label ( "Timeout" )
211
212
. help ( "Connection timeout to the server" )
212
213
. typ ( Type :: Duration )
213
- . display_if_eq ( "type" , [ "ldap" , "smtp" , "lmtp" , "imap" ] )
214
+ . display_if_eq ( "type" , [ "ldap" , "smtp" , "lmtp" , "imap" , "oidc" ] )
214
215
. default ( "15s" )
215
216
. build ( )
216
217
// LDAP settings
@@ -342,11 +343,133 @@ impl Builder<Schemas, ()> {
342
343
. help ( "DAP attribute for the user's disk quota" )
343
344
. default ( "diskQuota" )
344
345
. build ( )
346
+ // OIDC
347
+ // Type
348
+ . new_field ( "endpoint.url" )
349
+ . enterprise_feature ( )
350
+ . label ( "URL" )
351
+ . help ( concat ! (
352
+ "URL of the OpenID Connect provider. This is used to " ,
353
+ "retrieve user information from the OpenID Connect provider."
354
+ ) )
355
+ . display_if_eq ( "type" , [ "oidc" ] )
356
+ . placeholder ( "https://accounts.example.org/userinfo" )
357
+ . typ ( Type :: Input )
358
+ . input_check ( [ Transformer :: Trim ] , [ Validator :: Required , Validator :: IsUrl ] )
359
+ . build ( )
360
+ . new_field ( "endpoint.method" )
361
+ . enterprise_feature ( )
362
+ . label ( "Type" )
363
+ . help ( concat ! (
364
+ "Type of endpoint to use for user information. " ,
365
+ "This is used to retrieve user information from the " ,
366
+ "OpenID Connect provider."
367
+ ) )
368
+ . default ( "userinfo" )
369
+ . display_if_eq ( "type" , [ "oidc" ] )
370
+ . typ ( Type :: Select {
371
+ source : Source :: Static ( & [
372
+ ( "userinfo" , "OpenID Connect Userinfo" ) ,
373
+ ( "introspect" , "OAuth Token Introspection" ) ,
374
+ ] ) ,
375
+ typ : SelectType :: Single ,
376
+ } )
377
+ . build ( )
378
+ . new_field ( "fields.email" )
379
+ . enterprise_feature ( )
380
+ . label ( "E-mail field" )
381
+ . help ( concat ! (
382
+ "Field name in the OpenID Connect provider response " ,
383
+ "that contains the user's email address."
384
+ ) )
385
+ . display_if_eq ( "type" , [ "oidc" ] )
386
+ . placeholder ( "email" )
387
+ . typ ( Type :: Input )
388
+ . input_check ( [ Transformer :: Trim ] , [ Validator :: Required ] )
389
+ . build ( )
390
+ . new_field ( "fields.username" )
391
+ . enterprise_feature ( )
392
+ . label ( "Username field" )
393
+ . help ( concat ! (
394
+ "Field name in the OpenID Connect provider response " ,
395
+ "that contains the user's username. If not provided, " ,
396
+ "the email field will be used."
397
+ ) )
398
+ . display_if_eq ( "type" , [ "oidc" ] )
399
+ . placeholder ( "preferred_username" )
400
+ . typ ( Type :: Input )
401
+ . input_check ( [ Transformer :: Trim ] , [ ] )
402
+ . build ( )
403
+ . new_field ( "fields.full-name" )
404
+ . enterprise_feature ( )
405
+ . label ( "Name field" )
406
+ . help ( concat ! (
407
+ "Field name in the OpenID Connect provider response " ,
408
+ "that contains the user's full name."
409
+ ) )
410
+ . display_if_eq ( "type" , [ "oidc" ] )
411
+ . placeholder ( "name" )
412
+ . typ ( Type :: Input )
413
+ . input_check ( [ Transformer :: Trim ] , [ ] )
414
+ . build ( )
415
+ . new_field ( "auth.method" )
416
+ . enterprise_feature ( )
417
+ . label ( "Method" )
418
+ . help ( concat ! (
419
+ "Type of endpoint to use for user information. " ,
420
+ "This is used to retrieve user information from the " ,
421
+ "OpenID Connect provider."
422
+ ) )
423
+ . default ( "none" )
424
+ . display_if_eq ( "endpoint.method" , [ "introspect" ] )
425
+ . typ ( Type :: Select {
426
+ source : Source :: Static ( & [
427
+ ( "none" , "No Authentication" ) ,
428
+ ( "basic" , "Basic Authentication" ) ,
429
+ ( "token" , "Bearer Token" ) ,
430
+ ( "user-token" , "User Access Token" ) ,
431
+ ] ) ,
432
+ typ : SelectType :: Single ,
433
+ } )
434
+ . build ( )
435
+ . new_field ( "auth.token" )
436
+ . label ( "Auth token" )
437
+ . typ ( Type :: Secret )
438
+ . help ( concat ! (
439
+ "Bearer token used to authenticate with the OAuth introspect endpoint." ,
440
+ ) )
441
+ . display_if_eq ( "auth.method" , [ "token" ] )
442
+ . build ( )
443
+ . new_field ( "auth.username" )
444
+ . label ( "Auth username" )
445
+ . help ( concat ! (
446
+ "Username used to authenticate with the OAuth introspect endpoint." ,
447
+ ) )
448
+ . typ ( Type :: Input )
449
+ . display_if_eq ( "auth.method" , [ "basic" ] )
450
+ . build ( )
451
+ . new_field ( "auth.secret" )
452
+ . label ( "Auth secret" )
453
+ . help ( concat ! (
454
+ "Password used to authenticate with the OAuth introspect endpoint." ,
455
+ ) )
456
+ . typ ( Type :: Secret )
457
+ . display_if_eq ( "auth.method" , [ "basic" ] )
458
+ . build ( )
345
459
// Form layouts
346
460
. new_form_section ( )
347
461
. title ( "Configuration" )
348
462
. fields ( [
349
- "_id" , "type" , "store" , "url" , "base-dn" , "host" , "port" , "timeout" ,
463
+ "_id" ,
464
+ "type" ,
465
+ "store" ,
466
+ "url" ,
467
+ "base-dn" ,
468
+ "host" ,
469
+ "port" ,
470
+ "endpoint.url" ,
471
+ "endpoint.method" ,
472
+ "timeout" ,
350
473
] )
351
474
. build ( )
352
475
. new_form_section ( )
@@ -360,6 +483,16 @@ impl Builder<Schemas, ()> {
360
483
. fields ( [ "tls.enable" , "tls.allow-invalid-certs" ] )
361
484
. build ( )
362
485
. new_form_section ( )
486
+ . title ( "Endpoint Authentication" )
487
+ . display_if_eq ( "endpoint.method" , [ "introspect" ] )
488
+ . fields ( [ "auth.method" , "auth.token" , "auth.username" , "auth.secret" ] )
489
+ . build ( )
490
+ . new_form_section ( )
491
+ . title ( "Field Mappings" )
492
+ . display_if_eq ( "type" , [ "oidc" ] )
493
+ . fields ( [ "fields.email" , "fields.username" , "fields.full-name" ] )
494
+ . build ( )
495
+ . new_form_section ( )
363
496
. title ( "Column Mappings" )
364
497
. display_if_eq ( "type" , [ "sql" ] )
365
498
. fields ( [
0 commit comments