dmarc 0.4.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 97e07c7f904e46b02faa4ce8358e3420b4ae4869
4
- data.tar.gz: 41f067c094fcf208cf93d7f06c2c3fdd139d2c18
2
+ SHA256:
3
+ metadata.gz: 2e3b30301fd8b3d2ab7d423ed7afbda2cc5222047256e947f18870290c48c69d
4
+ data.tar.gz: 31b591fb978c4ff538b5d36bea8c896dff0e7bc30a196c64e501215abd0610d2
5
5
  SHA512:
6
- metadata.gz: 3083a287ebfbf9aa267721fb7383f17404ce392c3481aa76e4873ac135bf2cad67a7148bfc787100447b6351b6e9459dc3a2d1c62f628b94543310831d42aabd
7
- data.tar.gz: ba197f0a39720736446c499cecb1b93e2f8b41826f3113a2014e4655503da3837a9c2501d42ea0218c963dd5337dd832f82a84fdc233855784f4542827f66072
6
+ metadata.gz: 3c1c83f438dfdbe45f58a3382e9404d6113ffbefa0d79174673867d3efc399a76128a38cadf0e6ddc06baa45a5719193be48784cc96361cad732e543bd6c4bd5
7
+ data.tar.gz: 37437cba5c79511cd060c4dc49aaead5356f76ff45c746f147349c19f3b28e1529cae4ec1b6f2f4c16fe1c41d089f441b28483809f24f78e833385dc41d54685
@@ -0,0 +1,29 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: master
6
+ pull_request: []
7
+
8
+ jobs:
9
+ tests:
10
+ strategy:
11
+ matrix:
12
+ ruby:
13
+ - "2.6"
14
+ - "2.7"
15
+ - "3.0"
16
+ - "3.1"
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - name: Set up Git repository
20
+ uses: actions/checkout@main
21
+
22
+ - name: Set up Ruby
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby }}
26
+ bundler-cache: true
27
+
28
+ - name: Run tests
29
+ run: bundle exec rake spec
data/.gitignore CHANGED
@@ -1,19 +1,7 @@
1
- Gemfile.lock
1
+ /Gemfile.lock
2
+ /.bundle/
3
+ /doc/
4
+ /coverage/
5
+ /pkg/
6
+ /.yardoc/
2
7
  *.gem
3
- *.rbc
4
- .bundle
5
- .config
6
- coverage
7
- InstalledFiles
8
- lib/bundler/man
9
- pkg
10
- rdoc
11
- spec/reports
12
- test/tmp
13
- test/version_tmp
14
- tmp
15
-
16
- # YARD artifacts
17
- .yardoc
18
- _yardoc
19
- doc/
data/CODEOWNERS ADDED
@@ -0,0 +1 @@
1
+ * @postmodern @woodruffw
data/ChangeLog.md CHANGED
@@ -1,4 +1,12 @@
1
- ### 0.4.0 / 2016-07-10
1
+ ### 0.6.0 / 2024-01-24
2
+
3
+ * {DMARC::Record.parse} now allows trailing whitespace, per DMARC spec.
4
+
5
+ ### 0.5.0 / 2016-06-16
6
+
7
+ * Added {DMARC::Uri} to represent `mailto:dmarc@example.com!10m` URIs.
8
+
9
+ ### 0.4.0 / 2016-06-10
2
10
 
3
11
  * Added {DMARC::Record#to_h}.
4
12
  * Added {DMARC::Record#adkim?}.
data/Gemfile CHANGED
@@ -4,14 +4,16 @@ 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
 
10
12
  gem 'kramdown'
11
- gem 'yard', '~> 0.8'
13
+ gem 'yard', '~> 0.9'
12
14
  end
13
15
 
14
16
  group :test do
15
17
  gem 'json'
16
- gem 'codeclimate-test-reporter', require: nil
18
+ gem 'simplecov', require: nil
17
19
  end
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
data/dmarc.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
18
18
  gem.require_paths = ["lib"]
19
19
  gem.required_ruby_version = '>= 1.9.1'
20
20
 
21
- gem.add_dependency 'parslet', '~> 1.5'
21
+ gem.add_dependency 'parslet', '>= 1.0.0', '< 3.0.0'
22
22
 
23
- gem.add_development_dependency 'bundler', '~> 1.0'
23
+ gem.add_development_dependency 'bundler', '~> 2.0'
24
24
  end
data/lib/dmarc/parser.rb CHANGED
@@ -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
@@ -15,7 +16,8 @@ module DMARC
15
16
  rule(:dmarc_record) do
16
17
  dmarc_version.repeat(1,1) >>
17
18
  (dmarc_sep >> dmarc_tag).repeat >>
18
- dmarc_sep.maybe
19
+ dmarc_sep.maybe >>
20
+ wsp?.maybe
19
21
  end
20
22
 
21
23
  rule(:dmarc_sep) { wsp? >> str(';') >> wsp? }
@@ -183,7 +185,20 @@ module DMARC
183
185
  rule(pct: simple(:pct)) { {pct: pct.to_i} }
184
186
  rule(ri: simple(:ri)) { {ri: ri.to_i} }
185
187
 
186
- rule(uri: simple(:uri)) { URI.parse(uri) }
188
+ rule(uri: simple(:uri), size: simple(:size), unit: simple(:unit)) do
189
+ Uri.new(
190
+ URI.parse(uri),
191
+ size.to_i,
192
+ unit.to_sym
193
+ )
194
+ end
195
+ rule(uri: simple(:uri), size: simple(:size)) do
196
+ Uri.new(
197
+ URI.parse(uri),
198
+ size.to_i
199
+ )
200
+ end
201
+ rule(uri: simple(:uri)) { Uri.new(URI.parse(uri)) }
187
202
  rule(rua: subtree(:uris)) { {rua: Array(uris)} }
188
203
  rule(ruf: subtree(:uris)) { {ruf: Array(uris)} }
189
204
 
data/lib/dmarc/record.rb CHANGED
@@ -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
  #
data/lib/dmarc/uri.rb ADDED
@@ -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
data/lib/dmarc/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module DMARC
2
2
  # dmarc version
3
- VERSION = '0.4.0'
3
+ VERSION = '0.6.0'
4
4
  end
data/spec/parser_spec.rb CHANGED
@@ -80,6 +80,15 @@ describe Parser do
80
80
  ])
