mta-settings 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 077a057f8597de915994a206fdd24f3dfdb94884
4
+ data.tar.gz: a5338bac532f193a5803e7564974131f66b1fb2f
5
+ SHA512:
6
+ metadata.gz: 6ff91e9730954becfbb21ef0e03eebf8af5cb744756c3affcb817a275f68b378622a72e872cd844b262e0b45447e449a6829eb640893d0aa06c6f5ed8fceff8d
7
+ data.tar.gz: ed82a6b4de34bac0e9f1df332d67c3e7e734f388faae0890abe4c69ed1aad623a5f631fc5af108024c71df7534d61e1d3c3edca6ec885a5efc548b5e9fef5f69
@@ -0,0 +1,22 @@
1
+ Copyright (c) Tim Pope
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,69 @@
1
+ # MTA Settings for Ruby
2
+
3
+ The `mta-settings` gem enables transparent MTA (mail transport agent)
4
+ configuration from the environment for both [ActionMailer][] and [Mail][],
5
+ based on either an explicit `MTA_URL` variable or popular conventions for
6
+ Sendgrid, Mandrill, Postmark, and Mailgun (as provided by Heroku addons, for
7
+ example).
8
+
9
+ [ActionMailer]: https://github.com/rails/rails/tree/master/actionmailer
10
+ [Mail]: https://github.com/mikel/mail
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ gem 'mta-settings'
17
+
18
+ ### ActionMailer
19
+
20
+ If `mta-settings` is required (which Bundler does automatically by default),
21
+ ActionMailer configuration is fully automatic. With Rails, be aware that
22
+ `config.action_mailer` assignments will take precedence, so you might want to
23
+ strip those out of your apps `config/environments/` files.
24
+
25
+ ### Mail
26
+
27
+ Mail.defaults do
28
+ delivery_method *MtaSettings.from_env
29
+ # delivery_method *MtaSettings.from_url(ENV['MTA_URL'])
30
+ end
31
+
32
+ ## Usage
33
+
34
+ Configuration will happen based on the presence of the following environment
35
+ variables, in order of decreasing precedence:
36
+
37
+ * `MTA_PROVIDER`: points to another environment variable containing an MTA URL
38
+ * `MTA_URL`: See below
39
+ * `SENDGRID_USERNAME`: Sendgrid
40
+ * `MANDRILL_APIKEY`: Mandrill
41
+ * `POSTMARK_API_TOKEN`: Postmark
42
+ * `MAILGUN_SMTP_LOGIN`: Mailgun
43
+
44
+ If no supported environment variable is found, the configuration is left
45
+ blank. This enables easy defaulting:
46
+
47
+ ActionMailer::Base.delivery_method ||= :letter_opener
48
+
49
+ ### MTA URLs
50
+
51
+ The scheme of an MTA URL is used to set the delivery method. The user,
52
+ password, host, port, and path portions are used to populate the `user_name`,
53
+ `address`, `port`, and `location` settings of the chosen delivery method.
54
+ Query parameters are then merged in.
55
+
56
+ * The `sendmail` and `file` adapters both respect the ActionMailer `location`
57
+ defaults, so you can just give `sendmail:///` or `file:///`.
58
+ * If a path is given in an `smtp` URL, it will be used as `domain` rather than
59
+ `location` (minus the leading slash).
60
+ * If `domain` is set, the default from address will be set to `noreply` at
61
+ that domain.
62
+
63
+ Here's an example for Gmail:
64
+
65
+ smtp://username%40gmail.com:password@smtp.gmail.com:587/
66
+
67
+ Using an MTA URL is highly recommended even when your SMTP provider is
68
+ supported out of the box. MTA URLs are much easier to copy between
69
+ environments or try out locally for debugging.
@@ -0,0 +1,10 @@
1
+ require 'mta_settings'
2
+
3
+ ActiveSupport.on_load(:action_mailer) do
4
+ self.mta_settings =
5
+ if ENV['RAILS_ENV'] == 'test'
6
+ :test
7
+ else
8
+ ENV
9
+ end
10
+ end
@@ -0,0 +1,156 @@
1
+ require 'uri'
2
+ require 'cgi'
3
+ require 'active_support/core_ext/object/blank'
4
+ require 'active_support/lazy_load_hooks'
5
+
6
+ module MtaSettings
7
+ LOCALHOST = 'localhost.localdomain'
8
+
9
+ def self.from_url(url)
10
+ return if url.blank?
11
+ # Use MTA_URL=: to short circuit configuration
12
+ return [nil, nil] if url == ':'
13
+ # Use MTA_URL=test: to use the test method without changing settings
14
+ return [$1.tr('+-.', '___').to_sym, nil] if url =~ /\A^([\w+-.]+):\z/
15
+ uri = URI.parse(url.to_s)
16
+
17
+ settings = {
18
+ :user_name => (CGI.unescape(uri.user) if uri.user),
19
+ :password => (CGI.unescape(uri.password) if uri.password),
20
+ :address => uri.host,
21
+ :port => uri.port,
22
+ :location => (uri.path if uri.path != '/'),
23
+ }.reject do |k, v|
24
+ v.nil?
25
+ end
26
+
27
+ if !settings[:location] && uri.opaque =~ /^[^?]/
28
+ settings[:location] = CGI.unescape(uri.opaque.split('?').first)
29
+ end
30
+
31
+ CGI.parse(uri.query || uri.opaque.to_s.split('?')[1].to_s).each do |k, v|
32
+ settings[k.to_sym] = v.join("\n")[/.+/m]
33
+ end
34
+
35
+ adapter = uri.scheme.downcase.tr('+-.', '___').to_sym
36
+ case adapter
37
+ when :sendmail, :exim
38
+ settings[:location] ||= "/usr/sbin/#{adapter}"
39
+ settings[:arguments] ||= '-i -t'
40
+
41
+ when :file
42
+ settings[:location] ||=
43
+ if defined?(Rails.root)
44
+ "#{Rails.root}/tmp/mails"
45
+ else
46
+ "#{Dir.tmpdir}/mails"
47
+ end
48
+
49
+ when :smtp, :smtps
50
+ settings[:ssl] = (adapter == :smtps)
51
+ adapter = :smtp
52
+ settings[:enable_starttls_auto] = true
53
+ settings[:authentication] ||= :plain if settings[:user_name]
54
+ settings[:domain] ||=
55
+ (settings.delete(:location) || LOCALHOST).sub(/^\//, '')
56
+
57
+ end
58
+
59
+ [adapter, settings]
60
+ end
61
+
62
+ def self.from_env(env = ENV)
63
+ domain = env['MTA_DOMAIN'] || LOCALHOST
64
+ if url = env[env['MTA_PROVIDER'].presence || 'MTA_URL'].presence
65
+ method, settings = from_url(url)
66
+ if method == :smtp && settings[:domain] == LOCALHOST
67
+ settings[:domain] = domain
68
+ end
69
+ [method, settings]
70
+ elsif env['SENDGRID_USERNAME'].present?
71
+ [:smtp, {
72
+ :address => "smtp.sendgrid.net",
73
+ :port => 587,
74
+ :authentication => :plain,
75
+ :enable_starttls_auto => true,
76
+ :user_name => env['SENDGRID_USERNAME'],
77
+ :password => env['SENDGRID_PASSWORD'],
78
+ :domain => domain,
79
+ }]
80
+ elsif env['MANDRILL_APIKEY'].present?
81
+ [:smtp, {
82
+ :address => "smtp.mandrillapp.com",
83
+ :port => 587,
84
+ :authentication => :plain,
85
+ :enable_starttls_auto => true,
86
+ :user_name => env['MANDRILL_USERNAME'],
87
+ :password => env['MANDRILL_APIKEY'],
88
+ :domain => domain,
89
+ }]
90
+ elsif env['POSTMARK_API_TOKEN'].present?
91
+ [:smtp, {
92
+ :address => env['POSTMARK_SMTP_SERVER'] || 'smtp.postmarkapp.com',
93
+ :port => 25,
94
+ :authentication => :cram_md5,
95
+ :enable_starttls_auto => true,
96
+ :user_name => env['POSTMARK_API_TOKEN'],
97
+ :password => env['POSTMARK_API_TOKEN'],
98
+ :domain => domain,
99
+ }]
100
+ elsif env['MAILGUN_SMTP_LOGIN'].present?
101
+ [:smtp, {
102
+ :address => env['MAILGUN_SMTP_SERVER'] || 'smtp.mailgun.org',
103
+ :port => env['MAILGUN_SMTP_PORT'] || '25',
104
+ :authentication => :plain,
105
+ :enable_starttls_auto => true,
106
+ :user_name => env['MAILGUN_SMTP_LOGIN'],
107
+ :password => env['MAILGUN_SMTP_PASSWORD'],
108
+ :domain => domain,
109
+ }]
110
+ end
111
+ end
112
+
113
+ module ActionMailerExtensions
114
+ def mta_settings
115
+ [delivery_method, send("#{delivery_method}_settings")] if delivery_method
116
+ end
117
+
118
+ def mta_settings=(arg)
119
+ self.delivery_method, settings =
120
+ *case arg
121
+ when nil, ""
122
+ [nil, nil]
123
+ when String, URI
124
+ MtaSettings.from_url(arg)
125
+ when Array
126
+ arg
127
+ when Symbol
128
+ [arg, {}]
129
+ when Hash
130
+ arg = arg.dup
131
+ [arg.delete(:adapter) || arg.delete(:transport), arg]
132
+ when ENV
133
+ MtaSettings.from_env(arg)
134
+ else
135
+ raise ArgumentError, "Unsupported MTA settings #{arg.inspect}"
136
+ end
137
+ return unless delivery_method && settings
138
+ accessor = :"#{delivery_method}_settings"
139
+ class_attribute(accessor) unless respond_to?(accessor)
140
+ send(:"#{accessor}=", settings)
141
+ if settings[:from]
142
+ default from: settings[:from]
143
+ elsif !default.has_key?(:from) &&
144
+ ![nil, LOCALHOST].include?(settings[:domain])
145
+ default from: "noreply@#{settings[:domain]}"
146
+ elsif !default.has_key?(:from) &&
147
+ settings[:user_name] =~ /\A\S+@\S+\.\w+\z/
148
+ default from: settings[:user_name]
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ ActiveSupport.on_load(:action_mailer) do
155
+ extend MtaSettings::ActionMailerExtensions
156
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mta-settings
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Pope
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 3.0.0
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '6'
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 3.0.0
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '6'
75
+ description: |
76
+ Configure ActionMailer or Mail delivery settings based on either a singular
77
+ MTA_URL environment variable or common conventions for popular off the shelf
78
+ SMTP providers.
79
+ email:
80
+ - codeAtpope.net
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - LICENSE.txt
86
+ - README.markdown
87
+ - lib/mta-settings.rb
88
+ - lib/mta_settings.rb
89
+ homepage: https://github.com/tpope/mta-settings
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.2.2
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Configure ActionMailer or Mail delivery settings based on the environment
113
+ test_files: []