naughty_or_nice 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +21 -0
  3. data/README.md +60 -0
  4. data/lib/naughty_or_nice.rb +112 -0
  5. metadata +49 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cc80dcfb26cbb5c4c7eac6db2ac75d5a753c8b67
4
+ data.tar.gz: 3ca21738914b3859ce1cf48feeeb92ee83cc9372
5
+ SHA512:
6
+ metadata.gz: b63b245920688a8b36b6b33bd2fd5d5bc18b558d5ca066882625da05aeb703dcaca9a1754a42cb30ead40f763b2425f9c40b2409934d3e27516946f5ea2f5cdc
7
+ data.tar.gz: b43c3c6c18074c5341c4d9185245580c276182ae845bc052c5587c6bfbe81aaed9a21c6ecb606f9245bc3366c455815ca3b6942ccc799ed09c1280889ab92b71
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Ben Balter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # Naughty or Nice
2
+
3
+ Naughty or Nice simplifies the process of extracting domain information from a domain-like string (an email, a URL, etc.) and checking whether it meets criteria you specify.
4
+
5
+ ## Usage
6
+
7
+ Naughty or Nice doesn't do too much on its own. Out of the box, it can extract a domain from a domain-like string, and can verify that it is, in fact, a valid domain. It does this by leveraging the power of the [Public Suffix List](http://publicsuffix.org/), and the associated [Ruby Gem](https://github.com/weppos/publicsuffix-ruby).
8
+
9
+ The true power of Naughty or Nice comes when you extended it into a child class.
10
+
11
+ ## Extending Naughty or Nice
12
+
13
+ Let's say you have a list of three domains, `foo.com`, `bar.com`, and `foobar.com`. You'd spec out a class like so:
14
+
15
+ ```ruby
16
+ class Checker < NaughtyOrNice
17
+ DOMAINS = %w[foo.com bar.com foobar.com]
18
+
19
+ def valid?
20
+ DOMAINS.include? domain
21
+ end
22
+ end
23
+ ```
24
+
25
+ That's it! Just overwrite the `valid?` method and Naughty or Nice takes care of the rest.
26
+
27
+ ## Using the extended class
28
+
29
+ There are a handful of magic methods that your child class automatically gets. You can throw any domain-like string at your new `Checker` class, and figure out if it's on the list. Here's a few examples:
30
+
31
+ ```ruby
32
+ Checker.valid? "foo.com" #=> true
33
+ Checker.valid? "foo.org" #=> false
34
+ ```
35
+
36
+ Notice we're using the class method `valid?` That automatically calls `Checker.new(string).valid?` for you. Cool, huh?
37
+
38
+ But you don't just need to give Checker crisp, clean domains. Let's get a bit trickier:
39
+
40
+ ```ruby
41
+ Checker.valid? "http://foo.bar.com" #=> true
42
+ Checker.valid? "foo@bar.com" #=> true
43
+ Checker.valid? "foobar" => false
44
+ ```
45
+
46
+ ## Extracting domain information
47
+
48
+ You can also you NaughtyOrNice to extract domain information for use elsewhere. Continuing our above example:
49
+
50
+ ```ruby
51
+ address = Checker.new "baz@foo.bar.com"
52
+ address.valid? #=> true
53
+ address.domain #=> "foo.bar.com"
54
+ address.domain_parts.tld #=> "com"
55
+ address.domain_parts.sld #=> "bar"
56
+ ```
57
+
58
+ ## See it in action
59
+
60
+ Take a look at [Gman](https://github.com/benbalter/gman) to see Naughty or Nice in action. Gman uses a crowd-sourced list of government domains to check if a given email address is a government email.
@@ -0,0 +1,112 @@
1
+ require 'public_suffix'
2
+ require "addressable/uri"
3
+
4
+ class NaughtyOrNice
5
+
6
+ class << self
7
+ def valid?(text)
8
+ self.new(text).valid?
9
+ end
10
+ end
11
+
12
+ # Source: http://bit.ly/1n2X9iv
13
+ EMAIL_REGEX = %r{
14
+ ^
15
+ (
16
+ [\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+
17
+ \.
18
+ )
19
+ *
20
+ [\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+
21
+ @
22
+ (
23
+ (
24
+ (
25
+ (
26
+ (
27
+ [a-z0-9]{1}
28
+ [a-z0-9\-]{0,62}
29
+ [a-z0-9]{1}
30
+ )
31
+ |
32
+ [a-z]
33
+ )
34
+ \.
35
+ )+
36
+ [a-z]{2,6}
37
+ )
38
+ |
39
+ (
40
+ \d{1,3}
41
+ \.
42
+ ){3}
43
+ \d{1,3}
44
+ (
45
+ \:\d{1,5}
46
+ )?
47
+ )
48
+ $
49
+ }xi
50
+
51
+ def initialize(text)
52
+ @text = text.to_s.downcase.strip
53
+ end
54
+
55
+ # Parse the domain from the input string
56
+ #
57
+ # Can handle urls, domains, or emails
58
+ #
59
+ # Returns the domain string
60
+ def domain
61
+ @domain ||= begin
62
+ return nil if @text.empty?
63
+
64
+ uri = Addressable::URI.parse(@text)
65
+
66
+ if uri.host # valid https?://* URI
67
+ uri.host
68
+ elsif email?
69
+ @text.match(/@([\w\.\-]+)\Z/i)[1]
70
+ else # url sans http://
71
+ begin
72
+ uri = Addressable::URI.parse("http://#{@text}")
73
+ # properly parse http://foo edge cases
74
+ # see https://github.com/sporkmonger/addressable/issues/145
75
+ uri.host if uri.host =~ /\./
76
+ rescue Addressable::URI::InvalidURIError
77
+ nil
78
+ end
79
+ end
80
+ end
81
+ end
82
+ alias_method :to_s, :domain
83
+
84
+ # Checks if the input string represents a valid domain
85
+ #
86
+ # Returns boolean true if a valid domain, otherwise false
87
+ def valid?
88
+ PublicSuffix.valid?(domain)
89
+ end
90
+
91
+ # Is the input text in the form of a valid email address?
92
+ #
93
+ # Returns true if email, otherwise false
94
+ def email?
95
+ !!(@text =~ EMAIL_REGEX)
96
+ end
97
+
98
+ # Helper function to return the public suffix domain object
99
+ #
100
+ # Supports all domain strings (URLs, emails)
101
+ #
102
+ # Returns the domain object or nil, but no errors, never an error
103
+ def domain_parts
104
+ PublicSuffix.parse domain
105
+ rescue PublicSuffix::DomainInvalid
106
+ nil
107
+ end
108
+
109
+ def inspect
110
+ "#<#{self.class} domain=\"#{domain}\" valid=#{valid?}>"
111
+ end
112
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: naughty_or_nice
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Balter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Naughty or Nice simplifies the process of extracting domain information
14
+ from a domain-like string (an email, a URL, etc.) and checking whether it meets
15
+ criteria you specify.
16
+ email: ben.balter@github.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - LICENSE.md
22
+ - README.md
23
+ - lib/naughty_or_nice.rb
24
+ homepage: http://github.com/benbalter/naughty_or_nice
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.2.0
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: You've made the list. We'll help you check it twice. Given a domain-like
48
+ string, verifies inclusion in a list you provide.
49
+ test_files: []