77 lines
2.1 KiB
Rust
77 lines
2.1 KiB
Rust
use axum::{
|
|
Extension,
|
|
extract,
|
|
http::StatusCode,
|
|
response::{Html, IntoResponse},
|
|
};
|
|
use cave::db::Database;
|
|
use crate::{
|
|
http_server::ServerState,
|
|
oauth,
|
|
};
|
|
|
|
async fn collect_token(
|
|
db: Database,
|
|
http_client: &reqwest::Client,
|
|
host: &str,
|
|
code: String,
|
|
) -> Result<(), String> {
|
|
// try a few registered apps until one works
|
|
for (client_id, client_secret) in db.get_apps(host).await
|
|
.map_err(|e| format!("{e}"))?
|
|
{
|
|
let app = oauth::Application {
|
|
client_id,
|
|
client_secret,
|
|
};
|
|
match app.obtain_token(http_client, host, code.clone()).await {
|
|
Ok(token) => {
|
|
db.add_token(host, &app.client_id, &token).await
|
|
.expect("db.add_token");
|
|
// success, done!
|
|
return Ok(());
|
|
}
|
|
Err(e) => {
|
|
tracing::error!("obtain_token for {}: {}", host, e);
|
|
// app seems blocked, remove
|
|
let _ = db.delete_app(host, &app.client_id).await;
|
|
}
|
|
}
|
|
}
|
|
|
|
Err(format!("No registered app found for instance {host}"))
|
|
}
|
|
|
|
#[derive(serde::Deserialize)]
|
|
pub struct OAuthCode {
|
|
code: String,
|
|
}
|
|
|
|
pub async fn get_token_collect(
|
|
Extension(ServerState { db, http_client, mut store, .. }): Extension<ServerState>,
|
|
extract::Path(host): extract::Path<String>,
|
|
extract::Query(OAuthCode { code }): extract::Query<OAuthCode>,
|
|
) -> impl IntoResponse {
|
|
match collect_token(db, &http_client, &host, code.clone()).await {
|
|
Ok(()) => {
|
|
let _ = store.save_host(&host).await;
|
|
(
|
|
StatusCode::SEE_OTHER,
|
|
[("location", "/token/thanks")]
|
|
).into_response()
|
|
}
|
|
Err(e) => {
|
|
tracing::error!("{}", e);
|
|
(
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
[("content-type", "text/plain")],
|
|
e
|
|
).into_response()
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn get_token_thanks() -> impl IntoResponse {
|
|
Html(&include_bytes!("../../templates/token_thanks.html")[..])
|
|
}
|