1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
# frozen_string_literal: true
require 'mail/check_delivery_params'
module Mail
# == Sending Email with SMTP
#
# Mail allows you to send emails using SMTP. This is done by wrapping Net::SMTP in
# an easy to use manner.
#
# === Sending via SMTP server on Localhost
#
# Sending locally (to a postfix or sendmail server running on localhost) requires
# no special setup. Just to Mail.deliver &block or message.deliver! and it will
# be sent in this method.
#
# === Sending via MobileMe
#
# Mail.defaults do
# delivery_method :smtp, { :address => "smtp.me.com",
# :port => 587,
# :domain => 'your.host.name',
# :user_name => '<username>',
# :password => '<password>',
# :authentication => 'plain',
# :enable_starttls_auto => true }
# end
#
# === Sending via GMail
#
# Mail.defaults do
# delivery_method :smtp, { :address => "smtp.gmail.com",
# :port => 587,
# :domain => 'your.host.name',
# :user_name => '<username>',
# :password => '<password>',
# :authentication => 'plain',
# :enable_starttls_auto => true }
# end
#
# === Certificate verification
#
# When using TLS, some mail servers provide certificates that are self-signed
# or whose names do not exactly match the hostname given in the address.
# OpenSSL will reject these by default. The best remedy is to use the correct
# hostname or update the certificate authorities trusted by your ruby. If
# that isn't possible, you can control this behavior with
# an :openssl_verify_mode setting. Its value may be either an OpenSSL
# verify mode constant (OpenSSL::SSL::VERIFY_NONE, OpenSSL::SSL::VERIFY_PEER),
# or a string containing the name of an OpenSSL verify mode (none, peer).
#
# === Others
#
# Feel free to send me other examples that were tricky
#
# === Delivering the email
#
# Once you have the settings right, sending the email is done by:
#
# Mail.deliver do
# to 'mikel@test.lindsaar.net'
# from 'ada@test.lindsaar.net'
# subject 'testing sendmail'
# body 'testing sendmail'
# end
#
# Or by calling deliver on a Mail message
#
# mail = Mail.new do
# to 'mikel@test.lindsaar.net'
# from 'ada@test.lindsaar.net'
# subject 'testing sendmail'
# body 'testing sendmail'
# end
#
# mail.deliver!
class SMTP
attr_accessor :settings
DEFAULTS = {
: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,
:ssl => nil,
:tls => nil,
:open_timeout => nil,
:read_timeout => nil
}
def initialize(values)
self.settings = DEFAULTS.merge(values)
end
def deliver!(mail)
response = start_smtp_session do |smtp|
Mail::SMTPConnection.new(:connection => smtp, :return_response => true).deliver!(mail)
end
settings[:return_response] ? response : self
end
private
def start_smtp_session(&block)
build_smtp_session.start(settings[:domain], settings[:user_name], settings[:password], settings[:authentication], &block)
end
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)
smtp.enable_tls(ssl_context)
end
elsif settings[:enable_starttls]
if smtp.respond_to?(:enable_starttls)
smtp.enable_starttls(ssl_context)
end
elsif settings[:enable_starttls_auto]
if smtp.respond_to?(:enable_starttls_auto)
smtp.enable_starttls_auto(ssl_context)
end
end
smtp.open_timeout = settings[:open_timeout] if settings[:open_timeout]
smtp.read_timeout = settings[:read_timeout] if settings[:read_timeout]
end
end
# Allow SSL context to be configured via settings, for Ruby >= 1.9
# Just returns openssl verify mode for Ruby 1.8.x
def ssl_context
openssl_verify_mode = settings[:openssl_verify_mode]
if openssl_verify_mode.kind_of?(String)
openssl_verify_mode = OpenSSL::SSL.const_get("VERIFY_#{openssl_verify_mode.upcase}")
end
context = Net::SMTP.default_ssl_context
context.verify_mode = openssl_verify_mode if openssl_verify_mode
context.ca_path = settings[:ca_path] if settings[:ca_path]
context.ca_file = settings[:ca_file] if settings[:ca_file]
context
end
end
end
|