@@ -38,7 +38,10 @@ use thiserror::Error;
3838use tracing:: warn;
3939use ulid:: Ulid ;
4040
41- use super :: { template:: environment, UpstreamSessionsCookie } ;
41+ use super :: {
42+ template:: { environment, AttributeMappingContext } ,
43+ UpstreamSessionsCookie ,
44+ } ;
4245use crate :: {
4346 impl_from_error_for_route, views:: shared:: OptionalPostAuthAction , PreferredLanguage , SiteConfig ,
4447} ;
@@ -130,9 +133,10 @@ impl IntoResponse for RouteError {
130133fn render_attribute_template (
131134 environment : & Environment ,
132135 template : & str ,
136+ context : & minijinja:: Value ,
133137 required : bool ,
134138) -> Result < Option < String > , RouteError > {
135- match environment. render_str ( template, ( ) ) {
139+ match environment. render_str ( template, context ) {
136140 Ok ( value) if value. is_empty ( ) => {
137141 if required {
138142 return Err ( RouteError :: RequiredAttributeEmpty {
@@ -320,32 +324,27 @@ pub(crate) async fn get(
320324 ( None , None ) => {
321325 // Session not linked and used not logged in: suggest creating an
322326 // account or logging in an existing user
323- let id_token = upstream_session
324- . id_token ( )
325- . map ( Jwt :: < ' _ , minijinja:: Value > :: try_from)
326- . transpose ( ) ?;
327+ let id_token = upstream_session. id_token ( ) . map ( Jwt :: try_from) . transpose ( ) ?;
327328
328329 let provider = repo
329330 . upstream_oauth_provider ( )
330331 . lookup ( link. provider_id )
331332 . await ?
332333 . ok_or ( RouteError :: ProviderNotFound ) ?;
333334
334- let payload = id_token
335- . map ( |id_token| id_token. into_parts ( ) . 1 )
336- . unwrap_or_default ( ) ;
337-
338335 let ctx = UpstreamRegister :: default ( ) ;
339336
340- let env = {
341- let mut e = environment ( ) ;
342- e. add_global ( "user" , payload) ;
343- e. add_global (
344- "extra_callback_parameters" ,
345- minijinja:: Value :: from_serialize ( upstream_session. extra_callback_parameters ( ) ) ,
346- ) ;
347- e
348- } ;
337+ let env = environment ( ) ;
338+
339+ let mut context = AttributeMappingContext :: new ( ) ;
340+ if let Some ( id_token) = id_token {
341+ let ( _, payload) = id_token. into_parts ( ) ;
342+ context = context. with_id_token_claims ( payload) ;
343+ }
344+ if let Some ( extra_callback_parameters) = upstream_session. extra_callback_parameters ( ) {
345+ context = context. with_extra_callback_parameters ( extra_callback_parameters. clone ( ) ) ;
346+ }
347+ let context = context. build ( ) ;
349348
350349 let ctx = if provider. claims_imports . displayname . ignore ( ) {
351350 ctx
@@ -360,6 +359,7 @@ pub(crate) async fn get(
360359 match render_attribute_template (
361360 & env,
362361 template,
362+ & context,
363363 provider. claims_imports . displayname . is_required ( ) ,
364364 ) ? {
365365 Some ( value) => ctx
@@ -381,6 +381,7 @@ pub(crate) async fn get(
381381 match render_attribute_template (
382382 & env,
383383 template,
384+ & context,
384385 provider. claims_imports . email . is_required ( ) ,
385386 ) ? {
386387 Some ( value) => ctx. with_email ( value, provider. claims_imports . email . is_forced ( ) ) ,
@@ -401,6 +402,7 @@ pub(crate) async fn get(
401402 match render_attribute_template (
402403 & env,
403404 template,
405+ & context,
404406 provider. claims_imports . localpart . is_required ( ) ,
405407 ) ? {
406408 Some ( localpart) => {
@@ -561,37 +563,31 @@ pub(crate) async fn post(
561563 let import_display_name = import_display_name. is_some ( ) ;
562564 let accept_terms = accept_terms. is_some ( ) ;
563565
564- let id_token = upstream_session
565- . id_token ( )
566- . map ( Jwt :: < ' _ , minijinja:: Value > :: try_from)
567- . transpose ( ) ?;
566+ let id_token = upstream_session. id_token ( ) . map ( Jwt :: try_from) . transpose ( ) ?;
568567
569568 let provider = repo
570569 . upstream_oauth_provider ( )
571570 . lookup ( link. provider_id )
572571 . await ?
573572 . ok_or ( RouteError :: ProviderNotFound ) ?;
574573
575- let payload = id_token
576- . map ( |id_token| id_token. into_parts ( ) . 1 )
577- . unwrap_or_default ( ) ;
574+ // Let's try to import the claims from the ID token
575+ let env = environment ( ) ;
578576
579- // Is the email verified according to the upstream provider?
580- let provider_email_verified = payload
581- . get_item ( & minijinja:: Value :: from ( "email_verified" ) )
582- . map ( |v| v. is_true ( ) )
583- . unwrap_or ( false ) ;
577+ let mut context = AttributeMappingContext :: new ( ) ;
578+ if let Some ( id_token) = id_token {
579+ let ( _, payload) = id_token. into_parts ( ) ;
580+ context = context. with_id_token_claims ( payload) ;
581+ }
582+ if let Some ( extra_callback_parameters) = upstream_session. extra_callback_parameters ( ) {
583+ context = context. with_extra_callback_parameters ( extra_callback_parameters. clone ( ) ) ;
584+ }
585+ let context = context. build ( ) ;
584586
585- // Let's try to import the claims from the ID token
586- let env = {
587- let mut e = environment ( ) ;
588- e. add_global ( "user" , payload) ;
589- e. add_global (
590- "extra_callback_parameters" ,
591- minijinja:: Value :: from_serialize ( upstream_session. extra_callback_parameters ( ) ) ,
592- ) ;
593- e
594- } ;
587+ // Is the email verified according to the upstream provider?
588+ let provider_email_verified = env
589+ . render_str ( "{{ user.email_verified | string }}" , & context)
590+ . map_or ( false , |v| v == "true" ) ;
595591
596592 // Create a template context in case we need to re-render because of an error
597593 let ctx = UpstreamRegister :: default ( ) ;
@@ -611,6 +607,7 @@ pub(crate) async fn post(
611607 render_attribute_template (
612608 & env,
613609 template,
610+ & context,
614611 provider. claims_imports . displayname . is_required ( ) ,
615612 ) ?
616613 } else {
@@ -637,6 +634,7 @@ pub(crate) async fn post(
637634 render_attribute_template (
638635 & env,
639636 template,
637+ & context,
640638 provider. claims_imports . email . is_required ( ) ,
641639 ) ?
642640 } else {
@@ -660,6 +658,7 @@ pub(crate) async fn post(
660658 render_attribute_template (
661659 & env,
662660 template,
661+ & context,
663662 provider. claims_imports . email . is_required ( ) ,
664663 ) ?
665664 } else {
0 commit comments