coppertone 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](https://travis-ci.org/
|
4
|
-
[![Test Coverage](https://codeclimate.com/github/
|
5
|
-
[![Code Climate](https://codeclimate.com/github/
|
3
|
+
[![Build Status](https://travis-ci.org/ValiMail/coppertone.svg?branch=master)](https://travis-ci.org/ValiMail/coppertone)
|
4
|
+
[![Test Coverage](https://codeclimate.com/github/ValiMail/coppertone/badges/coverage.svg)](https://codeclimate.com/github/ValiMail/coppertone)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/ValiMail/coppertone/badges/gpa.svg)](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
|
|