@@ -10,8 +10,8 @@ use axum_extra::extract::{PrivateCookieJar, cookie::Cookie};
1010use cookie:: { Key , SameSite } ;
1111use hyper:: header:: { ACCEPT , USER_AGENT } ;
1212use oauth2:: {
13- AuthUrl , AuthorizationCode , ClientId , ClientSecret , CsrfToken , RedirectUrl , Scope ,
14- TokenResponse , TokenUrl , basic:: BasicClient , reqwest:: async_http_client ,
13+ AuthUrl , AuthorizationCode , ClientId , ClientSecret , CsrfToken , EndpointNotSet , EndpointSet ,
14+ RedirectUrl , Scope , TokenResponse , TokenUrl , basic:: BasicClient , reqwest as oauth2_reqwest ,
1515} ;
1616use serde:: Deserialize ;
1717use std:: fmt:: Debug ;
@@ -27,9 +27,13 @@ static GITHUB_TOKEN_URL: &str = "https://github.com/login/oauth/access_token";
2727static GITHUB_USER_URL : & str = "https://api.github.com/user" ;
2828static GITHUB_ACCEPT_TYPE : & str = "application/vnd.github+json" ;
2929
30+ type GithubClient =
31+ BasicClient < EndpointSet , EndpointNotSet , EndpointNotSet , EndpointNotSet , EndpointSet > ;
32+
3033#[ derive( Clone ) ]
3134pub struct GithubOauthService {
32- oauth_client : BasicClient ,
35+ oauth_client : GithubClient ,
36+ http_client : oauth2_reqwest:: Client ,
3337 session_key : Key ,
3438}
3539
@@ -43,18 +47,22 @@ impl GithubOauthService {
4347 /// Creates a new instance of `GithubOauthService`.
4448 /// Returns a `Result` containing the `GithubOauthService` instance or an `Error` if there was an error creating the service.
4549 pub fn new ( config : & Config ) -> anyhow:: Result < Self > {
46- let oauth_client = BasicClient :: new (
47- ClientId :: new ( config. github_client_id . clone ( ) ) ,
48- Some ( ClientSecret :: new ( config. github_client_secret . clone ( ) ) ) ,
49- AuthUrl :: from_url ( GITHUB_AUTH_URL . parse ( ) ?) ,
50- Some ( TokenUrl :: from_url ( GITHUB_TOKEN_URL . parse ( ) ?) ) ,
51- )
52- . set_redirect_uri ( RedirectUrl :: from_url ( config. authorize_url . parse ( ) ?) ) ;
50+ let oauth_client: GithubClient =
51+ BasicClient :: new ( ClientId :: new ( config. github_client_id . clone ( ) ) )
52+ . set_client_secret ( ClientSecret :: new ( config. github_client_secret . clone ( ) ) )
53+ . set_auth_uri ( AuthUrl :: from_url ( GITHUB_AUTH_URL . parse ( ) ?) )
54+ . set_token_uri ( TokenUrl :: from_url ( GITHUB_TOKEN_URL . parse ( ) ?) )
55+ . set_redirect_uri ( RedirectUrl :: from_url ( config. authorize_url . parse ( ) ?) ) ;
56+
57+ let http_client = oauth2_reqwest:: Client :: builder ( )
58+ . redirect ( oauth2_reqwest:: redirect:: Policy :: none ( ) )
59+ . build ( ) ?;
5360
5461 let session_key: Key = Key :: from ( & sha512 ( & config. session_key ) ) ;
5562
5663 Ok ( Self {
5764 oauth_client,
65+ http_client,
5866 session_key,
5967 } )
6068 }
@@ -111,7 +119,8 @@ pub(super) async fn login(
111119 let updated_jar = jar. add ( csrf_cookie) ;
112120
113121 // Return the updated cookie jar and a redirect response to the authorization URL
114- Ok ( ( updated_jar, Redirect :: to ( auth_url. to_string ( ) . as_str ( ) ) ) )
122+ let auth_url = auth_url. to_string ( ) ;
123+ Ok ( ( updated_jar, Redirect :: to ( & auth_url) ) )
115124}
116125
117126/// Handles the logout request.
@@ -174,7 +183,7 @@ pub(super) async fn authorize(
174183 let token = service
175184 . oauth_client
176185 . exchange_code ( AuthorizationCode :: new ( query. code . clone ( ) ) )
177- . request_async ( async_http_client )
186+ . request_async ( & service . http_client )
178187 . await
179188 . context ( "Invalid token provided" ) ?;
180189
@@ -198,21 +207,23 @@ pub(super) async fn authorize(
198207 return Err ( AppError :: Client ( anyhow ! ( "Invalid CSRF token" ) ) ) ;
199208 }
200209
201- // Create a new HTTP client
202- let client = reqwest:: Client :: new ( ) ;
203-
204210 // Fetch user data from the GitHub API
205- let user: GitHubUser = client
211+ let user_response = service
212+ . http_client
206213 . get ( GITHUB_USER_URL )
207214 . header ( ACCEPT , HeaderValue :: from_static ( GITHUB_ACCEPT_TYPE ) )
208215 . header ( USER_AGENT , HeaderValue :: from_static ( USER_AGENT_VALUE ) )
209216 . bearer_auth ( token. access_token ( ) . secret ( ) )
210217 . send ( )
211218 . await
212- . context ( "Failed to fetch user data" ) ?
213- . json ( )
214- . await
215- . context ( "Failed te deserialize GitHub user data" ) ?;
219+ . context ( "Failed to fetch user data" ) ?;
220+ let user: GitHubUser = serde_json:: from_slice (
221+ & user_response
222+ . bytes ( )
223+ . await
224+ . context ( "Failed to read GitHub user response body" ) ?,
225+ )
226+ . context ( "Failed te deserialize GitHub user data" ) ?;
216227
217228 // Serialize the user data as a string
218229 let session_cookie_value = serde_json:: to_string ( & user) ?;
0 commit comments