@@ -920,16 +920,18 @@ pub(crate) async fn post(
920920mod tests {
921921 use hyper:: { Request , StatusCode , header:: CONTENT_TYPE } ;
922922 use mas_data_model:: {
923- UpstreamOAuthProviderClaimsImports , UpstreamOAuthProviderImportPreference ,
924- UpstreamOAuthProviderTokenAuthMethod ,
923+ UpstreamOAuthAuthorizationSession , UpstreamOAuthLink , UpstreamOAuthProviderClaimsImports , UpstreamOAuthProviderImportPreference , UpstreamOAuthProviderTokenAuthMethod , User
925924 } ;
926925 use mas_iana:: jose:: JsonWebSignatureAlg ;
927926 use mas_jose:: jwt:: { JsonWebSignatureHeader , Jwt } ;
927+ use mas_keystore:: Keystore ;
928928 use mas_router:: Route ;
929929 use mas_storage:: {
930- Pagination , upstream_oauth2:: UpstreamOAuthProviderParams , user:: UserEmailFilter ,
930+ upstream_oauth2:: UpstreamOAuthProviderParams , user:: UserEmailFilter , Pagination , Repository , RepositoryError
931931 } ;
932932 use oauth2_types:: scope:: { OPENID , Scope } ;
933+ use rand_chacha:: ChaChaRng ;
934+ use serde_json:: { Value } ;
933935 use sqlx:: PgPool ;
934936
935937 use super :: UpstreamSessionsCookie ;
@@ -959,21 +961,11 @@ mod tests {
959961960962 "email_verified" : true ,
961963 } ) ;
962-
963- // Grab a key to sign the id_token
964- // We could generate a key on the fly, but because we have one available here,
965- // why not use it?
966- let key = state
967- . key_store
968- . signing_key_for_algorithm ( & JsonWebSignatureAlg :: Rs256 )
964+
965+ let id_token =
966+ sign_token ( & mut rng, & state. key_store , id_token)
969967 . unwrap ( ) ;
970968
971- let signer = key
972- . params ( )
973- . signing_key_for_alg ( & JsonWebSignatureAlg :: Rs256 )
974- . unwrap ( ) ;
975- let header = JsonWebSignatureHeader :: new ( JsonWebSignatureAlg :: Rs256 ) ;
976- let id_token = Jwt :: sign_with_rng ( & mut rng, header, id_token, & signer) . unwrap ( ) ;
977969
978970 // Provision a provider and a link
979971 let mut repo = state. repository ( ) . await . unwrap ( ) ;
@@ -1011,44 +1003,11 @@ mod tests {
10111003 . await
10121004 . unwrap ( ) ;
10131005
1014- let session = repo
1015- . upstream_oauth_session ( )
1016- . add (
1017- & mut rng,
1018- & state. clock ,
1019- & provider,
1020- "state" . to_owned ( ) ,
1021- None ,
1022- None ,
1023- )
1024- . await
1025- . unwrap ( ) ;
1026-
1027- let link = repo
1028- . upstream_oauth_link ( )
1029- . add (
1030- & mut rng,
1031- & state. clock ,
1032- & provider,
1033- "subject" . to_owned ( ) ,
1034- None ,
1035- )
1036- . await
1037- . unwrap ( ) ;
1038-
1039- let session = repo
1040- . upstream_oauth_session ( )
1041- . complete_with_link (
1042- & state. clock ,
1043- session,
1044- & link,
1045- Some ( id_token. into_string ( ) ) ,
1046- None ,
1047- None ,
1048- )
1049- . await
1050- . unwrap ( ) ;
1051-
1006+ let ( link, session) =
1007+ add_linked_upstream_session ( & mut rng, & state. clock , & mut repo, & provider, "subject" , & id_token. into_string ( ) )
1008+ . await
1009+ . unwrap ( ) ;
1010+
10521011 repo. save ( ) . await . unwrap ( ) ;
10531012
10541013 let cookie_jar = state. cookie_jar ( ) ;
@@ -1157,22 +1116,10 @@ mod tests {
11571116 "email" : oidc_email,
11581117 "email_verified" : true ,
11591118 } ) ;
1160-
1161- // Grab a key to sign the id_token
1162- // We could generate a key on the fly, but because we have one available here,
1163- // why not use it?
1164- let key = state
1165- . key_store
1166- . signing_key_for_algorithm ( & JsonWebSignatureAlg :: Rs256 )
1119+
1120+ let id_token = sign_token ( & mut rng, & state. key_store , id_token)
11671121 . unwrap ( ) ;
11681122
1169- let signer = key
1170- . params ( )
1171- . signing_key_for_alg ( & JsonWebSignatureAlg :: Rs256 )
1172- . unwrap ( ) ;
1173- let header = JsonWebSignatureHeader :: new ( JsonWebSignatureAlg :: Rs256 ) ;
1174- let id_token = Jwt :: sign_with_rng ( & mut rng, header, id_token, & signer) . unwrap ( ) ;
1175-
11761123 // Provision a provider and a link
11771124 let mut repo = state. repository ( ) . await . unwrap ( ) ;
11781125 let provider = repo
@@ -1209,52 +1156,12 @@ mod tests {
12091156 . await
12101157 . unwrap ( ) ;
12111158
1212- let session = repo
1213- . upstream_oauth_session ( )
1214- . add (
1215- & mut rng,
1216- & state. clock ,
1217- & provider,
1218- "state" . to_owned ( ) ,
1219- None ,
1220- Some ( "nonce" . to_owned ( ) ) ,
1221- )
1222- . await
1223- . unwrap ( ) ;
1224-
1225- let link = repo
1226- . upstream_oauth_link ( )
1227- . add ( & mut rng, & state. clock , & provider, subject. clone ( ) , None )
1228- . await
1229- . unwrap ( ) ;
1230-
1231- let session = repo
1232- . upstream_oauth_session ( )
1233- . complete_with_link (
1234- & state. clock ,
1235- session,
1236- & link,
1237- Some ( id_token. into_string ( ) ) ,
1238- None ,
1239- None ,
1240- )
1241- . await
1242- . unwrap ( ) ;
1243-
1244- //create a user with an email
1245- let user = repo
1246- . user ( )
1247- . add ( & mut rng, & state. clock , existing_username. clone ( ) )
1159+ //provision upstream authorization session to setup cookies
1160+ let ( link, session) =
1161+ add_linked_upstream_session ( & mut rng, & state. clock , & mut repo, & provider, & subject, & id_token. into_string ( ) )
12481162 . await
12491163 . unwrap ( ) ;
1250-
1251- let _user_email = repo
1252- . user_email ( )
1253- . add ( & mut rng, & state. clock , & user, existing_email. clone ( ) )
1254- . await ;
1255-
1256- repo. save ( ) . await . unwrap ( ) ;
1257-
1164+
12581165 let cookie_jar = state. cookie_jar ( ) ;
12591166 let upstream_sessions = UpstreamSessionsCookie :: default ( )
12601167 . add ( session. id , provider. id , "state" . to_owned ( ) , None )
@@ -1263,6 +1170,18 @@ mod tests {
12631170 let cookie_jar = upstream_sessions. save ( cookie_jar, & state. clock ) ;
12641171 cookies. import ( cookie_jar) ;
12651172
1173+ let user =
1174+ create_user (
1175+ & mut rng,
1176+ & state. clock ,
1177+ & mut repo,
1178+ existing_username. clone ( ) ,
1179+ existing_email. clone ( ) )
1180+ . await
1181+ . unwrap ( ) ;
1182+
1183+ repo. save ( ) . await . unwrap ( ) ;
1184+
12661185 let request = Request :: get ( & * mas_router:: UpstreamOAuth2Link :: new ( link. id ) . path ( ) ) . empty ( ) ;
12671186 let request = cookies. with_cookies ( request) ;
12681187 let response = state. request ( request) . await ;
@@ -1357,22 +1276,10 @@ mod tests {
13571276 "email" : oidc_email,
13581277 "email_verified" : true ,
13591278 } ) ;
1360-
1361- // Grab a key to sign the id_token
1362- // We could generate a key on the fly, but because we have one available here,
1363- // why not use it?
1364- let key = state
1365- . key_store
1366- . signing_key_for_algorithm ( & JsonWebSignatureAlg :: Rs256 )
1279+
1280+ let id_token = sign_token ( & mut rng, & state. key_store , id_token)
13671281 . unwrap ( ) ;
13681282
1369- let signer = key
1370- . params ( )
1371- . signing_key_for_alg ( & JsonWebSignatureAlg :: Rs256 )
1372- . unwrap ( ) ;
1373- let header = JsonWebSignatureHeader :: new ( JsonWebSignatureAlg :: Rs256 ) ;
1374- let id_token = Jwt :: sign_with_rng ( & mut rng, header, id_token, & signer) . unwrap ( ) ;
1375-
13761283 // Provision a provider and a link
13771284 let mut repo = state. repository ( ) . await . unwrap ( ) ;
13781285 let provider = repo
@@ -1409,49 +1316,26 @@ mod tests {
14091316 . await
14101317 . unwrap ( ) ;
14111318
1412- let session = repo
1413- . upstream_oauth_session ( )
1414- . add (
1415- & mut rng,
1416- & state. clock ,
1417- & provider,
1418- "state" . to_owned ( ) ,
1419- None ,
1420- Some ( "nonce" . to_owned ( ) ) ,
1421- )
1422- . await
1423- . unwrap ( ) ;
1424-
1425- let link = repo
1426- . upstream_oauth_link ( )
1427- . add ( & mut rng, & state. clock , & provider, subject. clone ( ) , None )
1428- . await
1429- . unwrap ( ) ;
1430-
1431- let session = repo
1432- . upstream_oauth_session ( )
1433- . complete_with_link (
1434- & state. clock ,
1435- session,
1436- & link,
1437- Some ( id_token. into_string ( ) ) ,
1438- None ,
1439- None ,
1440- )
1441- . await
1442- . unwrap ( ) ;
1443-
1444- //create a user with an email
1445- let user = repo
1446- . user ( )
1447- . add ( & mut rng, & state. clock , existing_username. clone ( ) )
1319+ let ( link, session) =
1320+ add_linked_upstream_session (
1321+ & mut rng,
1322+ & state. clock ,
1323+ & mut repo,
1324+ & provider,
1325+ & subject,
1326+ & id_token. into_string ( ) )
14481327 . await
14491328 . unwrap ( ) ;
1450-
1451- let _user_email = repo
1452- . user_email ( )
1453- . add ( & mut rng, & state. clock , & user, existing_email. clone ( ) )
1454- . await ;
1329+
1330+ let _user =
1331+ create_user (
1332+ & mut rng,
1333+ & state. clock ,
1334+ & mut repo,
1335+ existing_username. clone ( ) ,
1336+ existing_email. clone ( ) )
1337+ . await
1338+ . unwrap ( ) ;
14551339
14561340 repo. save ( ) . await . unwrap ( ) ;
14571341
@@ -1472,4 +1356,87 @@ mod tests {
14721356
14731357 assert ! ( response. body( ) . contains( "Unexpected error" ) ) ;
14741358 }
1359+
1360+ fn sign_token (
1361+ rng : & mut ChaChaRng ,
1362+ keystore : & Keystore ,
1363+ payload : Value ,
1364+ ) -> Result < Jwt < ' static , Value > , mas_jose:: jwt:: JwtSignatureError > {
1365+ let key = keystore
1366+ . signing_key_for_algorithm ( & JsonWebSignatureAlg :: Rs256 )
1367+ . unwrap ( ) ;
1368+
1369+ let signer = key
1370+ . params ( )
1371+ . signing_key_for_alg ( & JsonWebSignatureAlg :: Rs256 )
1372+ . unwrap ( ) ;
1373+
1374+ let header = JsonWebSignatureHeader :: new ( JsonWebSignatureAlg :: Rs256 ) ;
1375+
1376+ Jwt :: sign_with_rng ( rng, header, payload, & signer)
1377+ }
1378+
1379+ async fn create_user (
1380+ rng : & mut ChaChaRng ,
1381+ clock : & impl mas_storage:: Clock ,
1382+ repo : & mut Box < dyn Repository < RepositoryError > + Send + Sync + ' static > ,
1383+ username : String ,
1384+ email : String
1385+ ) ->Result < User , anyhow:: Error > {
1386+
1387+ //create a user with an email
1388+ let user = repo
1389+ . user ( )
1390+ . add ( rng, clock, username)
1391+ . await
1392+ . unwrap ( ) ;
1393+
1394+ let _user_email = repo
1395+ . user_email ( )
1396+ . add ( rng, clock, & user, email)
1397+ . await ;
1398+
1399+ Ok ( user)
1400+
1401+ }
1402+
1403+ async fn add_linked_upstream_session (
1404+ rng : & mut ChaChaRng ,
1405+ clock : & impl mas_storage:: Clock ,
1406+ repo : & mut Box < dyn Repository < RepositoryError > + Send + Sync + ' static > ,
1407+ provider : & mas_data_model:: UpstreamOAuthProvider ,
1408+ subject : & str ,
1409+ id_token : & str
1410+ ) -> Result < ( UpstreamOAuthLink , UpstreamOAuthAuthorizationSession ) , anyhow:: Error > {
1411+ let session = repo
1412+ . upstream_oauth_session ( )
1413+ . add (
1414+ rng,
1415+ clock,
1416+ provider,
1417+ "state" . to_owned ( ) ,
1418+ None ,
1419+ Some ( "nonce" . to_owned ( ) ) ,
1420+ )
1421+ . await ?;
1422+
1423+ let link = repo
1424+ . upstream_oauth_link ( )
1425+ . add ( rng, clock, provider, subject. to_owned ( ) , None )
1426+ . await ?;
1427+
1428+ let session = repo
1429+ . upstream_oauth_session ( )
1430+ . complete_with_link (
1431+ clock,
1432+ session,
1433+ & link,
1434+ Some ( id_token. to_owned ( ) ) ,
1435+ None ,
1436+ None ,
1437+ )
1438+ . await ?;
1439+
1440+ Ok ( ( link, session) )
1441+ }
14751442}
0 commit comments