src/client/http_client.rs: try to login
use an environment var to store passphrase (PBS_PASSWORD)
This commit is contained in:
parent
33d64b81e0
commit
0dffe3f99a
@ -53,7 +53,7 @@ impl BackupRepository {
|
||||
|
||||
fn backup_directory(repo: &BackupRepository, body: Body, archive_name: &str) -> Result<(), Error> {
|
||||
|
||||
let client = HttpClient::new(&repo.host);
|
||||
let client = HttpClient::new(&repo.host, &repo.user);
|
||||
|
||||
let epoch = std::time::SystemTime::now().duration_since(
|
||||
std::time::SystemTime::UNIX_EPOCH)?.as_secs();
|
||||
@ -107,7 +107,7 @@ fn list_backups(
|
||||
let repo_url = tools::required_string_param(¶m, "repository")?;
|
||||
let repo = BackupRepository::parse(repo_url)?;
|
||||
|
||||
let client = HttpClient::new(&repo.host);
|
||||
let client = HttpClient::new(&repo.host, &repo.user);
|
||||
|
||||
let path = format!("api2/json/admin/datastore/{}/backups", repo.store);
|
||||
|
||||
|
@ -9,16 +9,19 @@ use http::Request;
|
||||
use futures::stream::Stream;
|
||||
|
||||
use serde_json::{Value};
|
||||
use url::percent_encoding::{percent_encode, DEFAULT_ENCODE_SET};
|
||||
|
||||
pub struct HttpClient {
|
||||
username: String,
|
||||
server: String,
|
||||
}
|
||||
|
||||
impl HttpClient {
|
||||
|
||||
pub fn new(server: &str) -> Self {
|
||||
pub fn new(server: &str, username: &str) -> Self {
|
||||
Self {
|
||||
server: String::from(server),
|
||||
username: String::from(username),
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,23 +80,64 @@ impl HttpClient {
|
||||
|
||||
let url: Uri = format!("https://{}:8007/{}", self.server, path).parse()?;
|
||||
|
||||
let ticket = self.login()?;
|
||||
|
||||
let enc_ticket = percent_encode(ticket.as_bytes(), DEFAULT_ENCODE_SET).to_string();
|
||||
|
||||
let request = Request::builder()
|
||||
.method("GET")
|
||||
.uri(url)
|
||||
.header("User-Agent", "proxmox-backup-client/1.0")
|
||||
.header("Cookie", format!("PBSAuthCookie={}", enc_ticket))
|
||||
.body(Body::empty())?;
|
||||
|
||||
Self::run_request(request)
|
||||
}
|
||||
|
||||
fn login(&self) -> Result<String, Error> {
|
||||
|
||||
let url: Uri = format!("https://{}:8007/{}", self.server, "/api2/json/access/ticket").parse()?;
|
||||
|
||||
let password = match std::env::var("PBS_PASSWORD") {
|
||||
Ok(p) => p,
|
||||
Err(err) => bail!("missing passphrase - {}", err),
|
||||
};
|
||||
|
||||
let query = url::form_urlencoded::Serializer::new(String::new())
|
||||
.append_pair("username", &self.username)
|
||||
.append_pair("password", &password)
|
||||
.finish();
|
||||
|
||||
let request = Request::builder()
|
||||
.method("POST")
|
||||
.uri(url)
|
||||
.header("User-Agent", "proxmox-backup-client/1.0")
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.body(Body::from(query))?;
|
||||
|
||||
let auth_res = Self::run_request(request)?;
|
||||
|
||||
let ticket = match auth_res["data"]["ticket"].as_str() {
|
||||
Some(t) => t,
|
||||
None => bail!("got unexpected respose for login request."),
|
||||
};
|
||||
|
||||
Ok(ticket.to_owned())
|
||||
}
|
||||
|
||||
pub fn upload(&self, content_type: &str, body: Body, path: &str) -> Result<Value, Error> {
|
||||
|
||||
let url: Uri = format!("https://{}:8007/{}", self.server, path).parse()?;
|
||||
|
||||
let ticket = self.login()?;
|
||||
|
||||
let enc_ticket = percent_encode(ticket.as_bytes(), DEFAULT_ENCODE_SET).to_string();
|
||||
|
||||
let request = Request::builder()
|
||||
.method("POST")
|
||||
.uri(url)
|
||||
.header("User-Agent", "proxmox-backup-client/1.0")
|
||||
.header("Cookie", format!("PBSAuthCookie={}", enc_ticket))
|
||||
.header("Content-Type", content_type)
|
||||
.body(body)?;
|
||||
|
||||
|
@ -70,7 +70,7 @@ impl Service for ApiService {
|
||||
match result {
|
||||
Ok(res) => Ok::<_, hyper::Error>(res),
|
||||
Err(err) => {
|
||||
if let Some(apierr) = err.downcast_ref::<HttpError>() {
|
||||
if let Some(apierr) = err.downcast_ref::<HttpError>() {
|
||||
let mut resp = Response::new(Body::from(apierr.message.clone()));
|
||||
*resp.status_mut() = apierr.code;
|
||||
Ok(resp)
|
||||
@ -458,6 +458,8 @@ pub fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> BoxFut {
|
||||
if let Some(_username) = rpcenv.get_user() {
|
||||
// fixme: check permissions
|
||||
} else {
|
||||
println!("Abort UNAUTHORIZED API REQUEST");
|
||||
|
||||
// always delay unauthorized calls by 3 seconds (from start of request)
|
||||
let resp = (formatter.format_error)(http_err!(UNAUTHORIZED, "permission check failed.".into()));
|
||||
let delayed_response = tokio::timer::Delay::new(delay_unauth_time)
|
||||
|
Loading…
Reference in New Issue
Block a user