spf-query 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: