Added SMTP_PORT configuration option.
This commit is contained in:
parent
d2911aa349
commit
118923e885
|
@ -14,6 +14,7 @@ jsonrpc-core = "8.0.1"
|
|||
lazy_static = "1.0.0"
|
||||
lettre = "0.8"
|
||||
lettre_email = "0.8"
|
||||
native-tls = "0.1.5"
|
||||
reqwest = "0.8.5"
|
||||
serde = "1.0.36"
|
||||
serde_derive = "1.0.36"
|
||||
|
|
|
@ -70,6 +70,13 @@ Add a comma-separated list of email address to the "VALIDATORS" config
|
|||
option in your .env file. These addresses will be sent emails when `poagov`
|
||||
encounters governance events on the POA blockchain.
|
||||
|
||||
*Note* `poagov` forces SMTP email notifcations to be sent over an encrypted
|
||||
channel, if your SMTP Host does not support TLS or STARTTLS, `poagov` will
|
||||
panic. You may notice that we default `SMTP_PORT` to port 587 for STARTTLS,
|
||||
but you may use port 465 for TLS, or any other port that your outgoing
|
||||
email server is lisening for secure connections. If you require unencrypted
|
||||
SMTP, submit an issue and I can add it.
|
||||
|
||||
# An Explained Example
|
||||
|
||||
$ ./target/release/poagov --sokol --earliest -kt --email
|
||||
|
|
|
@ -8,6 +8,7 @@ SEND_PUSH_NOTIFICATIONS=false
|
|||
|
||||
# Email configuration.
|
||||
SMTP_HOST_DOMAIN=
|
||||
SMTP_PORT=587
|
||||
SMTP_USERNAME=
|
||||
SMTP_PASSWORD=
|
||||
OUTGOING_EMAIL_ADDRESS=
|
||||
|
|
|
@ -159,6 +159,7 @@ pub struct Config {
|
|||
pub validators: Vec<Validator>,
|
||||
pub avg_block_time: Duration,
|
||||
pub smtp_host_domain: String,
|
||||
pub smtp_port: u16,
|
||||
pub smtp_username: String,
|
||||
pub smtp_password: String,
|
||||
pub outgoing_email: String
|
||||
|
@ -263,17 +264,16 @@ impl Config {
|
|||
};
|
||||
|
||||
let smtp_host_domain = env::var("SMTP_HOST_DOMAIN").unwrap();
|
||||
let smtp_port = env::var("SMTP_PORT").unwrap().parse().unwrap();
|
||||
let smtp_username = env::var("SMTP_USERNAME").unwrap();
|
||||
let smtp_password = env::var("SMTP_PASSWORD").unwrap();
|
||||
let outgoing_email = env::var("OUTGOING_EMAIL_ADDRESS").unwrap();
|
||||
|
||||
Config {
|
||||
network, endpoint, contracts, start_block,
|
||||
send_email_notifications,
|
||||
send_push_notifications,
|
||||
validators, avg_block_time,
|
||||
smtp_host_domain, smtp_username,
|
||||
smtp_password, outgoing_email
|
||||
send_email_notifications, send_push_notifications,
|
||||
validators, avg_block_time, smtp_host_domain,
|
||||
smtp_port, smtp_username, smtp_password, outgoing_email
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,12 @@ lazy_static! {
|
|||
}
|
||||
|
||||
pub fn log_notification(notif: &Notification) {
|
||||
info!(LOGGER, "notification"; "data" => format!("{:#?}", notif));
|
||||
let notif_data = match *notif {
|
||||
Notification::Keys(ref inner) => format!("{:#?}", inner),
|
||||
Notification::Threshold(ref inner) => format!("{:#?}", inner),
|
||||
Notification::Proxy(ref inner) => format!("{:#?}", inner)
|
||||
};
|
||||
info!(LOGGER, "notification"; "data" => notif_data);
|
||||
}
|
||||
|
||||
pub fn log_email_sent(email: &str) {
|
||||
|
|
|
@ -8,6 +8,7 @@ extern crate jsonrpc_core;
|
|||
#[macro_use] extern crate lazy_static;
|
||||
extern crate lettre;
|
||||
extern crate lettre_email;
|
||||
extern crate native_tls;
|
||||
extern crate reqwest;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
use ethereum_types::Address;
|
||||
use lettre::{EmailTransport, SmtpTransport};
|
||||
use lettre::smtp::{self, ConnectionReuseParameters};
|
||||
use lettre::smtp::{ClientSecurity, ConnectionReuseParameters, SmtpTransportBuilder};
|
||||
use lettre::smtp::authentication::{Credentials, Mechanism};
|
||||
use lettre_email::{self, Email, EmailBuilder};
|
||||
use lettre::smtp::client::net::{ClientTlsParameters, DEFAULT_TLS_PROTOCOLS};
|
||||
use lettre::smtp::error::Error as BuildSmtpError;
|
||||
use lettre_email::{Email, EmailBuilder};
|
||||
use lettre_email::error::Error as BuildEmailError;
|
||||
use native_tls::TlsConnector;
|
||||
|
||||
use config::{Config, ContractType, Network, Validator};
|
||||
use logging::{log_email_failed, log_email_sent, log_notification};
|
||||
use rpc::{BallotCreatedLog, BallotType, KeyType, VotingData};
|
||||
|
||||
type BuildEmailResult = Result<Email, lettre_email::error::Error>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Notification {
|
||||
Keys(KeysNotification),
|
||||
|
@ -119,23 +121,35 @@ pub struct Notifier<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Notifier<'a> {
|
||||
pub fn new(config: &'a Config) -> Result<Self, smtp::error::Error> {
|
||||
let mailer = if config.send_email_notifications {
|
||||
let creds = Credentials::new(
|
||||
pub fn new(config: &'a Config) -> Result<Self, BuildSmtpError> {
|
||||
let mut notifier = Notifier { config, mailer: None };
|
||||
|
||||
if config.send_email_notifications {
|
||||
let smtp_addr = (config.smtp_host_domain.as_str(), config.smtp_port);
|
||||
|
||||
let smtp_tls = {
|
||||
let mut tls_builder = TlsConnector::builder().unwrap();
|
||||
tls_builder.supported_protocols(DEFAULT_TLS_PROTOCOLS).unwrap();
|
||||
let tls = tls_builder.build().unwrap();
|
||||
let tls_params = ClientTlsParameters::new(config.smtp_host_domain.clone(), tls);
|
||||
ClientSecurity::Required(tls_params)
|
||||
};
|
||||
|
||||
let smtp_creds = Credentials::new(
|
||||
config.smtp_username.clone(),
|
||||
config.smtp_password.clone()
|
||||
);
|
||||
let mailer = SmtpTransport::simple_builder(&config.smtp_host_domain)?
|
||||
|
||||
let mailer = SmtpTransportBuilder::new(smtp_addr, smtp_tls)?
|
||||
.connection_reuse(ConnectionReuseParameters::ReuseUnlimited)
|
||||
.authentication_mechanism(Mechanism::Plain)
|
||||
.credentials(creds)
|
||||
.credentials(smtp_creds)
|
||||
.build();
|
||||
Some(mailer)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Notifier { config, mailer })
|
||||
notifier.mailer = Some(mailer);
|
||||
}
|
||||
|
||||
Ok(notifier)
|
||||
}
|
||||
|
||||
pub fn build_notification(&self, log: &BallotCreatedLog, voting_data: &VotingData) -> Notification {
|
||||
|
@ -161,7 +175,7 @@ impl<'a> Notifier<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_email(&self, validator: &Validator, notif: &Notification) -> BuildEmailResult {
|
||||
fn build_email(&self, validator: &Validator, notif: &Notification) -> Result<Email, BuildEmailError> {
|
||||
let body = match *notif {
|
||||
Notification::Keys(ref inner) => format!("{:#?}\n", inner),
|
||||
Notification::Threshold(ref inner) => format!("{:#?}\n", inner),
|
||||
|
|
Loading…
Reference in New Issue