Skip to content

Commit d4175d7

Browse files
committed
OIDC directory
1 parent 430a444 commit d4175d7

File tree

2 files changed

+136
-3
lines changed

2 files changed

+136
-3
lines changed

src/pages/config/schema/directory.rs

+135-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ impl Builder<Schemas, ()> {
2828
("internal", "Internal"),
2929
("ldap", "LDAP Directory"),
3030
("sql", "SQL Database"),
31+
("oidc", "OpenID Connect"),
3132
("lmtp", "LMTP Server"),
3233
("smtp", "SMTP Server"),
3334
("imap", "IMAP4 Server"),
@@ -210,7 +211,7 @@ impl Builder<Schemas, ()> {
210211
.label("Timeout")
211212
.help("Connection timeout to the server")
212213
.typ(Type::Duration)
213-
.display_if_eq("type", ["ldap", "smtp", "lmtp", "imap"])
214+
.display_if_eq("type", ["ldap", "smtp", "lmtp", "imap", "oidc"])
214215
.default("15s")
215216
.build()
216217
// LDAP settings
@@ -342,11 +343,133 @@ impl Builder<Schemas, ()> {
342343
.help("DAP attribute for the user's disk quota")
343344
.default("diskQuota")
344345
.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()
345459
// Form layouts
346460
.new_form_section()
347461
.title("Configuration")
348462
.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",
350473
])
351474
.build()
352475
.new_form_section()
@@ -360,6 +483,16 @@ impl Builder<Schemas, ()> {
360483
.fields(["tls.enable", "tls.allow-invalid-certs"])
361484
.build()
362485
.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()
363496
.title("Column Mappings")
364497
.display_if_eq("type", ["sql"])
365498
.fields([

src/pages/directory/list.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,8 @@ pub fn PrincipalList() -> impl IntoView {
350350
PrincipalType::OauthClient => {
351351
vec![
352352
"Name".to_string(),
353-
"Type".to_string(),
354353
"Contact".to_string(),
354+
"Type".to_string(),
355355
"".to_string(),
356356
]
357357
}

0 commit comments

Comments
 (0)