sanitize_email 0.3.9 → 1.0.0.alpha2

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,34 @@
1
+ module SanitizeEmail
2
+ class Config
3
+ cattr_accessor :config
4
+ self.config ||= {
5
+ # Adds the following class attributes to the classes that include NinthBit::SanitizeEmail
6
+ :force_sanitize => nil,
7
+
8
+ # Specify the BCC addresses for the messages that go out in 'local' environments
9
+ :sanitized_bcc => nil,
10
+
11
+ # Specify the CC addresses for the messages that go out in 'local' environments
12
+ :sanitized_cc => nil,
13
+
14
+ # The recipient addresses for the messages, either as a string (for a single
15
+ # address) or an array (for multiple addresses) that go out in 'local' environments
16
+ :sanitized_recipients => nil,
17
+
18
+ # Use the 'real' email address as the username for the sanitized email address
19
+ # e.g. "real@example.com <sanitized@example.com>"
20
+ :use_actual_email_as_sanitized_user_name => false,
21
+
22
+ # Prepend the 'real' email address onto the Subject line of the message
23
+ # e.g. "real@example.com rest of subject"
24
+ :use_actual_email_prepended_to_subject => false,
25
+
26
+ :local_environments => %w( development test )
27
+ }
28
+
29
+ def self.configure &block
30
+ yield self.config
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,12 @@
1
+ #Copyright (c) 2008-12 Peter H. Boling of 9thBit LLC
2
+ #Released under the MIT license
3
+ # For Rails >= 3.1
4
+ module SanitizeEmail
5
+ class Engine < ::Rails::Engine
6
+
7
+ config.to_prepare do
8
+ ActionMailer::Base.register_interceptor(SanitizeEmail::Hook)
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,30 @@
1
+ #Copyright (c) 2008-12 Peter H. Boling of 9thBit LLC
2
+ #Released under the MIT license
3
+
4
+ module SanitizeEmail
5
+ class Hook
6
+
7
+ include SanitizeEmail::Sanitizer
8
+
9
+ def self.delivering_email(message)
10
+ if self.localish?
11
+ message.subject = self.subject_override(message.subject, message.to)
12
+ message.to = self.recipients_override(message.to)
13
+ message.cc = self.cc_override(message.cc)
14
+ message.bcc = self.bcc_override(message.bcc)
15
+ end
16
+ end
17
+
18
+ def self.consider_local?
19
+ SanitizeEmail.local_environments.include?(Rails.env) if defined?(Rails)
20
+ end
21
+
22
+ # This method will be called by the Hook to determine if an override should occur
23
+ def self.localish?
24
+ !SanitizeEmail.force_sanitize.nil? ? SanitizeEmail.force_sanitize : self.consider_local?
25
+ end
26
+
27
+ end # end Class Hook
28
+ end # end Module SanitizeEmail
29
+
30
+
@@ -0,0 +1,12 @@
1
+ #Copyright (c) 2008-12 Peter H. Boling of 9thBit LLC
2
+ #Released under the MIT license
3
+ # For Rails 3.0, which didn't yet support Engines'
4
+ module SanitizeEmail
5
+ class Railtie < ::Rails::Railtie
6
+
7
+ config.before_configuration do
8
+ ActionMailer::Base.register_interceptor(SanitizeEmail::Hook)
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,73 @@
1
+ #Copyright (c) 2008-12 Peter H. Boling of 9thBit LLC
2
+ #Released under the MIT license
3
+ module SanitizeEmail
4
+ module Sanitizer
5
+ def self.included(base)
6
+ base.extend SanitizeEmail::Sanitizer::ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def subject_override(real_subject, actual_addresses)
12
+ if actual_addresses.nil? || !SanitizeEmail.use_actual_email_prepended_to_subject
13
+ real_subject
14
+ else
15
+ "(#{actual_addresses.join(',').gsub(/@/,' at ').gsub(/[<>]/,'~')}) #{real_subject}"
16
+ end
17
+ end
18
+
19
+ def recipients_override(actual_addresses)
20
+ override_email(:recipients, actual_addresses)
21
+ end
22
+
23
+ def cc_override(actual_addresses)
24
+ override_email(:cc, actual_addresses)
25
+ end
26
+
27
+ def bcc_override(actual_addresses)
28
+ override_email(:bcc, actual_addresses)
29
+ end
30
+
31
+ #######
32
+ private
33
+ #######
34
+
35
+ def override_email(type, actual_addresses)
36
+ real_addresses, sanitized_addresses = case type
37
+ when :recipients
38
+ [actual_addresses, SanitizeEmail.sanitized_recipients]
39
+ when :cc
40
+ [actual_addresses, SanitizeEmail.sanitized_cc]
41
+ when :bcc
42
+ [actual_addresses, SanitizeEmail.sanitized_bcc]
43
+ else raise "sanitize_email error: unknown email override"
44
+ end
45
+ # Normalize to an array
46
+ real_addresses = [real_addresses] unless real_addresses.is_a?(Array)
47
+ # Normalize to an array
48
+ sanitized_addresses = [sanitized_addresses] unless sanitized_addresses.is_a?(Array)
49
+
50
+ # If there were no original recipients, then we DO NOT override the nil with the sanitized recipients
51
+ return nil if real_addresses.blank?
52
+ # If there are no sanitized addresses we can't override!
53
+ return nil if sanitized_addresses.blank?
54
+ # If we don't want to inject the actual email in the 'user name' section of the sanitized recipients,
55
+ # then just return the default sanitized recipients
56
+ return sanitized_addresses unless SanitizeEmail.use_actual_email_as_sanitized_user_name
57
+
58
+ out = real_addresses.inject([]) do |result, real_recipient|
59
+ if real_recipient.nil?
60
+ new_recipient = sanitized_addresses
61
+ else
62
+ new_recipient = sanitized_addresses.map{|sanitized| "#{real_recipient.gsub(/@/,' at ').gsub(/[<>]/,'~')} <#{sanitized}>"}
63
+ end
64
+ result << new_recipient
65
+ result
66
+ end.flatten
67
+ return out
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+ end
@@ -1,3 +1,5 @@
1
+ #Copyright (c) 2008-12 Peter H. Boling of 9thBit LLC
2
+ #Released under the MIT license
1
3
  module SanitizeEmail
