86 lines
2.3 KiB
Rust
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)
|
|
}
|
|
}
|