spf-query 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,38 @@
1
+ require 'spec_helper'
2
+ require 'spf/query/query'
3
+
4
+ describe SPF::Query do
5
+ subject { described_class }
6
+
7
+ describe ".query" do
8
+ let(:domain) { 'gmail.com' }
9
+
10
+ it "should return the first SPF record" do
11
+ expect(subject.query(domain)).to be == %{v=spf1 redirect=_spf.google.com}
12
+ end
13
+
14
+ context "when _spf.domain.com exists" do
15
+ let(:domain) { 'google.com' }
16
+
17
+ it "should return the first SPF record" do
18
+ expect(subject.query(domain)).to be == %{v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all}
19
+ end
20
+ end
21
+
22
+ context "when the domain has a SPF type record" do
23
+ let(:domain) { 'getlua.com' }
24
+
25
+ it "should prefer the SPF type record over other TXT records" do
26
+ expect(subject.query(domain)).to be == %{v=spf1 include:mail.zendesk.com include:servers.mcsv.net include:_spf.google.com include:sendgrid.net include:mktomail.com ~all}
27
+ end
28
+ end
29
+
30
+ context "when given an invalid domain" do
31
+ let(:domain) { 'foo.bar.com' }
32
+
33
+ it "should return nil" do
34
+ expect(subject.query(domain)).to be_nil
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,212 @@
1
+ require 'spec_helper'
2
+ require 'spf/query/record'
3
+
4
+ describe SPF::Query::Record do
5
+ let(:spf) do
6
+ %{v=spf1 ip4:199.16.156.0/22 ip4:199.59.148.0/22 ip4:8.25.194.0/23 ip4:8.25.196.0/23 ip4:204.92.114.203 ip4:204.92.114.204/31 ip4:107.20.52.15 ip4:23.21.83.90 include:_spf.google.com include:_thirdparty.twitter.com all}
7
+ end
8
+
9
+ subject { described_class.parse(spf) }
10
+
11
+ describe "#initialize" do
12
+ let(:version) { :spf1 }
13
+
14
+ let(:ip4_rules) do
15
+ [
16
+ Mechanism.new(:ip4, value: IP.new('199.16.156.0', 22)),
17
+ Mechanism.new(:ip4, value: IP.new('199.59.148.0', 22)),
18
+ Mechanism.new(:ip4, value: IP.new('8.25.194.0', 23)),
19
+ Mechanism.new(:ip4, value: IP.new('8.25.196.0', 23)),
20
+ Mechanism.new(:ip4, value: IP.new('204.92.114.203')),
21
+ Mechanism.new(:ip4, value: IP.new('204.92.114.204', 31)),
22
+ Mechanism.new(:ip4, value: IP.new('107.20.52.15')),
23
+ Mechanism.new(:ip4, value: IP.new('23.21.83.90')),
24
+ ]
25
+ end
26
+
27
+ let(:include_rules) do
28
+ [
29
+ Mechanism.new(:include, value: '_spf.google.com'),
30
+ Mechanism.new(:include, value: '_thirdparty.twitter.com'),
31
+ ]
32
+ end
33
+
34
+ let(:all_rule) { Mechanism.new(:all) }
35
+ let(:rules) { ip4_rules + include_rules + [all_rule] }
36
+
37
+ subject { described_class.new(version,rules) }
38
+
39
+ it "should set version" do
40
+ expect(subject.version).to be version
41
+ end
42
+
43
+ it "should set rules" do
44
+ expect(subject.rules).to be rules
45
+ end
46
+
47
+ describe "#mechanisms" do
48
+ subject { super().mechanisms }
49
+
50
+ it "should contain every Mechanism object" do
51
+ expect(subject).to all(be_a(Mechanism))
52
+ end
53
+ end
54
+
55
+ describe "#modifiers" do
56
+ pending "need to add modifiers"
57
+ end
58
+
59
+ describe "#all" do
60
+ subject { super().all }
61
+
62
+ it "should find the last all mechanism" do
63
+ expect(subject).to be all_rule
64
+ end
65
+ end
66
+
67
+ describe "#include" do
68
+ subject { super().include }
69
+
70
+ it "should find all include: mechanisms" do
71
+ expect(subject).to be == include_rules
72
+ end
73
+ end
74
+
75
+ describe "#a" do
76
+ subject { super().a }
77
+
78
+ pending "need to add a: mechanisms" do
79
+ it "should find all a: mechanisms" do
80
+ expect(subject).to be == a
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#mx" do
86
+ subject { super().mx }
87
+
88
+ pending "need to add mx: mechanisms" do
89
+ it "should find all mx: mechanisms" do
90
+ expect(subject).to be == mx
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "#ptr" do
96
+ subject { super().ptr }
97
+
98
+ pending "need to add ptr: mechanisms" do
99
+ it "should find all ptr: mechanisms" do
100
+ expect(subject).to be == ptr
101
+ end
102
+ end
103
+ end
104
+
105
+ describe "#ip4" do
106
+ subject { super().ip4 }
107
+
108
+ it "should find all ip4: mechanisms" do
109
+ expect(subject).to be == ip4_rules
110
+ end
111
+ end
112
+
113
+ describe "#ip6" do
114
+ subject { super().ptr }
115
+
116
+ pending "need to add ip6: mechanisms" do
117
+ it "should find all ip6: mechanisms" do
118
+ expect(subject).to be == ip6
119
+ end
120
+ end
121
+ end
122
+
123
+ describe "#exists" do
124
+ subject { super().exists }
125
+
126
+ pending "need to add exists: mechanisms" do
127
+ it "should find all exists: mechanisms" do
128
+ expect(subject).to be == exists
129
+ end
130
+ end
131
+ end
132
+
133
+ describe "#redirect" do
134
+ subject { super().exists }
135
+
136
+ pending "need to add a redirect: modifier" do
137
+ it "should find the first redirect: modifier" do
138
+ expect(subject).to be == redirect
139
+ end
140
+ end
141
+ end
142
+
143
+ describe "#exp" do
144
+ subject { super().exp }
145
+
146
+ pending "need to add a exp: modifier" do
147
+ it "should find the first exp: modifier" do
148
+ expect(subject).to be == exp
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ describe ".parse" do
155
+ context "when parsing a valid record" do
156
+ let(:spf) do
157
+ %{v=spf1 ip4:199.16.156.0/22 ip4:199.59.148.0/22 ip4:8.25.194.0/23 ip4:8.25.196.0/23 ip4:204.92.114.203 ip4:204.92.114.204/31 ip4:107.20.52.15 ip4:23.21.83.90 include:_spf.google.com include:_thirdparty.twitter.com all}
158
+ end
159
+
160
+ subject { described_class.parse(spf) }
161
+
162
+ it "should return a Record" do
163
+ expect(subject).to be_kind_of(Record)
164
+ end
165
+ end
166
+
167
+ context "when parsing an invalid record" do
168
+ let(:spf) { %{v=foo} }
169
+
170
+ it "should raise an InvalidRecord exception" do
171
+ expect {
172
+ described_class.parse(spf)
173
+ }.to raise_error(InvalidRecord)
174
+ end
175
+ end
176
+ end
177
+
178
+ describe ".query" do
179
+ let(:domain) { 'twitter.com' }
180
+
181
+ subject { described_class.query(domain) }
182
+
183
+ it "should return a Record" do
184
+ expect(subject).to be_kind_of(Record)
185
+ end
186
+
187
+ context "when given a domain without SPF" do
188
+ let(:domain) { 'geocities.com' }
189
+
190
+ it "should return nil" do
191
+ expect(subject).to be nil
192
+ end
193
+ end
194
+ end
195
+
196
+ describe "#each" do
197
+ it "should enumerate over ever record" do
198
+ end
199
+ end
200
+
201
+ describe "#to_s" do
202
+ it "should convert the record back into SPF" do
203
+ expect(subject.to_s).to be == spf
204
+ end
205
+ end
206
+
207
+ describe "#inspect" do
208
+ it "should display the raw SPF" do
209
+ expect(subject.inspect).to be == "#<#{described_class}: #{spf}>"
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,9 @@
1
+ if ENV['CODECLIMATE_REPO_TOKEN']
2
+ require "codeclimate-test-reporter"
3
+ CodeClimate::TestReporter.start
4
+ end
5
+
6
+ require 'rspec'
7
+ require 'spf/query'
8
+
9
+ include SPF::Query
data/spf-query.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'spf/query/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "spf-query"
8
+ gem.version = SPF::Query::VERSION
9
+ gem.authors = ["nicktitle"]
10
+ gem.email = ["nick.esposito@trailofbits.com"]
11
+ gem.summary = %q{SPF Retriever and Parser}
12
+ gem.description = %q{Search and retrieve SPF records for any number of hosts}
13
+ gem.homepage = "https://github.com/trailofbits/spf-query#readme"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files -z`.split("\x0")
17
+ gem.executables = ['spf-query']
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+ gem.required_ruby_version = '>= 1.9.1'
21
+
22
+ gem.add_dependency "parslet", "~> 1.0"
23
+
24
+ gem.add_development_dependency "bundler", "~> 1.6"
25
+ gem.add_development_dependency "rake", "~> 10.0"
26
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spf-query
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - nicktitle
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: parslet
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ description: Search and retrieve SPF records for any number of hosts
56
+ email:
57
+ - nick.esposito@trailofbits.com
58
+ executables:
59
+ - spf-query
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - ChangeLog.md
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - bin/spf-query
72
+ - lib/resolv/dns/resource/in/spf.rb
73
+ - lib/spf/query.rb
74
+ - lib/spf/query/exceptions.rb
75
+ - lib/spf/query/ip.rb
76
+ - lib/spf/query/macro.rb
77
+ - lib/spf/query/macro_string.rb
78
+ - lib/spf/query/mechanism.rb
79
+ - lib/spf/query/modifier.rb
80
+ - lib/spf/query/parser.rb
81
+ - lib/spf/query/query.rb
82
+ - lib/spf/query/record.rb
83
+ - lib/spf/query/version.rb
84
+ - spec/mechanism_spec.rb
85
+ - spec/parser_spec.rb
86
+ - spec/query_spec.rb
87
+ - spec/record_spec.rb
88
+ - spec/spec_helper.rb
89
+ - spf-query.gemspec
90
+ homepage: https://github.com/trailofbits/spf-query#readme
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 1.9.1
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.4.7
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: SPF Retriever and Parser
114
+ test_files:
115
+ - spec/mechanism_spec.rb
116
+ - spec/parser_spec.rb
117
+ - spec/query_spec.rb
118
+ - spec/record_spec.rb
119
+ - spec/spec_helper.rb
120
+ has_rdoc: