src/bin/proxmox-backup-client.rs: implement login/logout
This commit is contained in:
parent
f71e8cc96f
commit
e240d8be0b
@ -389,6 +389,35 @@ fn forget_snapshots(
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn api_login(
|
||||||
|
param: Value,
|
||||||
|
_info: &ApiMethod,
|
||||||
|
_rpcenv: &mut dyn RpcEnvironment,
|
||||||
|
) -> Result<Value, Error> {
|
||||||
|
|
||||||
|
let repo = extract_repository_from_value(¶m)?;
|
||||||
|
|
||||||
|
let client = HttpClient::new(repo.host(), repo.user())?;
|
||||||
|
client.login().wait()?;
|
||||||
|
|
||||||
|
record_repository(&repo);
|
||||||
|
|
||||||
|
Ok(Value::Null)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn api_logout(
|
||||||
|
param: Value,
|
||||||
|
_info: &ApiMethod,
|
||||||
|
_rpcenv: &mut dyn RpcEnvironment,
|
||||||
|
) -> Result<Value, Error> {
|
||||||
|
|
||||||
|
let repo = extract_repository_from_value(¶m)?;
|
||||||
|
|
||||||
|
delete_ticket_info(repo.host(), repo.user())?;
|
||||||
|
|
||||||
|
Ok(Value::Null)
|
||||||
|
}
|
||||||
|
|
||||||
fn dump_catalog(
|
fn dump_catalog(
|
||||||
param: Value,
|
param: Value,
|
||||||
_info: &ApiMethod,
|
_info: &ApiMethod,
|
||||||
@ -1640,6 +1669,22 @@ We do not extraxt '.pxar' archives when writing to stdandard output.
|
|||||||
))
|
))
|
||||||
.completion_cb("repository", complete_repository);
|
.completion_cb("repository", complete_repository);
|
||||||
|
|
||||||
|
let login_cmd_def = CliCommand::new(
|
||||||
|
ApiMethod::new(
|
||||||
|
api_login,
|
||||||
|
ObjectSchema::new("Try to login. If successful, store ticket.")
|
||||||
|
.optional("repository", REPO_URL_SCHEMA.clone())
|
||||||
|
))
|
||||||
|
.completion_cb("repository", complete_repository);
|
||||||
|
|
||||||
|
let logout_cmd_def = CliCommand::new(
|
||||||
|
ApiMethod::new(
|
||||||
|
api_logout,
|
||||||
|
ObjectSchema::new("Logout (delete stored ticket).")
|
||||||
|
.optional("repository", REPO_URL_SCHEMA.clone())
|
||||||
|
))
|
||||||
|
.completion_cb("repository", complete_repository);
|
||||||
|
|
||||||
let cmd_def = CliCommandMap::new()
|
let cmd_def = CliCommandMap::new()
|
||||||
.insert("backup".to_owned(), backup_cmd_def.into())
|
.insert("backup".to_owned(), backup_cmd_def.into())
|
||||||
.insert("upload-log".to_owned(), upload_log_cmd_def.into())
|
.insert("upload-log".to_owned(), upload_log_cmd_def.into())
|
||||||
@ -1647,6 +1692,8 @@ We do not extraxt '.pxar' archives when writing to stdandard output.
|
|||||||
.insert("catalog".to_owned(), catalog_cmd_def.into())
|
.insert("catalog".to_owned(), catalog_cmd_def.into())
|
||||||
.insert("garbage-collect".to_owned(), garbage_collect_cmd_def.into())
|
.insert("garbage-collect".to_owned(), garbage_collect_cmd_def.into())
|
||||||
.insert("list".to_owned(), list_cmd_def.into())
|
.insert("list".to_owned(), list_cmd_def.into())
|
||||||
|
.insert("login".to_owned(), login_cmd_def.into())
|
||||||
|
.insert("logout".to_owned(), logout_cmd_def.into())
|
||||||
.insert("prune".to_owned(), prune_cmd_def.into())
|
.insert("prune".to_owned(), prune_cmd_def.into())
|
||||||
.insert("restore".to_owned(), restore_cmd_def.into())
|
.insert("restore".to_owned(), restore_cmd_def.into())
|
||||||
.insert("snapshots".to_owned(), snapshots_cmd_def.into())
|
.insert("snapshots".to_owned(), snapshots_cmd_def.into())
|
||||||
|
@ -34,7 +34,7 @@ use super::merge_known_chunks::*;
|
|||||||
use crate::backup::*;
|
use crate::backup::*;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct AuthInfo {
|
pub struct AuthInfo {
|
||||||
username: String,
|
username: String,
|
||||||
ticket: String,
|
ticket: String,
|
||||||
token: String,
|
token: String,
|
||||||
@ -47,6 +47,27 @@ pub struct HttpClient {
|
|||||||
auth: BroadcastFuture<AuthInfo>,
|
auth: BroadcastFuture<AuthInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete stored ticket data (logout)
|
||||||
|
pub fn delete_ticket_info(server: &str, username: &str) -> Result<(), Error> {
|
||||||
|
|
||||||
|
let base = BaseDirectories::with_prefix("proxmox-backup")?;
|
||||||
|
|
||||||
|
// usually /run/user/<uid>/...
|
||||||
|
let path = base.place_runtime_file("tickets")?;
|
||||||
|
|
||||||
|
let mode = nix::sys::stat::Mode::from_bits_truncate(0o0600);
|
||||||
|
|
||||||
|
let mut data = file_get_json(&path, Some(json!({})))?;
|
||||||
|
|
||||||
|
if let Some(map) = data[server].as_object_mut() {
|
||||||
|
map.remove(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_set_contents(path, data.to_string().as_bytes(), Some(mode))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn store_ticket_info(server: &str, username: &str, ticket: &str, token: &str) -> Result<(), Error> {
|
fn store_ticket_info(server: &str, username: &str, ticket: &str, token: &str) -> Result<(), Error> {
|
||||||
|
|
||||||
let base = BaseDirectories::with_prefix("proxmox-backup")?;
|
let base = BaseDirectories::with_prefix("proxmox-backup")?;
|
||||||
@ -144,6 +165,14 @@ impl HttpClient {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Login future
|
||||||
|
///
|
||||||
|
/// Login is done on demand, so this is onyl required if you need
|
||||||
|
/// access to authentication data in 'AuthInfo'.
|
||||||
|
pub fn login(&self) -> impl Future<Item=AuthInfo, Error=Error> {
|
||||||
|
self.auth.listen()
|
||||||
|
}
|
||||||
|
|
||||||
fn get_password(_username: &str) -> Result<String, Error> {
|
fn get_password(_username: &str) -> Result<String, Error> {
|
||||||
use std::env::VarError::*;
|
use std::env::VarError::*;
|
||||||
match std::env::var("PBS_PASSWORD") {
|
match std::env::var("PBS_PASSWORD") {
|
||||||
|
Loading…
Reference in New Issue
Block a user