2
- VERSION = "0.3.9"
4
+ VERSION = '1.0.0.alpha2'
3
5
  end
@@ -1,26 +1,85 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'sanitize_email/version'
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
5
 
6
- Gem::Specification.new do |spec|
7
- spec.name = "sanitize_email"
8
- spec.version = SanitizeEmail::VERSION
9
- spec.authors = ["Peter Boling", "John Trupiano", "George Anderson"]
10
- spec.email = ["peter.boling@gmail.com", "jtrupiano@gmail.com", "george@benevolentcode.com"]
11
- spec.summary = %q{Test an application's email abilities without ever sending a message to actual live addresses}
12
- spec.description = %q{Test an application's email abilities without ever sending a message to actual live addresses}
13
- spec.homepage = "http://github.com/pboling/sanitize_email"
14
- spec.license = "MIT"
15
- spec.rdoc_options = ["--charset=UTF-8"]
6
+ Gem::Specification.new do |s|
7
+ s.name = "sanitize_email"
8
+ s.version = "1.0.0.alpha2"
16
9
 
17
- spec.files = `git ls-files -z`.split("\x0")
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
- spec.require_paths = ["lib"]
10
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Peter Boling", "John Trupiano", "George Anderson"]
12
+ s.date = "2012-07-28"
13
+ s.description = "Tool to aid in development, testing, qa, and production troubleshooting of email issues without worrying that emails will get sent to actual live addresses."
14
+ s.email = ["peter.boling@gmail.com", "jtrupiano@gmail.com", "george@benevolentcode.com"]
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".rspec",
20
+ "CHANGELOG",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "MIT-LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION.yml",
27
+ "init.rb",
28
+ "lib/sanitize_email.rb",
29
+ "lib/sanitize_email/config.rb",
30
+ "lib/sanitize_email/engine.rb",
31
+ "lib/sanitize_email/hook.rb",
32
+ "lib/sanitize_email/railtie.rb",
33
+ "lib/sanitize_email/sanitizer.rb",
34
+ "lib/sanitize_email/version.rb",
35
+ "sanitize_email.gemspec",
36
+ "spec/sanitize_email_spec.rb",
37
+ "spec/spec_helper.rb",
38
+ "spec/tmp/mail_dump/1343461037_3f3edd7/plain.html"
39
+ ]
40
+ s.homepage = "http://github.com/pboling/sanitize_email"
41
+ s.licenses = ["MIT"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = "1.8.24"
44
+ s.summary = "Test an application's email abilities without ever sending a message to actual live addresses"
21
45
 
22
- spec.add_runtime_dependency(%q<actionmailer>, [">= 0",'<= 3.1'])
46
+ if s.respond_to? :specification_version then
47
+ s.specification_version = 3
23
48
 
24
- spec.add_development_dependency "bundler", "~> 1.5"
25
- spec.add_development_dependency "rake"
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
+ s.add_runtime_dependency(%q<rails>, ["> 3"])
51
+ s.add_runtime_dependency(%q<actionmailer>, ["> 3"])
52
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
53
+ s.add_development_dependency(%q<letter_opener>, [">= 0"])
54
+ s.add_development_dependency(%q<launchy>, [">= 0"])
55
+ s.add_development_dependency(%q<rspec>, [">= 0"])
56
+ s.add_development_dependency(%q<mail>, [">= 0"])
57
+ s.add_development_dependency(%q<rdoc>, [">= 3.12"])
58
+ s.add_development_dependency(%q<reek>, [">= 1.2.8"])
59
+ s.add_development_dependency(%q<roodi>, [">= 2.1.0"])
60
+ else
61
+ s.add_dependency(%q<rails>, ["> 3"])
62
+ s.add_dependency(%q<actionmailer>, ["> 3"])
63
+ s.add_dependency(%q<jeweler>, [">= 0"])
64
+ s.add_dependency(%q<letter_opener>, [">= 0"])
65
+ s.add_dependency(%q<launchy>, [">= 0"])
66
+ s.add_dependency(%q<rspec>, [">= 0"])
67
+ s.add_dependency(%q<mail>, [">= 0"])
68
+ s.add_dependency(%q<rdoc>, [">= 3.12"])
69
+ s.add_dependency(%q<reek>, [">= 1.2.8"])
70
+ s.add_dependency(%q<roodi>, [">= 2.1.0"])
71
+ end
72
+ else
73
+ s.add_dependency(%q<rails>, ["> 3"])
74
+ s.add_dependency(%q<actionmailer>, ["> 3"])
75
+ s.add_dependency(%q<jeweler>, [">= 0"])
76
+ s.add_dependency(%q<letter_opener>, [">= 0"])
77
+ s.add_dependency(%q<launchy>, [">= 0"])
78
+ s.add_dependency(%q<rspec>, [">= 0"])
79
+ s.add_dependency(%q<mail>, [">= 0"])
80
+ s.add_dependency(%q<rdoc>, [">= 3.12"])
81
+ s.add_dependency(%q<reek>, [">= 1.2.8"])
82
+ s.add_dependency(%q<roodi>, [">= 2.1.0"])
83
+ end
26
84
  end
85
+
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe SanitizeEmail do
4
+
5
+ SanitizeEmail::Config.configure do |config|
6
+ config[:sanitized_recipients] = 'to@sanitize_email.org'
7
+ config[:sanitized_bcc] = 'bcc@sanitize_email.org'
8
+ config[:sanitized_cc] = 'cc@sanitize_email.org'
9
+ config[:local_environments] = []
10
+ config[:use_actual_email_prepended_to_subject] = true
11
+ config[:use_actual_email_as_sanitized_user_name] = true
12
+ end
13
+
14
+ def sanitize_mail_delivery(sanitization_switch = false)
15
+ # Ensure that localish? will returns sanitization_switch
16
+ SanitizeEmail::Config.config[:force_sanitize] = sanitization_switch
17
+ Launchy.should_receive(:open)
18
+ mail = Mail.deliver do
19
+ from 'from@example.org'
20
+ to 'to@example.org'
21
+ cc 'cc@example.org'
22
+ reply_to 'reply_to@example.org'
23
+ subject 'original subject'
24
+ end
25
+ end
26
+
27
+ before(:each) do
28
+ Launchy.stub(:open)
29
+ location = File.expand_path('../tmp/mail_dump', __FILE__)
30
+ FileUtils.rm_rf(location)
31
+ Mail.defaults do
32
+ delivery_method LetterOpener::DeliveryMethod, :location => location
33
+ end
34
+ Mail.register_interceptor(SanitizeEmail::Hook)
35
+ @location = location
36
+ end
37
+
38
+ context "localish? is false" do
39
+ it "alters nothing" do
40
+ sanitize_mail_delivery(false)
41
+ # All the email gets dumped to file once for each type of recipient (:to, :cc, :bcc)
42
+ # Each file is identical, so we only need to check one of them:
43
+ email = File.read(Dir["#{@location}/*/plain.html"].first)
44
+ email.should have_from("from@example.org")
45
+ email.should have_to("to@example.org")
46
+ # Letter Opener won't let us test the cc
47
+ #email.should have_cc("cc@example.org")
48
+ # Letter Opener won't let us test the bcc
49
+ #email.should have_bcc("cc@example.org")
50
+ email.should have_subject("original subject")
51
+ end
52
+ end
53
+
54
+ context "localish? is true" do
55
+ it "should override" do
56
+ sanitize_mail_delivery(true)
57
+ # All the email gets dumped to file once for each type of recipient (:to, :cc, :bcc)
58
+ # Each file is identical, so we only need to check one of them:
59
+ email = File.read(Dir["#{@location}/*/plain.html"].first)
60
+ email.should have_from("from@example.org")
61
+ # Letter Opener won't let us test the to when the to has a 'user name'
62
+ #email.should have_to("~to at example.org~ <to@sanitize_email.org>")
63
+ # Letter Opener won't let us test the bcc
64
+ #email.should have_cc("cc@sanitize_email.org")
65
+ email.should have_subject("(to at example.org) original subject")
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,40 @@
1
+ require 'sanitize_email'
2
+ require 'launchy'
3
+ require 'mail'
4
+ require 'rails'
5
+ require 'letter_opener'
6
+
7
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
8
+ RSpec.configure do |config|
9
+ config.treat_symbols_as_metadata_keys_with_true_values = true
10
+ config.run_all_when_everything_filtered = true
11
+ #config.filter_run :focus
12
+ end
13
+
14
+ RSpec::Matchers.define :have_from do |from|
15
+ match do |container|
16
+ container =~ Regexp.new(Regexp.escape(from))
17
+ end
18
+ end
19
+ RSpec::Matchers.define :have_to do |to|
20
+ match do |container|
21
+ container =~ Regexp.new(Regexp.escape(to))
22
+ end
23
+ end
24
+ RSpec::Matchers.define :have_cc do |cc|
25
+ match do |container|
26
+ container =~ Regexp.new(Regexp.escape(cc))
27
+ end
28
+ end
29
+ # The ActionMailer :file delivery method never prints bcc recipients...
30
+ # so not testable as such, but with letter_opener we can work magic
31
+ RSpec::Matchers.define :have_bcc do |bcc|
32
+ match do |container|
33
+ container =~ Regexp.new(Regexp.escape(bcc))
34
+ end
35
+ end
36
+ RSpec::Matchers.define :have_subject do |subject|
37
+ match do |container|
38
+ container =~ Regexp.new(Regexp.escape(subject))
39
+ end
40
+ end
@@ -0,0 +1,76 @@
1
+ <style type="text/css">
2
+ #message_headers {
3
+ position: absolute;
4
+ top: 0px;
5
+ left: 0;
6
+ width: 100%;
7
+ height: 85px;
8
+ padding: 10px 0 0 0;
9
+ margin: 0;
10
+ background: #fff;
11
+ font-size: 12px;
12
+ font-family: "Lucida Grande";
13
+ border-bottom: 1px solid #dedede;
14
+ overflow: hidden;
15
+ }
16
+
17
+ #message_headers dl {
18
+ margin: 0;
19
+ padding: 0;
20
+ }
21
+
22
+ #message_headers dt {
23
+ width: 60px;
24
+ padding: 1px;
25
+ float: left;
26
+ text-align: right;
27
+ font-weight: bold;
28
+ color: #7f7f7f;
29
+ }
30
+
31
+ #message_headers dd {
32
+ margin-left: 70px;
33
+ padding: 1px;
34
+ }
35
+
36
+ #message_headers p.alternate {
37
+ position: absolute;
38
+ top: 0;
39
+ right: 15px;
40
+ }
41
+
42
+ #message_headers p.alternate a {
43
+ color: #09c;
44
+ }
45
+
46
+ pre#message_body {
47
+ padding: 10px;
48
+ word-wrap: break-word;
49
+ }
50
+
51
+ body {
52
+ margin-top: 96px;
53
+ }
54
+ </style>
55
+
56
+ <div id="message_headers">
57
+ <dl>
58
+ <dt>From:</dt>
59
+ <dd>from@example.org</dd>
60
+
61
+ <dt>Subject:</dt>
62
+ <dd><strong>(to at example.org) original subject</strong></dd>
63
+
64
+ <dt>Date:</dt>
65
+ <dd>Jul 28, 2012 03:37:17 AM EDT</dd>
66
+
67
+ <dt>To:</dt>
68
+ <dd>to@sanitize_email.org</dd>
69
+ </dl>
70
+
71
+
72
+ </div>
73
+
74
+
75
+ <pre id="message_body"></pre>
76
+