Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,20 @@ to run the tests
require 'ruby-bandwidth-iris'

# Using directly
client = BandwidthIris::Client.new('accountId', 'userName', 'password')
client = BandwidthIris::Client.new('accountId', 'userName', 'password') # Basic Auth
client = BandwidthIris::Client.new({access_token: 'accessToken'}) # Bearer Token Auth
client = BandwidthIris::Client.new({client_id: 'clientId', client_secret: 'clientSecret'}) # OAuth 2 using Client Credentials
sites = BandwidthIris::Site.list(client)

# Or you can use default client instance (do this only once)
BandwidthIris::Client.global_options = {
:account_id => 'accountId',
:username => 'userName',
:password => 'password'
:password => 'password',
:access_token => 'accessToken',
:access_token_expiration => Time.now + 3600
:client_id => 'client_id',
:client_secret => 'client_secret'
}

# Now you can call any functions without first arg 'client'
Expand Down
38 changes: 32 additions & 6 deletions lib/bandwidth-iris/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ def initialize (account_id = nil, user_name = nil, password = nil, options = nil
end
options = options || @@global_options
account_id = options[:account_id] unless account_id
user_name = options[:user_name] || options[:username] unless user_name
user_name = options[:user_name] || options[:username] unless user_name
password = options[:password] unless password
@access_token = options[:access_token]
@access_token_expiration = options[:access_token_expiration] || Time.now + 3600
@client_id = options[:client_id]
@client_secret = options[:client_secret]
options[:api_endpoint] = @@global_options[:api_endpoint] unless options[:api_endpoint]
options[:api_version] = @@global_options[:api_version] unless options[:api_version]
api_endpoint = options[:api_endpoint] || "https://dashboard.bandwidth.com"
Expand All @@ -31,8 +35,15 @@ def initialize (account_id = nil, user_name = nil, password = nil, options = nil
@create_connection = lambda{||
Faraday.new(api_endpoint) { |faraday|
# To make this gem compatible with Faraday v1 and v2, the basic_auth middleware can't be used because it was removed in v2
faraday.request :authorization, 'Basic', Base64.strict_encode64("#{user_name}:#{password}")
#faraday.response :logger
if @access_token && @access_token_expiration > Time.now + 60
faraday.request :authorization, 'Bearer', @access_token
elsif @client_id && @client_secret
refresh_auth_token
faraday.request :authorization, 'Bearer', @access_token
else
faraday.request :authorization, 'Basic', Base64.strict_encode64("#{user_name}:#{password}")
end
# faraday.response :logger
faraday.headers['Accept'] = 'application/xml'
faraday.headers['user-agent'] = 'Ruby-Bandwidth-Iris'
faraday.response :follow_redirects # use Faraday::FollowRedirects::Middleware
Expand Down Expand Up @@ -67,9 +78,24 @@ def Client.get_id_from_location_header(location)
items.last
end

def refresh_auth_token
token_url = 'https://api.bandwidth.com/api/v1/oauth2/token'
response = Faraday.new do |faraday|
faraday.request :url_encoded
faraday.request :authorization, :basic, @client_id, @client_secret
@set_adapter.call(faraday)
end.post(token_url, {grant_type: 'client_credentials'})
if response.status >= 400
raise Errors::GenericError.new(response.status, response.reason_phrase, response.headers, response.body)
end
body = JSON.parse(response.body)
@access_token = body['access_token']
@access_token_expiration = Time.now + body['expires_in']
end

# Make HTTP request to IRIS API
# @param method [Symbol] http method to make
# @param path [string] path of url (exclude api verion and endpoint) to make call
# @param path [string] path of url (exclude api version and endpoint) to make call
# @param data [Hash] data which will be sent with request (for :get and :delete request they will be sent with query in url)
# @return [Array] array with 2 elements: parsed data of response and response headers
def make_request(method, path, data = {})
Expand All @@ -89,7 +115,7 @@ def make_request(method, path, data = {})

# Makes an HTTP request for file uploads
# @param method [Symbol] http method to make
# @param path [string] path of url (exclude api verion and endpoint) to make call
# @param path [string] path of url (exclude api version and endpoint) to make call
# @param data [string] the raw binary string representing the file to upload
# @param content_type [string] the content type of the request
# @return [Array] array with 2 elements: parsed data of response and response headers
Expand All @@ -102,7 +128,7 @@ def make_request_file_upload(method, path, data, content_type)

# Makes an HTTP request for a file download
# @param method [Symbol] http method to make
# @param path [string] path of url (exclude api verion and endpoint) to make call
# @param path [string] path of url (exclude api version and endpoint) to make call
# @param data [Hash] data which will be sent with request (for :get and :delete request they will be sent with query in url)
# @return [string] raw response from the API
def make_request_file_download(method, path, data = {})
Expand Down
2 changes: 1 addition & 1 deletion lib/bandwidth-iris/site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def delete()
def get_sip_peer(peer_id)
item = @client.make_request(:get, "#{@client.concat_account_path(SITE_PATH)}/#{id}/sippeers/#{peer_id}")[0][:sip_peer]
item[:site_id] = id
puts item
# puts item
item
end

Expand Down
2 changes: 1 addition & 1 deletion lib/bandwidth-iris/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module BandwidthIris
# Version of this gem
VERSION = "7.3.2"
VERSION = "7.4.0"
end
37 changes: 35 additions & 2 deletions spec/bandwidth-iris/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
expect(Client.get_id_from_location_header('http://localhost/path1/path2/id')).to eql('id')
end
it 'should raise error if location is missing or nil' do
expect{Client.get_id_from_location_header('')}.to raise_error
expect{Client.get_id_from_location_header(nil)}.to raise_error
expect{Client.get_id_from_location_header('')}.to raise_error(StandardError)
expect{Client.get_id_from_location_header(nil)}.to raise_error(StandardError)
end
end

Expand Down Expand Up @@ -51,12 +51,22 @@

describe '#make_request' do
client = nil
token_client = nil
expired_token_client = nil
client_credentials_client = nil

before :each do
client = Helper.get_client()
token_client = Helper.get_token_client()
expired_token_client = Helper.get_expired_token_client()
client_credentials_client = Helper.get_client_credentials_client()
end

after :each do
client.stubs.verify_stubbed_calls()
token_client.stubs.verify_stubbed_calls()
expired_token_client.stubs.verify_stubbed_calls()
client_credentials_client.stubs.verify_stubbed_calls()
end

it 'should pass basic auth headers' do
Expand All @@ -65,6 +75,29 @@
expect(client.make_request(:get, '/test-auth')).to eql([{:echoed_auth=>"Basic #{Base64.strict_encode64('username:password')}"}, {}])
end

it 'should pass bearer auth header using token' do
token_client.stubs.get('/v1.0/test-auth-token') { |env| [200, {}, "<Result><EchoedAuth>#{env[:request_headers]['Authorization']}</EchoedAuth></Result>"] }
expect(token_client.make_request(:get, '/test-auth-token')).to eql([{:echoed_auth=>"Bearer accessToken"}, {}])
expect(token_client.instance_variable_get(:@access_token)).to eql('accessToken')
expect(token_client.instance_variable_get(:@access_token_expiration)).to be_a(Time)
end

it 'should refresh expired token and pass bearer auth header' do
expired_token_client.stubs.post('https://api.bandwidth.com/api/v1/oauth2/token') { |env| [200, {}, '{"access_token":"newAccessToken","expires_in":3600}'] }
expired_token_client.stubs.get('/v1.0/test-auth-expired-token') { |env| [200, {}, "<Result><EchoedAuth>#{env[:request_headers]['Authorization']}</EchoedAuth></Result>"] }
expect(expired_token_client.make_request(:get, '/test-auth-expired-token')).to eql([{:echoed_auth=>"Bearer newAccessToken"}, {}])
expect(expired_token_client.instance_variable_get(:@access_token)).to eql('newAccessToken')
expect(expired_token_client.instance_variable_get(:@access_token_expiration)).to be_a(Time)
end

it 'should use client credentials to get token and pass bearer auth header' do
client_credentials_client.stubs.post('https://api.bandwidth.com/api/v1/oauth2/token') { |env| [200, {}, '{"access_token":"clientCredentialsAccessToken","expires_in":3600}'] }
client_credentials_client.stubs.get('/v1.0/test-auth-client-credentials') { |env| [200, {}, "<Result><EchoedAuth>#{env[:request_headers]['Authorization']}</EchoedAuth></Result>"] }
expect(client_credentials_client.make_request(:get, '/test-auth-client-credentials')).to eql([{:echoed_auth=>"Bearer clientCredentialsAccessToken"}, {}])
expect(client_credentials_client.instance_variable_get(:@access_token)).to eql('clientCredentialsAccessToken')
expect(client_credentials_client.instance_variable_get(:@access_token_expiration)).to be_a(Time)
end

it 'should make GET request and return xml data' do
client.stubs.get('/v1.0/path1') { |env| [200, {}, '<Result><Test>data</Test></Result>'] }
client.stubs.get('/v1.0/path2?testField=10') { |env| [200, {'Location'=>'url'}, '<Root><TestValue>10</TestValue><DataArray>1</DataArray><DataArray>2</DataArray><BoolValue>true</BoolValue><BoolValue2>false</BoolValue2><DateTimeValue>2015-05-29T01:02:03Z</DateTimeValue></Root>'] }
Expand Down
17 changes: 17 additions & 0 deletions spec/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,23 @@ def self.get_client()
Client.new('accountId', 'username', 'password')
end

def self.get_token_client()
Client.new({access_token: 'accessToken'})
end

def self.get_expired_token_client()
Client.new({
access_token: 'expiredAccessToken',
access_token_expiration: Time.now - 3600,
client_id: 'clientId',
client_secret: 'clientSecret'
})
end

def self.get_client_credentials_client()
Client.new({client_id: 'clientId', client_secret: 'clientSecret'})
end

def self.setup_environment()
Client.global_options[:account_id] = 'accountId'
Client.global_options[:username] = 'username'
Expand Down