Skip to content

Commit

Permalink
Merge pull request #1480 from ahorek/disabling-starttls-auto
Browse files Browse the repository at this point in the history
SMTP: allow disabling starttls_auto since it's now true by default in Ruby 3
  • Loading branch information
mikel committed Nov 30, 2022
2 parents c38e092 + 8ede2ac commit 8e17809
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 49 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Compatibility:
* Multipart Content-Type no longer includes a needless charset param. (kirikak2)
* Replies prefix subject with "Re: " instead of "RE: " per 5322 3.6.5. (mashedcode)
* Gracefully handle multiple, possibly-invalid headers for what should be singular fields. (rosa)
* SMTP delivery with enable_tls/starttls/starttls_auto: false now disables these options, since starttls is now :auto by default in upstream net-smtp. (jeremy)

Features:
* Message#inspect_structure and PartsList#inspect_structure pretty-print the hierarchy of message parts. (TylerRick)
Expand Down
28 changes: 22 additions & 6 deletions lib/mail/network/delivery_methods/smtp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,33 @@ def start_smtp_session(&block)

def build_smtp_session
Net::SMTP.new(settings[:address], settings[:port]).tap do |smtp|
if settings[:tls] || settings[:ssl]
if smtp.respond_to?(:enable_tls)
tls = settings[:tls] || settings[:ssl]
if !tls.nil?
case tls
when true
smtp.enable_tls(ssl_context)
when false
smtp.disable_tls
else
raise ArgumentError, "Unrecognized :tls value #{settings[:tls].inspect}; expected true, false, or nil"
end
elsif settings[:enable_starttls]
if smtp.respond_to?(:enable_starttls)
elsif settings.include?(:enable_starttls) && !settings[:enable_starttls].nil?
case settings[:enable_starttls]
when true
smtp.enable_starttls(ssl_context)
when false
smtp.disable_starttls
else
raise ArgumentError, "Unrecognized :enable_starttls value #{settings[:enable_starttls].inspect}; expected true, false, or nil"
end
elsif settings[:enable_starttls_auto]
if smtp.respond_to?(:enable_starttls_auto)
elsif settings.include?(:enable_starttls_auto) && !settings[:enable_starttls_auto].nil?
case settings[:enable_starttls_auto]
when true
smtp.enable_starttls_auto(ssl_context)
when false
smtp.disable_starttls_auto
else
raise ArgumentError, "Unrecognized :enable_starttls_auto value #{settings[:enable_starttls_auto].inspect}; expected true, false, or nil"
end
end

Expand Down
45 changes: 26 additions & 19 deletions spec/mail/network/delivery_methods/smtp_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,10 @@
describe "SMTP Delivery Method" do

before(:each) do
MockSMTP.reset

# Reset all defaults back to original state
Mail.defaults do
delivery_method :smtp, { :address => "localhost",
:port => 25,
:domain => 'localhost.localdomain',
:user_name => nil,
:password => nil,
:authentication => nil,
:enable_starttls => nil,
:enable_starttls_auto => true,
:openssl_verify_mode => nil,
:tls => nil,
:ssl => nil,
:open_timeout => nil,
:read_timeout => nil
}
end
MockSMTP.clear_deliveries
Mail.defaults { delivery_method :smtp, {} }
end

describe "general usage" do
Expand Down Expand Up @@ -207,7 +193,7 @@ def redefine_verify_none(new_value)

message.deliver!

expect(MockSMTP.security).to eq :enable_starttls_auto
expect(MockSMTP.starttls).to eq :auto
end

it 'should allow forcing STARTTLS' do
Expand All @@ -228,7 +214,28 @@ def redefine_verify_none(new_value)

message.deliver!

expect(MockSMTP.security).to eq :enable_starttls
expect(MockSMTP.starttls).to eq :always
end

it 'should allow disabling automatic STARTTLS' do
message = Mail.new do
from 'mikel@test.lindsaar.net'
to 'ada@test.lindsaar.net'
subject 'Re: No way!'
body 'Yeah sure'
delivery_method :smtp, { :address => "localhost",
:port => 25,
:domain => 'localhost.localdomain',
:user_name => nil,
:password => nil,
:authentication => nil,
:enable_starttls => false }

end

message.deliver!

expect(MockSMTP.starttls).to eq false
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/mail/network_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class MyRetriever; def initialize(settings); end; end

before(:each) do
# Set the delivery method to test as the default
MockSMTP.clear_deliveries
MockSMTP.reset
end

it "should deliver a mail message" do
Expand Down
63 changes: 40 additions & 23 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,44 @@ def strip_heredoc(string)
string.gsub(/^[ \t]{#{indent}}/, '')
end

class Net::SMTP
class << self
alias unstubbed_new new
end

def self.new(*args)
MockSMTP.new
end
end

# Original mockup from ActionMailer
class MockSMTP
attr_accessor :open_timeout, :read_timeout

def self.reset
test = Net::SMTP.unstubbed_new('example.com')
@@tls = test.tls?
@@starttls = test.starttls?

@@deliveries = []
end

reset

def self.deliveries
@@deliveries
end

def self.security
@@security
def self.tls
@@tls
end

def self.starttls
@@starttls
end

def initialize
@@deliveries = []
@@security = nil
self.class.reset
end

def sendmail(mail, from, to)
Expand All @@ -104,37 +127,31 @@ def finish
return true
end

def self.clear_deliveries
@@deliveries = []
end

def self.clear_security
@@security = nil
end

def enable_tls(context)
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @@security && @@security != :enable_tls
@@security = :enable_tls
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @@starttls == :always
@@tls = true
context
end

def disable_tls
@@tls = false
end

def enable_starttls(context = nil)
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @@security == :enable_tls
@@security = :enable_starttls
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @@tls
@@starttls = :always
context
end

def enable_starttls_auto(context)
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @@security == :enable_tls
@@security = :enable_starttls_auto
raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @@tls
@@starttls = :auto
context
end
end

class Net::SMTP
def self.new(*args)
MockSMTP.new
def disable_starttls
@@starttls = false
end

end

class MockPopMail
Expand Down

0 comments on commit 8e17809

Please sign in to comment.