gman 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +20 -0
- data/gman.gemspec +3 -1
- data/lib/gman.rb +35 -13
- data/test/test_gman.rb +52 -4
- metadata +34 -2
data/README.md
CHANGED
@@ -28,6 +28,15 @@ Or add this to your `Gemfile` before doing a `bundle install`:
|
|
28
28
|
Gman.valid? "foo@bar.gov" #true
|
29
29
|
Gman.valid? "foo@bar.com" #false
|
30
30
|
```
|
31
|
+
|
32
|
+
### Really verify an email address
|
33
|
+
|
34
|
+
(also verifies that the server returns a valid MX record)
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
Gman.valid? "foo@whitehouse.gov", true #true
|
38
|
+
Gman.valid? "foo@bar.gov", true #false
|
39
|
+
```
|
31
40
|
### Verify domain
|
32
41
|
|
33
42
|
```ruby
|
@@ -37,6 +46,17 @@ Gman.valid? "foo.gov" #true
|
|
37
46
|
Gman.valid? "foo.biz" #false
|
38
47
|
```
|
39
48
|
|
49
|
+
### Get a domain name from an arbitrary domainy string
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
Gman.get_domain "http://foo.bar.gov" # foo.bar.gov
|
53
|
+
Gman.get_domain "foo@bar.gov" # bar.gov
|
54
|
+
Gman.get_domain "foo.bar.gov" # foo.bar.gov
|
55
|
+
Gman.get_domain "asdf@asdf" # nil (no domain within the string)
|
56
|
+
Gman.get_domain "foo@bar.gov", true #false (no MX record)
|
57
|
+
Gman.get_domain "foo@whitehouse.gov", true # true (valid MX record)
|
58
|
+
```
|
59
|
+
|
40
60
|
## Contributing
|
41
61
|
|
42
62
|
Contributions welcome! Please see [the contribution guidelines](CONTRIBUTING.md) for code contributions or for details on how to add, update, or delete government domains.
|
data/gman.gemspec
CHANGED
@@ -2,7 +2,7 @@ Gem::Specification.new do |s|
|
|
2
2
|
s.name = "gman"
|
3
3
|
s.summary = "Check if a given domain or email address belong to a governemnt entity"
|
4
4
|
s.description = "A ruby gem to check if the owner of a given email address is working for THE MAN."
|
5
|
-
s.version = "0.0
|
5
|
+
s.version = "0.1.0"
|
6
6
|
s.authors = ["Ben Balter"]
|
7
7
|
s.email = "ben.balter@github.com"
|
8
8
|
s.homepage = "https://github.com/benbalter/gman"
|
@@ -26,6 +26,8 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.require_paths = ["lib"]
|
27
27
|
s.add_dependency( "public_suffix" )
|
28
28
|
s.add_dependency( "swot" )
|
29
|
+
s.add_dependency( "email_veracity" )
|
30
|
+
s.add_dependency( "addressable" )
|
29
31
|
|
30
32
|
s.add_development_dependency( "rake" )
|
31
33
|
s.add_development_dependency( "shoulda" )
|
data/lib/gman.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'public_suffix'
|
2
2
|
require 'yaml'
|
3
3
|
require 'swot'
|
4
|
+
require "addressable/uri"
|
5
|
+
require "email_veracity"
|
4
6
|
|
5
7
|
module Gman
|
6
8
|
|
@@ -14,10 +16,19 @@ module Gman
|
|
14
16
|
# "foo.gov.uk"
|
15
17
|
# "http://foo.bar.gov"
|
16
18
|
#
|
19
|
+
# check_mx - if an email is passed, check the domain for an mx record
|
20
|
+
#
|
17
21
|
# Returns boolean true if a government domain
|
18
|
-
def valid?(text)
|
19
|
-
|
22
|
+
def valid?(text, check_mx=false)
|
23
|
+
|
20
24
|
domain = get_domain text
|
25
|
+
return false unless PublicSuffix.valid?(domain)
|
26
|
+
|
27
|
+
# validate mx record
|
28
|
+
if check_mx && email?(text)
|
29
|
+
EmailVeracity::Config[:skip_lookup] = false
|
30
|
+
return false unless EmailVeracity::Address.new(text).valid?
|
31
|
+
end
|
21
32
|
|
22
33
|
# Ensure non-edu
|
23
34
|
return false if Swot::is_academic?(domain)
|
@@ -27,8 +38,6 @@ module Gman
|
|
27
38
|
return true if !rule.nil? && rule.allow?(domain)
|
28
39
|
|
29
40
|
# also allow for explicit matches to domain list
|
30
|
-
# but still make sure it's at least a valid domain
|
31
|
-
return false unless PublicSuffix.valid? domain
|
32
41
|
list.rules.any? { |rule| rule.value == domain }
|
33
42
|
end
|
34
43
|
|
@@ -41,18 +50,31 @@ module Gman
|
|
41
50
|
# Get the FQDN name from a URL or email address.
|
42
51
|
#
|
43
52
|
# Returns a string with the FQDN; nil if there's an error.
|
44
|
-
# Source: https://github.com/leereilly/swot/blob/master/lib/swot.rb#L190
|
45
53
|
def get_domain(text)
|
46
|
-
text.strip.downcase.match(domain_regex).captures.first
|
47
|
-
rescue
|
48
|
-
return nil
|
49
|
-
end
|
50
54
|
|
51
|
-
|
55
|
+
return nil if text.to_s.empty?
|
52
56
|
|
53
|
-
|
54
|
-
|
55
|
-
|
57
|
+
text = text.downcase
|
58
|
+
uri = Addressable::URI.parse(text)
|
59
|
+
|
60
|
+
if uri.host # valid https?://* URI
|
61
|
+
uri.host
|
62
|
+
elsif email?(text)
|
63
|
+
EmailVeracity::Address.new(text).domain.to_s
|
64
|
+
else # url sans http://
|
65
|
+
uri = Addressable::URI.parse("http://#{text}")
|
66
|
+
# properly parse http://foo edge cases
|
67
|
+
# see https://github.com/sporkmonger/addressable/issues/145
|
68
|
+
uri.host if uri.host =~ /\./
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Is the given string in the form of a valid email address?
|
73
|
+
#
|
74
|
+
# Returns true if email, otherwise false
|
75
|
+
def email?(text)
|
76
|
+
EmailVeracity::Config[:skip_lookup] = true
|
77
|
+
EmailVeracity::Address.new(text).valid?
|
56
78
|
end
|
57
79
|
end
|
58
80
|
end
|
data/test/test_gman.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'helper'
|
2
|
-
require 'swot'
|
3
2
|
|
4
3
|
VALID = [ "foo.gov",
|
5
4
|
"http://foo.mil",
|
6
5
|
"foo@bar.gc.ca",
|
7
6
|
"foo.gov.au",
|
8
|
-
"
|
7
|
+
"https://www.foo.gouv.fr",
|
9
8
|
"foo@ci.champaign.il.us",
|
10
9
|
"foo.bar.baz.gov.au",
|
11
|
-
"foo@bar.gov.uk"
|
10
|
+
"foo@bar.gov.uk",
|
11
|
+
".gov",
|
12
|
+
"foo.fed.us",
|
12
13
|
]
|
13
14
|
|
14
15
|
INVALID = [ "foo.bar.com",
|
@@ -17,7 +18,10 @@ INVALID = [ "foo.bar.com",
|
|
17
18
|
"foo.uk",
|
18
19
|
"gov",
|
19
20
|
"foo@k12.champaign.il.us",
|
20
|
-
"foo@kii.gov.by"
|
21
|
+
"foo@kii.gov.by",
|
22
|
+
"foo",
|
23
|
+
"",
|
24
|
+
nil,
|
21
25
|
]
|
22
26
|
|
23
27
|
class TestGman < Test::Unit::TestCase
|
@@ -39,4 +43,48 @@ class TestGman < Test::Unit::TestCase
|
|
39
43
|
assert_equal false, Swot::is_academic?(entry.name), "#{entry.name} is an academic domain"
|
40
44
|
end
|
41
45
|
end
|
46
|
+
|
47
|
+
should "not contain any invalid domains" do
|
48
|
+
Gman.list.each do |entry|
|
49
|
+
assert_equal true, PublicSuffix.valid?("foo.#{entry.name}"), "#{entry.name} is not a valid domain"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
should "not allow educational domains" do
|
54
|
+
assert_equal false, Gman::valid?("foo@gwu.edu")
|
55
|
+
end
|
56
|
+
|
57
|
+
should "properly parse domains from strings" do
|
58
|
+
assert_equal "github.gov", Gman::get_domain("foo@github.gov")
|
59
|
+
assert_equal "foo.github.gov", Gman::get_domain("foo.github.gov")
|
60
|
+
assert_equal "github.gov", Gman::get_domain("http://github.gov")
|
61
|
+
assert_equal "github.gov", Gman::get_domain("https://github.gov")
|
62
|
+
assert_equal ".gov", Gman::get_domain(".gov")
|
63
|
+
assert_equal nil, Gman.get_domain("foo")
|
64
|
+
end
|
65
|
+
|
66
|
+
should "validate mx records when asked" do
|
67
|
+
assert_equal true, Gman.valid?("foo@nasa.gov", true)
|
68
|
+
assert_equal false, Gman.valid?("foo@github.gov", true)
|
69
|
+
assert_equal true, Gman.valid?("foo@github.gov", false)
|
70
|
+
end
|
71
|
+
|
72
|
+
should "pass any url on the list" do
|
73
|
+
Gman.list.each do |entry|
|
74
|
+
assert_equal true, Gman.valid?("http://foo.#{entry.name}/bar"), "http://foo.#{entry.name}/bar is not a valid"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
should "pass any email on the list" do
|
79
|
+
Gman.list.each do |entry|
|
80
|
+
assert_equal true, Gman.valid?("foo@bar.#{entry.name}"), "foo@bar.#{entry.name} is not a valid"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
should "pass any domain on the list" do
|
85
|
+
Gman.list.each do |entry|
|
86
|
+
assert_equal true, Gman.valid?("foo.#{entry.name}"), "foo.#{entry.name} is not a valid domain"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
42
90
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: public_suffix
|
@@ -43,6 +43,38 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: email_veracity
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: addressable
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
46
78
|
- !ruby/object:Gem::Dependency
|
47
79
|
name: rake
|
48
80
|
requirement: !ruby/object:Gem::Requirement
|