@@ -202,6 +202,46 @@ pub(crate) async fn get(
202202 None
203203 } ;
204204
205+ // If this registration was created from an upstream OAuth session, check
206+ // it is still valid and wasn't linked to a user in the meantime
207+ let upstream_oauth = if let Some ( upstream_oauth_authorization_session_id) =
208+ registration. upstream_oauth_authorization_session_id
209+ {
210+ let upstream_oauth_authorization_session = repo
211+ . upstream_oauth_session ( )
212+ . lookup ( upstream_oauth_authorization_session_id)
213+ . await ?
214+ . context ( "Could not load the upstream OAuth authorization session" )
215+ . map_err ( InternalError :: from_anyhow) ?;
216+
217+ let link_id = upstream_oauth_authorization_session
218+ . link_id ( )
219+ // This should not happen, the session is associated with the user
220+ // registration once the link was already created
221+ . context ( "Authorization session as no upstream link associated with it" )
222+ . map_err ( InternalError :: from_anyhow) ?;
223+
224+ let upstream_oauth_link = repo
225+ . upstream_oauth_link ( )
226+ . lookup ( link_id)
227+ . await ?
228+ . context ( "Could not load the upstream OAuth link" )
229+ . map_err ( InternalError :: from_anyhow) ?;
230+
231+ if upstream_oauth_link. user_id . is_some ( ) {
232+ // This means the link was already associated to a user. This could
233+ // in theory happen if the same user registers concurrently, but
234+ // this is not going to happen often enough to have a dedicated page
235+ return Err ( InternalError :: from_anyhow ( anyhow:: anyhow!(
236+ "The upstream identity was already linked to a user. Try logging in again"
237+ ) ) ) ;
238+ }
239+
240+ Some ( ( upstream_oauth_authorization_session, upstream_oauth_link) )
241+ } else {
242+ None
243+ } ;
244+
205245 // Check that the display name is set
206246 if registration. display_name . is_none ( ) {
207247 return Ok ( (
@@ -266,6 +306,16 @@ pub(crate) async fn get(
266306 PASSWORD_REGISTER_COUNTER . add ( 1 , & [ ] ) ;
267307 }
268308
309+ if let Some ( ( upstream_session, upstream_link) ) = upstream_oauth {
310+ repo. upstream_oauth_link ( )
311+ . associate_to_user ( & upstream_link, & user)
312+ . await ?;
313+
314+ repo. browser_session ( )
315+ . authenticate_with_upstream ( & mut rng, & clock, & user_session, & upstream_session)
316+ . await ?;
317+ }
318+
269319 if let Some ( terms_url) = registration. terms_url {
270320 repo. user_terms ( )
271321 . accept_terms ( & mut rng, & clock, & user, terms_url)
0 commit comments