81
81
  end
82
82
 
83
+ it 'ignores trailing spacing without final separator' do
84
+ record = 'v=DMARC1; p=none '
85
+
86
+ expect(subject.parse(record)).to eq([
87
+ {v: 'DMARC1'},
88
+ {p: 'none'}
89
+ ])
90
+ end
91
+
83
92
  it "ignores unknown tags" do
84
93
  record = 'v=DMARC1;p=none;foo=xxx;sp=reject;bar=xxx;adkim=r;aspf=r'
85
94
  expect(subject.parse(record)).to eq([
@@ -365,8 +374,8 @@ describe Parser do
365
374
  expect(subject).to include(aspf: :r)
366
375
  end
367
376
 
368
- it "should convert {uri: ...} to URI objects" do
369
- expect(subject).to include(rua: [URI("mailto:d@rua.agari.com")])
377
+ it "should convert {uri: ...} to Uri objects" do
378
+ expect(subject).to include(rua: [Uri.new(URI("mailto:d@rua.agari.com"))])
370
379
  end
371
380
  end
372
381
 
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,5 @@
1
- require "codeclimate-test-reporter"
2
- CodeClimate::TestReporter.start
1
+ require 'simplecov'
2
+ SimpleCov.start
3
3
 
4
4
  require 'rspec'
5
5
  require 'dmarc'
data/spec/uri_spec.rb ADDED
@@ -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,43 +1,49 @@
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.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Davis Gallinghouse
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-11 00:00:00.000000000 Z
11
+ date: 2024-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '1.5'
22
+ version: 3.0.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.0
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: '1.5'
32
+ version: 3.0.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: bundler
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '1.0'
39
+ version: '2.0'
34
40
  type: :development
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
44
  - - "~>"
39
45
  - !ruby/object:Gem::Version
40
- version: '1.0'
46
+ version: '2.0'
41
47
  description: DMARC Record Parser
42
48
  email:
43
49
  - davis@trailofbits.com
@@ -46,10 +52,11 @@ extensions: []
46
52
  extra_rdoc_files: []
47
53
  files:
48
54
  - ".document"
55
+ - ".github/workflows/ci.yml"
49
56
  - ".gitignore"
50
57
  - ".rspec"
51
- - ".travis.yml"
52
58
  - ".yardopts"
59
+ - CODEOWNERS
53
60
  - ChangeLog.md
54
61
  - Gemfile
55
62
  - LICENSE.txt
@@ -61,18 +68,20 @@ files:
61
68
  - lib/dmarc/exceptions.rb
62
69
  - lib/dmarc/parser.rb
63
70
  - lib/dmarc/record.rb
71
+ - lib/dmarc/uri.rb
64
72
  - lib/dmarc/version.rb
65
73
  - spec/data/alexa.csv
66
74
  - spec/dmarc_spec.rb
67
75
  - spec/parser_spec.rb
68
76
  - spec/record_spec.rb
69
77
  - spec/spec_helper.rb
78
+ - spec/uri_spec.rb
70
79
  - tasks/alexa.rb
71
80
  homepage: https://github.com/trailofbits/dmarc#readme
72
81
  licenses:
73
82
  - MIT
74
83
  metadata: {}
75
- post_install_message:
84
+ post_install_message:
76
85
  rdoc_options: []
77
86
  require_paths:
78
87
  - lib
@@ -87,9 +96,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
96
  - !ruby/object:Gem::Version
88
97
  version: '0'
89
98
  requirements: []
90
- rubyforge_project:
91
- rubygems_version: 2.4.5.1
92
- signing_key:
99
+ rubygems_version: 3.4.10
100
+ signing_key:
93
101
  specification_version: 4
94
102
  summary: DMARC Record Parser
95
103
  test_files:
@@ -98,4 +106,4 @@ test_files:
98
106
  - spec/parser_spec.rb
99
107
  - spec/record_spec.rb
100
108
  - spec/spec_helper.rb
101
- has_rdoc:
109
+ - spec/uri_spec.rb
data/.travis.yml DELETED
@@ -1,16 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.1.8
4
- - 2.2.4
5
- - 2.3.0
6
- - jruby
7
- - rbx-2
8
- matrix:
9
- allow_failures:
10
- - rvm: rbx-2
11
- addons:
12
- code_climate:
13
- repo_token: 27519af871c1d9576b91e6f264e841eb7b7babbdcda315bf94fcbd095c202949
14
- notifications:
15
- slack:
16
- secure: Jqj30lwH2fnyu8adMI2nXa7rfF70o5JSrL0ZOe425XVu3YMMpfIp8J4DD0Ks/nCxgGRhJpq35oAHXjKmJAEHyda9oxx7GV9QwOuu2oviUrW3VUQQj9UsXPQP0sc0GD9BPI+KVNp4dbGki1ik90I6HVVsqDauek/z5MWt6MJY+tA=