lib/figo.rb in figo-1.1 vs lib/figo.rb in figo-1.1.1
- old
+ new
@@ -19,26 +19,22 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
require "json"
-require "logger"
-require 'net/http/persistent'
+require "net/http/persistent"
require "digest/sha1"
require_relative "models.rb"
# Ruby bindings for the figo Connect API: http://developer.figo.me
module Figo
- $api_endpoint = "api.leanbank.com"
+ $api_endpoint = "api.figo.me"
- $valid_fingerprints = ["A6:FE:08:F4:A8:86:F9:C1:BF:4E:70:0A:BD:72:AE:B8:8E:B7:78:52",
- "AD:A0:E3:2B:1F:CE:E8:44:F2:83:BA:AE:E4:7D:F2:AD:44:48:7F:1E"]
+ $valid_fingerprints = ["3A:62:54:4D:86:B4:34:38:EA:34:64:4E:95:10:A9:FF:37:27:69:C0"]
- $logger = Logger.new(STDOUT)
-
# Base class for all errors transported via the figo Connect API.
class Error < RuntimeError
# Initialize error object.
#
@@ -102,11 +98,10 @@
when Net::HTTPMethodNotAllowed
raise Error.new("method_not_allowed", "Unexpected request method.")
when Net::HTTPServiceUnavailable
raise Error.new("service_unavailable", "Exceeded rate limit.")
else
- $logger.warn("Querying the API failed when accessing '#{path}': #{response.code}")
raise Error.new("internal_server_error", "We are very sorry, but something went wrong.")
end
end
end
@@ -139,11 +134,11 @@
# Setup HTTP request.
request = Net::HTTP::Post.new(path)
request.basic_auth(@client_id, @client_secret)
request["Accept"] = "application/json"
request["Content-Type"] = "application/x-www-form-urlencoded"
- request['User-Agent'] = "ruby-figo"
+ request["User-Agent"] = "ruby-figo"
request.body = URI.encode_www_form(data) unless data.nil?
# Send HTTP request.
response = @https.request(uri, request)
@@ -161,10 +156,11 @@
# @param state [String] this string will be passed on through the complete login
# process and to the redirect target at the end. It should be used to
# validated the authenticity of the call to the redirect URL
# @param scope [String] optional scope of data access to ask the user for,
# e.g. `accounts=ro`
+ # @return [String] the URL to be opened by the user.
def login_url(state, scope = nil)
data = { "response_type" => "code", "client_id" => @client_id, "state" => state }
data["redirect_uri"] = @redirect_uri unless @redirect_uri.nil?
data["scope"] = scope unless scope.nil?
return "https://#{$api_endpoint}/auth/code?" + URI.encode_www_form(data)
@@ -177,11 +173,11 @@
# code received as part of the call to the redirect URL at the end of the
# logon process, or a refresh token
# @param scope [String] optional scope of data access to ask the user for,
# e.g. `accounts=ro`
# @return [Hash] object with the keys `access_token`, `refresh_token` and
- # `expires,` as documented in the figo Connect API specification.
+ # `expires`, as documented in the figo Connect API specification.
def obtain_access_token(authorization_code_or_refresh_token, scope = nil)
# Authorization codes always start with "O" and refresh tokens always start with "R".
if authorization_code_or_refresh_token[0] == "O"
data = { "grant_type" => "authorization_code", "code" => authorization_code_or_refresh_token }
data["redirect_uri"] = @redirect_uri unless @redirect_uri.nil?
@@ -194,11 +190,11 @@
# Revoke refresh token or access token.
#
# @note this action has immediate effect, i.e. you will not be able use that token anymore after this call.
#
- # @param token [String] access or refresh token to be revoked
+ # @param refresh_token_or_access_token [String] access or refresh token to be revoked
# @return [nil]
def revoke_token(refresh_token_or_access_token)
data = { "token" => refresh_token_or_access_token }
query_api("/auth/revoke?" + URI.encode_www_form(data))
return nil
@@ -219,10 +215,11 @@
# Helper method for making a REST request.
#
# @param path [String] the URL path on the server
# @param data [hash] this optional object will be used as JSON-encoded POST content.
+ # @param method [String] the HTTP method
# @return [Hash] JSON response
def query_api(path, data=nil, method="GET") # :nodoc:
uri = URI("https://#{$api_endpoint}#{path}")
# Setup HTTP request.
@@ -238,11 +235,11 @@
end
request["Authorization"] = "Bearer #{@access_token}"
request["Accept"] = "application/json"
request["Content-Type"] = "application/json"
- request['User-Agent'] = "ruby-figo"
+ request["User-Agent"] = "ruby-figo"
request.body = JSON.generate(data) unless data.nil?
# Send HTTP request.
response = @https.request(uri, request)
@@ -268,18 +265,18 @@
#
# @param account_id [String] ID of the account to be retrieved.
# @return [Account] account object
def get_account(account_id)
response = query_api("/rest/accounts/#{account_id}")
- return Account.new(self, response)
+ return response.nil? ? nil : Account.new(self, response)
end
# Request list of transactions.
#
- # @param since [String] this parameter can either be a transaction ID or a date
+ # @param since [String, Date] this parameter can either be a transaction ID or a date
# @param start_id [String] do only return transactions which were booked after the start transaction ID
- # @param count [Intger] limit the number of returned transactions
+ # @param count [Integer] limit the number of returned transactions
# @param include_pending [Boolean] this flag indicates whether pending transactions should be included
# in the response; pending transactions are always included as a complete set, regardless of
# the `since` parameter
# @return [Array] an array of `Transaction` objects, one for each transaction of the user
def transactions(since = nil, start_id = nil, count = 1000, include_pending = false)
@@ -292,11 +289,11 @@
return response["transactions"].map {|transaction| Transaction.new(self, transaction)}
end
# Request the URL a user should open in the web browser to start the synchronization process.
#
- # @param redirect_uri [String] URI the user is redirected to after the process completes
+ # @param redirect_uri [String] the user will be redirected to this URL after the process completes
# @param state [String] this string will be passed on through the complete synchronization process
# and to the redirect target at the end. It should be used to validated the authenticity of
# the call to the redirect URL
# @param disable_notifications [Booleon] this flag indicates whether notifications should be sent
# @param if_not_synced_since [Integer] if this parameter is set, only those accounts will be
@@ -336,16 +333,16 @@
data = { "observe_key" => observe_key, "notify_uri" => notify_uri, "state" => state }
response = query_api("/rest/notifications", data, "POST")
return Notification.new(self, response)
end
- # Modify a notification.
+ # Modify notification.
#
# @param notification [Notification] modified notification object
# @return [nil]
def modify_notification(notification)
data = { "observe_key" => notification.observe_key, "notify_uri" => notification.notify_uri, "state" => notification.state }
- response = query_api("/rest/notifications/#{notification.notification_id}", data, "PUT")
+ query_api("/rest/notifications/#{notification.notification_id}", data, "PUT")
return nil
end
# Unregister notification.
#