mailsafe 0.1.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 047172ca62085b8affb85a38a9ffa18123dc8589
4
- data.tar.gz: a07b0d33e190716d9d4076f90dc41ea9fa08726d
3
+ metadata.gz: 67ad0adc4f46869bab060bd9c07f998e5515fc3b
4
+ data.tar.gz: e99ad41b2eae6e0e9e3c248d740ca5e29db51993
5
5
  SHA512:
6
- metadata.gz: c494132d2bd2f9ba140c836a689f713b51b01cb4a78fad6e4169c8ccaa52c6944bddf0b9decf32327eeb190bb355c12c04e23f07b1de16faf33442a4da1d094e
7
- data.tar.gz: 2924839ee61347f45107c12dd5af6e651deb196011144fc5d18b7d40726a7ffbec67fe133d8da534272be97c11b62b270e213203e43180d73a15eca75bbe97b5
6
+ metadata.gz: 75f2a2260bc81b28beee198fc22e36d9382065ac915892b1c901b9a715c8b21f2fb251cb4f9dceddaa7b765e96c9afefdeb0ebcc47a0d4a8cfa03526a9a170f8
7
+ data.tar.gz: 49259b685320f13a7858aa35b44c7f6e4d32b4177028876624ed0537815352aa6a26367cc6c54c7e5bdb9a9f9d5f8404bd871ebc5357be69d8d99da820fc3375
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ # 0.2.0
4
+
5
+ * Filter CC and BCC addresses ([#2](https://github.com/stemps/mailsafe/issues/2))
6
+
7
+ # 0.1.0
8
+
9
+ * First public version
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  [![Code Climate](https://codeclimate.com/github/stemps/mailsafe.png)](https://codeclimate.com/github/stemps/mailsafe)
2
+ [![Build Status](https://travis-ci.org/stemps/mailsafe.svg)](https://travis-ci.org/stemps/mailsafe)
2
3
  # Mailsafe
3
4
 
4
5
  Safe emailing for Rails. Prevents you from sending emails to real customers from non-production environments. You can choose to either re-route all emails to a single developer account or allow only recipients of your own domain.
data/Rakefile CHANGED
@@ -1 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
@@ -3,7 +3,7 @@ require "mailsafe/version"
3
3
  require "mailsafe/railtie"
4
4
  require "mailsafe/change_subject_interceptor"
5
5
  require "mailsafe/reroute_interceptor"
6
- require "mailsafe/receipient_whitelist"
6
+ require "mailsafe/recipient_whitelist"
7
7
 
8
8
  module Mailsafe
9
9
  def self.setup
@@ -0,0 +1,52 @@
1
+ module Mailsafe
2
+ class RecipientWhitelist
3
+ def initialize(message)
4
+ @message = message
5
+ @allowed_domain_config = Mailsafe.allowed_domain
6
+ @allowed_domains = parse_allowed_domains
7
+ end
8
+
9
+ def filter_recipient_domains
10
+ return unless @allowed_domains.present?
11
+ [ :to, :cc, :bcc ].each { |rec_type| filter_receipient_type(rec_type) }
12
+ end
13
+
14
+ private
15
+
16
+ def filter_receipient_type(rec_type)
17
+ receivers = @message.send(rec_type)
18
+ return unless receivers
19
+
20
+ receivers.select! { |recipient| email_has_domain?(recipient) }
21
+ @message.send("#{rec_type}=", receivers)
22
+ end
23
+
24
+ def email_has_domain?(email_address)
25
+ email_domain = extract_domain_from_address(email_address)
26
+ email_domain.present? && @allowed_domains.include?(email_domain)
27
+ end
28
+
29
+ def extract_domain_from_address(email_address)
30
+ email_address.split("@")[1].try(:downcase)
31
+ end
32
+
33
+ def parse_allowed_domains
34
+ if @allowed_domain_config.present?
35
+ @allowed_domain_config.split(',').map(&:strip).map(&:downcase)
36
+ end
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ # Unfortunately, monkeypatching Mail is the only way I found to actually prevent sending an email
43
+ require 'mail'
44
+
45
+ class Mail::Message
46
+ def deliver_with_recipient_filter
47
+ Mailsafe::RecipientWhitelist.new(self).filter_recipient_domains
48
+ self.deliver_without_recipient_filter unless self.to.blank? || self.to.empty?
49
+ end
50
+
51
+ alias_method_chain :deliver, :recipient_filter
52
+ end
@@ -2,9 +2,20 @@ module Mailsafe
2
2
  class RerouteInterceptor
3
3
  def self.delivering_email(message)
4
4
  unless Mailsafe.override_receiver.blank?
5
- message.subject = "[#{message.to}] #{message.subject}"
5
+ message.subject = "[#{receivers(message)}] #{message.subject}"
6
6
  message.to = Mailsafe.override_receiver
7
+ message.cc = []
8
+ message.bcc = []
7
9
  end
8
10
  end
11
+
12
+ private
13
+
14
+ def self.receivers(message)
15
+ [ :to, :cc, :bcc ].map do |rec_type|
16
+ recs = message.send(rec_type)
17
+ "#{rec_type}: #{recs.join ', '}" if recs.present?
18
+ end.compact.join '; '
19
+ end
9
20
  end
10
21
  end
@@ -1,3 +1,3 @@
1
1
  module Mailsafe
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
- spec.add_development_dependency "rspec", "~> 2.13.0"
23
+ spec.add_development_dependency "pry"
24
+ spec.add_development_dependency "rspec", "~> 3.2.0"
24
25
  spec.add_development_dependency "rails", "~> 4.1.5"
25
26
  end
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ module Mailsafe
4
+ describe RecipientWhitelist do
5
+
6
+ describe ".filter_recipient_domain" do
7
+ subject { Mail.new(to: to, cc: cc, bcc: bcc) }
8
+ let(:to) { ["to@gmail.com", "to@yahoo.com"] }
9
+ let(:cc) { ["cc@gmail.com", "cc@yahoo.com"] }
10
+ let(:bcc) { ["bcc@gmail.com", "bcc@yahoo.com"] }
11
+
12
+ context "allowed_domains configured" do
13
+ before do
14
+ Mailsafe.allowed_domain = "gmail.com"
15
+ RecipientWhitelist.new(subject).filter_recipient_domains
16
+ end
17
+
18
+ it "filters 'to' email addresses" do
19
+ expect(subject.to).to eq ["to@gmail.com"]
20
+ end
21
+
22
+ it "filters 'cc' email addresses" do
23
+ expect(subject.cc).to eq ["cc@gmail.com"]
24
+ end
25
+
26
+ it "filters 'bcc' email addresses" do
27
+ expect(subject.bcc).to eq ["bcc@gmail.com"]
28
+ end
29
+ end
30
+
31
+ context "uninitialized receivers" do
32
+ subject { Mail.new() }
33
+
34
+ before do
35
+ Mailsafe.allowed_domain = "gmail.com"
36
+ RecipientWhitelist.new(subject).filter_recipient_domains
37
+ end
38
+
39
+ it "Regression: and does not crash" do
40
+ expect(subject.to).to eq nil
41
+ expect(subject.cc).to eq nil
42
+ expect(subject.bcc).to eq nil
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "#email_has_domain" do
48
+ before { Mailsafe.allowed_domain = whitelist }
49
+ subject { RecipientWhitelist.new(double) }
50
+
51
+ context "single whitelisted domain" do
52
+ let(:whitelist) { "gmail.com" }
53
+
54
+ it "accepts the allowed domains" do
55
+ expect(subject.send(:email_has_domain?, "bert@gmail.com")).to be_truthy
56
+ end
57
+
58
+ it "does not accept other domains" do
59
+ expect(subject.send(:email_has_domain?, "bert@gmx.de")).to be_falsy
60
+ expect(subject.send(:email_has_domain?, "bert@yahoo.com")).to be_falsy
61
+ expect(subject.send(:email_has_domain?, "bert@ggmail.com")).to be_falsy
62
+ expect(subject.send(:email_has_domain?, "bert@gmail.com.de")).to be_falsy
63
+ end
64
+ end
65
+
66
+ context "multiple whitelisted domains" do
67
+ let(:whitelist) { "gmail.com, gmx.de" }
68
+
69
+ it "accepts the allowed domains" do
70
+ expect(subject.send(:email_has_domain?, "bert@gmail.com")).to be_truthy
71
+ expect(subject.send(:email_has_domain?, "bert@gmx.de")).to be_truthy
72
+ end
73
+
74
+ it "does not accept other domains" do
75
+ expect(subject.send(:email_has_domain?, "bert@yahoo.com")).to be_falsy
76
+ expect(subject.send(:email_has_domain?, "bert@ggmail.com")).to be_falsy
77
+ end
78
+ end
79
+
80
+ context "invalid email addresses" do
81
+ let(:whitelist) { "gmail.com" }
82
+
83
+ it "does not accept them" do
84
+ expect(subject.send(:email_has_domain?, "bert")).to be_falsy
85
+ end
86
+ end
87
+
88
+ context "invalid whitelist" do
89
+ let(:whitelist) { "gmail.com, " }
90
+
91
+ it "accepts the allowed domains" do
92
+ expect(subject.send(:email_has_domain?, "bert@gmail.com")).to be_truthy
93
+ end
94
+
95
+ it "does not accept other domains" do
96
+ expect(subject.send(:email_has_domain?, "bert@gmx.de")).to be_falsy
97
+ expect(subject.send(:email_has_domain?, "bert@yahoo.com")).to be_falsy
98
+ expect(subject.send(:email_has_domain?, "bert@ggmail.com")).to be_falsy
99
+ expect(subject.send(:email_has_domain?, "bert@gmail.com.de")).to be_falsy
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ module Mailsafe
4
+ describe RerouteInterceptor do
5
+
6
+ describe ".delivering_mail" do
7
+ subject { Mail.new(to: to, cc: cc, bcc: bcc, subject: mail_subject) }
8
+ let(:to) { nil }
9
+ let(:cc) { nil }
10
+ let(:bcc) { nil }
11
+ let(:override_rec) { nil }
12
+ let(:mail_subject) { "Hi!" }
13
+
14
+ before do
15
+ Mailsafe.override_receiver = override_rec
16
+ RerouteInterceptor.delivering_email(subject)
17
+ end
18
+
19
+ context "override_receiver is not set" do
20
+ let(:to) { "joe@example.com" }
21
+ let(:cc) { "jane@example.com" }
22
+ let(:bcc) { "bob@example.com" }
23
+
24
+ # leaves the email unchanged
25
+ specify { expect(subject.subject).to eq mail_subject }
26
+ specify { expect(subject.to).to eq [to] }
27
+ specify { expect(subject.cc).to eq [cc] }
28
+ specify { expect(subject.bcc).to eq [bcc] }
29
+ end
30
+
31
+ context "override_receiver is set" do
32
+ let(:override_rec) { "override@example.com" }
33
+
34
+ context "Message without any receivers" do
35
+ specify { expect(subject.subject).to eq "[] Hi!" }
36
+ specify { expect(subject.to).to eq [override_rec] }
37
+ specify { expect(subject.cc).to eq [] }
38
+ specify { expect(subject.bcc).to eq [] }
39
+ end
40
+
41
+ context "message with a 'to' receiver" do
42
+ let(:to) { "bob@example.com" }
43
+
44
+ specify { expect(subject.subject).to eq "[to: bob@example.com] Hi!" }
45
+ specify { expect(subject.to).to eq [override_rec] }
46
+ specify { expect(subject.cc).to eq [] }
47
+ specify { expect(subject.bcc).to eq [] }
48
+ end
49
+
50
+ context "message with multiple 'to' receivers" do
51
+ let(:to) { ["bob@example.com", "jane@example.com"] }
52
+
53
+ specify { expect(subject.subject).to eq "[to: bob@example.com, jane@example.com] Hi!" }
54
+ specify { expect(subject.to).to eq [override_rec] }
55
+ specify { expect(subject.cc).to eq [] }
56
+ specify { expect(subject.bcc).to eq [] }
57
+ end
58
+
59
+ context "message with 'to', 'cc' and 'bcc' receivers" do
60
+ let(:to) { ["bob@example.com", "jane@example.com"] }
61
+ let(:cc) { "joe@example.com" }
62
+ let(:bcc) { ["mary@example.com", "alice@example.com"] }
63
+
64
+ specify { expect(subject.subject).to eq "[to: bob@example.com, jane@example.com; cc: joe@example.com; bcc: mary@example.com, alice@example.com] Hi!" }
65
+ specify { expect(subject.to).to eq [override_rec] }
66
+ specify { expect(subject.cc).to eq [] }
67
+ specify { expect(subject.bcc).to eq [] }
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,10 +1,10 @@
1
+ require 'pry'
1
2
  require 'bundler/setup'
2
3
  Bundler.setup
3
4
 
4
5
  require 'mailsafe'
5
6
 
6
7
  RSpec.configure do |config|
7
- config.treat_symbols_as_metadata_keys_with_true_values = true
8
8
  config.run_all_when_everything_filtered = true
9
9
  config.filter_run :focus
10
10
 
metadata CHANGED
@@ -1,69 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailsafe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Stemplinger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-19 00:00:00.000000000 Z
11
+ date: 2015-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - ~>
59
+ - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: 2.13.0
61
+ version: 3.2.0
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - ~>
66
+ - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: 2.13.0
68
+ version: 3.2.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rails
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - ~>
73
+ - - "~>"
60
74
  - !ruby/object:Gem::Version
61
75
  version: 4.1.5
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - ~>
80
+ - - "~>"
67
81
  - !ruby/object:Gem::Version
68
82
  version: 4.1.5
69
83
  description: Safe emailing for Rails
@@ -73,8 +87,9 @@ executables: []
73
87
  extensions: []
74
88
  extra_rdoc_files: []
75
89
  files:
76
- - .gitignore
77
- - .rspec
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - CHANGELOG.md
78
93
  - Gemfile
79
94
  - LICENSE.txt
80
95
  - README.md
@@ -82,11 +97,12 @@ files:
82
97
  - lib/mailsafe.rb
83
98
  - lib/mailsafe/change_subject_interceptor.rb
84
99
  - lib/mailsafe/railtie.rb
85
- - lib/mailsafe/receipient_whitelist.rb
100
+ - lib/mailsafe/recipient_whitelist.rb
86
101
  - lib/mailsafe/reroute_interceptor.rb
87
102
  - lib/mailsafe/version.rb
88
103
  - mailsafe.gemspec
89
- - spec/receipient_whitelist_spec.rb
104
+ - spec/recipient_whitelist_spec.rb
105
+ - spec/reroute_interceptor_spec.rb
90
106
  - spec/spec_helper.rb
91
107
  homepage: https://github.com/stemps/mailsafe
92
108
  licenses:
@@ -98,21 +114,22 @@ require_paths:
98
114
  - lib
99
115
  required_ruby_version: !ruby/object:Gem::Requirement
100
116
  requirements:
101
- - - '>='
117
+ - - ">="
102
118
  - !ruby/object:Gem::Version
103
119
  version: '0'
104
120
  required_rubygems_version: !ruby/object:Gem::Requirement
105
121
  requirements:
106
- - - '>='
122
+ - - ">="
107
123
  - !ruby/object:Gem::Version
108
124
  version: '0'
109
125
  requirements: []
110
126
  rubyforge_project:
111
- rubygems_version: 2.0.3
127
+ rubygems_version: 2.4.2
112
128
  signing_key:
113
129
  specification_version: 4
114
130
  summary: Safe emailing for Rails - do not send emails to real users from development
115
131
  or staging environments.
116
132
  test_files:
117
- - spec/receipient_whitelist_spec.rb
133
+ - spec/recipient_whitelist_spec.rb
134
+ - spec/reroute_interceptor_spec.rb
118
135
  - spec/spec_helper.rb
@@ -1,41 +0,0 @@
1
- require 'mailsafe/receipient_whitelist'
2
-
3
- module Mailsafe
4
- class ReceipientWhitelist
5
- def self.filter_receipient_domain(message)
6
- allowed_domain = Mailsafe.allowed_domain
7
- if allowed_domain.present?
8
- receipients = []
9
- message.to.each do |receipient|
10
- if email_has_domain?(receipient, allowed_domain)
11
- receipients << receipient
12
- end
13
- end
14
- message.to = receipients
15
- end
16
- end
17
-
18
- def self.email_has_domain?(email, allowed_domain_config)
19
- allowed_domains = allowed_domain_config.split(',').map(&:strip).map(&:downcase)
20
- email_domain = email.split("@")[1]
21
-
22
- if email_domain.present?
23
- allowed_domains.include? email_domain.downcase
24
- else
25
- false
26
- end
27
- end
28
- end
29
- end
30
-
31
- # Unfortunately, monkeypatching Mail is the only way I found to actually prevent sending an email
32
- require 'mail'
33
-
34
- class Mail::Message
35
- def deliver_with_recipient_filter
36
- Mailsafe::ReceipientWhitelist.filter_receipient_domain(self)
37
- self.deliver_without_recipient_filter unless self.to.blank? || self.to.empty?
38
- end
39
-
40
- alias_method_chain :deliver, :recipient_filter
41
- end
@@ -1,61 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Mailsafe
4
- RSpec.describe ReceipientWhitelist do
5
-
6
- describe ".email_has_domain" do
7
- context "single whitelisted domain" do
8
- let!(:whitelist) { "gmail.com" }
9
-
10
- it "accepts the allowed domains" do
11
- expect(ReceipientWhitelist.email_has_domain?("bert@gmail.com", whitelist)).to be_true
12
- end
13
-
14
- it "does not accept other domains" do
15
- expect(ReceipientWhitelist.email_has_domain?("bert@gmx.de", whitelist)).to be_false
16
- expect(ReceipientWhitelist.email_has_domain?("bert@yahoo.com", whitelist)).to be_false
17
- expect(ReceipientWhitelist.email_has_domain?("bert@ggmail.com", whitelist)).to be_false
18
- expect(ReceipientWhitelist.email_has_domain?("bert@gmail.com.de", whitelist)).to be_false
19
- end
20
- end
21
-
22
- context "multiple whitelisted domains" do
23
- let!(:whitelist) { "gmail.com, gmx.de" }
24
-
25
- it "accepts the allowed domains" do
26
- expect(ReceipientWhitelist.email_has_domain?("bert@gmail.com", whitelist)).to be_true
27
- expect(ReceipientWhitelist.email_has_domain?("bert@gmx.de", whitelist)).to be_true
28
- end
29
-
30
- it "does not accept other domains" do
31
- expect(ReceipientWhitelist.email_has_domain?("bert@yahoo.com", whitelist)).to be_false
32
- expect(ReceipientWhitelist.email_has_domain?("bert@ggmail.com", whitelist)).to be_false
33
- end
34
- end
35
-
36
- context "invalid email addresses" do
37
- let!(:whitelist) { "gmail.com" }
38
-
39
- it "does not accept them" do
40
- expect(ReceipientWhitelist.email_has_domain?("bert", whitelist)).to be_false
41
- end
42
- end
43
-
44
- context "invalid whitelist" do
45
- let!(:whitelist) { "gmail.com, " }
46
-
47
- it "accepts the allowed domains" do
48
- expect(ReceipientWhitelist.email_has_domain?("bert@gmail.com", whitelist)).to be_true
49
- end
50
-
51
- it "does not accept other domains" do
52
- expect(ReceipientWhitelist.email_has_domain?("bert@gmx.de", whitelist)).to be_false
53
- expect(ReceipientWhitelist.email_has_domain?("bert@yahoo.com", whitelist)).to be_false
54
- expect(ReceipientWhitelist.email_has_domain?("bert@ggmail.com", whitelist)).to be_false
55
- expect(ReceipientWhitelist.email_has_domain?("bert@gmail.com.de", whitelist)).to be_false
56
- end
57
- end
58
-
59
- end
60
- end
61
- end