gman 0.0.7 → 0.1.0
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 +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
|