pub mod results;
pub mod token;
use crate::token::{check_token_valide, generate_token};
use log::{self, debug, warn};
use reqwest::header::AUTHORIZATION;
use serde::Deserialize;
use std::fs;
use thiserror::Error;
#[derive(Clone, Debug, Default, Deserialize)]
pub struct Session {
client_id: String,
client_secret: String,
access_token: Option<String>,
}
#[derive(Error, Debug)]
pub enum SessionError {
#[error(transparent)]
IoError(#[from] std::io::Error),
#[error(transparent)]
ParseUrlError(#[from] url::ParseError),
#[error(transparent)]
ReqwestError(#[from] reqwest::Error),
#[error(transparent)]
JsonError(#[from] serde_json::Error),
#[error("Error: toml Error")]
TomlError(#[from] toml::de::Error),
#[error("Error: Not valide token Error")]
TokenNotValid,
#[error("Error: NoneError")]
NoneError,
#[error("Error: Server Unauthorized")]
UnauthorizedServerError,
#[error("Error: 403 Fobidden Access")]
Fobidden,
#[error("Error: 404 Page or resource is not found")]
NotFound,
}
impl Session {
pub fn new(path: &str) -> Result<Self, SessionError> {
let content = fs::read_to_string(path)?;
Ok(toml::from_str(&content)?)
}
pub fn get_client_id(&self) -> &str {
self.client_id.as_str()
}
pub fn get_client_secret(&self) -> &str {
self.client_secret.as_str()
}
pub fn get_access_token(&self) -> Option<String> {
self.access_token.clone()
}
pub fn set_access_token(&mut self, token: String) {
self.access_token = Some(token);
}
pub fn update_access_token(&mut self, token: String) {
self.access_token = Some(token);
}
}
impl Session {
pub async fn call(&mut self, uri: &str) -> Result<String, SessionError> {
if !(check_token_valide(self.get_access_token()).await?) {
let token = generate_token(self.clone()).await?;
self.set_access_token(token);
if let Ok(false) = check_token_valide(self.get_access_token()).await {
println!("Token is not valid, please check access token.");
return Err(SessionError::TokenNotValid);
}
}
let ac_token = self.get_access_token().unwrap_or_default();
let client = reqwest::Client::new();
let params = [
("grant_type", "client_credentials"),
("client_id", self.get_client_id()),
];
let response = client
.get(format!("https://api.intra.42.fr/{}", uri))
.header(AUTHORIZATION, format!("Bearer {}", ac_token))
.form(¶ms)
.send()
.await?;
match response.status() {
reqwest::StatusCode::OK => {
debug!("call(): reqwest OK");
}
reqwest::StatusCode::UNAUTHORIZED => {
warn!("call(): unauthorized");
return Err(SessionError::UnauthorizedServerError);
}
reqwest::StatusCode::FORBIDDEN => {
warn!("call(): 402 FORBIDDEN ACCESS");
return Err(SessionError::Fobidden);
}
reqwest::StatusCode::NOT_FOUND => {
warn!("404 NOT FOUND");
return Err(SessionError::NotFound);
}
_ => {
panic!("uh oh! something unexpected happened");
}
}
let tmp = response.text().await?;
Ok(tmp)
}
}