melib: add server_password_command to jmap
Move the handling of either `server_password` or `server_password_command` from the imap backend to the common `AccountSettings` struct and add it for jmap as well.jmap-bearer-token
parent
f9ac9b607a
commit
12cb717bda
|
@ -1259,33 +1259,15 @@ impl ImapType {
|
|||
let server_hostname = get_conf_val!(s["server_hostname"])?;
|
||||
let server_username = get_conf_val!(s["server_username"])?;
|
||||
let use_oauth2: bool = get_conf_val!(s["use_oauth2"], false)?;
|
||||
let server_password = if !s.extra.contains_key("server_password_command") {
|
||||
if use_oauth2 {
|
||||
return Err(Error::new(format!(
|
||||
"({}) `use_oauth2` use requires `server_password_command` set with a command that returns an OAUTH2 token. Consult documentation for guidance.",
|
||||
s.name,
|
||||
)));
|
||||
}
|
||||
get_conf_val!(s["server_password"])?.to_string()
|
||||
} else {
|
||||
let invocation = get_conf_val!(s["server_password_command"])?;
|
||||
let output = std::process::Command::new("sh")
|
||||
.args(&["-c", invocation])
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()?;
|
||||
if !output.status.success() {
|
||||
return Err(Error::new(format!(
|
||||
"({}) server_password_command `{}` returned {}: {}",
|
||||
s.name,
|
||||
get_conf_val!(s["server_password_command"])?,
|
||||
output.status,
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
)));
|
||||
}
|
||||
std::str::from_utf8(&output.stdout)?.trim_end().to_string()
|
||||
};
|
||||
|
||||
if use_oauth2 && !s.extra.contains_key("server_password_command") {
|
||||
return Err(Error::new(format!(
|
||||
"({}) `use_oauth2` use requires `server_password_command` set with a command that returns an OAUTH2 token. Consult documentation for guidance.",
|
||||
s.name,
|
||||
)));
|
||||
}
|
||||
|
||||
let server_password = s.server_password()?;
|
||||
let server_port = get_conf_val!(s["server_port"], 143)?;
|
||||
let use_tls = get_conf_val!(s["use_tls"], true)?;
|
||||
let use_starttls = use_tls && get_conf_val!(s["use_starttls"], server_port != 993)?;
|
||||
|
|
|
@ -126,7 +126,7 @@ impl JmapServerConf {
|
|||
Ok(JmapServerConf {
|
||||
server_url: get_conf_val!(s["server_url"])?.to_string(),
|
||||
server_username: get_conf_val!(s["server_username"])?.to_string(),
|
||||
server_password: get_conf_val!(s["server_password"])?.to_string(),
|
||||
server_password: s.server_password()?,
|
||||
danger_accept_invalid_certs: get_conf_val!(s["danger_accept_invalid_certs"], false)?,
|
||||
timeout: get_conf_val!(s["timeout"], 16_u64).map(|t| {
|
||||
if t == 0 {
|
||||
|
@ -924,7 +924,10 @@ impl JmapType {
|
|||
}
|
||||
get_conf_val!(s["server_url"])?;
|
||||
get_conf_val!(s["server_username"])?;
|
||||
get_conf_val!(s["server_password"])?;
|
||||
|
||||
// either of these two needed
|
||||
get_conf_val!(s["server_password"]).or(get_conf_val!(s["server_password_command"]))?;
|
||||
|
||||
get_conf_val!(s["danger_accept_invalid_certs"], false)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
//! Basic mail account configuration to use with [`backends`](./backends/index.html)
|
||||
use crate::backends::SpecialUsageMailbox;
|
||||
use crate::error::{Error, Result};
|
||||
pub use crate::{SortField, SortOrder};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::collections::HashMap;
|
||||
|
@ -79,6 +80,36 @@ impl AccountSettings {
|
|||
pub fn vcard_folder(&self) -> Option<&str> {
|
||||
self.extra.get("vcard_folder").map(String::as_str)
|
||||
}
|
||||
|
||||
/// Get the server password, either directly from the `server_password`
|
||||
/// settings value, or by running the `server_password_command` and reading
|
||||
/// the output.
|
||||
pub fn server_password(&self) -> Result<String> {
|
||||
if let Some(cmd) = self.extra.get("server_password_command") {
|
||||
let output = std::process::Command::new("sh")
|
||||
.args(&["-c", cmd])
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.output()?;
|
||||
|
||||
if output.status.success() {
|
||||
Ok(std::str::from_utf8(&output.stdout)?.trim_end().to_string())
|
||||
} else {
|
||||
Err(Error::new(format!(
|
||||
"({}) server_password_command `{}` returned {}: {}",
|
||||
self.name,
|
||||
cmd,
|
||||
output.status,
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
)))
|
||||
}
|
||||
} else if let Some(pass) = self.extra.get("server_password") {
|
||||
Ok(pass.to_owned())
|
||||
} else {
|
||||
Err(Error::new(format!("Configuration error: connection requires either server_password or server_password_command")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
|
Loading…
Reference in New Issue