dmarc 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 97e07c7f904e46b02faa4ce8358e3420b4ae4869
4
- data.tar.gz: 41f067c094fcf208cf93d7f06c2c3fdd139d2c18
3
+ metadata.gz: 0722fed71bbda69dbc298ae1219aefb479d398d5
4
+ data.tar.gz: c8478c89eb381f682c7ec0a96036222dc31b7623
5
5
  SHA512:
6
- metadata.gz: 3083a287ebfbf9aa267721fb7383f17404ce392c3481aa76e4873ac135bf2cad67a7148bfc787100447b6351b6e9459dc3a2d1c62f628b94543310831d42aabd
7
- data.tar.gz: ba197f0a39720736446c499cecb1b93e2f8b41826f3113a2014e4655503da3837a9c2501d42ea0218c963dd5337dd832f82a84fdc233855784f4542827f66072
6
+ metadata.gz: 27faec135d37a31823e5c0df6e5e1bc42e42f8064434a110e36faac3b97863696948a7f69ae3c3f87d2c6f2753cc41ec940a1962bd11231a1093113392283929
7
+ data.tar.gz: eaeb4b38ef303231a5c52722c4f093d0f24d856d6f604c66f8639d81975311c68d4aa88fc5da3d00a54462d5ab37d2044e6d01f7f7c3cb16aeb06f8c1c737f36
@@ -1,3 +1,7 @@
1
+ ### 0.5.0 / 2016-07-16
2
+
3
+ * Added {DMARC::Uri} to represent `mailto:dmarc@example.com!10m` URIs.
4
+
1
5
  ### 0.4.0 / 2016-07-10
2
6
 
