mail_gate 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
6
+
7
+ group :test do
8
+ gem 'mail'
9
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Garrett Bjerkhoel
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,129 @@
1
+ MailGate [![Build Status](https://secure.travis-ci.org/dewski/mail_gate.png)](http://travis-ci.org/dewski/mail_gate)
2
+ ========
3
+
4
+ MailGate is an additional delivery method for the [Mail](https://github.com/mikel/mail) gem that lets you restrict the delivery of mail to only whitelisted emails. Ideal for staging environments where you may be using production data and do not want them to recieve emails from your mailers when you submit comments, contact forms, or anything else that may trigger mail delivery.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'mail_gate'
11
+
12
+ And then run:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install mail_gate
19
+
20
+ ## Usage
21
+
22
+ MailGate works as a standalone extension to the [Mail](https://github.com/mikel/mail) gem or as a delivery method within Rails applications.
23
+
24
+ To configure MailGate, edit your ActionMailer configuration to use `:mail_gate` as the delivery method, then copy your existing settings to `mail_gate_settings`:
25
+
26
+ ```ruby
27
+ # config/environments/staging.rb
28
+ CNN::Application.configure do
29
+ config.action_mailer.delivery_method = :smtp
30
+ config.action_mailer.smtp_settings = {
31
+ :address => 'smtp.sendgrid.net',
32
+ :port => '25',
33
+ :authentication => :plain,
34
+ :user_name => ENV['SENDGRID_USERNAME'],
35
+ :password => ENV['SENDGRID_PASSWORD'],
36
+ :domain => ENV['SENDGRID_DOMAIN']
37
+ }
38
+ end
39
+ ```
40
+
41
+ Becomes:
42
+
43
+ ```ruby
44
+ # config/environments/staging.rb
45
+ CNN::Application.configure do
46
+ config.action_mailer.delivery_method = :mail_gate
47
+ config.action_mailer.mail_gate_settings = {
48
+ :whitelist => /cnn.com/,
49
+ :delivery_method => :smtp,
50
+ :delivery_settings => {
51
+ :address => 'smtp.sendgrid.net',
52
+ :port => '25',
53
+ :authentication => :plain,
54
+ :user_name => ENV['SENDGRID_USERNAME'],
55
+ :password => ENV['SENDGRID_PASSWORD'],
56
+ :domain => ENV['SENDGRID_DOMAIN']
57
+ }
58
+ }
59
+ end
60
+ ```
61
+
62
+ By default the emails send will have the same subject that they normally would. If you'd like to customize the subject to inform the reader where it was sent from you can do that with the `:subject_prefix` option:
63
+
64
+ ```ruby
65
+ # config/environments/staging.rb
66
+ CNN::Application.configure do
67
+ config.action_mailer.delivery_method = :mail_gate
68
+ config.action_mailer.mail_gate_settings = {
69
+ :whitelist => /cnn.com/,
70
+ :subject_prefix => '[Staging] ',
71
+ # ...
72
+ }
73
+ end
74
+ ```
75
+
76
+ Now your emails that are sent will have `[Staging] New comment on your article!` as the subject rather than just `New comment on your article!`. It's entirely up to you what you may put as the prefix, be it the current deploy git SHA, or if you want to send the server's hostname that sent the mail.
77
+
78
+ Email now sent within the staging environment will extract any recipient emails that don't match the whitelist. If after being filtered there aren't any recipients left because they were filtered out, no email will be sent:
79
+
80
+ ```
81
+ > Article.first.comments.each do |comment|
82
+ > "Email for: #{comment.user.email}"
83
+ > ArticleMailer.new_comment(article, comment).deliver
84
+ > end
85
+ => Email for: john.doe@gmail.com
86
+ => Email for: megatron@transformers.com
87
+ => Email for: george@cnn.com
88
+ => #<Mail::Message:70236177475420, Headers: <From: no-reply@cnn.com>, <To: george@cnn.com>, <Subject: [Staging] New comment on your article!>>
89
+ ```
90
+
91
+ Notice only the email for `george@cnn.com` was delivered.
92
+
93
+ ## Using MailGate outside of Rails
94
+
95
+ If you have a Sinatra app or just using the Mail library in your Ruby project you can still use MailGate:
96
+
97
+ ```ruby
98
+ require 'mail_gate'
99
+
100
+ Mail.defaults do
101
+ delivery_method MailGate::Filter,
102
+ :whitelist => /cnn.com/,
103
+ :subject_prefix => '[local] ',
104
+ :delivery_method => :file,
105
+ :location => '/dev/null'
106
+ end
107
+ ```
108
+
109
+ Then just deliver the email as normal:
110
+
111
+ ```ruby
112
+ Mail.deliver do
113
+ to 'george@cnn.com'
114
+ from 'no-reply@cnn.com'
115
+ subject 'Testing MailGate'
116
+ body 'Hi! :)'
117
+ end
118
+ ```
119
+
120
+ ## Contributing
121
+
122
+ 1. Fork it
123
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
124
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
125
+ 4. Push to the branch (`git push origin my-new-feature`)
126
+ 5. Create new Pull Request
127
+
128
+ ## Copyright
129
+ Copyright © 2012 Garrett Bjerkhoel. See [LICENSE](https://github.com/dewski/mail_gate/blob/master/LICENSE) for details.
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env rake
2
+ require 'rubygems'
3
+ require 'rake/testtask'
4
+ begin
5
+ require 'bundler/setup'
6
+ Bundler::GemHelper.install_tasks
7
+ rescue LoadError
8
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
9
+ end
10
+
11
+ desc 'Default: run tests'
12
+ task :default => :test
13
+
14
+ desc 'Run MailGate tests.'
15
+ Rake::TestTask.new(:test) do |t|
16
+ t.libs << 'lib'
17
+ t.libs << 'test'
18
+ t.test_files = FileList['test/**/*_test.rb']
19
+ t.verbose = true
20
+ end
@@ -0,0 +1,5 @@
1
+ require 'mail_gate/version'
2
+
3
+ module MailGate
4
+ autoload :Filter, 'mail_gate/filter'
5
+ end
@@ -0,0 +1,86 @@
1
+ module MailGate
2
+ # MailGate class restricts email delivery to non-whitelisted emails.
3
+ #
4
+ # Each element within the whitelist needs to be a Regex object.
5
+ #
6
+ # To use MailGate within a Rails project, configure a specific environment
7
+ # file or global configuration using the mail_gate delivery method:
8
+ #
9
+ # config.action_mailer.delivery_method = :mail_gate
10
+ # config.action_mailer.mail_gate_settings = {
11
+ # :whitelist => /evil.com|allowed@site.com/
12
+ # }
13
+ #
14
+ # If you aren't using MailGate within a Rails application, you can still
15
+ # configure Mail to use it as it's default delivery_method.
16
+ #
17
+ # Mail.defaults do
18
+ # delivery_method MailGate::Filter, :whitelist => /application.com/
19
+ # end
20
+ #
21
+ class Filter
22
+ attr_accessor :settings
23
+
24
+ # The Regexp to compare emails against.
25
+ attr_accessor :whitelist
26
+
27
+ def initialize(settings = {})
28
+ self.settings = settings
29
+ @whitelist = Regexp.new(settings.delete(:whitelist) || /.*/)
30
+ delivery_method = settings.fetch(:delivery_method, :test)
31
+ delivery_settings = settings.fetch(:delivery_settings, {})
32
+ @delivery_method = Mail::Configuration.instance.lookup_delivery_method(delivery_method).new(delivery_settings)
33
+ end
34
+
35
+ # Public: Filter out recipients who may match the whitelist regex.
36
+ # If no emails are present after being filtered, don't deliver the email.
37
+ #
38
+ # mail - Mail object containing headers and body.
39
+ #
40
+ # Returns instance of Mail::Message.
41
+ def deliver!(mail)
42
+ %w{ to cc bcc }.each do |field|
43
+ mail.send(:"#{field}=", filter_emails(mail.send(field)))
44
+ end
45
+
46
+ if settings[:subject_prefix]
47
+ mail.subject = settings[:subject_prefix] + mail.subject
48
+ end
49
+
50
+ @delivery_method.deliver!(mail) unless mail.to.blank?
51
+
52
+ mail
53
+ end
54
+
55
+ private
56
+
57
+ # Private: Filter out any emails that match the whitelist regex.
58
+ #
59
+ # emails - List of emails to filter through.
60
+ #
61
+ # Examples
62
+ #
63
+ # Given [/hacking.com/] being the whitelist.
64
+ #
65
+ # filter_emails('me@garrettbjerkhoel.com')
66
+ # # => nil
67
+ #
68
+ # filter_emails(['me@garrettbjerkhoel.com', 'evil@hacking.com'])
69
+ # # => 'garrett@github.com'
70
+ #
71
+ # filter_emails(['matt@github.com', 'garrett@github.com'])
72
+ # # => ['matt@github.com', 'garrett@github.com']
73
+ #
74
+ # Returns array of emails if the list is greater than one, if only one item
75
+ # return just that single email, if empty, return nil to reset the field.
76
+ def filter_emails(emails)
77
+ return if emails.blank?
78
+
79
+ email_list = Array(emails).select do |recipient|
80
+ recipient.to_s =~ @whitelist
81
+ end
82
+
83
+ email_list.length > 1 ? email_list : email_list.shift
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,7 @@
1
+ module MailGate
2
+ class Railtie < Rails::Railtie
3
+ config.before_configuration do
4
+ ActionMailer::Base.add_delivery_method :mail_gate, MailGate::Filter
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module MailGate
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mail_gate/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ['Garrett Bjerkhoel']
6
+ gem.email = ['me@garrettbjerkhoel.com']
7
+ gem.description = %q{MailGate is an additional delivery method for the Mail gem that lets you restrict the delivery of mail to only whitelisted emails.}
8
+ gem.summary = %q{MailGate is an additional delivery method for the Mail gem that lets you restrict the delivery of mail to only whitelisted emails.}
9
+ gem.homepage = 'https://github.com/dewski/mail_gate'
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = 'mail_gate'
15
+ gem.require_paths = ['lib']
16
+ gem.version = MailGate::VERSION
17
+
18
+ gem.add_dependency 'mail', '~> 2.4.1'
19
+ end
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup(:default, :test)
4
+ Bundler.require(:default, :test)
5
+
6
+ dir = File.dirname(File.expand_path(__FILE__))
7
+ $LOAD_PATH.unshift dir + '/../lib'
8
+ $TESTING = true
9
+ require 'test/unit'
10
+ require 'mail_gate'
11
+
12
+ class Test::Unit::TestCase
13
+ # Return a stubbed mail object helpful for writing unit tests.
14
+ #
15
+ # options - The Hash options used to refine the selection (default: {}):
16
+ # :whitelist - The Regex to match against emails (optional).
17
+ # :subject_prefix - The String to be prepended to the subject (optional).
18
+ # :from - The email responsible for sending the email (optional) (default: test@mail_gate.com).
19
+ # :to - The Array or String of emails for the to field (optional).
20
+ # :cc - The Array or String of emails for the cc field (optional).
21
+ # :bcc - The Array or String of emails for the bcc field (optional).
22
+ #
23
+ # Examples
24
+ #
25
+ # mail = with_whitelist :to => 'test@email.com'
26
+ # # => #<Mail::Message to: "test@email.com">
27
+ #
28
+ # Returns instance of Mail::Message.
29
+ def with_whitelist(options={})
30
+ filter = MailGate::Filter.new \
31
+ :whitelist => options.delete(:whitelist),
32
+ :subject_prefix => options.delete(:subject_prefix)
33
+
34
+ mail = Mail.new options.merge(:from => 'test@mail_gate.com')
35
+
36
+ filter.deliver!(mail)
37
+ end
38
+ end
39
+
40
+ Mail.defaults do
41
+ delivery_method :test
42
+ end
43
+
@@ -0,0 +1,78 @@
1
+ require 'test_helper'
2
+
3
+ class TestFilter < Test::Unit::TestCase
4
+ def test_without_whitelist_regex
5
+ mail = with_whitelist :to => 'garrett@site.com'
6
+ assert_equal %w{ garrett@site.com }, mail.to
7
+ end
8
+
9
+ def test_with_whitelist_as_string
10
+ mail = with_whitelist \
11
+ :to => 'garrett@site.com',
12
+ :whitelist => '@site.com'
13
+ assert_equal %w{ garrett@site.com }, mail.to
14
+ end
15
+
16
+ def test_with_no_matching_whitelist
17
+ mail = with_whitelist \
18
+ :to => 'garrett@site.com',
19
+ :whitelist => /cnn.com/
20
+ assert mail.to.blank?, 'no mail values'
21
+ end
22
+
23
+ def test_to_field_whitelisted_emails
24
+ mail = with_whitelist \
25
+ :to => %w{ garrett@site.com matt@site.com non-staff@user.com },
26
+ :whitelist => /site.com/
27
+
28
+ assert_equal %w{ garrett@site.com matt@site.com }, mail.to
29
+ end
30
+
31
+ def test_to_field_domain_and_user_whitelist
32
+ mail = with_whitelist \
33
+ :to => %w{ garrett@site.com someone@special.com },
34
+ :whitelist => /site.com|someone@special.com/
35
+
36
+ assert_equal %w{ garrett@site.com someone@special.com }, mail.to
37
+ end
38
+
39
+ def test_cc_field_domain_and_user_whitelist
40
+ mail = with_whitelist \
41
+ :to => %w{ garrett@site.com matt@site.com },
42
+ :cc => 'george@whitehouse.gov',
43
+ :whitelist => /site.com/
44
+
45
+ assert_equal %w{ garrett@site.com matt@site.com }, mail.to
46
+ assert mail.cc.blank?, 'no cc field'
47
+ end
48
+
49
+ def test_bcc_field_domain_and_user_whitelist
50
+ mail = with_whitelist \
51
+ :to => %w{ garrett@site.com matt@site.com },
52
+ :bcc => 'luke@skywalker.com',
53
+ :whitelist => /site.com/
54
+
55
+ assert_equal %w{ garrett@site.com matt@site.com }, mail.to
56
+ assert mail.cc.blank?, 'no cc field'
57
+ assert mail.bcc.blank?, 'no bcc field'
58
+ end
59
+
60
+ def test_bcc_field_domain_and_user_whitelist
61
+ mail = with_whitelist \
62
+ :to => %w{ garrett@site.com matt@site.com },
63
+ :bcc => %w{ luke@skywalker.com luke@copy.com },
64
+ :whitelist => /site.com|copy.com/
65
+
66
+ assert_equal %w{ garrett@site.com matt@site.com }, mail.to
67
+ assert_equal %w{ luke@copy.com }, mail.bcc
68
+ end
69
+
70
+ def test_settings_prefix
71
+ mail = with_whitelist \
72
+ :to => 'garrett@site.com',
73
+ :subject => 'Welcome to the site!',
74
+ :subject_prefix => '[staging] '
75
+
76
+ assert_equal '[staging] Welcome to the site!', mail.subject
77
+ end
78
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mail_gate
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Garrett Bjerkhoel
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mail
16
+ requirement: &70328114755100 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.4.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70328114755100
25
+ description: MailGate is an additional delivery method for the Mail gem that lets
26
+ you restrict the delivery of mail to only whitelisted emails.
27
+ email:
28
+ - me@garrettbjerkhoel.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - .travis.yml
35
+ - Gemfile
36
+ - LICENSE
37
+ - README.md
38
+ - Rakefile
39
+ - lib/mail_gate.rb
40
+ - lib/mail_gate/filter.rb
41
+ - lib/mail_gate/railtie.rb
42
+ - lib/mail_gate/version.rb
43
+ - mail_gate.gemspec
44
+ - test/test_helper.rb
45
+ - test/unit/mail_gate/filter_test.rb
46
+ homepage: https://github.com/dewski/mail_gate
47
+ licenses: []
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ segments:
59
+ - 0
60
+ hash: -2561250797758868510
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ segments:
68
+ - 0
69
+ hash: -2561250797758868510
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 1.8.17
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: MailGate is an additional delivery method for the Mail gem that lets you
76
+ restrict the delivery of mail to only whitelisted emails.
77
+ test_files:
78
+ - test/test_helper.rb
79
+ - test/unit/mail_gate/filter_test.rb