55// Please see LICENSE in the repository root for full details. 
66
77use  axum:: { 
8-     extract:: { Path ,  Query ,  State } , 
8+     extract:: { Path ,  State } , 
9+     http:: Method , 
910    response:: { IntoResponse ,  Response } , 
1011    Form , 
1112} ; 
@@ -110,9 +111,6 @@ pub(crate) enum RouteError {
110111    #[ error( "Missing form parameters" ) ]  
111112    MissingFormParams , 
112113
113-     #[ error( "Ambiguous parameters: got both query and form parameters" ) ]  
114-     AmbiguousParams , 
115- 
116114    #[ error( "Invalid response mode, expected '{expected}'" ) ]  
117115    InvalidParamsMode  { 
118116        expected :  UpstreamOAuthProviderResponseMode , 
@@ -161,11 +159,11 @@ pub(crate) async fn handler(
161159    State ( keystore) :  State < Keystore > , 
162160    State ( client) :  State < reqwest:: Client > , 
163161    State ( templates) :  State < Templates > , 
162+     method :  Method , 
164163    PreferredLanguage ( locale) :  PreferredLanguage , 
165164    cookie_jar :  CookieJar , 
166165    Path ( provider_id) :  Path < Ulid > , 
167-     query_params :  Option < Query < Params > > , 
168-     form_params :  Option < Form < Params > > , 
166+     params :  Option < Form < Params > > , 
169167)  -> Result < Response ,  RouteError >  { 
170168    let  provider = repo
171169        . upstream_oauth_provider ( ) 
@@ -176,35 +174,37 @@ pub(crate) async fn handler(
176174
177175    let  sessions_cookie = UpstreamSessionsCookie :: load ( & cookie_jar) ; 
178176
179-     // Read the parameters from the query or the form, depending on what 
180-     // response_mode the provider uses 
181-     let  params = match  ( provider. response_mode ,  query_params,  form_params)  { 
182-         ( UpstreamOAuthProviderResponseMode :: Query ,  Some ( Query ( query_params) ) ,  None )  => query_params, 
183-         ( UpstreamOAuthProviderResponseMode :: FormPost ,  None ,  Some ( Form ( mut  form_params) ) )  => { 
177+     let  Some ( Form ( params) )  = params else  { 
178+         if  let  Method :: GET  = method { 
179+             return  Err ( RouteError :: MissingQueryParams ) ; 
180+         } 
181+ 
182+         return  Err ( RouteError :: MissingFormParams ) ; 
183+     } ; 
184+ 
185+     // The `Form` extractor will use the body of the request for POST requests and 
186+     // the query parameters for GET requests. We need to then look at the method do 
187+     // make sure it matches the expected `response_mode` 
188+     match  ( provider. response_mode ,  method)  { 
189+         ( UpstreamOAuthProviderResponseMode :: Query ,  Method :: GET )  => { } 
190+         ( UpstreamOAuthProviderResponseMode :: FormPost ,  Method :: POST )  => { 
184191            // We set the cookies with a `Same-Site` policy set to `Lax`, so because this is 
185192            // usually a cross-site form POST, we need to render a form with the 
186193            // same values, which posts back to the same URL. However, there are 
187194            // other valid reasons for the cookie to be missing, so to track whether we did 
188195            // this POST ourselves, we set a flag. 
189-             if  sessions_cookie. is_empty ( )  && !form_params. did_mas_repost_to_itself  { 
190-                 form_params. did_mas_repost_to_itself  = true ; 
191-                 let  context =
192-                     FormPostContext :: new_for_current_url ( form_params) . with_language ( & locale) ; 
196+             if  sessions_cookie. is_empty ( )  && !params. did_mas_repost_to_itself  { 
197+                 let  params = Params  { 
198+                     did_mas_repost_to_itself :  true , 
199+                     ..params
200+                 } ; 
201+                 let  context = FormPostContext :: new_for_current_url ( params) . with_language ( & locale) ; 
193202                let  html = templates. render_form_post ( & context) ?; 
194203                return  Ok ( Html ( html) . into_response ( ) ) ; 
195204            } 
196- 
197-             form_params
198-         } 
199-         ( UpstreamOAuthProviderResponseMode :: Query ,  None ,  None )  => { 
200-             return  Err ( RouteError :: MissingQueryParams ) 
201-         } 
202-         ( UpstreamOAuthProviderResponseMode :: FormPost ,  None ,  None )  => { 
203-             return  Err ( RouteError :: MissingFormParams ) 
204205        } 
205-         ( _,  Some ( _) ,  Some ( _) )  => return  Err ( RouteError :: AmbiguousParams ) , 
206-         ( expected,  _,  _)  => return  Err ( RouteError :: InvalidParamsMode  {  expected } ) , 
207-     } ; 
206+         ( expected,  _)  => return  Err ( RouteError :: InvalidParamsMode  {  expected } ) , 
207+     } 
208208
209209    let  ( session_id,  _post_auth_action)  = sessions_cookie
210210        . find_session ( provider_id,  & params. state ) 
0 commit comments