3
7
  * Added {DMARC::Record#to_h}.
data/Gemfile CHANGED
@@ -4,6 +4,8 @@ gemspec
4
4
 
5
5
  group :development do
6
6
  gem 'rake'
7
+ gem 'rubygems-tasks', '~> 0.2'
8
+
7
9
  gem 'nokogiri'
8
10
  gem 'rspec', '~> 3.0'
9
11
 
data/README.md CHANGED
@@ -12,7 +12,7 @@ parser for DMARC records.
12
12
 
13
13
  ## Example
14
14
 
15
- Parse a SPF record:
15
+ Parse a DMARC record:
16
16
 
17
17
  require 'dmarc'
18
18
 
@@ -43,18 +43,18 @@ Parse a SPF record:
43
43
  # => 86400
44
44
 
45
45
  record.rua
46
- # => [#<URI::MailTo:0x000000034a1cc8 URL:mailto:d@rua.agari.com>]
46
+ # => [#<DMARC::Uri:0x0055ede60711e0 @uri=#<URI::MailTo mailto:d@rua.agari.com>, @size=nil, @unit=nil>]
47
47
 
48
48
  record.ruf
49
- # => [#<URI::MailTo:0x000000034a02b0 URL:mailto:d@ruf.agari.com>]
49
+ # => [#<DMARC::Uri:0x0055ede606f138 @uri=#<URI::MailTo mailto:d@ruf.agari.com>, @size=nil, @unit=nil>]
50
50
 
51
51
  record.sp
52
52
  # => :reject
53
53
 
54
- Query the SPF record for a domain:
54
+ Query the DMARC record for a domain:
55
55
 
56
56
  record = DMARC::Record.query('twitter.com')
57
- # => #<DMARC::Record:0x0000000313bd90 @adkim=:r, @aspf=:r, @fo=["1"@79], @p=:reject, @pct=100, @rf=:afrf, @ri=86400, @rua=[#<URI::MailTo:0x00000003124e38 URL:mailto:d@rua.agari.com>], @ruf=[#<URI::MailTo:0x00000003132678 URL:mailto:d@ruf.agari.com>], @sp=:reject, @v=:DMARC1>
57
+ # => #<DMARC::Record:0x0055ede6b808b0 @v=:DMARC1, @adkim=nil, @aspf=nil, @fo=["1"@79], @p=:reject, @pct=nil, @rf=nil, @ri=nil, @rua=[#<DMARC::Uri:0x0055ede6ba1c40 @uri=#<URI::MailTo mailto:d@rua.agari.com>, @size=nil, @unit=nil>], @ruf=[#<DMARC::Uri:0x0055ede6b8b760 @uri=#<URI::MailTo mailto:d@ruf.agari.com>, @size=nil, @unit=nil>], @sp=nil>
58
58
 
59
59
  ## Requirements
60
60
 
data/Rakefile CHANGED
@@ -11,7 +11,8 @@ rescue LoadError => e
11
11
  end
12
12
 
13
13
  require 'rake'
14
- require 'bundler/gem_tasks'
14
+ require 'rubygems/tasks'
15
+ Gem::Tasks.new
15
16
 
16
17
  require 'rspec/core/rake_task'
17
18
  RSpec::Core::RakeTask.new
@@ -1,5 +1,6 @@
1
- require 'parslet'
1
+ require 'dmarc/uri'
2
2
 
3
+ require 'parslet'
3
4
  require 'uri'
4
5
 
5
6
  module DMARC
@@ -183,7 +184,20 @@ module DMARC
183
184
  rule(pct: simple(:pct)) { {pct: pct.to_i} }
184
185
  rule(ri: simple(:ri)) { {ri: ri.to_i} }
185
186
 
186
- rule(uri: simple(:uri)) { URI.parse(uri) }
187
+ rule(uri: simple(:uri), size: simple(:size), unit: simple(:unit)) do
188
+ Uri.new(
189
+ URI.parse(uri),
190
+ size.to_i,
191
+ unit.to_sym
192
+ )
193
+ end
194
+ rule(uri: simple(:uri), size: simple(:size)) do
195
+ Uri.new(
196
+ URI.parse(uri),
197
+ size.to_i
198
+ )
199
+ end
200
+ rule(uri: simple(:uri)) { Uri.new(URI.parse(uri)) }
187
201
  rule(rua: subtree(:uris)) { {rua: Array(uris)} }
188
202
  rule(ruf: subtree(:uris)) { {ruf: Array(uris)} }
189
203
 
@@ -14,12 +14,12 @@ module DMARC
14
14
 
15
15
  # `rua` field.
16
16
  #
17
- # @return [Array<URI::MailTo>]
17
+ # @return [Array<Uri>]
18
18
  attr_reader :rua
19
19
 
20
20
  # `rua` field.
21
21
  #
22
- # @return [Array<URI::MailTo>]
22
+ # @return [Array<Uri>]
23
23
  attr_reader :ruf
24
24
 
25
25
  # `sp` field.
@@ -52,9 +52,9 @@ module DMARC
52
52
  #
53
53
  # @option attributes [Integer] :ri (86400)
54
54
  #
55
- # @option attributes [Array<URI::MailTo>] :rua
55
+ # @option attributes [Array<Uri>] :rua
56
56
  #
57
- # @option attributes [Array<URI::MailTo>] :ruf
57
+ # @option attributes [Array<Uri>] :ruf
58
58
  #
59
59
  # @option attributes [:none, :quarantine, :reject] :sp
60
60
  #
@@ -0,0 +1,105 @@
1
+ module DMARC
2
+ #
3
+ # Represents a DMARC URI.
4
+ #
5
+ # @see https://tools.ietf.org/html/rfc7489#section-6.2
6
+ #
7
+ # @since 0.5.0
8
+ #
9
+ class Uri
10
+
11
+ # The `mailto:` URI.
12
+ #
13
+ # @return [URI::MailTo]
14
+ attr_reader :uri
15
+
16
+ # The optional maximum-size.
17
+ #
18
+ # @return [Integer, nil]
19
+ attr_reader :size
20
+
21
+ # The optional unit.
22
+ #
23
+ # @return [:k, :m, :g, :t, nil]
24
+ attr_reader :unit
25
+
26
+ #
27
+ # Initializes the DMARC URI.
28
+ #
29
+ # @param [URI::MailTo] uri
30
+ # The `mailto:` URI.
31
+ #
32
+ # @param [Integer] size
33
+ # The optional maximum-size.
34
+ #
35
+ # @param [:k, :m, :g, :t] unit
36
+ # The optional size unit.
37
+ #
38
+ def initialize(uri,size=nil,unit=nil)
39
+ @uri = uri
40
+
41
+ @size = size
42
+ @unit = unit
43
+ end
44
+
45
+ #
46
+ # Determines if a maximum-size was set.
47
+ #
48
+ # @return [Boolean]
49
+ #
50
+ def size?
51
+ !@size.nil?
52
+ end
53
+
54
+ #
55
+ # Determines if a size unit was set.
56
+ #
57
+ # @return [Boolean]
58
+ #
59
+ def unit?
60
+ !@unit.nil?
61
+ end
62
+
63
+ #
64
+ # Determines if the DMARC URI matches the other.
65
+ #
66
+ # @param [Object] other
67
+ # the other DMARC URI to compare against.
68
+ #
69
+ # @return [Boolean]
70
+ #
71
+ def ==(other)
72
+ (self.class == other.class) &&
73
+ (@uri == other.uri) &&
74
+ (@size == other.size) &&
75
+ (@unit == other.unit)
76
+ end
77
+
78
+ #
79
+ # Converts the DMARC URI back into a String.
80
+ #
81
+ # @return [String]
82
+ #
83
+ def to_s
84
+ str = @uri.to_s
85
+
86
+ if (@size || @unit)
87
+ str << "!"
88
+ str << "#{@size}" if @size
89
+ str << "#{@unit}" if @unit
90
+ end
91
+
92
+ return str
93
+ end
94
+
95
+ protected
96
+
97
+ #
98
+ # Pass all missing methods to {#uri}.
99
+ #
100
+ def method_missing(name,*arguments,&block)
101
+ @uri.send(name,*arguments,&block)
102
+ end
103
+
104
+ end
105
+ end
@@ -1,4 +1,4 @@
1
1
  module DMARC
2
2
  # dmarc version
3
- VERSION = '0.4.0'
3
+ VERSION = '0.5.0'
4
4
  end
@@ -365,8 +365,8 @@ describe Parser do
365
365
  expect(subject).to include(aspf: :r)
366
366
  end
367
367
 
368
- it "should convert {uri: ...} to URI objects" do
369
- expect(subject).to include(rua: [URI("mailto:d@rua.agari.com")])
368
+ it "should convert {uri: ...} to Uri objects" do
369
+ expect(subject).to include(rua: [Uri.new(URI("mailto:d@rua.agari.com"))])
370
370
  end
371
371
  end
372
372
 
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+ require 'dmarc/uri'
3
+
4
+ describe DMARC::Uri do
5
+ let(:uri) { URI("mailto:d@ruf.agari.com") }
6
+ let(:size) { 10 }
7
+ let(:unit) { :m }
8
+
9
+ subject { described_class.new(uri,size,unit) }
10
+
11
+ describe "#initialize" do
12
+ it "should set the uri" do
13
+ expect(subject.uri).to be uri
14
+ end
15
+
16
+ it "should set the size" do
17
+ expect(subject.size).to be size
18
+ end
19
+
20
+ it "should set the unit" do
21
+ expect(subject.unit).to be unit
22
+ end
23
+
24
+ context "when size is omitted" do
25
+ subject { described_class.new(uri) }
26
+
27
+ it "should set size to nil" do
28
+ expect(subject.size).to be(nil)
29
+ end
30
+
31
+ it "should set unit to nil" do
32
+ expect(subject.unit).to be(nil)
33
+ end
34
+ end
35
+
36
+ context "when unit is omitted" do
37
+ subject { described_class.new(uri,size) }
38
+
39
+ it "should set size" do
40
+ expect(subject.size).to be(size)
41
+ end
42
+
43
+ it "should set unit to nil" do
44
+ expect(subject.unit).to be(nil)
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "#size?" do
50
+ context "when size is nil" do
51
+ subject { described_class.new(uri) }
52
+
53
+ it { expect(subject.size?).to be(false) }
54
+ end
55
+
56
+ context "when size is set" do
57
+ subject { described_class.new(uri,size) }
58
+
59
+ it { expect(subject.size?).to be(true) }
60
+ end
61
+ end
62
+
63
+ describe "#unit?" do
64
+ context "when unit is nil" do
65
+ subject { described_class.new(uri,size) }
66
+
67
+ it { expect(subject.unit?).to be(false) }
68
+ end
69
+
70
+ context "when unit is set" do
71
+ subject { described_class.new(uri,size,unit) }
72
+
73
+ it { expect(subject.unit?).to be(true) }
74
+ end
75
+ end
76
+
77
+ describe "#==" do
78
+ context "when other is a #{described_class}" do
79
+ context "and all fields match" do
80
+ let(:other) { described_class.new(uri.dup,size,unit) }
81
+
82
+ it { expect(subject == other).to be(true) }
83
+ end
84
+
85
+ context "but the uri is different" do
86
+ let(:other_uri) { URI("mailto:foo@example.com") }
87
+ let(:other) { described_class.new(other_uri,size,unit) }
88
+
89
+ it { expect(subject == other).to be(false) }
90
+ end
91
+
92
+ context "but the size is different" do
93
+ let(:other) { described_class.new(uri,42,unit) }
94
+
95
+ it { expect(subject == other).to be(false) }
96
+ end
97
+
98
+ context "but the unit is different" do
99
+ let(:other) { described_class.new(uri,size,:t) }
100
+
101
+ it { expect(subject == other).to be(false) }
102
+ end
103
+ end
104
+
105
+ context "when other is a different class" do
106
+ let(:other) { Object.new }
107
+
108
+ it { expect(subject == other).to be(false) }
109
+ end
110
+ end
111
+
112
+ describe "#to_s" do
113
+ context "when only the uri is set" do
114
+ subject { described_class.new(uri) }
115
+
116
+ it "should return the uri" do
117
+ expect(subject.to_s).to be == uri.to_s
118
+ end
119
+ end
120
+
121
+ context "when uri and size are set" do
122
+ subject { described_class.new(uri,size) }
123
+
124
+ it "should return the uri!size" do
125
+ expect(subject.to_s).to be == "#{uri}!#{size}"
126
+ end
127
+ end
128
+
129
+ context "when uri, size and unit are set" do
130
+ it "should return the uri!size" do
131
+ expect(subject.to_s).to be == "#{uri}!#{size}#{unit}"
132
+ end
133
+ end
134
+ end
135
+
136
+ describe "#method_missing" do
137
+ it "should pass through methods to uri" do
138
+ expect(subject.host).to be(uri.host)
139
+ end
140
+ end
141
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dmarc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Davis Gallinghouse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-11 00:00:00.000000000 Z
11
+ date: 2016-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
@@ -61,12 +61,14 @@ files:
61
61
  - lib/dmarc/exceptions.rb
62
62
  - lib/dmarc/parser.rb
63
63
  - lib/dmarc/record.rb
64
+ - lib/dmarc/uri.rb
64
65
  - lib/dmarc/version.rb
65
66
  - spec/data/alexa.csv
66
67
  - spec/dmarc_spec.rb
67
68
  - spec/parser_spec.rb
68
69
  - spec/record_spec.rb
69
70
  - spec/spec_helper.rb
71
+ - spec/uri_spec.rb
70
72
  - tasks/alexa.rb
71
73
  homepage: https://github.com/trailofbits/dmarc#readme
72
74
  licenses:
@@ -98,4 +100,4 @@ test_files:
98
100
  - spec/parser_spec.rb
99
101
  - spec/record_spec.rb
100
102
  - spec/spec_helper.rb
101
- has_rdoc:
103
+ - spec/uri_spec.rb