truemail 1.6.1 → 1.9.1

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.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'truemail/core'
3
+ require_relative 'truemail/core'
4
4
 
5
5
  module Truemail
6
6
  INCOMPLETE_CONFIG = 'verifier_email is required parameter'
@@ -3,12 +3,20 @@
3
3
  module Truemail
4
4
  module Audit
5
5
  class Base < Truemail::Worker
6
+ require 'net/http'
7
+ require 'ipaddr'
8
+ require 'resolv'
9
+
6
10
  private
7
11
 
8
12
  def add_warning(message)
9
13
  result.warnings[self.class.name.split('::').last.downcase.to_sym] = message
10
14
  end
11
15
 
16
+ def current_host_ip
17
+ result.current_host_ip
18
+ end
19
+
12
20
  def configuration
13
21
  result.configuration
14
22
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Audit
5
+ class Dns < Truemail::Audit::Base
6
+ VERIFIER_DOMAIN_NOT_REFER = 'A-record of verifier domain not refers to current host ip address'
7
+
8
+ def run
9
+ return if verifier_domain_refer_to_current_host_ip?
10
+ add_warning(Truemail::Audit::Dns::VERIFIER_DOMAIN_NOT_REFER)
11
+ end
12
+
13
+ private
14
+
15
+ def a_record
16
+ Truemail::Wrapper.call(configuration: configuration) do
17
+ Resolv::DNS.new.getaddress(verifier_domain).to_s
18
+ end
19
+ end
20
+
21
+ def verifier_domain_refer_to_current_host_ip?
22
+ a_record.eql?(current_host_ip)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Audit
5
+ class Ip < Truemail::Audit::Base
6
+ GET_MY_IP_URL = 'https://api.ipify.org'
7
+ IPIFY_ERROR = 'impossible to detect current host address via third party service'
8
+
9
+ def run
10
+ return add_warning(Truemail::Audit::Ip::IPIFY_ERROR) unless detect_current_host_ip
11
+ Truemail::Audit::Dns.check(result)
12
+ Truemail::Audit::Ptr.check(result)
13
+ end
14
+
15
+ private
16
+
17
+ def detect_ip_via_ipify
18
+ Net::HTTP.get(URI(Truemail::Audit::Ip::GET_MY_IP_URL))
19
+ end
20
+
21
+ def detect_current_host_ip
22
+ result.current_host_ip = Truemail::Wrapper.call(configuration: configuration) do
23
+ detect_ip_via_ipify
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -3,38 +3,19 @@
3
3
  module Truemail
4
4
  module Audit
5
5
  class Ptr < Truemail::Audit::Base
6
- require 'net/http'
7
- require 'ipaddr'
8
- require 'resolv'
9
-
10
- GET_MY_IP_URL = 'https://api.ipify.org'
11
- IPIFY_ERROR = 'impossible to detect current host address via third party service'
12
- PTR_NOT_FOUND = 'ptr record for current host address was not found'
13
- PTR_NOT_REFER = 'ptr record does not reference to current verifier domain'
14
- VERIFIER_DOMAIN_NOT_REFER = 'a record of verifier domain not refers to current host address'
6
+ PTR_NOT_FOUND = 'PTR-record for current host ip address was not found'
7
+ PTR_NOT_REFER = 'PTR-record does not reference to current verifier domain'
15
8
 
16
9
  def run
17
- return if !current_host_address && add_warning(Truemail::Audit::Ptr::IPIFY_ERROR)
18
- return if ptr_records.empty? && add_warning(Truemail::Audit::Ptr::PTR_NOT_FOUND)
19
- return if ptr_not_refer_to_verifier_domain? && add_warning(Truemail::Audit::Ptr::PTR_NOT_REFER)
20
- return if verifier_domain_refer_to_current_host_address?
21
- add_warning(Truemail::Audit::Ptr::VERIFIER_DOMAIN_NOT_REFER)
10
+ return add_warning(Truemail::Audit::Ptr::PTR_NOT_FOUND) if ptr_records.empty?
11
+ return if ptr_refer_to_verifier_domain?
12
+ add_warning(Truemail::Audit::Ptr::PTR_NOT_REFER)
22
13
  end
23
14
 
24
15
  private
25
16
 
26
- def detect_ip_via_ipify
27
- Net::HTTP.get(URI(Truemail::Audit::Ptr::GET_MY_IP_URL))
28
- end
29
-
30
- def current_host_address
31
- @current_host_address ||= Truemail::Wrapper.call(configuration: configuration) do
32
- IPAddr.new(detect_ip_via_ipify)
33
- end
34
- end
35
-
36
17
  def current_host_reverse_lookup
37
- current_host_address.reverse
18
+ IPAddr.new(current_host_ip).reverse
38
19
  end
39
20
 
40
21
  def ptr_records
@@ -45,18 +26,8 @@ module Truemail
45
26
  end || []
46
27
  end
47
28
 
48
- def ptr_not_refer_to_verifier_domain?
49
- !ptr_records.include?(verifier_domain)
50
- end
51
-
52
- def a_record
53
- Truemail::Wrapper.call(configuration: configuration) do
54
- Resolv::DNS.new.getaddress(verifier_domain).to_s
55
- end
56
- end
57
-
58
- def verifier_domain_refer_to_current_host_address?
59
- a_record.eql?(current_host_address.to_s)
29
+ def ptr_refer_to_verifier_domain?
30
+ ptr_records.include?(verifier_domain)
60
31
  end
61
32
  end
62
33
  end
@@ -1,22 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truemail
4
- class Auditor
5
- Result = Struct.new(:warnings, :configuration, keyword_init: true) do
4
+ class Auditor < Truemail::Executor
5
+ Result = Struct.new(:current_host_ip, :warnings, :configuration, keyword_init: true) do
6
6
  def initialize(warnings: {}, **args)
7
7
  super
8
8
  end
9
9
  end
10
10
 
11
- attr_reader :result
12
-
13
11
  def initialize(configuration:)
14
12
  @result = Truemail::Auditor::Result.new(configuration: configuration)
15
13
  end
16
14
 
17
15
  def run
18
- Truemail::Audit::Ptr.check(result)
16
+ Truemail::Audit::Ip.check(result)
19
17
  self
20
18
  end
19
+
20
+ def as_json
21
+ Truemail::Log::Serializer::AuditorJson.call(self)
22
+ end
21
23
  end
22
24
  end
@@ -6,6 +6,7 @@ module Truemail
6
6
  DEFAULT_RESPONSE_TIMEOUT = 2
7
7
  DEFAULT_CONNECTION_ATTEMPTS = 2
8
8
  DEFAULT_VALIDATION_TYPE = :smtp
9
+ DEFAULT_LOGGER_OPTIONS = { tracking_event: :error, stdout: false, log_absolute_path: nil }.freeze
9
10
 
10
11
  attr_reader :email_pattern,
11
12
  :smtp_error_body_pattern,
@@ -20,7 +21,7 @@ module Truemail
20
21
  :blacklisted_domains,
21
22
  :logger
22
23
 
23
- attr_accessor :whitelist_validation, :smtp_safe_check
24
+ attr_accessor :whitelist_validation, :not_rfc_mx_lookup_flow, :smtp_safe_check
24
25
 
25
26
  def initialize(&block)
26
27
  instance_initializer.each do |instace_variable, value|
@@ -71,7 +72,8 @@ module Truemail
71
72
  end
72
73
  end
73
74
 
74
- def logger=(tracking_event: :error, stdout: false, log_absolute_path: nil)
75
+ def logger=(options)
76
+ tracking_event, stdout, log_absolute_path = logger_options(options)
75
77
  valid_event = Truemail::Log::Event::TRACKING_EVENTS.key?(tracking_event)
76
78
  stdout_only = stdout && log_absolute_path.nil?
77
79
  file_only = log_absolute_path.is_a?(String)
@@ -99,6 +101,7 @@ module Truemail
99
101
  whitelisted_domains: [],
100
102
  whitelist_validation: false,
101
103
  blacklisted_domains: [],
104
+ not_rfc_mx_lookup_flow: false,
102
105
  smtp_safe_check: false
103
106
  }
104
107
  end
@@ -108,7 +111,7 @@ module Truemail
108
111
  end
109
112
 
110
113
  def validate_arguments(argument, method)
