truemail 1.6.0 → 1.9.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.
@@ -1,17 +1,16 @@
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'
7
7
  NOT_CONFIGURED = 'use Truemail.configure before or pass custom configuration'
8
8
 
9
9
  class << self
10
- def configuration
10
+ def configuration(&block)
11
11
  @configuration ||= begin
12
12
  return unless block_given?
13
- configuration = Truemail::Configuration.new
14
- yield(configuration)
13
+ configuration = Truemail::Configuration.new(&block)
15
14
  raise_unless(configuration.complete?, Truemail::INCOMPLETE_CONFIG)
16
15
  configuration
17
16
  end
@@ -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,37 +3,19 @@
3
3
  module Truemail
4
4
  module Audit
5
5
  class Ptr < Truemail::Audit::Base
6
- require 'ipaddr'
7
- require 'resolv'
8
-
9
- GET_MY_IP_URL = 'https://api.ipify.org'
10
- IPIFY_ERROR = 'impossible to detect current host address via third party service'
11
- PTR_NOT_FOUND = 'ptr record for current host address was not found'
12
- PTR_NOT_REFER = 'ptr record does not reference to current verifier domain'
13
- 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'
14
8
 
15
9
  def run
16
- return if !current_host_address && add_warning(Truemail::Audit::Ptr::IPIFY_ERROR)
17
- return if ptr_records.empty? && add_warning(Truemail::Audit::Ptr::PTR_NOT_FOUND)
18
- return if ptr_not_refer_to_verifier_domain? && add_warning(Truemail::Audit::Ptr::PTR_NOT_REFER)
19
- return if verifier_domain_refer_to_current_host_address?
20
- 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)
21
13
  end
22
14
 
23
15
  private
24
16
 
25
- def detect_ip_via_ipify
26
- Net::HTTP.get(URI(Truemail::Audit::Ptr::GET_MY_IP_URL))
27
- end
28
-
29
- def current_host_address
30
- @current_host_address ||= Truemail::Wrapper.call(configuration: configuration) do
31
- IPAddr.new(detect_ip_via_ipify)
32
- end
33
- end
34
-
35
17
  def current_host_reverse_lookup
36
- current_host_address.reverse
18
+ IPAddr.new(current_host_ip).reverse
37
19
  end
38
20
 
39
21
  def ptr_records
@@ -44,18 +26,8 @@ module Truemail
44
26
  end || []
45
27
  end
46
28
 
47
- def ptr_not_refer_to_verifier_domain?
48
- !ptr_records.include?(verifier_domain)
49
- end
50
-
51
- def a_record
52
- Truemail::Wrapper.call(configuration: configuration) do
53
- Resolv::DNS.new.getaddress(verifier_domain).to_s
54
- end
55
- end
56
-
57
- def verifier_domain_refer_to_current_host_address?
58
- a_record.eql?(current_host_address.to_s)
29
+ def ptr_refer_to_verifier_domain?
30
+ ptr_records.include?(verifier_domain)
59
31
  end
60
32
  end
61
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
@@ -20,9 +20,7 @@ module Truemail
20
20
  :blacklisted_domains,
21
21
  :logger
22
22
 
23
- attr_accessor :whitelist_validation, :smtp_safe_check
24
-
25
- alias retry_count connection_attempts
23
+ attr_accessor :whitelist_validation, :not_rfc_mx_lookup_flow, :smtp_safe_check
26
24
 
27
25
  def initialize(&block)
28
26
  instance_initializer.each do |instace_variable, value|
@@ -101,6 +99,7 @@ module Truemail
101
99
  whitelisted_domains: [],
102
100
  whitelist_validation: false,
103
101
  blacklisted_domains: [],
102
+ not_rfc_mx_lookup_flow: false,
104
103
  smtp_safe_check: false
105
104
  }
106
105
  end
@@ -110,7 +109,7 @@ module Truemail
110
109
  end
111
110
 
112
111
  def validate_arguments(argument, method)
113
- constant = Truemail::RegexConstant.const_get("regex_#{method[/\A.+_(.+)\=\z/, 1]}_pattern".upcase)
112
+ constant = Truemail::RegexConstant.const_get("regex_#{method[/\A.+_(.+)=\z/, 1]}_pattern".upcase)
114
113
  raise_unless(argument, method, constant.match?(argument.to_s))
115
114
  end
116
115
 
@@ -1,19 +1,20 @@
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
 
14
15
  ArgumentError = Class.new(StandardError) do
15
- def initialize(current_param, class_name)
16
- super("#{current_param} is not a valid #{class_name}")
16
+ def initialize(arg_value, arg_name)
17
+ super("#{arg_value} is not a valid #{arg_name}")
17
18
  end
18
19
  end
19
20
 
@@ -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
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Log
5
+ module Serializer
6
+ class ValidatorBase < Truemail::Log::Serializer::Base
7
+ def initialize(executor_instance)
8
+ @validation_type = executor_instance.validation_type
9
+ super
10
+ end
11
+
12
+ private
13
+
14
+ attr_reader :validation_type
15
+
16
+ def smtp_debug
17
+ validation_smtp_debug = executor_result.smtp_debug
18
+ return unless validation_smtp_debug
19
+ validation_smtp_debug.map do |smtp_request|
20
+ smtp_response = smtp_request.response
21
+ {
22
+ mail_host: smtp_request.host,
23
+ port_opened: smtp_response.port_opened,
24
+ connection: smtp_response.connection,
25
+ errors: smtp_response.errors
26
+ }
27
+ end
28
+ end
29
+
30
+ def result
31
+ @result ||=
32
+ {
33
+ date: Time.now,
34
+ email: executor_result.email,
35
+ validation_type: validation_type,
36
+ success: executor_result.success,
37
+ errors: errors(executor_result.errors),
38
+ smtp_debug: smtp_debug,
39
+ configuration: configuration
40
+ }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end