Skip to content

Commit

Permalink
use a single encryption option to specify STARTTLS or SSL/TLS
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian D. Burns committed Mar 26, 2013
1 parent c363c5f commit d433372
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 75 deletions.
138 changes: 83 additions & 55 deletions lib/backup/notifier/mail.rb
Expand Up @@ -10,106 +10,131 @@ class Mail < Base

##
# Mail delivery method to be used by the Mail gem.
#
# Supported methods:
#
# `:smtp` [::Mail::SMTP] (default)
# : Settings used only by this method:
# : `address`, `port`, `domain`, `user_name`, `password`
# : `authentication`, `enable_starttls_auto`, `openssl_verify_mode`
# [:smtp - ::Mail::SMTP (default)]
# Settings used by this method:
# {#address}, {#port}, {#domain}, {#user_name}, {#password},
# {#authentication}, {#encryption}, {#openssl_verify_mode}
#
# `:sendmail` [::Mail::Sendmail]
# : Settings used only by this method:
# : `sendmail`, `sendmail_args`
# [:sendmail - ::Mail::Sendmail]
# Settings used by this method:
# {#sendmail}, {#sendmail_args}
#
# `:exim` [::Mail::Exim]
# : Settings used only by this method:
# : `exim`, `exim_args`
# [:exim - ::Mail::Exim]
# Settings used by this method:
# {#exim}, {#exim_args}
#
# `:file` [::Mail::FileDelivery]
# : Settings used only by this method:
# : `mail_folder`
# [:file - ::Mail::FileDelivery]
# Settings used by this method:
# {#mail_folder}
#
attr_accessor :delivery_method

##
# Sender and Receiver email addresses
# Examples:
# sender - my.email.address@gmail.com
# receiver - your.email.address@gmail.com
attr_accessor :from, :to
# Sender Email Address
attr_accessor :from

##
# Receiver Email Address
attr_accessor :to

##
# The address to use
# Example: smtp.gmail.com
# SMTP Server Address
attr_accessor :address

##
# The port to connect to
# Example: 587
# SMTP Server Port
attr_accessor :port

##
# Your domain (if applicable)
# Example: mydomain.com
attr_accessor :domain

##
# Username and Password (sender email's credentials)
# Examples:
# user_name - meskyanichi
# password - my_secret_password
attr_accessor :user_name, :password
# SMTP Server Username (sender email's credentials)
attr_accessor :user_name

##
# SMTP Server Password (sender email's credentials)
attr_accessor :password

##
# Authentication type
# Example: plain
#
# Acceptable values: +:plain+, +:login+, +:cram_md5+
attr_accessor :authentication

##
# Automatically set TLS
# Example: true
attr_accessor :enable_starttls_auto
# Set the method of encryption to be used for the +SMTP+ connection.
#
# [:none (default)]
# No encryption will be used.
#
# [:starttls]
# Use +STARTTLS+ to upgrade the connection to a +SSL/TLS+ connection.
#
# [:tls or :ssl]
# Use a +SSL/TLS+ connection.
attr_accessor :encryption

attr_deprecate :enable_starttls_auto, :version => '3.2.0',
:message => "Use #encryption instead.\n" +
'e.g. mail.encryption = :starttls',
:action => lambda {|klass, val|
klass.encryption = val ? :starttls : :none
}

##
# OpenSSL Verify Mode
# Example: none - Only use this option for a self-signed and/or wildcard certificate
#
# Valid modes: +:none+, +:peer+, +:client_once+, +:fail_if_no_peer_cert+
# See +OpenSSL::SSL+ for details.
#
# Use +:none+ for a self-signed and/or wildcard certificate
attr_accessor :openssl_verify_mode

##
# Automatically set SSL
# Example: true
attr_accessor :ssl

##
# Path to `sendmail` (if needed)
#
# When using the `:sendmail` `delivery_method` option,
# this may be used to specify the absolute path to `sendmail` (if needed)
# this may be used to specify the absolute path to `sendmail`
#
# Example: '/usr/sbin/sendmail'
attr_accessor :sendmail

##
# Optional arguments to pass to `sendmail`
#
# Note that this will override the defaults set by the Mail gem (currently: '-i -t')
# So, if set here, be sure to set all the arguments you require.
#
# Example: '-i -t -X/tmp/traffic.log'
attr_accessor :sendmail_args

##
# Path to `exim` (if needed)
#
# When using the `:exim` `delivery_method` option,
# this may be used to specify the absolute path to `exim` (if needed)
# this may be used to specify the absolute path to `exim`
#
# Example: '/usr/sbin/exim'
attr_accessor :exim

##
# Optional arguments to pass to `exim`
#
# Note that this will override the defaults set by the Mail gem (currently: '-i -t')
# So, if set here, be sure to set all the arguments you require.
#
# Example: '-i -t -X/tmp/traffic.log'
attr_accessor :exim_args

##
# Folder where mail will be kept when using the `:file` `delivery_method` option.
#
# Default location is '$HOME/Backup/emails'
# Example: '/tmp/test-mails'
attr_accessor :mail_folder

def initialize(model, &block)
Expand All @@ -122,22 +147,23 @@ def initialize(model, &block)

