update: should fix the token getting too old
This commit is contained in:
parent
7a130a06ff
commit
e198fb0ce0
2 changed files with 60 additions and 24 deletions
12
src/main.rs
12
src/main.rs
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue