dmarc 0.4.0 → 0.6.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
- 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=