Class: PrivateCaptcha::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/private_captcha/client.rb

Overview

Client is the main class for verifying Private Captcha solutions

Constant Summary collapse

MIN_BACKOFF_MILLIS =

rubocop:disable Metrics/ClassLength

500

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize {|@config| ... } ⇒ Client

Returns a new instance of Client.

Yields:

Raises:



16
17
18
19
20
21
22
23
24
25
# File 'lib/private_captcha/client.rb', line 16

def initialize
  @config = Configuration.new
  yield(@config) if block_given?

  raise EmptyAPIKeyError if @config.api_key.nil? || @config.api_key.empty?

  @config.domain = normalize_domain(@config.domain)
  @endpoint = URI("https://#{@config.domain}/verify")
  @logger = @config.logger || Logger.new(IO::NULL)
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



14
15
16
# File 'lib/private_captcha/client.rb', line 14

def config
  @config
end

Instance Method Details

#verify(solution, max_backoff_seconds: nil, attempts: nil, sitekey: nil) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity

Raises:



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/private_captcha/client.rb', line 28

def verify(solution, max_backoff_seconds: nil, attempts: nil, sitekey: nil)
  raise EmptySolutionError if solution.nil? || solution.empty?

  max_backoff = max_backoff_seconds || @config.max_backoff_seconds
  max_attempts = attempts || @config.attempts

  @logger.debug('About to start verifying solution') do
    "maxAttempts=#{max_attempts} maxBackoff=#{max_backoff} solution_length=#{solution.length}"
  end

  response = nil
  error = nil
  attempt = 0
  trace_id = nil

  max_attempts.times do |i|
    attempt = i + 1

    if i.positive?
      backoff_duration = calculate_backoff(i, max_backoff, error)
      @logger.debug('Failed to send verify request') do
        "attempt=#{attempt} backoff=#{backoff_duration}s error=#{error&.message}"
      end
      sleep(backoff_duration)
    end

    begin
      response = do_verify(solution, sitekey: sitekey)
      error = nil
      break
    rescue RetriableError => e
      error = e.original_error
      trace_id = e.trace_id if e.trace_id
    end
  end

  @logger.debug('Finished verifying solution') do
    "attempts=#{attempt} success=#{error.nil?}"
  end

  if error
    @logger.error("Failed to verify solution after #{attempt} attempts")
    raise VerificationFailedError.new("Failed to verify solution after #{attempt} attempts", attempt,
                                      trace_id: trace_id)
  end

  response
end

#verify_request(request, form_field: nil) ⇒ Object

rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/private_captcha/client.rb', line 78

def verify_request(request, form_field: nil)
  field = form_field || @config.form_field
  solution = extract_form_value(request, field)

  output = verify(solution)

  unless output.ok?
    raise Error.new("captcha verification failed: #{output.error_message}",
                    trace_id: output.trace_id)
  end

  output
end