##
# Notify the user of the backup operation results.
#
# `status` indicates one of the following:
#
# `:success`
# : The backup completed successfully.
# : Notification will be sent if `on_success` was set to `true`
# [:success]
# The backup completed successfully.
# Notification will be sent if `on_success` was set to `true`
#
# `:warning`
# : The backup completed successfully, but warnings were logged
# : Notification will be sent, including a copy of the current
# : backup log, if `on_warning` was set to `true`
# [:warning]
# The backup completed successfully, but warnings were logged
# Notification will be sent, including a copy of the current
# backup log, if `on_warning` was set to `true`
#
# `:failure`
# : The backup operation failed.
# : Notification will be sent, including the Exception which caused
# : the failure, the Exception's backtrace, a copy of the current
# : backup log and other information if `on_failure` was set to `true`
# [:failure]
# The backup operation failed.
# Notification will be sent, including the Exception which caused
# the failure, the Exception's backtrace, a copy of the current
# backup log and other information if `on_failure` was set to `true`
#
def notify!(status)
name, send_log =
Expand Down Expand Up @@ -178,9 +204,11 @@ def new_email
:user_name => @user_name,
:password => @password,
:authentication => @authentication,
:enable_starttls_auto => @enable_starttls_auto,
:enable_starttls_auto => @encryption == :starttls,
:openssl_verify_mode => @openssl_verify_mode,
:ssl => @ssl }
:ssl => @encryption == :ssl,
:tls => @encryption == :tls
}
when 'sendmail'
opts = {}
opts.merge!(:location => File.expand_path(@sendmail)) if @sendmail
Expand Down
92 changes: 73 additions & 19 deletions spec/notifier/mail_spec.rb
Expand Up @@ -15,7 +15,7 @@
mail.user_name = 'user'
mail.password = 'secret'
mail.authentication = 'plain'
mail.enable_starttls_auto = true
mail.encryption = :starttls

mail.sendmail = '/path/to/sendmail'
mail.sendmail_args = '-i -t -X/tmp/traffic.log'
Expand All @@ -26,23 +26,9 @@
end
end

it 'should be a subclass of Notifier::Base' do
Backup::Notifier::Mail.
superclass.should == Backup::Notifier::Base
end

describe '#initialize' do
after { Backup::Notifier::Mail.clear_defaults! }

it 'should load pre-configured defaults through Base' do
Backup::Notifier::Mail.any_instance.expects(:load_defaults!)
notifier
end

it 'should pass the model reference to Base' do
notifier.instance_variable_get(:@model).should == model
end

context 'when no pre-configured defaults have been set' do
it 'should use the values given' do
notifier.delivery_method.should == :smtp
Expand All @@ -54,7 +40,7 @@
notifier.user_name.should == 'user'
notifier.password.should == 'secret'
notifier.authentication.should == 'plain'
notifier.enable_starttls_auto.should == true
notifier.encryption.should == :starttls

notifier.sendmail.should == '/path/to/sendmail'
notifier.sendmail_args.should == '-i -t -X/tmp/traffic.log'
Expand All @@ -79,7 +65,7 @@
notifier.user_name.should be_nil
notifier.password.should be_nil
notifier.authentication.should be_nil
notifier.enable_starttls_auto.should be_nil
notifier.encryption.should be_nil

notifier.sendmail.should be_nil
notifier.sendmail_args.should be_nil
Expand Down Expand Up @@ -115,7 +101,7 @@
notifier.user_name.should be_nil
notifier.password.should be_nil
notifier.authentication.should be_nil
notifier.enable_starttls_auto.should be_nil
notifier.encryption.should be_nil

notifier.sendmail.should be_nil
notifier.sendmail_args.should be_nil
Expand Down Expand Up @@ -247,8 +233,26 @@
settings[:user_name].should == 'user'
settings[:password].should == 'secret'
settings[:authentication].should == 'plain'
settings[:enable_starttls_auto].should == true
settings[:enable_starttls_auto].should be(true)
settings[:openssl_verify_mode].should be_nil
settings[:ssl].should be(false)
settings[:tls].should be(false)
end

it 'should properly set other encryption settings' do
notifier.encryption = :ssl
email = notifier.send(:new_email)
settings = email.delivery_method.settings
settings[:enable_starttls_auto].should be(false)
settings[:ssl].should be(true)
settings[:tls].should be(false)

notifier.encryption = :tls
email = notifier.send(:new_email)
settings = email.delivery_method.settings
settings[:enable_starttls_auto].should be(false)
settings[:ssl].should be(false)
settings[:tls].should be(true)
end
end

Expand Down Expand Up @@ -309,4 +313,54 @@
end
end # describe '#new_email'

describe 'deprecations' do

describe '#enable_starttls_auto' do
before do
Backup::Logger.expects(:warn).with {|err|
err.should be_an_instance_of Backup::Errors::ConfigurationError
err.message.should match(
/Use #encryption instead/
)
}
end

context 'when set directly' do
it 'warns and transfers true value' do
notifier = Backup::Notifier::Mail.new(model) do |mail|
mail.enable_starttls_auto = true
end
notifier.encryption.should == :starttls
end

it 'warns and transfers false value' do
notifier = Backup::Notifier::Mail.new(model) do |mail|
mail.enable_starttls_auto = false
end
notifier.encryption.should == :none
end
end

context 'when set as a default' do
after { Backup::Notifier::Mail.clear_defaults! }

it 'warns and transfers true value' do
Backup::Notifier::Mail.defaults do |mail|
mail.enable_starttls_auto = true
end
notifier = Backup::Notifier::Mail.new(model)
notifier.encryption.should == :starttls
end

it 'warns and transfers false value' do
Backup::Notifier::Mail.defaults do |mail|
mail.enable_starttls_auto = false
end
notifier = Backup::Notifier::Mail.new(model)
notifier.encryption.should == :none
end
end
end # describe '#enable_starttls_auto'

end # describe 'deprecations'
end
2 changes: 1 addition & 1 deletion templates/cli/notifier/mail
Expand Up @@ -18,5 +18,5 @@
mail.user_name = "sender@email.com"
mail.password = "my_password"
mail.authentication = "plain"
mail.enable_starttls_auto = true
mail.encryption = :starttls
end

0 comments on commit d433372

Please sign in to comment.