111
- constant = Truemail::RegexConstant.const_get("regex_#{method[/\A.+_(.+)\=\z/, 1]}_pattern".upcase)
114
+ constant = Truemail::RegexConstant.const_get("regex_#{method[/\A.+_(.+)=\z/, 1]}_pattern".upcase)
112
115
  raise_unless(argument, method, constant.match?(argument.to_s))
113
116
  end
114
117
 
@@ -139,5 +142,9 @@ module Truemail
139
142
  check_validation_type(validation_type)
140
143
  end
141
144
  end
145
+
146
+ def logger_options(current_options)
147
+ Truemail::Configuration::DEFAULT_LOGGER_OPTIONS.merge(current_options).values
148
+ end
142
149
  end
143
150
  end
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truemail
4
- require 'truemail/version'
5
- require 'truemail/configuration'
6
- require 'truemail/worker'
7
- require 'truemail/wrapper'
8
- require 'truemail/auditor'
9
- require 'truemail/validator'
10
- require 'truemail/logger'
4
+ require_relative '../truemail/version'
5
+ require_relative '../truemail/configuration'
6
+ require_relative '../truemail/worker'
7
+ require_relative '../truemail/executor'
8
+ require_relative '../truemail/wrapper'
9
+ require_relative '../truemail/auditor'
10
+ require_relative '../truemail/validator'
11
+ require_relative '../truemail/logger'
11
12
 
12
13
  ConfigurationError = Class.new(StandardError)
13
14
 
@@ -29,32 +30,36 @@ module Truemail
29
30
  end
30
31
 
31
32
  module RegexConstant
