email_domain_validator 0.0.1

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: d575d0411e6af35d7700ebf5ec9f0dd0a033ccb6
4
+ data.tar.gz: 3711b6e48446125d946ec9c5eb7b500d18576062
5
+ SHA512:
6
+ metadata.gz: 2134efaceda88b7c0ebca822add75a008a351f4093282ee2de0ee193265d463cd4f638ea8c5d98c61e0c5338630b5f86e9521c2c86bc23b972abe234ce03cf80
7
+ data.tar.gz: 17af139aff1088cf8d5ecbd8b4637d2f7bdc8ef4305630a80c5708682e925163066a1889f6ef2ad75a1da288d50f600490fa8a823cf5ac8e2c5369b58e54b1b7
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in email_domain_validator.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 lulalala
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,62 @@
1
+ # EmailDomainValidator
2
+
3
+ Email address's domain validator by checking presence of MX and A record.
4
+
5
+ Extra filters are available such as caching and whitelisting.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'email_domain_validator'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install email_domain_validator
22
+
23
+ ## Usage
24
+
25
+ Validate email:
26
+
27
+ v = EmailDomainValidator.new
28
+ v.valid?('saki@yahoo.co.jp')
29
+
30
+ Add cache filter
31
+
32
+ v.add_filter(:rails_cache, expires_in: 12.hours)
33
+ v.valid?('saki@yahoo.co.jp')
34
+ v.valid?('amy@yahoo.co.jp') # same domain will not be checked again
35
+
36
+ ## Filters
37
+
38
+ ### dummy
39
+
40
+ Always returns true. Useful for testing or development purposes.
41
+
42
+ v.add_filter(:dummy)
43
+
44
+ ### rails_cache
45
+
46
+ Use Rails' caching capability to cache lookup results. Options used in Rails caching such as :expires_in can be used here.
47
+
48
+ v.add_filter(:rails_cache, expires_in: 12.hours, race_condition_ttl: 1)
49
+
50
+ ### whitelist
51
+
52
+ Declare a whitelist of domains which will always be considered valid.
53
+
54
+ v.add_filter(:rails_cache, ['yahoo.com.tw', 'gmail.com'])
55
+
56
+ ## Contributing
57
+
58
+ 1. Fork it ( https://github.com/[my-github-username]/email_domain_validator/fork )
59
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
60
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
61
+ 4. Push to the branch (`git push origin my-new-feature`)
62
+ 5. Create a new Pull Request
@@ -0,0 +1,4 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new('spec')
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'email_domain_validator/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "email_domain_validator"
8
+ spec.version = EmailDomainValidator::VERSION
9
+ spec.authors = ["lulalala"]
10
+ spec.email = ["mark@goodlife.tw"]
11
+ spec.summary = %q{Validates Email address domains using MX and A records, with caching and whitelisting.}
12
+ spec.description = %q{Validates Email address domains using MX and A records, with caching and whitelisting.}
13
+ spec.homepage = "https://github.com/lulalala/email_domain_validator"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", '~> 3.1'
24
+ end
@@ -0,0 +1,41 @@
1
+ require "email_domain_validator/version"
2
+ require "email_domain_validator/core"
3
+
4
+ class EmailDomainValidator
5
+ def initialize
6
+ @validator = Core.new
7
+ end
8
+
9
+ def valid?(email)
10
+ domain = self.class.get_domain(email)
11
+
12
+ if domain.nil? || domain.empty?
13
+ return false
14
+ end
15
+
16
+ @validator.valid?(domain)
17
+ end
18
+
19
+ def add_filter(filter_class, options={})
20
+ require_path = "email_domain_validator/#{filter_class}"
21
+
22
+ require require_path
23
+
24
+ klass = self.class.constantize(require_path)
25
+
26
+ @validator = klass.new(@validator, options)
27
+ end
28
+
29
+ private
30
+
31
+ # @email
32
+ def self.get_domain(email)
33
+ email[/@(.*)/,1]
34
+ end
35
+
36
+ def self.constantize(string)
37
+ string.split('/').inject(Object){|o,c|
38
+ o.const_get(c.split('_').map{|e| e.capitalize}.join)
39
+ }
40
+ end
41
+ end
@@ -0,0 +1,8 @@
1
+ class EmailDomainValidator::Core
2
+ def valid?(domain)
3
+ Resolv::DNS.open do |dns|
4
+ return dns.getresources(domain, Resolv::DNS::Resource::IN::MX).size > 0 ||
5
+ dns.getresources(domain, Resolv::DNS::Resource::IN::A).size > 0
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ class EmailDomainValidator::Dummy
2
+ def initialize(app, options = nil)
3
+ end
4
+
5
+ def valid?(domain)
6
+ true
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ class EmailDomainValidator::RailsCache
2
+ def initialize(app, options = {})
3
+ @app = app
4
+ @options = options
5
+ end
6
+
7
+ def valid?(domain)
8
+ result = Rails.cache.read(self.class.cache_key(domain))
9
+ if result.nil?
10
+ result = @app.valid?(domain)
11
+ Rails.cache.write(self.class.cache_key(domain), result, @options)
12
+ end
13
+ result
14
+ end
15
+
16
+ def self.cache_key(domain)
17
+ [:email_domain_validator, domain]
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ class EmailDomainValidator
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,14 @@
1
+ class EmailDomainValidator::Whitelist
2
+ def initialize(app, whitelist = [])
3
+ @app = app
4
+ @whitelist = whitelist
5
+ end
6
+
7
+ def valid?(domain)
8
+ if @whitelist.include?(domain)
9
+ true
10
+ else
11
+ @app.valid?(domain)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ require_relative '../helper'
2
+ require 'email_domain_validator/core'
3
+
4
+ RSpec.describe EmailDomainValidator::Core do
5
+ it 'returns true for valid domain' do
6
+ subject.valid?('example.com').should == true
7
+ subject.valid?('gmail.com').should == true
8
+ subject.valid?('hotmail.com').should == true
9
+ subject.valid?('yahoo.com').should == true
10
+ end
11
+
12
+ it 'returns true for domain with only A record but no MX record' do
13
+ subject.valid?('lulalala.com').should == true
14
+ end
15
+
16
+ it 'returns false for invalid domain' do
17
+ subject.valid?('anonymous.invalid').should == false
18
+ subject.valid?('gmail.comm1').should == false
19
+ end
20
+ end
21
+
@@ -0,0 +1,14 @@
1
+ require 'helper'
2
+ require 'email_domain_validator/dummy'
3
+
4
+ describe EmailDomainValidator::Dummy do
5
+ let(:core){ double(:core_app) }
6
+ subject{ described_class.new(core) }
7
+
8
+ it 'returns true always' do
9
+ core.should_not_receive(:valid?)
10
+
11
+ subject.valid?('localhost').should == true
12
+ subject.valid?('test').should == true
13
+ end
14
+ end
@@ -0,0 +1,55 @@
1
+ require 'helper'
2
+ require 'email_domain_validator/rails_cache'
3
+
4
+ dummy_cache = Object.new
5
+ def dummy_cache.valid?; end
6
+ def dummy_cache.post_check; end
7
+
8
+ module Rails
9
+ class DummyCache
10
+ def read(key)
11
+ store[key]
12
+ end
13
+
14
+ def write(key, value, options)
15
+ store[key] = value
16
+ end
17
+
18
+ def store
19
+ @store ||= {}
20
+ end
21
+ end
22
+
23
+ def self.cache
24
+ @cache ||= DummyCache.new
25
+ end
26
+
27
+ def self.reset
28
+ @cache = DummyCache.new
29
+ end
30
+ end
31
+
32
+ describe EmailDomainValidator::RailsCache do
33
+ let(:core){ double(:core_app) }
34
+ subject{ described_class.new(core) }
35
+
36
+ before do
37
+ Rails.reset
38
+ end
39
+
40
+ it 'returns true if cached' do
41
+ Rails.cache.write(described_class.cache_key('localhost'), true, nil)
42
+
43
+ core.should_not_receive(:valid?)
44
+
45
+ subject.valid?('localhost').should == true
46
+ end
47
+
48
+ it 'caches result' do
49
+ core.stub(:valid?){ true }
50
+
51
+ subject.valid?('localhost')
52
+
53
+ Rails.cache.read(described_class.cache_key('localhost')).should == true
54
+ end
55
+ end
@@ -0,0 +1,22 @@
1
+ require 'helper'
2
+ require 'email_domain_validator/whitelist'
3
+
4
+ describe EmailDomainValidator::Whitelist do
5
+ let(:core){ double(:core_app) }
6
+ subject{
7
+ described_class.new(core, ['gmail.com', 'yahoo.com.tw'])
8
+ }
9
+
10
+ it 'returns true if in whitelist' do
11
+ core.should_not_receive(:valid?)
12
+
13
+ subject.valid?('gmail.com').should == true
14
+ subject.valid?('yahoo.com.tw').should == true
15
+ end
16
+
17
+ it 'calls inner app if not in whitelist' do
18
+ core.should_receive(:valid?)
19
+
20
+ subject.valid?('yahoo.co.uk')
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+ require 'helper'
2
+ require 'email_domain_validator'
3
+ require 'email_domain_validator/dummy'
4
+
5
+ describe EmailDomainValidator do
6
+ it 'has version' do
7
+ described_class.const_get('VERSION').empty?.should == false
8
+ end
9
+
10
+ it 'returns false if domain cannot be extracted from provided email address' do
11
+ subject.valid?('not_email_address').should == false
12
+ subject.valid?('').should == false
13
+ end
14
+
15
+ describe '.get_domain' do
16
+ it 'fetches domain from email address' do
17
+ described_class.send(:get_domain, 'akira@gmail.com').should == 'gmail.com'
18
+ described_class.send(:get_domain, 'saki@yahoo.co.jp').should == 'yahoo.co.jp'
19
+ described_class.send(:get_domain, 'pants+spam@scipkr.co.jp').should == 'scipkr.co.jp'
20
+ end
21
+ end
22
+
23
+ describe '#add_filter' do
24
+ it 'wraps middleware with another middleware' do
25
+ EmailDomainValidator::Dummy.any_instance.should_receive :valid?
26
+
27
+ subject.add_filter(:dummy)
28
+
29
+ subject.valid?('test@localhost')
30
+ end
31
+ end
32
+
33
+ describe '.constantize' do
34
+ it 'returns middleware constant' do
35
+ described_class.send(:constantize, 'email_domain_validator/dummy').should == EmailDomainValidator::Dummy
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+
3
+ begin
4
+ require 'bundler'
5
+ rescue LoadError => e
6
+ STDERR.puts e.message
7
+ STDERR.puts "Run `gem install bundler` to install Bundler."
8
+ exit e.status_code
9
+ end
10
+
11
+ begin
12
+ Bundler.setup(:default, :development, :test)
13
+ rescue Bundler::BundlerError => e
14
+ STDERR.puts e.message
15
+ STDERR.puts "Run `bundle install` to install missing gems."
16
+ exit e.status_code
17
+ end
18
+
19
+ RSpec.configure do |config|
20
+ config.expect_with :rspec do |c|
21
+ c.syntax = :should
22
+ end
23
+ config.mock_with :rspec do |c|
24
+ c.syntax = :should
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: email_domain_validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - lulalala
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-23 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.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
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.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
55
+ description: Validates Email address domains using MX and A records, with caching
56
+ and whitelisting.
57
+ email:
58
+ - mark@goodlife.tw
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - email_domain_validator.gemspec
69
+ - lib/email_domain_validator.rb
70
+ - lib/email_domain_validator/core.rb
71
+ - lib/email_domain_validator/dummy.rb
72
+ - lib/email_domain_validator/rails_cache.rb
73
+ - lib/email_domain_validator/version.rb
74
+ - lib/email_domain_validator/whitelist.rb
75
+ - spec/email_domain_validator/core_spec.rb
76
+ - spec/email_domain_validator/dummy_spec.rb
77
+ - spec/email_domain_validator/rails_cache_spec.rb
78
+ - spec/email_domain_validator/whitelist_spec.rb
79
+ - spec/email_domain_validator_spec.rb
80
+ - spec/helper.rb
81
+ homepage: https://github.com/lulalala/email_domain_validator
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.2.2
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Validates Email address domains using MX and A records, with caching and
105
+ whitelisting.
106
+ test_files:
107
+ - spec/email_domain_validator/core_spec.rb
108
+ - spec/email_domain_validator/dummy_spec.rb
109
+ - spec/email_domain_validator/rails_cache_spec.rb
110
+ - spec/email_domain_validator/whitelist_spec.rb
111
+ - spec/email_domain_validator_spec.rb
112
+ - spec/helper.rb