email_verifier 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.
data/.README.md.swp ADDED
Binary file
data/.gitignore ADDED
@@ -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
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in verifier.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Kamil Ciemniewski
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.
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # Email Verifier
2
+
3
+ Helper validation utility for checking whether given email address is real or not.
4
+ Many times as developers we've put in our models statements for checking email address
5
+ *format*. This gem will complete your existing setups with validator that actually
6
+ connects with given mail server and asks if given email address exists for real.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'email_verifier'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install verifier
21
+
22
+ ## Usage
23
+
24
+ Just put this in your model e. g:
25
+
26
+ validates_email_realness_of :email
27
+
28
+ Or - if you'd like to use it outside of your models:
29
+
30
+ EmailValidator.check(youremail)
31
+
32
+ This method will return true or false, or - will throw exception
33
+ with nicely detailed info about what's wrong.
34
+
35
+ ## Credits
36
+ ![End Point Corporation](http://www.endpoint.com/images/end_point.png)
37
+
38
+ Email Verifier is maintained and funded by [End Point Corporation](http://www.endpoint.com/)
39
+
40
+ Please send questions to [kamil@endpoint.com](mailto:kamil@endpoint.com)
41
+
42
+ ## Contributing
43
+
44
+ 1. Fork it
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
47
+ 4. Push to the branch (`git push origin my-new-feature`)
48
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'email_verifier/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "email_verifier"
8
+ gem.version = EmailVerifier::VERSION
9
+ gem.authors = ["Kamil Ciemniewski"]
10
+ gem.email = ["kamil@endpoint.com"]
11
+ gem.description = %q{Helper utility checking if given email address exists or not}
12
+ gem.summary = %q{Helper utility checking if given email address exists or not}
13
+ gem.homepage = "http://endpoint.com"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
Binary file
Binary file
@@ -0,0 +1,94 @@
1
+ require 'net/smtp'
2
+
3
+ class EmailVerifier::Checker
4
+
5
+ ##
6
+ # Returns server object for given email address or throws exception
7
+ # Object returned isn't yet connected. It has internally a list of
8
+ # real mail servers got from MX dns lookup
9
+ def initialize(address)
10
+ @email = address
11
+ @domain = address.split("@").last
12
+ @servers = list_mxs @domain
13
+ raise EmailVerifier::NoMailServerException.new("No mail server for #{address}") if @servers.empty?
14
+ @smtp = nil
15
+
16
+ # this is because some mail servers won't give any info unless
17
+ # a real user asks for it:
18
+ @user_email = EmailVerifier.config.verifier_email
19
+ end
20
+
21
+ def list_mxs(domain)
22
+ `host -t MX #{domain}`.scan(/(?<=by ).+/).map do |mx|
23
+ res = mx.split(" ")
24
+ next if res.last[0..-2].strip.empty?
25
+ { priority: res.first.to_i, address: res.last[0..-2] }
26
+ end.reject(&:nil?).sort_by { |mx| mx[:priority] }
27
+ end
28
+
29
+ def is_connected
30
+ !@smtp.nil?
31
+ end
32
+
33
+ def connect
34
+ begin
35
+ server = next_server
36
+ raise EmailVerifier::OutOfMailServersException.new("Unable to connect to any one of mail servers for #{@email}") if server.nil?
37
+ @smtp = Net::SMTP.start(server[:address], 25)
38
+ return true
39
+ rescue EmailVerifier::OutOfMailServersException => e
40
+ return false
41
+ rescue => e
42
+ retry
43
+ end
44
+ end
45
+
46
+ def next_server
47
+ @servers.shift
48
+ end
49
+
50
+ def verify
51
+ self.helo @user_email
52
+ self.mailfrom @user_email
53
+ self.rcptto(@email)
54
+ end
55
+
56
+ def helo(address)
57
+ ensure_connected
58
+
59
+ ensure_250 @smtp.helo(@domain)
60
+ end
61
+
62
+ def mailfrom(address)
63
+ ensure_connected
64
+
65
+ ensure_250 @smtp.mailfrom(address)
66
+ end
67
+
68
+ def rcptto(address)
69
+ ensure_connected
70
+
71
+ begin
72
+ ensure_250 @smtp.rcptto(address)
73
+ rescue => e
74
+ if e.message[/^550/]
75
+ return false
76
+ else
77
+ raise EmailVerifier::FailureException.new(e.message)
78
+ end
79
+ end
80
+ end
81
+
82
+ def ensure_connected
83
+ raise EmailVerifier::NotConnectedException.new("You have to connect first") if @smtp.nil?
84
+ end
85
+
86
+ def ensure_250(smtp_return)
87
+ if smtp_return.status.to_i == 250
88
+ return true
89
+ else
90
+ raise EmailVerifier::FailureException.new "Mail server responded with #{smtp_return.status} when we were expecting 250"
91
+ end
92
+ end
93
+
94
+ end
@@ -0,0 +1,12 @@
1
+ module EmailVerifier
2
+ module Config
3
+ class << self
4
+ attr_accessor :verifier_email
5
+
6
+ def reset
7
+ @verifier_email = "nobody@nonexistant.com"
8
+ end
9
+ end
10
+ self.reset
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+
2
+ module EmailVerifier
3
+
4
+ class NoMailServerException < StandardError; end
5
+ class OutOfMailServersException < StandardError; end
6
+ class NotConnectedException < StandardError; end
7
+ class FailureException < StandardError; end
8
+
9
+ end
@@ -0,0 +1,32 @@
1
+ require "active_record"
2
+
3
+ module EmailVerifier
4
+ module ValidatesEmailRealness
5
+
6
+ module Validator
7
+ class EmailRealnessValidator < ActiveModel::EachValidator
8
+ def validate_each(record, attribute, value)
9
+ begin
10
+ record.errors.add attribute, 'must point to a real mail account' unless EmailVerifier.check(value)
11
+ rescue EmailVerifier::OutOfMailServersException
12
+ record.errors.add attribute, 'appears to point to dead mail server'
13
+ rescue EmailVerifier::NoMailServerException
14
+ record.errors.add attribute, "appears to point to domain which doesn't handle e-mail"
15
+ rescue EmailVerifier::FailureException
16
+ record.errors.add attribute, "could not be checked if is real"
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ module ClassMethods
23
+ def validates_email_realness_of(*attr_names)
24
+ validates_with ActiveRecord::Base::EmailRealnessValidator, _merge_attributes(attr_names)
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+
31
+ ActiveRecord::Base.send(:include, EmailVerifier::ValidatesEmailRealness::Validator)
32
+ ActiveRecord::Base.send(:extend, EmailVerifier::ValidatesEmailRealness::ClassMethods)
@@ -0,0 +1,3 @@
1
+ module EmailVerifier
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,22 @@
1
+ require "email_verifier/version"
2
+
3
+ module EmailVerifier
4
+ require 'email_verifier/checker'
5
+ require 'email_verifier/exceptions'
6
+ require 'email_verifier/config'
7
+ require "email_verifier/validates_email_realness"
8
+
9
+ def self.check(email)
10
+ v = EmailVerifier::Checker.new(email)
11
+ v.connect
12
+ v.verify
13
+ end
14
+
15
+ def self.config(&block)
16
+ if block_given?
17
+ block.call(EmailVerifier::Config)
18
+ else
19
+ EmailVerifier::Config
20
+ end
21
+ end
22
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'email_verifier'
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: email_verifier
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kamil Ciemniewski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-13 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Helper utility checking if given email address exists or not
15
+ email:
16
+ - kamil@endpoint.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .README.md.swp
22
+ - .gitignore
23
+ - Gemfile
24
+ - LICENSE.txt
25
+ - README.md
26
+ - Rakefile
27
+ - email_verifier.gemspec
28
+ - lib/.verifier.rb.swp
29
+ - lib/email_verifier.rb
30
+ - lib/email_verifier/.server.rb.swp
31
+ - lib/email_verifier/.validates_email_realness.rb.swp
32
+ - lib/email_verifier/checker.rb
33
+ - lib/email_verifier/config.rb
34
+ - lib/email_verifier/exceptions.rb
35
+ - lib/email_verifier/validates_email_realness.rb
36
+ - lib/email_verifier/version.rb
37
+ - rails/init.rb
38
+ homepage: http://endpoint.com
39
+ licenses: []
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ segments:
51
+ - 0
52
+ hash: -1110459712102920340
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ segments:
60
+ - 0
61
+ hash: -1110459712102920340
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 1.8.23
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: Helper utility checking if given email address exists or not
68
+ test_files: []