caveman/gatherer/src/oauth.rs
2023-08-08 22:04:29 +02:00

86 lines
2.3 KiB
Rust

#[derive(serde::Serialize)]
struct AppRegistration {
client_name: String,
redirect_uris: String,
scopes: String,
website: String,
}
#[derive(serde::Serialize)]
struct TokenRequest {
grant_type: String,
scope: String,
client_id: String,
client_secret: String,
redirect_uri: String,
code: String,
}
#[derive(serde::Deserialize)]
struct TokenResult {
pub access_token: String,
}
#[derive(serde::Deserialize)]
pub struct Application {
pub client_id: String,
pub client_secret: String,
}
const SCOPES: &str = "read:statuses";
impl Application {
pub async fn register(host: &str) -> Result<Self, reqwest::Error> {
let url = format!("https://{}/api/v1/apps", host);
let form = AppRegistration {
client_name: "#FediBuzz".to_string(),
website: "https://fedi.buzz/".to_string(),
redirect_uris: Self::generate_redirect_url(host),
scopes: SCOPES.to_string(),
};
let client = reqwest::Client::new();
let res = client.post(url)
.form(&form)
.send()
.await?
.json()
.await?;
Ok(res)
}
pub fn generate_redirect_url(host: &str) -> String {
format!("https://fedi.buzz/token/collect/{}", host)
}
pub fn generate_auth_url(&self, host: &str) -> String {
format!(
"https://{}/oauth/authorize?client_id={}&scope={}&response_type=code&redirect_uri={}",
host,
urlencoding::encode(&self.client_id),
urlencoding::encode(SCOPES),
urlencoding::encode(&Self::generate_redirect_url(host)),
)
}
pub async fn obtain_token(&self, host: &str, code: String) -> Result<String, reqwest::Error> {
let url = format!("https://{}/oauth/token", host);
let form = TokenRequest {
grant_type: "authorization_code".to_string(),
scope: SCOPES.to_string(),
client_id: self.client_id.clone(),
client_secret: self.client_secret.clone(),
redirect_uri: Self::generate_redirect_url(host),
code,
};
let client = reqwest::Client::new();
let res: TokenResult = client.post(url)
.form(&form)
.send()
.await?
.json()
.await?;
Ok(res.access_token)
}
}