coppertone 0.0.6 → 0.0.7
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 +4 -4
- data/.rubocop.yml +20 -0
- data/.travis.yml +5 -8
- data/README.md +4 -4
- data/Rakefile +6 -6
- data/coppertone.gemspec +2 -2
- data/lib/coppertone/directive.rb +1 -1
- data/lib/coppertone/domain_spec.rb +3 -3
- data/lib/coppertone/ip_address_wrapper.rb +8 -8
- data/lib/coppertone/macro_context.rb +6 -5
- data/lib/coppertone/macro_string/macro_expand.rb +9 -9
- data/lib/coppertone/macro_string/macro_parser.rb +5 -5
- data/lib/coppertone/macro_string/macro_static_expand.rb +1 -1
- data/lib/coppertone/macro_string.rb +1 -1
- data/lib/coppertone/mechanism/a.rb +1 -1
- data/lib/coppertone/mechanism/all.rb +2 -2
- data/lib/coppertone/mechanism/cidr_parser.rb +3 -2
- data/lib/coppertone/mechanism/domain_spec_mechanism.rb +4 -3
- data/lib/coppertone/mechanism/domain_spec_optional.rb +3 -2
- data/lib/coppertone/mechanism/domain_spec_required.rb +4 -3
- data/lib/coppertone/mechanism/domain_spec_with_dual_cidr.rb +10 -8
- data/lib/coppertone/mechanism/exists.rb +1 -1
- data/lib/coppertone/mechanism/include.rb +3 -3
- data/lib/coppertone/mechanism/include_matcher.rb +4 -4
- data/lib/coppertone/mechanism/ip4.rb +1 -1
- data/lib/coppertone/mechanism/ip6.rb +1 -1
- data/lib/coppertone/mechanism/ip_mechanism.rb +9 -9
- data/lib/coppertone/mechanism/mx.rb +2 -2
- data/lib/coppertone/mechanism/ptr.rb +3 -3
- data/lib/coppertone/mechanism.rb +1 -1
- data/lib/coppertone/modifier/base.rb +3 -2
- data/lib/coppertone/modifier/exp.rb +2 -1
- data/lib/coppertone/modifier/redirect.rb +3 -2
- data/lib/coppertone/modifier/unknown.rb +3 -1
- data/lib/coppertone/null_macro_context.rb +2 -2
- data/lib/coppertone/record.rb +6 -4
- data/lib/coppertone/record_evaluator.rb +1 -1
- data/lib/coppertone/record_finder.rb +2 -2
- data/lib/coppertone/record_term_parser.rb +3 -3
- data/lib/coppertone/request.rb +12 -2
- data/lib/coppertone/request_count_limiter.rb +1 -1
- data/lib/coppertone/sender_identity.rb +4 -4
- data/lib/coppertone/terms_parser.rb +1 -1
- data/lib/coppertone/utils/domain_utils.rb +14 -5
- data/lib/coppertone/utils/ip_in_domain_checker.rb +4 -1
- data/lib/coppertone/utils/validated_domain_finder.rb +1 -1
- data/lib/coppertone/version.rb +2 -2
- data/lib/coppertone.rb +1 -0
- data/spec/mechanism/a_spec.rb +9 -9
- data/spec/mechanism/exists_spec.rb +5 -5
- data/spec/mechanism/ip6_spec.rb +0 -1
- data/spec/open_spf/ALL_mechanism_syntax_spec.rb +0 -1
- data/spec/open_spf/A_mechanism_syntax_spec.rb +0 -1
- data/spec/open_spf/EXISTS_mechanism_syntax_spec.rb +0 -1
- data/spec/open_spf/IP4_mechanism_syntax_spec.rb +0 -1
- data/spec/open_spf/IP6_mechanism_syntax_spec.rb +0 -1
- data/spec/open_spf/Include_mechanism_semantics_and_syntax_spec.rb +0 -1
- data/spec/open_spf/Initial_processing_spec.rb +0 -1
- data/spec/open_spf/MX_mechanism_syntax_spec.rb +0 -1
- data/spec/open_spf/Macro_expansion_rules_spec.rb +0 -1
- data/spec/open_spf/PTR_mechanism_syntax_spec.rb +0 -1
- data/spec/open_spf/Processing_limits_spec.rb +0 -1
- data/spec/open_spf/Record_evaluation_spec.rb +0 -1
- data/spec/open_spf/Record_lookup_spec.rb +0 -1
- data/spec/open_spf/Selecting_records_spec.rb +0 -1
- data/spec/open_spf/Semantics_of_exp_and_other_modifiers_spec.rb +0 -1
- data/spec/open_spf/Test_cases_from_implementation_bugs_spec.rb +0 -1
- data/spec/record_spec.rb +5 -5
- data/spec/utils/domain_utils_spec.rb +69 -5
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 739f6dacf79f523ba1cffcab857bd8e569260e48
|
4
|
+
data.tar.gz: ae128f802f7ab9ab04c3f953ccaf133bf1378ceb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b299645448f6a340a39f608f69ebac56345fcd05296f17cf85bb78306154b51add899345853e5edfa95b157753e5cc8ae9e5e4f51922f6cf5d8f65cffcc96ec
|
7
|
+
data.tar.gz: d13f36a9a62cb95fd6961cc9716944afdc992706ea727818ebf8fbe3a4dcfb30b8bb6c93622bb7cdfc8f52e31f322398bbbe27789639dc2dd488eb2659dd8e8c
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.2
|
3
|
+
|
4
|
+
Metrics/AbcSize:
|
5
|
+
Exclude:
|
6
|
+
- 'Rakefile'
|
7
|
+
Metrics/LineLength:
|
8
|
+
Enabled: false
|
9
|
+
Metrics/MethodLength:
|
10
|
+
Exclude:
|
11
|
+
- 'Rakefile'
|
12
|
+
Style/Documentation:
|
13
|
+
Enabled: false
|
14
|
+
Rails/HttpPositionalArguments:
|
15
|
+
Enabled: false
|
16
|
+
Style/FrozenStringLiteralComment:
|
17
|
+
Enabled: false
|
18
|
+
Style/FileName:
|
19
|
+
Exclude:
|
20
|
+
- 'spec/open_spf/**/*'
|
data/.travis.yml
CHANGED
@@ -1,12 +1,9 @@
|
|
1
|
+
sudo: false
|
1
2
|
language: ruby
|
2
3
|
env:
|
3
|
-
- CODECLIMATE_REPO_TOKEN=
|
4
|
+
- CODECLIMATE_REPO_TOKEN=437199ed4348853fa1dd6561b2e17a5668a7a6e78485d7ac3a21d12670fb6f2f
|
4
5
|
rvm:
|
5
|
-
- 2.
|
6
|
-
- 2.1
|
7
|
-
-
|
8
|
-
- jruby-19mode
|
9
|
-
- rbx-2.2.10
|
10
|
-
allow_failures:
|
11
|
-
- rvm: rbx-2.2.10
|
6
|
+
- 2.2.5
|
7
|
+
- 2.3.1
|
8
|
+
- jruby-9.1.5.0
|
12
9
|
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# Coppertone
|
2
2
|
|
3
|
-
[](https://travis-ci.org/ValiMail/coppertone)
|
4
|
+
[](https://codeclimate.com/github/ValiMail/coppertone)
|
5
|
+
[](https://codeclimate.com/github/ValiMail/coppertone)
|
6
6
|
|
7
7
|
A Sender Policy Framework (SPF) toolkit for Ruby.
|
8
8
|
|
@@ -23,7 +23,7 @@ If you'd like to suggest amending these guidelines, please open an issue for dis
|
|
23
23
|
|
24
24
|
## Requirements
|
25
25
|
|
26
|
-
Coppertone supports MRI 2.
|
26
|
+
Coppertone supports MRI 2.2 and up - earlier MRI rubies are not supported. JRuby 9.1.5.0+ is also supported.
|
27
27
|
|
28
28
|
Coppertone does not require Rails, although it does depend on ActiveSupport.
|
29
29
|
|
data/Rakefile
CHANGED
@@ -24,18 +24,18 @@ desc 'Parse OpenSPF tests'
|
|
24
24
|
def spec_file_name(doc, output_path)
|
25
25
|
description = doc['description']
|
26
26
|
file_name = description.gsub(/[^\w\s_-]+/, '')
|
27
|
-
|
28
|
-
|
27
|
+
.gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
|
28
|
+
.gsub(/\s+/, '_') + '_spec.rb'
|
29
29
|
File.join(output_path, file_name)
|
30
30
|
end
|
31
31
|
|
32
|
-
INDENT_STRING = ' '
|
32
|
+
INDENT_STRING = ' '.freeze
|
33
33
|
def indented_string(num_indents = 1)
|
34
|
-
num_indents
|
34
|
+
Array.new(num_indents) { INDENT_STRING }.join('')
|
35
35
|
end
|
36
36
|
|
37
37
|
def puts_prefixed_string(f, s, indent = 0)
|
38
|
-
f.write indented_string(indent) unless indent
|
38
|
+
f.write indented_string(indent) unless indent.zero?
|
39
39
|
f.puts s
|
40
40
|
end
|
41
41
|
|
@@ -62,7 +62,7 @@ end
|
|
62
62
|
|
63
63
|
def clean_description(description)
|
64
64
|
return unless description
|
65
|
-
description.
|
65
|
+
description.tr("\n", ' ').delete("'")
|
66
66
|
end
|
67
67
|
|
68
68
|
def as_array(val)
|
data/coppertone.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = 'https://github.com/petergoldstein/coppertone'
|
14
14
|
spec.license = 'Apache'
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
16
|
-
spec.executables = spec.files.grep(
|
17
|
-
spec.test_files = spec.files.grep(
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
20
|
spec.add_runtime_dependency 'dns_adapter'
|
data/lib/coppertone/directive.rb
CHANGED
@@ -15,10 +15,10 @@ module Coppertone
|
|
15
15
|
|
16
16
|
def validate_domain_spec_restrictions
|
17
17
|
return if only_allowed_macros? && ends_in_allowed_term?
|
18
|
-
|
18
|
+
raise Coppertone::DomainSpecParsingError
|
19
19
|
end
|
20
20
|
|
21
|
-
EXP_ONLY_MACRO_LETTERS = %w(c r t)
|
21
|
+
EXP_ONLY_MACRO_LETTERS = %w(c r t).freeze
|
22
22
|
def only_allowed_macros?
|
23
23
|
@macros.select { |m| m.is_a?(Coppertone::MacroString::MacroExpand) }
|
24
24
|
.none? { |m| EXP_ONLY_MACRO_LETTERS.include?(m.macro_letter) }
|
@@ -37,7 +37,7 @@ module Coppertone
|
|
37
37
|
ends_with = ends_with[0..-2] if ends_with[-1] == '.'
|
38
38
|
_, match, tail = ends_with.rpartition('.')
|
39
39
|
return false if match.blank?
|
40
|
-
hostname = Coppertone::Utils::DomainUtils.
|
40
|
+
hostname = Coppertone::Utils::DomainUtils.valid_tld?(tail)
|
41
41
|
return false unless hostname
|
42
42
|
true
|
43
43
|
end
|
@@ -12,16 +12,16 @@ module Coppertone
|
|
12
12
|
attr_reader :string_representation, :ip
|
13
13
|
def initialize(s)
|
14
14
|
@ip = self.class.parse(s)
|
15
|
-
|
15
|
+
raise ArgumentError unless @ip
|
16
16
|
@string_representation = s
|
17
17
|
end
|
18
18
|
|
19
19
|
# Hack for JRuby - remove when JRuby moves to 2.0.x
|
20
|
-
if RUBY_VERSION < '2.0'
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
IP_PARSE_ERROR = if RUBY_VERSION < '2.0'
|
21
|
+
ArgumentError
|
22
|
+
else
|
23
|
+
IPAddr::InvalidAddressError
|
24
|
+
end
|
25
25
|
|
26
26
|
def self.parse(s)
|
27
27
|
return nil unless s
|
@@ -44,12 +44,12 @@ module Coppertone
|
|
44
44
|
@ip.to_s
|
45
45
|
end
|
46
46
|
end
|
47
|
-
|
47
|
+
alias i to_dotted_notation
|
48
48
|
|
49
49
|
def to_human_readable
|
50
50
|
@ip.to_s
|
51
51
|
end
|
52
|
-
|
52
|
+
alias c to_human_readable
|
53
53
|
|
54
54
|
def v
|
55
55
|
original_ipv4? ? 'in-addr' : 'ip6'
|
@@ -10,11 +10,11 @@ module Coppertone
|
|
10
10
|
attr_reader :domain, :ip_address_wrapper, :sender_identity, :helo_domain
|
11
11
|
|
12
12
|
delegate :s, :l, :o, to: :sender_identity
|
13
|
-
|
13
|
+
alias d domain
|
14
14
|
delegate :i, :v, :c, to: :ip_address_wrapper
|
15
15
|
delegate :ip_v4, :ip_v6, :original_ipv4?, :original_ipv6?,
|
16
16
|
to: :ip_address_wrapper
|
17
|
-
|
17
|
+
alias h helo_domain
|
18
18
|
|
19
19
|
attr_reader :hostname
|
20
20
|
def initialize(domain, ip_as_s, sender, helo_domain = 'unknown',
|
@@ -26,7 +26,7 @@ module Coppertone
|
|
26
26
|
@hostname = options[:hostname]
|
27
27
|
end
|
28
28
|
|
29
|
-
UNKNOWN_HOSTNAME = 'unknown'
|
29
|
+
UNKNOWN_HOSTNAME = 'unknown'.freeze
|
30
30
|
def r
|
31
31
|
valid = Coppertone::Utils::DomainUtils.valid?(raw_hostname)
|
32
32
|
valid ? raw_hostname : UNKNOWN_HOSTNAME
|
@@ -46,8 +46,9 @@ module Coppertone
|
|
46
46
|
|
47
47
|
def raw_hostname
|
48
48
|
@raw_hostname ||=
|
49
|
-
|
50
|
-
|
49
|
+
begin
|
50
|
+
hostname || Coppertone.config.hostname || Coppertone::Utils::HostUtils.hostname
|
51
|
+
end
|
51
52
|
end
|
52
53
|
|
53
54
|
# Generates a new MacroContext with all the same info, but a new
|
@@ -8,18 +8,18 @@ module Coppertone
|
|
8
8
|
# 7.2, as well as against the set of delimiters, transformers, and
|
9
9
|
# grammer defined in section 7.1.
|
10
10
|
class MacroExpand
|
11
|
-
MACRO_LETTER_CHAR_SET = '[slodiphcrtvSLODIPHCRTV]'
|
12
|
-
PTR_MACRO_CHAR_SET = %w(p P)
|
13
|
-
DELIMITER_CHAR_SET = '[\.\-\+\,\/\_\=]'
|
11
|
+
MACRO_LETTER_CHAR_SET = '[slodiphcrtvSLODIPHCRTV]'.freeze
|
12
|
+
PTR_MACRO_CHAR_SET = %w(p P).freeze
|
13
|
+
DELIMITER_CHAR_SET = '[\.\-\+\,\/\_\=]'.freeze
|
14
14
|
VALID_BODY_REGEXP =
|
15
15
|
/\A(#{MACRO_LETTER_CHAR_SET})(\d*)(r?)(#{DELIMITER_CHAR_SET}*)\z/
|
16
16
|
|
17
17
|
attr_reader :macro_letter, :digit_transformers, :reverse,
|
18
18
|
:delimiter_regexp
|
19
|
-
|
19
|
+
alias reverse? reverse
|
20
20
|
def initialize(s)
|
21
21
|
matches = VALID_BODY_REGEXP.match(s)
|
22
|
-
|
22
|
+
raise Coppertone::MacroStringParsingError if matches.nil?
|
23
23
|
@macro_letter = matches[1]
|
24
24
|
initialize_digit_transformers(matches[2])
|
25
25
|
@reverse = (matches[3] == 'r')
|
@@ -29,9 +29,9 @@ module Coppertone
|
|
29
29
|
|
30
30
|
def initialize_digit_transformers(raw_value)
|
31
31
|
return unless raw_value
|
32
|
-
@digit_transformers = raw_value.to_i
|
32
|
+
@digit_transformers = raw_value.to_i unless raw_value.empty?
|
33
33
|
return unless @digit_transformers
|
34
|
-
|
34
|
+
raise Coppertone::MacroStringParsingError if @digit_transformers.zero?
|
35
35
|
end
|
36
36
|
|
37
37
|
def ptr_macro?
|
@@ -42,7 +42,7 @@ module Coppertone
|
|
42
42
|
context.send(@macro_letter) if context.respond_to?(@macro_letter)
|
43
43
|
ptr =
|
44
44
|
Coppertone::Utils::ValidatedDomainFinder
|
45
|
-
|
45
|
+
.new(context, request, false).find(context.d)
|
46
46
|
return 'unknown' unless ptr
|
47
47
|
@macro_letter == 'P' ? ::Addressable::URI.encode_component(ptr) : ptr
|
48
48
|
end
|
@@ -69,7 +69,7 @@ module Coppertone
|
|
69
69
|
|
70
70
|
private
|
71
71
|
|
72
|
-
DEFAULT_DELIMITER = '.'
|
72
|
+
DEFAULT_DELIMITER = '.'.freeze
|
73
73
|
def initialize_delimiter(raw_delimiter)
|
74
74
|
delimiter_chars =
|
75
75
|
if raw_delimiter && raw_delimiter.length >= 1
|
@@ -16,7 +16,7 @@ module Coppertone
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def parse_macro_array
|
19
|
-
while @s &&
|
19
|
+
while @s && !@s.empty?
|
20
20
|
if starting_macro?
|
21
21
|
parse_interpolated_macro
|
22
22
|
else
|
@@ -30,17 +30,17 @@ module Coppertone
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def parse_contextual_interpolated_macro
|
33
|
-
|
33
|
+
raise MacroStringParsingError unless @s[1] == '{'
|
34
34
|
closing_index = @s.index('}')
|
35
|
-
|
35
|
+
raise MacroStringParsingError unless closing_index
|
36
36
|
interpolated_body = @s[2, closing_index - 2]
|
37
37
|
@macros << MacroExpand.new(interpolated_body)
|
38
38
|
@s = @s[(closing_index + 1)..-1]
|
39
39
|
end
|
40
40
|
|
41
|
-
SIMPLE_MACRO_LETTERS = %w(% _ -)
|
41
|
+
SIMPLE_MACRO_LETTERS = %w(% _ -).freeze
|
42
42
|
def parse_interpolated_macro
|
43
|
-
|
43
|
+
raise MacroStringParsingError if @s.length == 1
|
44
44
|
macro_code = @s[0, 2]
|
45
45
|
if MacroStaticExpand.exists_for?(macro_code)
|
46
46
|
@macros << MacroStaticExpand.macro_for(macro_code)
|
@@ -2,7 +2,7 @@ require 'coppertone/mechanism/domain_spec_with_dual_cidr'
|
|
2
2
|
require 'coppertone/utils/ip_in_domain_checker'
|
3
3
|
|
4
4
|
module Coppertone
|
5
|
-
class Mechanism
|
5
|
+
class Mechanism
|
6
6
|
# Implements the A mechanism.
|
7
7
|
class A < DomainSpecWithDualCidr
|
8
8
|
def match_target_name(macro_context, request_context, target_name)
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Coppertone
|
2
|
-
class Mechanism
|
2
|
+
class Mechanism
|
3
3
|
# Implements the All mechanism. To reduce unnecessary object creation, this
|
4
4
|
# class is a singleton since all All mechanisms behave identically.
|
5
5
|
class All < Mechanism
|
6
6
|
def self.create(attributes)
|
7
|
-
|
7
|
+
raise InvalidMechanismError unless attributes.blank?
|
8
8
|
SINGLETON
|
9
9
|
end
|
10
10
|
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module Coppertone
|
2
|
-
class Mechanism
|
2
|
+
class Mechanism
|
3
|
+
# Parses a CIDR parameter subject to a max_val (32 for IPv4, 128 for IPv6)
|
3
4
|
class CidrParser
|
4
5
|
def self.parse(raw_length, max_val)
|
5
6
|
return if raw_length.blank?
|
6
7
|
length_as_i = raw_length.to_i
|
7
8
|
if length_as_i < 0 || length_as_i > max_val
|
8
|
-
|
9
|
+
raise Coppertone::InvalidMechanismError
|
9
10
|
end
|
10
11
|
length_as_i
|
11
12
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module Coppertone
|
2
|
-
class Mechanism
|
2
|
+
class Mechanism
|
3
|
+
# Parent class for mechanisms that use a domain spec.
|
3
4
|
class DomainSpecMechanism < Mechanism
|
4
5
|
attr_reader :domain_spec
|
5
6
|
|
@@ -29,7 +30,7 @@ module Coppertone
|
|
29
30
|
end
|
30
31
|
|
31
32
|
def target_domain
|
32
|
-
|
33
|
+
raise Coppertone::NeedsContextError if context_dependent?
|
33
34
|
domain_spec.to_s
|
34
35
|
end
|
35
36
|
|
@@ -37,7 +38,7 @@ module Coppertone
|
|
37
38
|
return false unless other.instance_of? self.class
|
38
39
|
domain_spec == other.domain_spec
|
39
40
|
end
|
40
|
-
|
41
|
+
alias eql? ==
|
41
42
|
|
42
43
|
def hash
|
43
44
|
domain_spec.hash
|
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'coppertone/mechanism/domain_spec_mechanism'
|
2
2
|
|
3
3
|
module Coppertone
|
4
|
-
class Mechanism
|
4
|
+
class Mechanism
|
5
|
+
# Parent class for mechanisms that use an optional domain spec.
|
5
6
|
class DomainSpecOptional < DomainSpecMechanism
|
6
7
|
def self.create(attributes)
|
7
8
|
new(attributes)
|
@@ -35,7 +36,7 @@ module Coppertone
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def handle_invalid_domain(_macro_context, _options)
|
38
|
-
|
39
|
+
raise RecordParsingError
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module Coppertone
|
2
|
-
class Mechanism
|
2
|
+
class Mechanism
|
3
|
+
# Parent class for mechanisms that use a required.
|
3
4
|
class DomainSpecRequired < DomainSpecMechanism
|
4
5
|
def self.create(attributes)
|
5
6
|
new(attributes)
|
@@ -8,7 +9,7 @@ module Coppertone
|
|
8
9
|
def initialize(attributes)
|
9
10
|
super(attributes)
|
10
11
|
raw_domain_spec = trim_domain_spec(attributes)
|
11
|
-
|
12
|
+
raise InvalidMechanismError if raw_domain_spec.blank?
|
12
13
|
@domain_spec = Coppertone::DomainSpec.new(raw_domain_spec)
|
13
14
|
rescue Coppertone::MacroStringParsingError
|
14
15
|
raise Coppertone::InvalidMechanismError
|
@@ -26,7 +27,7 @@ module Coppertone
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def handle_invalid_domain(_macro_context, _options)
|
29
|
-
|
30
|
+
raise RecordParsingError
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
@@ -3,7 +3,9 @@ require 'ipaddr'
|
|
3
3
|
require 'coppertone/mechanism/cidr_parser'
|
4
4
|
|
5
5
|
module Coppertone
|
6
|
-
class Mechanism
|
6
|
+
class Mechanism
|
7
|
+
# Parent class for mechanisms that use a domain spec, and permit
|
8
|
+
# specification of an optional IPv4 CIDR and optional IPv6 CIDR.
|
7
9
|
class DomainSpecWithDualCidr < DomainSpecMechanism
|
8
10
|
def self.create(attributes)
|
9
11
|
new(attributes)
|
@@ -37,9 +39,9 @@ module Coppertone
|
|
37
39
|
|
38
40
|
CIDR_REGEXP = %r{(/(\d*))?(//(\d*))?\z}
|
39
41
|
def parse_argument(attributes)
|
40
|
-
|
42
|
+
raise InvalidMechanismError if attributes.blank?
|
41
43
|
cidr_matches = CIDR_REGEXP.match(attributes)
|
42
|
-
|
44
|
+
raise InvalidMechanismError unless cidr_matches
|
43
45
|
macro_string, raw_ip_v4_cidr_length, raw_ip_v6_cidr_length =
|
44
46
|
clean_matches(attributes, cidr_matches)
|
45
47
|
process_matches(macro_string, raw_ip_v4_cidr_length,
|
@@ -53,7 +55,7 @@ module Coppertone
|
|
53
55
|
cand = trim_domain_spec(cand)
|
54
56
|
# At this point we've ascertained that there is
|
55
57
|
# a body to the domain spec
|
56
|
-
|
58
|
+
raise InvalidMechanismError if cand.blank?
|
57
59
|
cand
|
58
60
|
end
|
59
61
|
|
@@ -90,16 +92,16 @@ module Coppertone
|
|
90
92
|
end
|
91
93
|
|
92
94
|
def handle_invalid_domain(_macro_context, _options)
|
93
|
-
|
95
|
+
raise RecordParsingError
|
94
96
|
end
|
95
97
|
|
96
98
|
def ==(other)
|
97
99
|
return false unless other.instance_of? self.class
|
98
100
|
domain_spec == other.domain_spec &&
|
99
|
-
|
100
|
-
|
101
|
+
ip_v4_cidr_length == other.ip_v4_cidr_length &&
|
102
|
+
ip_v6_cidr_length == other.ip_v6_cidr_length
|
101
103
|
end
|
102
|
-
|
104
|
+
alias eql? ==
|
103
105
|
|
104
106
|
def hash
|
105
107
|
domain_spec.hash ^ ip_v4_cidr_length.hash ^ ip_v6_cidr_length.hash
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'coppertone/mechanism/domain_spec_required'
|
2
2
|
|
3
3
|
module Coppertone
|
4
|
-
class Mechanism
|
4
|
+
class Mechanism
|
5
5
|
# Implements the exists mechanism.
|
6
6
|
class Exists < DomainSpecRequired
|
7
7
|
def match_target_name(_macro_context, request_context, target_name)
|
@@ -3,14 +3,14 @@ require 'coppertone/mechanism/include_matcher'
|
|
3
3
|
require 'coppertone/record_finder'
|
4
4
|
|
5
5
|
module Coppertone
|
6
|
-
class Mechanism
|
6
|
+
class Mechanism
|
7
7
|
# Implements the include mechanism.
|
8
8
|
class Include < DomainSpecRequired
|
9
9
|
def match_target_name(macro_context, request_context, target_name)
|
10
10
|
record = included_record(request_context, target_name)
|
11
11
|
IncludeMatcher.new(record)
|
12
|
-
|
13
|
-
|
12
|
+
.match?(context_for_include(macro_context, target_name),
|
13
|
+
request_context)
|
14
14
|
end
|
15
15
|
|
16
16
|
def context_for_include(macro_context, target_name)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'coppertone/record_evaluator'
|
2
2
|
|
3
3
|
module Coppertone
|
4
|
-
class Mechanism
|
4
|
+
class Mechanism
|
5
5
|
# Implements the include mechanism.
|
6
6
|
class IncludeMatcher
|
7
7
|
# Evaluates records that are referenced via an include
|
@@ -13,7 +13,7 @@ module Coppertone
|
|
13
13
|
def evaluate_none_result(result, m, r)
|
14
14
|
new_result = super
|
15
15
|
return new_result unless new_result.none?
|
16
|
-
|
16
|
+
raise Coppertone::NoneIncludeResultError
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -23,10 +23,10 @@ module Coppertone
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def match?(macro_context, request_context)
|
26
|
-
|
26
|
+
raise Coppertone::NoneIncludeResultError if record.nil?
|
27
27
|
record_result =
|
28
28
|
IncludeRecordEvaluator.new(record)
|
29
|
-
|
29
|
+
.evaluate(macro_context, request_context)
|
30
30
|
record_result.pass?
|
31
31
|
end
|
32
32
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Coppertone
|
2
|
-
class Mechanism
|
2
|
+
class Mechanism
|
3
3
|
# Implements the ip4 mechanism.
|
4
4
|
class IPMechanism < Mechanism
|
5
5
|
attr_reader :netblock
|
@@ -13,21 +13,21 @@ module Coppertone
|
|
13
13
|
attributes = attributes[1..-1] if attributes[0] == ':'
|
14
14
|
@netblock = parse_netblock(attributes)
|
15
15
|
end
|
16
|
-
|
16
|
+
raise Coppertone::InvalidMechanismError if @netblock.nil?
|
17
17
|
end
|
18
18
|
|
19
|
-
LEADING_ZEROES_IN_CIDR_REGEXP =
|
19
|
+
LEADING_ZEROES_IN_CIDR_REGEXP = %r{\/0\d}
|
20
20
|
def validate_no_leading_zeroes_in_cidr(ip_as_s)
|
21
21
|
return unless LEADING_ZEROES_IN_CIDR_REGEXP.match(ip_as_s)
|
22
|
-
|
22
|
+
raise Coppertone::InvalidMechanismError
|
23
23
|
end
|
24
24
|
|
25
25
|
# Hack for JRuby - remove when JRuby moves to 2.0.x
|
26
|
-
if RUBY_VERSION < '2.0'
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
IP_PARSE_ERROR = if RUBY_VERSION < '2.0'
|
27
|
+
ArgumentError
|
28
|
+
else
|
29
|
+
IPAddr::Error
|
30
|
+
end
|
31
31
|
|
32
32
|
def parse_netblock(ip_as_s)
|
33
33
|
validate_no_leading_zeroes_in_cidr(ip_as_s)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'coppertone/mechanism/domain_spec_with_dual_cidr'
|
2
2
|
|
3
3
|
module Coppertone
|
4
|
-
class Mechanism
|
4
|
+
class Mechanism
|
5
5
|
# Implements the MX mechanism.
|
6
6
|
class MX < DomainSpecWithDualCidr
|
7
7
|
def match_target_name(macro_context, request_context, target_name)
|
@@ -32,7 +32,7 @@ module Coppertone
|
|
32
32
|
def check_a_record_limit(request_context, count)
|
33
33
|
limit = request_context.dns_lookups_per_mx_mechanism_limit
|
34
34
|
return unless limit && count > limit
|
35
|
-
|
35
|
+
raise Coppertone::MXLimitExceededError
|
36
36
|
end
|
37
37
|
|
38
38
|
def self.label
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'coppertone/mechanism/domain_spec_optional'
|
2
2
|
|
3
3
|
module Coppertone
|
4
|
-
class Mechanism
|
4
|
+
class Mechanism
|
5
5
|
# Implements the ptr mechanism.
|
6
6
|
class Ptr < DomainSpecOptional
|
7
7
|
def match_target_name(macro_context, request_context, target_name)
|
8
8
|
matching_name =
|
9
9
|
Coppertone::Utils::ValidatedDomainFinder
|
10
|
-
|
11
|
-
|
10
|
+
.new(macro_context, request_context)
|
11
|
+
.find(target_name)
|
12
12
|
!matching_name.nil?
|
13
13
|
end
|
14
14
|
|