Class: DuoApi

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

Overview

A Ruby implementation of the Duo API

Constant Summary collapse

MAX_BACKOFF_WAIT_SECS =

Constants for handling rate limit backoff

32
INITIAL_BACKOFF_WAIT_SECS =
1
BACKOFF_FACTOR =
2
RATE_LIMITED_RESP_CODE =
'429'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ikey, skey, host, proxy = nil, ca_file: nil) ⇒ DuoApi

Returns a new instance of DuoApi.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/duo_api.rb', line 19

def initialize(ikey, skey, host, proxy = nil, ca_file: nil)
  @ikey = ikey
  @skey = skey
  @host = host
  if proxy.nil?
    @proxy = []
  else
    proxy_uri = URI.parse proxy
    @proxy = [
      proxy_uri.host,
      proxy_uri.port,
      proxy_uri.user,
      proxy_uri.password
    ]
  end
  @ca_file = ca_file ||
             File.join(File.dirname(__FILE__), '..', 'ca_certs.pem')
end

Instance Attribute Details

#ca_fileObject

Returns the value of attribute ca_file.



11
12
13
# File 'lib/duo_api.rb', line 11

def ca_file
  @ca_file
end

Instance Method Details

#request(method, path, params = nil) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/duo_api.rb', line 38

def request(method, path, params = nil)
  uri = request_uri(path, params)
  current_date, signed = sign(method, uri.host, path, params)

  request = Net::HTTP.const_get(method.capitalize).new uri.to_s
  request.basic_auth(@ikey, signed)
  request['Date'] = current_date
  request['User-Agent'] = 'duo_api_ruby/1.3.0'

  Net::HTTP.start(uri.host, uri.port, *@proxy,
                  use_ssl: true, ca_file: @ca_file,
                  verify_mode: OpenSSL::SSL::VERIFY_PEER) do |http|
    wait_secs = INITIAL_BACKOFF_WAIT_SECS
    while true do
      resp = http.request(request)
      if resp.code != RATE_LIMITED_RESP_CODE or wait_secs > MAX_BACKOFF_WAIT_SECS
          return resp
      end
      random_offset = rand()
      sleep(wait_secs + random_offset)
      wait_secs *= BACKOFF_FACTOR
    end
  end
end