mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-16 20:57:53 +08:00
add pgp support
This commit is contained in:
+37
-1
@@ -5,7 +5,9 @@ use pimalaya_email::backend::{ImapAuthConfig, ImapConfig};
|
||||
#[cfg(feature = "smtp-sender")]
|
||||
use pimalaya_email::sender::{SmtpAuthConfig, SmtpConfig};
|
||||
use pimalaya_email::{
|
||||
account::{OAuth2Config, OAuth2Method, OAuth2Scopes, PasswdConfig},
|
||||
account::{
|
||||
OAuth2Config, OAuth2Method, OAuth2Scopes, PasswdConfig, PgpConfig, PgpKey, PgpNativeConfig,
|
||||
},
|
||||
backend::{BackendConfig, MaildirConfig},
|
||||
email::{EmailHooks, EmailTextPlainFormat},
|
||||
folder::sync::FolderSyncStrategy,
|
||||
@@ -387,3 +389,37 @@ pub enum FolderSyncStrategyDef {
|
||||
#[serde(alias = "ignore")]
|
||||
Exclude(HashSet<String>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(remote = "PgpConfig", tag = "backend", rename_all = "kebab-case")]
|
||||
pub enum PgpConfigDef {
|
||||
#[default]
|
||||
None,
|
||||
#[serde(with = "PgpNativeConfigDef")]
|
||||
Native(PgpNativeConfig),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(remote = "PgpNativeConfig", rename_all = "kebab-case")]
|
||||
pub struct PgpNativeConfigDef {
|
||||
#[serde(default, with = "PgpKeyDef")]
|
||||
secret_key: PgpKey,
|
||||
#[serde(default, with = "SecretDef")]
|
||||
secret_key_passwd: Secret,
|
||||
#[serde(default, with = "PgpKeyDef")]
|
||||
public_key: PgpKey,
|
||||
#[serde(default = "PgpNativeConfig::default_wkd")]
|
||||
wkd: bool,
|
||||
#[serde(default = "PgpNativeConfig::default_key_servers")]
|
||||
key_servers: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(remote = "PgpKey", rename_all = "kebab-case")]
|
||||
pub enum PgpKeyDef {
|
||||
#[default]
|
||||
None,
|
||||
Path(PathBuf),
|
||||
#[serde(with = "EntryDef")]
|
||||
Keyring(Entry),
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use pimalaya_email::backend::ImapAuthConfig;
|
||||
#[cfg(feature = "smtp-sender")]
|
||||
use pimalaya_email::sender::SmtpAuthConfig;
|
||||
use pimalaya_email::{
|
||||
account::AccountConfig,
|
||||
account::{AccountConfig, PgpConfig},
|
||||
backend::BackendConfig,
|
||||
email::{EmailHooks, EmailTextPlainFormat},
|
||||
folder::sync::FolderSyncStrategy,
|
||||
@@ -90,6 +90,9 @@ pub struct DeserializedAccountConfig {
|
||||
pub backend: BackendConfig,
|
||||
#[serde(flatten, with = "SenderConfigDef")]
|
||||
pub sender: SenderConfig,
|
||||
|
||||
#[serde(default, with = "PgpConfigDef")]
|
||||
pub pgp: PgpConfig,
|
||||
}
|
||||
|
||||
impl DeserializedAccountConfig {
|
||||
@@ -155,46 +158,6 @@ impl DeserializedAccountConfig {
|
||||
.map(ToOwned::to_owned)
|
||||
.or_else(|| config.email_reading_headers.as_ref().map(ToOwned::to_owned)),
|
||||
email_reading_format: self.email_reading_format.clone(),
|
||||
email_reading_verify_cmd: self
|
||||
.email_reading_verify_cmd
|
||||
.as_ref()
|
||||
.map(ToOwned::to_owned)
|
||||
.or_else(|| {
|
||||
config
|
||||
.email_reading_verify_cmd
|
||||
.as_ref()
|
||||
.map(ToOwned::to_owned)
|
||||
}),
|
||||
email_reading_decrypt_cmd: self
|
||||
.email_reading_decrypt_cmd
|
||||
.as_ref()
|
||||
.map(ToOwned::to_owned)
|
||||
.or_else(|| {
|
||||
config
|
||||
.email_reading_decrypt_cmd
|
||||
.as_ref()
|
||||
.map(ToOwned::to_owned)
|
||||
}),
|
||||
email_writing_sign_cmd: self
|
||||
.email_writing_sign_cmd
|
||||
.as_ref()
|
||||
.map(ToOwned::to_owned)
|
||||
.or_else(|| {
|
||||
config
|
||||
.email_writing_sign_cmd
|
||||
.as_ref()
|
||||
.map(ToOwned::to_owned)
|
||||
}),
|
||||
email_writing_encrypt_cmd: self
|
||||
.email_writing_encrypt_cmd
|
||||
.as_ref()
|
||||
.map(ToOwned::to_owned)
|
||||
.or_else(|| {
|
||||
config
|
||||
.email_writing_encrypt_cmd
|
||||
.as_ref()
|
||||
.map(ToOwned::to_owned)
|
||||
}),
|
||||
email_writing_headers: self
|
||||
.email_writing_headers
|
||||
.as_ref()
|
||||
@@ -258,7 +221,7 @@ impl DeserializedAccountConfig {
|
||||
|
||||
sender
|
||||
},
|
||||
pgp: Default::default(),
|
||||
pgp: self.pgp.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,8 @@ pub async fn configure(config: &AccountConfig, reset: bool) -> Result<()> {
|
||||
warn!("{err}");
|
||||
}
|
||||
}
|
||||
|
||||
config.pgp.reset().await?;
|
||||
}
|
||||
|
||||
#[cfg(feature = "imap-backend")]
|
||||
@@ -102,6 +104,11 @@ pub async fn configure(config: &AccountConfig, reset: bool) -> Result<()> {
|
||||
}?;
|
||||
}
|
||||
|
||||
config
|
||||
.pgp
|
||||
.configure(&config.email, || prompt_passwd("PGP secret key password"))
|
||||
.await?;
|
||||
|
||||
println!(
|
||||
"Account successfully {}configured!",
|
||||
if reset { "re" } else { "" }
|
||||
|
||||
@@ -185,7 +185,7 @@ pub async fn mailto<P: Printer>(
|
||||
|
||||
let tpl = config
|
||||
.generate_tpl_interpreter()
|
||||
.show_only_headers(config.email_writing_headers())
|
||||
.with_show_only_headers(config.email_writing_headers())
|
||||
.interpret_msg_builder(builder)
|
||||
.await?;
|
||||
|
||||
@@ -235,9 +235,9 @@ pub async fn read<P: Printer>(
|
||||
let tpl: String = email
|
||||
.to_read_tpl(&config, |tpl| match text_mime {
|
||||
"html" => tpl
|
||||
.hide_all_headers()
|
||||
.filter_parts(FilterParts::Only("text/html".into())),
|
||||
_ => tpl.show_additional_headers(&headers),
|
||||
.with_hide_all_headers()
|
||||
.with_filter_parts(FilterParts::Only("text/html".into())),
|
||||
_ => tpl.with_show_additional_headers(&headers),
|
||||
})
|
||||
.await?
|
||||
.into();
|
||||
|
||||
@@ -3,7 +3,7 @@ use atty::Stream;
|
||||
use pimalaya_email::{
|
||||
account::AccountConfig,
|
||||
backend::Backend,
|
||||
email::{Flags, Message, Tpl},
|
||||
email::{Flag, Flags, Message, Tpl},
|
||||
sender::Sender,
|
||||
};
|
||||
use std::io::{stdin, BufRead};
|
||||
@@ -86,8 +86,8 @@ pub async fn save<P: Printer>(
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
})
|
||||
.some_pgp_sign_cmd(config.email_writing_sign_cmd.clone())
|
||||
.some_pgp_encrypt_cmd(config.email_writing_encrypt_cmd.clone())
|
||||
.with_pgp_encrypt(config.pgp.clone())
|
||||
.with_pgp_sign(config.pgp.clone())
|
||||
.compile()
|
||||
.await?
|
||||
.write_to_vec()?;
|
||||
@@ -103,9 +103,9 @@ pub async fn send<P: Printer>(
|
||||
printer: &mut P,
|
||||
backend: &mut dyn Backend,
|
||||
sender: &mut dyn Sender,
|
||||
folder: &str,
|
||||
tpl: String,
|
||||
) -> Result<()> {
|
||||
let folder = config.sent_folder_alias()?;
|
||||
let email = Tpl::from(if atty::is(Stream::Stdin) || printer.is_json() {
|
||||
tpl.replace("\r", "")
|
||||
} else {
|
||||
@@ -116,8 +116,8 @@ pub async fn send<P: Printer>(
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
})
|
||||
.some_pgp_sign_cmd(config.email_writing_sign_cmd.clone())
|
||||
.some_pgp_encrypt_cmd(config.email_writing_encrypt_cmd.clone())
|
||||
.with_pgp_encrypt(config.pgp.clone())
|
||||
.with_pgp_sign(config.pgp.clone())
|
||||
.compile()
|
||||
.await?
|
||||
.write_to_vec()?;
|
||||
@@ -125,7 +125,9 @@ pub async fn send<P: Printer>(
|
||||
sender.send(&email).await?;
|
||||
|
||||
if config.email_sending_save_copy {
|
||||
backend.add_email(folder, &email, &Flags::default()).await?;
|
||||
backend
|
||||
.add_email(&folder, &email, &Flags::from_iter([Flag::Seen]))
|
||||
.await?;
|
||||
}
|
||||
|
||||
printer.print("Template successfully sent!")?;
|
||||
|
||||
@@ -513,7 +513,6 @@ async fn main() -> Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
Some(tpl::args::Cmd::Send(tpl)) => {
|
||||
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
|
||||
let mut backend = backend_builder.clone().into_build().await?;
|
||||
let mut sender = sender_builder.build().await?;
|
||||
tpl::handlers::send(
|
||||
@@ -521,7 +520,6 @@ async fn main() -> Result<()> {
|
||||
&mut printer,
|
||||
backend.as_mut(),
|
||||
sender.as_mut(),
|
||||
&folder,
|
||||
tpl,
|
||||
)
|
||||
.await?;
|
||||
|
||||
+4
-4
@@ -76,8 +76,8 @@ pub async fn edit_tpl_with_editor<P: Printer>(
|
||||
Ok(PostEditChoice::Send) => {
|
||||
printer.print_log("Sending email…")?;
|
||||
let email = tpl
|
||||
.some_pgp_sign_cmd(config.email_writing_sign_cmd.clone())
|
||||
.some_pgp_encrypt_cmd(config.email_writing_encrypt_cmd.clone())
|
||||
.with_pgp_encrypt(config.pgp.clone())
|
||||
.with_pgp_sign(config.pgp.clone())
|
||||
.compile()
|
||||
.await?
|
||||
.write_to_vec()?;
|
||||
@@ -103,8 +103,8 @@ pub async fn edit_tpl_with_editor<P: Printer>(
|
||||
}
|
||||
Ok(PostEditChoice::RemoteDraft) => {
|
||||
let email = tpl
|
||||
.some_pgp_sign_cmd(config.email_writing_sign_cmd.clone())
|
||||
.some_pgp_encrypt_cmd(config.email_writing_encrypt_cmd.clone())
|
||||
.with_pgp_encrypt(config.pgp.clone())
|
||||
.with_pgp_sign(config.pgp.clone())
|
||||
.compile()
|
||||
.await?
|
||||
.write_to_vec()?;
|
||||
|
||||
Reference in New Issue
Block a user