use crate::{
handlers::{handle_torrent_add, handle_torrent_get, handle_torrent_remove},
putio,
transmission::{TransmissionConfig, TransmissionRequest, TransmissionResponse},
AppData,
};
use actix_web::{
get,
http::header::{ContentType, Header},
post, web, HttpRequest, HttpResponse,
};
use actix_web_httpauth::headers::authorization::{Authorization, Basic};
use anyhow::{Context, Result};
use log::info;
use serde_json::json;
#[post("/transmission/rpc")]
pub(crate) async fn rpc_post(
payload: web::Json<TransmissionRequest>,
req: HttpRequest,
app_data: web::Data<AppData>,
) -> HttpResponse {
let api_token = &app_data.api_token;
if validate_user(req).await.is_err() {
return HttpResponse::Conflict()
.content_type(ContentType::json())
.insert_header(("X-Transmission-Session-Id", "useless-session-id"))
.body("");
}
let arguments = match payload.method.as_str() {
"session-get" => Some(json!(TransmissionConfig {
download_dir: app_data.download_dir.clone(),
..Default::default()
})),
"torrent-get" => handle_torrent_get(api_token, &app_data).await,
"torrent-set" => None, "queue-move-top" => None,
"torrent-remove" => handle_torrent_remove(api_token, &payload).await,
"torrent-add" => {
let a = handle_torrent_add(api_token, &payload).await;
info!("Torrent added, informing download task.");
app_data.tx.send(true).await.unwrap();
a
}
_ => panic!("Unknwon method {}", payload.method),
};
let response = TransmissionResponse {
result: String::from("success"),
arguments,
};
HttpResponse::Ok()
.content_type(ContentType::json())
.json(response)
}
#[get("/transmission/rpc")]
async fn rpc_get(req: HttpRequest) -> HttpResponse {
if validate_user(req).await.is_err() {
return HttpResponse::Forbidden().body("forbidden");
}
HttpResponse::Conflict()
.content_type(ContentType::json())
.insert_header(("X-Transmission-Session-Id", "useless-session-id"))
.body("")
}
async fn validate_user(req: HttpRequest) -> Result<()> {
let auth = Authorization::<Basic>::parse(&req)?;
let api_key = auth.as_ref().password().context("No password given")?;
putio::account_info(api_key).await?;
Ok(())
}