32
- REGEX_DOMAIN = /[\p{L}0-9]+([\-\.]{1}[\p{L}0-9]+)*\.[\p{L}]{2,63}/i.freeze
33
- REGEX_EMAIL_PATTERN = /(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|\.|\+]*)@(#{REGEX_DOMAIN})\z)/.freeze
33
+ REGEX_DOMAIN = /[\p{L}0-9]+([\-.]{1}[\p{L}0-9]+)*\.\p{L}{2,63}/i.freeze
34
+ REGEX_EMAIL_PATTERN = /(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|.|+]*)@(#{REGEX_DOMAIN})\z)/.freeze
34
35
  REGEX_DOMAIN_PATTERN = /(?=\A.{4,255}\z)(\A#{REGEX_DOMAIN}\z)/.freeze
35
36
  REGEX_DOMAIN_FROM_EMAIL = /\A.+@(.+)\z/.freeze
36
37
  REGEX_SMTP_ERROR_BODY_PATTERN = /(?=.*550)(?=.*(user|account|customer|mailbox)).*/i.freeze
37
38
  end
38
39
 
39
40
  module Audit
40
- require 'truemail/audit/base'
41
- require 'truemail/audit/ptr'
41
+ require_relative '../truemail/audit/base'
42
+ require_relative '../truemail/audit/ip'
43
+ require_relative '../truemail/audit/dns'
44
+ require_relative '../truemail/audit/ptr'
42
45
  end
43
46
 
44
47
  module Validate
45
- require 'truemail/validate/base'
46
- require 'truemail/validate/domain_list_match'
47
- require 'truemail/validate/regex'
48
- require 'truemail/validate/mx'
49
- require 'truemail/validate/smtp'
50
- require 'truemail/validate/smtp/response'
51
- require 'truemail/validate/smtp/request'
48
+ require_relative '../truemail/validate/base'
49
+ require_relative '../truemail/validate/domain_list_match'
50
+ require_relative '../truemail/validate/regex'
51
+ require_relative '../truemail/validate/mx'
52
+ require_relative '../truemail/validate/smtp'
53
+ require_relative '../truemail/validate/smtp/response'
54
+ require_relative '../truemail/validate/smtp/request'
52
55
  end
53
56
 
54
57
  module Log
55
- require 'truemail/log/event'
56
- require 'truemail/log/serializer/base'
57
- require 'truemail/log/serializer/text'
58
- require 'truemail/log/serializer/json'
58
+ require_relative '../truemail/log/event'
59
+ require_relative '../truemail/log/serializer/base'
60
+ require_relative '../truemail/log/serializer/auditor_json'
61
+ require_relative '../truemail/log/serializer/validator_base'
62
+ require_relative '../truemail/log/serializer/validator_text'
63
+ require_relative '../truemail/log/serializer/validator_json'
59
64
  end
60
65
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ class Executor
5
+ attr_reader :result
6
+
7
+ def run; end
8
+
9
+ def as_json; end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Log
5
+ module Serializer
6
+ class AuditorJson < Truemail::Log::Serializer::Base
7
+ def serialize
8
+ result.to_json
9
+ end
10
+
11
+ private
12
+
13
+ def result
14
+ @result ||=
15
+ {
16
+ date: Time.now,
17
+ current_host_ip: executor_result.current_host_ip,
18
+ warnings: warnings(executor_result.warnings),
19
+ configuration: configuration
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -4,47 +4,35 @@ module Truemail
4
4
  module Log
5
5
  module Serializer
6
6
  class Base
7
+ require 'json'
8
+
7
9
  DEFAULT_GEM_VALUE = 'default gem value'
8
10
 
9
- def self.call(validator_instance)
10
- new(validator_instance).serialize
11
+ def self.call(executor_instance)
12
+ new(executor_instance).serialize
11
13
  end
12
14
 
13
- def initialize(validator_instance)
14
- @validation_type = validator_instance.validation_type
15
- @validation_result = validator_instance.result
16
- @validation_configuration = validation_result.configuration
15
+ def initialize(executor_instance)
16
+ @executor_result = executor_instance.result
17
+ @executor_configuration = executor_result.configuration
17
18
  end
18
19
 
19
20
  def serialize; end
20
21
 
21
22
  private
22
23
 
23
- attr_reader :validation_type, :validation_result, :validation_configuration
24
+ attr_reader :executor_result, :executor_configuration
24
25
 
25
- def errors
26
- validation_errors = validation_result.errors
27
- return if validation_errors.empty?
28
- validation_errors
26
+ def errors(executor_result_target)
27
+ return if executor_result_target.empty?
28
+ executor_result_target
29
29
  end
30
30
 
31
- def smtp_debug
32
- validation_smtp_debug = validation_result.smtp_debug
33
- return unless validation_smtp_debug
34
- validation_smtp_debug.map do |smtp_request|
35
- smtp_response = smtp_request.response
36
- {
37
- mail_host: smtp_request.host,
38
- port_opened: smtp_response.port_opened,
39
- connection: smtp_response.connection,
40
- errors: smtp_response.errors
41
- }
42
- end
43
- end
31
+ alias warnings errors
44
32
 
45
33
  %i[validation_type_by_domain whitelisted_domains blacklisted_domains].each do |method|
46
34
  define_method(method) do
47
- value = validation_configuration.public_send(method)
35
+ value = executor_configuration.public_send(method)
48
36
  return if value.empty?
49
37
  value
50
38
  end
@@ -52,7 +40,7 @@ module Truemail
52
40
 
53
41
  %i[email_pattern smtp_error_body_pattern].each do |method|
54
42
  define_method(method) do
55
- value = validation_configuration.public_send(method)
43
+ value = executor_configuration.public_send(method)
56
44
  default_pattern = Truemail::RegexConstant.const_get(
57
45
  (method.eql?(:email_pattern) ? :regex_email_pattern : :regex_smtp_error_body_pattern).upcase
58
46
  )
@@ -64,27 +52,15 @@ module Truemail
64
52
  def configuration
65
53
  {
66
54
  validation_type_by_domain: validation_type_by_domain,
67
- whitelist_validation: validation_configuration.whitelist_validation,
55
+ whitelist_validation: executor_configuration.whitelist_validation,
68
56
  whitelisted_domains: whitelisted_domains,
69
57
  blacklisted_domains: blacklisted_domains,
70
- smtp_safe_check: validation_configuration.smtp_safe_check,
58
+ not_rfc_mx_lookup_flow: executor_configuration.not_rfc_mx_lookup_flow,
59
+ smtp_safe_check: executor_configuration.smtp_safe_check,
71
60
  email_pattern: email_pattern,
72
61
  smtp_error_body_pattern: smtp_error_body_pattern
73
62
  }
74
63
  end
75
-
76
- def result
77
- @result ||=
78
- {
79
- date: Time.now,
80
- email: validation_result.email,
81
- validation_type: validation_type,
82
- success: validation_result.success,
83
- errors: errors,
84
- smtp_debug: smtp_debug,
85
- configuration: configuration
86
- }
87
- end
88
64
  end
89
65
  end
90
66
  end