update: should fix the token getting too old

This commit is contained in:
maix0 2024-09-30 17:36:45 +02:00
parent 7a130a06ff
commit e198fb0ce0
2 changed files with 60 additions and 24 deletions

View file

@ -74,7 +74,7 @@ async fn tutors(config: AppState) {
.oauth .oauth
.do_request::<Vec<User42>>( .do_request::<Vec<User42>>(
"https://api.intra.42.fr/v2/groups/166/users", "https://api.intra.42.fr/v2/groups/166/users",
&json! ({ json! ({
"page[number]": page_nb, "page[number]": page_nb,
"page[size]": 100, "page[size]": 100,
}), }),
@ -120,7 +120,7 @@ async fn main() {
http.clone(), http.clone(),
unwrap_env!("CLIENT_ID"), unwrap_env!("CLIENT_ID"),
unwrap_env!("CLIENT_SECRET"), unwrap_env!("CLIENT_SECRET"),
"https://t.maix.me/auth/callback", "http://local.maix.me:9911/auth/callback",
) )
.await .await
.unwrap(); .unwrap();
@ -198,13 +198,17 @@ async fn oauth2_callback(
let res: User42 = state let res: User42 = state
.oauth .oauth
.do_request("https://api.intra.42.fr/v2/me", &(), Some(&token)) .do_request(
"https://api.intra.42.fr/v2/me",
&[] as &[(String, String); 0],
Some(&token),
)
.await .await
.wrap_err("Unable to get user self")?; .wrap_err("Unable to get user self")?;
let mut cookie = Cookie::new("token", res.id.to_string()); let mut cookie = Cookie::new("token", res.id.to_string());
cookie.set_same_site(SameSite::None); cookie.set_same_site(SameSite::None);
cookie.set_secure(true); cookie.set_secure(false);
cookie.set_path("/"); cookie.set_path("/");
// cookie.set_domain("localhost:3000"); // cookie.set_domain("localhost:3000");
// cookie.set_http_only(Some(false)); // cookie.set_http_only(Some(false));

View file

@ -3,13 +3,20 @@ use std::collections::HashMap;
use base64::Engine; use base64::Engine;
use color_eyre::eyre::{self, WrapErr}; use color_eyre::eyre::{self, WrapErr};
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
use tracing::info;
#[derive(Clone, Serialize, Deserialize)]
struct ApiError<'a> {
message: &'a str,
error: &'a str,
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct OauthClient { pub struct OauthClient {
client_id: String, client_id: String,
client_secret: String, client_secret: String,
redirect_uri: String, redirect_uri: String,
token: Token, token: std::sync::Arc<tokio::sync::Mutex<Token>>,
http: reqwest::Client, http: reqwest::Client,
} }
@ -71,7 +78,7 @@ impl OauthClient {
Ok(Self { Ok(Self {
client_id: uid.to_string(), client_id: uid.to_string(),
client_secret: secret.to_string(), client_secret: secret.to_string(),
token, token: std::sync::Arc::new(tokio::sync::Mutex::new(token)),
redirect_uri, redirect_uri,
http: client, http: client,
}) })
@ -125,24 +132,49 @@ impl OauthClient {
pub async fn do_request<R: DeserializeOwned>( pub async fn do_request<R: DeserializeOwned>(
&self, &self,
url: impl AsRef<str>, url: impl AsRef<str>,
qs: &impl Serialize, qs: impl Serialize,
token: Option<&impl IntoToken>, token: Option<&Token>,
) -> eyre::Result<R> { ) -> eyre::Result<R> {
let url = url.as_ref(); loop {
let token = token let url = url.as_ref();
.map(IntoToken::get_token) let is_apptoken = token.is_none();
.unwrap_or_else(|| self.token.get_token()); let s: String;
let res = self let token = match token {
.http Some(i) => i.get_token(),
.get(url) None => {
.query(qs) s = self.token.lock().await.get_token().to_string();
.bearer_auth(token) s.as_str()
.send() }
.await };
.wrap_err("Failed to send request")?; let res = self
let text = res.text().await.wrap_err("API reponse to text")?; .http
let json = serde_json::from_str(&text) .get(url)
.wrap_err_with(|| format!("API response to json: {text}"))?; .query(&qs)
Ok(json) .bearer_auth(token)
.send()
.await
.wrap_err("Failed to send request")?;
let text = res.text().await.wrap_err("API reponse to text")?;
if let Ok(err) = serde_json::from_str::<ApiError<'_>>(&text) {
if is_apptoken
&& err.message == "The access token expired"
&& err.error == "Not authorized"
{
info!("Refreshing token !");
let tok = Self::get_app_token(
self.http.clone(),
&self.client_id,
&self.client_secret,
)
.await?;
*self.token.lock().await = tok;
continue;
}
}
let json = serde_json::from_str(&text)
.wrap_err_with(|| format!("API response to json: {text}"))?;
break Ok(json);
}
} }
} }