truemail 1.7.0 → 1.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,
@@ -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)
@@ -109,7 +111,7 @@ module Truemail
109
111
  end
110
112
 
111
113
  def validate_arguments(argument, method)
112
- 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)
113
115
  raise_unless(argument, method, constant.match?(argument.to_s))
114
116
  end
115
117
 
@@ -140,5 +142,9 @@ module Truemail
140
142
  check_validation_type(validation_type)
141
143
  end
142
144
  end
145
+
146
+ def logger_options(current_options)
147
+ Truemail::Configuration::DEFAULT_LOGGER_OPTIONS.merge(current_options).values
148
+ end
143
149
  end
144
150
  end
@@ -1,15 +1,17 @@
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)
14
+ TypeError = Class.new(StandardError)
13
15
 
14
16
  ArgumentError = Class.new(StandardError) do
15
17
  def initialize(arg_value, arg_name)
@@ -29,32 +31,36 @@ module Truemail
29
31
  end
30
32
 
31
33
  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
34
+ REGEX_DOMAIN = /[\p{L}0-9]+([\-.]{1}[\p{L}0-9]+)*\.\p{L}{2,63}/i.freeze
35
+ REGEX_EMAIL_PATTERN = /(?=\A.{6,255}\z)(\A([\p{L}0-9]+[\w|\-|.|+]*)@(#{REGEX_DOMAIN})\z)/.freeze
34
36
  REGEX_DOMAIN_PATTERN = /(?=\A.{4,255}\z)(\A#{REGEX_DOMAIN}\z)/.freeze
35
37
  REGEX_DOMAIN_FROM_EMAIL = /\A.+@(.+)\z/.freeze
36
38
  REGEX_SMTP_ERROR_BODY_PATTERN = /(?=.*550)(?=.*(user|account|customer|mailbox)).*/i.freeze
37
39
  end
38
40
 
39
41
  module Audit
40
- require 'truemail/audit/base'
41
- require 'truemail/audit/ptr'
42
+ require_relative '../truemail/audit/base'
43
+ require_relative '../truemail/audit/ip'
44
+ require_relative '../truemail/audit/dns'
45
+ require_relative '../truemail/audit/ptr'
42
46
  end
43
47
 
44
48
  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'
49
+ require_relative '../truemail/validate/base'
50
+ require_relative '../truemail/validate/domain_list_match'
51
+ require_relative '../truemail/validate/regex'
52
+ require_relative '../truemail/validate/mx'
53
+ require_relative '../truemail/validate/smtp'
54
+ require_relative '../truemail/validate/smtp/response'
55
+ require_relative '../truemail/validate/smtp/request'
52
56
  end
53
57
 
54
58
  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'
59
+ require_relative '../truemail/log/event'
60
+ require_relative '../truemail/log/serializer/base'
61
+ require_relative '../truemail/log/serializer/auditor_json'
62
+ require_relative '../truemail/log/serializer/validator_base'
63
+ require_relative '../truemail/log/serializer/validator_text'
64
+ require_relative '../truemail/log/serializer/validator_json'
59
65
  end
60
66
  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
@@ -3,7 +3,7 @@
3
3
  module Truemail
4
4
  module Log
5
5
  module Serializer
6
- class Json < Truemail::Log::Serializer::Base
6
+ class ValidatorJson < Truemail::Log::Serializer::ValidatorBase
7
7
  def serialize
8
8
  result.to_json
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Truemail
4
4
  module Log
5
5
  module Serializer
6
- class Text < Truemail::Log::Serializer::Base
6
+ class ValidatorText < Truemail::Log::Serializer::ValidatorBase
7
7
  ATTEMPT = 'ATTEMPT #'
8
8
 
9
9
  def serialize
@@ -30,7 +30,7 @@ module Truemail
30
30
 
31
31
  def collection_printer(collection)
32
32
  collection.inject([]) { |array, hash| array << printer(hash) }.map.with_index do |item, index|
33
- "\n#{Truemail::Log::Serializer::Text::ATTEMPT}#{index + 1}:\n#{item}\n"
33
+ "\n#{Truemail::Log::Serializer::ValidatorText::ATTEMPT}#{index + 1}:\n#{item}\n"
34
34
  end
35
35
  end
36
36
 
@@ -15,7 +15,7 @@ module Truemail
15
15
  def push(validator_instance)
16
16
  current_event = Truemail::Log::Event.new(event, validator_instance)
17
17
  return unless current_event.valid?
18
- create_logs(current_event.log_level, Truemail::Log::Serializer::Text.call(validator_instance))
18
+ create_logs(current_event.log_level, Truemail::Log::Serializer::ValidatorText.call(validator_instance))
19
19
  end
20
20
 
21
21
  private
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truemail
4
- class Validator
4
+ class Validator < Truemail::Executor
5
5
  RESULT_ATTRS = %i[success email domain mail_servers errors smtp_debug configuration].freeze
6
6
  VALIDATION_TYPES = %i[regex mx smtp].freeze
7
7
 
@@ -16,9 +16,9 @@ module Truemail
16
16
  alias_method :valid?, :success
17
17
  end
18
18
 
19
- attr_reader :validation_type, :result
19
+ attr_reader :validation_type
20
20
 
21
- def initialize(email, with: nil, configuration:)
21
+ def initialize(email, configuration:, with: nil)
22
22
  with ||= configuration.default_validation_type
23
23
  raise Truemail::ArgumentError.new(with, :argument) unless Truemail::Validator::VALIDATION_TYPES.include?(with)
24
24
  @result = Truemail::Validator::Result.new(email: email, configuration: configuration)
@@ -33,7 +33,7 @@ module Truemail
33
33
  end
34
34
 
35
35
  def as_json
36
- Truemail::Log::Serializer::Json.call(self)
36
+ Truemail::Log::Serializer::ValidatorJson.call(self)
37
37
  end
38
38
 
39
39
  private