figo 1.2.5 → 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/config.yml +4 -0
  4. data/console_demo.rb +1 -1
  5. data/figo.gemspec +3 -3
  6. data/lib/account/api_call.rb +55 -0
  7. data/lib/account/model.rb +122 -0
  8. data/lib/account_balance/api_call.rb +18 -0
  9. data/lib/account_balance/model.rb +31 -0
  10. data/lib/authentification/api_call.rb +88 -0
  11. data/lib/bank/api_call.rb +49 -0
  12. data/lib/bank/model.rb +23 -0
  13. data/lib/base.rb +56 -0
  14. data/lib/cacert.pem +0 -0
  15. data/lib/figo.rb +54 -380
  16. data/lib/helpers/error.rb +20 -0
  17. data/lib/helpers/https.rb +52 -0
  18. data/lib/notification/api_call.rb +40 -0
  19. data/lib/notification/model.rb +27 -0
  20. data/lib/payment/api_call.rb +71 -0
  21. data/lib/payment/model.rb +75 -0
  22. data/lib/process/api_call.rb +17 -0
  23. data/lib/process/model.rb +34 -0
  24. data/lib/security/api_call.rb +59 -0
  25. data/lib/security/model.rb +83 -0
  26. data/lib/standing_order/api_call.rb +24 -0
  27. data/lib/standing_order/model.rb +75 -0
  28. data/lib/synchronization_status/api_call.rb +27 -0
  29. data/lib/synchronization_status/model.rb +23 -0
  30. data/lib/task/api_call.rb +37 -0
  31. data/lib/task/model.rb +43 -0
  32. data/lib/transaction/api_call.rb +57 -0
  33. data/lib/transaction/model.rb +75 -0
  34. data/lib/user/api_call.rb +46 -0
  35. data/lib/user/model.rb +55 -0
  36. data/test/config.yml +7 -0
  37. data/test/test_account_sync_and_setup.rb +67 -0
  38. data/test/test_accounts.rb +106 -0
  39. data/test/test_authentififcation.rb +68 -0
  40. data/test/test_business_processes.rb +43 -0
  41. data/test/test_figo.rb +5 -86
  42. data/test/test_notifications.rb +83 -0
  43. data/test/test_payments.rb +106 -0
  44. data/test/test_securities.rb +70 -0
  45. data/test/test_standing_orders.rb +49 -0
  46. data/test/test_transactions.rb +87 -0
  47. data/test/test_user_management.rb +91 -0
  48. metadata +64 -14
  49. data/lib/models.rb +0 -466
@@ -0,0 +1,20 @@
1
+ module Figo
2
+ # Base class for all errors transported via the figo Connect API.
3
+ class Error < RuntimeError
4
+ # Initialize error object.
5
+ #
6
+ # @param error [String] the error code
7
+ # @param error_description [String] the error description
8
+ def initialize(error, error_description)
9
+ @error = error
10
+ @error_description = error_description
11
+ end
12
+
13
+ # Convert error object to string.
14
+ #
15
+ # @return [String] the error description
16
+ def to_s
17
+ return @error_description
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,52 @@
1
+ require "net/http/persistent"
2
+ module Figo
3
+ # HTTPS class with certificate authentication and enhanced error handling.
4
+ class HTTPS < Net::HTTP::Persistent
5
+ # Overwrite `initialize` method from `Net::HTTP::Persistent`.
6
+ #
7
+ # Verify fingerprints of server SSL/TLS certificates.
8
+ def initialize(name = nil, proxy = nil, fingerprints)
9
+ super(name: name, proxy: proxy)
10
+
11
+ # Attribute ca_file must be set, otherwise verify_callback would never be called.
12
+ @ca_file = "lib/cacert.pem"
13
+ @verify_callback = proc do |preverify_ok, store_context|
14
+ if preverify_ok and store_context.error == 0
15
+ certificate = OpenSSL::X509::Certificate.new(store_context.chain[0])
16
+ fingerprint = Digest::SHA1.hexdigest(certificate.to_der).upcase.scan(/../).join(":")
17
+ fingerprints.include?(fingerprint)
18
+ else
19
+ false
20
+ end
21
+ end
22
+ end
23
+
24
+ # Overwrite `request` method from `Net::HTTP::Persistent`.
25
+ #
26
+ # Raise error when a REST API error is returned.
27
+ def request(uri, req = nil, &block)
28
+ response = super(uri, req, &block)
29
+
30
+ # Evaluate HTTP response.
31
+ case response
32
+ when Net::HTTPSuccess
33
+ return response
34
+ when Net::HTTPBadRequest
35
+ hash = JSON.parse(response.body)
36
+ raise Error.new(hash["error"], hash["error"]["description"])
37
+ when Net::HTTPUnauthorized
38
+ raise Error.new("unauthorized", "Missing, invalid or expired access token.")
39
+ when Net::HTTPForbidden
40
+ raise Error.new("forbidden", "Insufficient permission.")
41
+ when Net::HTTPNotFound
42
+ return nil
43
+ when Net::HTTPMethodNotAllowed
44
+ raise Error.new("method_not_allowed", "Unexpected request method.")
45
+ when Net::HTTPServiceUnavailable
46
+ raise Error.new("service_unavailable", "Exceeded rate limit.")
47
+ else
48
+ raise Error.new("internal_server_error", "We are very sorry, but something went wrong.")
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,40 @@
1
+ require_relative "model.rb"
2
+ module Figo
3
+ # Retrieve list of registered notifications.
4
+ #
5
+ # @return [Notification] an array of `Notification` objects, one for each registered notification
6
+ def notifications
7
+ query_api_object Notification, "/rest/notifications", nil, "GET", "notifications"
8
+ end
9
+
10
+ # Retrieve specific notification.
11
+ #
12
+ # @param notification_id [String] ID of the notification to be retrieved
13
+ # @return [Notification] `Notification` object for the respective notification
14
+ def get_notification(notification_id)
15
+ query_api_object Notification, "/rest/notifications/#{notification_id}"
16
+ end
17
+
18
+ # Register a new notification.
19
+ #
20
+ # @param notification [Notification] notification to be crated. It should not have a notification_id set.
21
+ # @return [Notification] newly created `Notification` object
22
+ def add_notification(notification)
23
+ query_api_object Notification, "/rest/notifications", notification.dump(), "POST"
24
+ end
25
+
26
+ # Modify notification.
27
+ #
28
+ # @param notification [Notification] modified notification object
29
+ # @return [Notification] modified notification returned by server
30
+ def modify_notification(notification)
31
+ query_api_object Notification, "/rest/notifications/#{notification.notification_id}", notification.dump(), "PUT"
32
+ end
33
+
34
+ # Unregister notification.
35
+ #
36
+ # @param notification [Notification, String] notification object which should be deleted or its ID
37
+ def remove_notification(notification)
38
+ query_api notification.is_a?(String) ? "/rest/notifications/#{notification}" : "/rest/notifications/#{notification.notification_id}", nil, "DELETE"
39
+ end
40
+ end
@@ -0,0 +1,27 @@
1
+ require_relative "../base.rb"
2
+ module Figo
3
+ # Object representing a configured notification, e.g. a webhook or email hook
4
+ class Notification < Base
5
+ @dump_attributes = [:observe_key, :notify_uri, :state]
6
+
7
+ def initialize(session, json)
8
+ super(session, json)
9
+ end
10
+
11
+ # Internal figo Connect notification ID from the notification registration response
12
+ # @return [String]
13
+ attr_accessor :notification_id
14
+
15
+ # One of the notification keys specified in the figo Connect API specification
16
+ # @return [String]
17
+ attr_accessor :observe_key
18
+
19
+ # Notification messages will be sent to this URL
20
+ # @return [String]
21
+ attr_accessor :notify_uri
22
+
23
+ # State similiar to sync and logon process. It will passed as POST payload for webhooks
24
+ # @return [String]
25
+ attr_accessor :state
26
+ end
27
+ end
@@ -0,0 +1,71 @@
1
+ require_relative "model.rb"
2
+ module Figo
3
+ # Retrieve list of all payments (on all accounts or one)
4
+ #
5
+ # @param account_id [String] ID of the account for whicht to list the payments
6
+ # @return [Payment] an array of `Payment` objects, one for each payment
7
+ def payments(account_id = nil)
8
+ query_api_object Payment, account_id.nil? ? "/rest/payments" : "/rest/accounts/#{account_id}/payments", nil, "GET", "payments"
9
+ end
10
+
11
+ # Retrieve specific payment.
12
+ #
13
+ # @param account_id [String] ID for the account on which the payment to be retrieved was created
14
+ # @param payment_id [String] ID of the notification to be retrieved
15
+ # @return [Payment] `Payment` object for the respective payment
16
+ def get_payment(account_id, payment_id)
17
+ query_api_object Payment, "/rest/accounts/#{account_id}/payments/#{payment_id}"
18
+ end
19
+
20
+ # Create new payment
21
+ #
22
+ # @param payment [Payment] payment object to be created. It should not have a payment_id set.
23
+ # @return [Payment] newly created `Payment` object
24
+ def add_payment(payment)
25
+ query_api_object Payment, "/rest/accounts/#{payment.account_id}/payments", payment.dump(), "POST"
26
+ end
27
+
28
+ # Modify payment
29
+ #
30
+ # @param payment [Payment] modified payment object
31
+ # @return [Payment] modified payment object
32
+ def modify_payment(payment)
33
+ query_api_object Payment, "/rest/accounts/#{payment.account_id}/payments/#{payment.payment_id}", payment.dump(), "PUT"
34
+ end
35
+
36
+ # Submit payment to bank server
37
+ #
38
+ # @param payment [Payment] payment to be submitted
39
+ # @param tan_scheme_id [String] TAN scheme ID of user-selected TAN scheme
40
+ # @param state [String] Any kind of string that will be forwarded in the callback response message
41
+ # @param redirect_uri [String] At the end of the submission process a response will be sent to this callback URL
42
+ # @return [String] The result parameter is the URL to be opened by the user.
43
+ def submit_payment (payment, tan_scheme_id, state, redirect_uri)
44
+ params = {tan_scheme_id: tan_scheme_id, state: state}
45
+ if(redirect_uri)
46
+ params["redirect_uri"] = redirect_uri;
47
+ end
48
+
49
+ res = query_api("/rest/accounts/" + payment.account_id + "/payments/" + payment.payment_id + "/submit", params, "POST")
50
+
51
+ if(res.task_token)
52
+ "https://" + Config.api_endpoint + "/task/start?id=" + result.task_token
53
+ callback(error);
54
+ else
55
+ res
56
+ end
57
+ end
58
+
59
+ # Remove payment
60
+ #
61
+ # @param payment [Payment, String] payment object which should be removed
62
+ def remove_payment(payment)
63
+ query_api "/rest/accounts/#{payment.account_id}/payments/#{payment.payment_id}", nil, "DELETE"
64
+ end
65
+
66
+ # Retreive payment proposals
67
+ #
68
+ def get_payment_proposals
69
+ query_api "/rest/address_book", nil, "GET"
70
+ end
71
+ end
@@ -0,0 +1,75 @@
1
+ require_relative "../base.rb"
2
+ module Figo
3
+ # Object representing a Payment
4
+ class Payment < Base
5
+ @dump_attributes = [:type, :name, :account_number, :bank_code, :amount, :currency, :purpose]
6
+
7
+ def initialize(session, json)
8
+ super(session, json)
9
+ end
10
+
11
+ # Internal figo Connect payment ID
12
+ # @return [String]
13
+ attr_accessor :payment_id
14
+
15
+ # Internal figo Connect account ID
16
+ # @return [String]
17
+ attr_accessor :account_id
18
+
19
+ # Payment type
20
+ # @return [String]
21
+ attr_accessor :type
22
+
23
+ # Name of creditor or debtor
24
+ # @return [String]
25
+ attr_accessor :name
26
+
27
+ # Account number of creditor or debtor
28
+ # @return [String]
29
+ attr_accessor :account_number
30
+
31
+ # Bank code of creditor or debtor
32
+ # @return [String]
33
+ attr_accessor :bank_code
34
+
35
+ # Bank name of creditor or debtor
36
+ # @return [String]
37
+ attr_accessor :bank_name
38
+
39
+ # Icon of creditor or debtor bank
40
+ # @return [String]
41
+ attr_accessor :bank_icon
42
+
43
+ # Icon of the creditor or debtor bank in other resolutions
44
+ # @return [Hash]
45
+ attr_accessor :bank_additional_icons
46
+
47
+ # Order amount
48
+ # @return [DecNum]
49
+ attr_accessor :amount
50
+
51
+ # Three-character currency code
52
+ # @return [String]
53
+ attr_accessor :currency
54
+
55
+ # Purpose text
56
+ # @return [String]
57
+ attr_accessor :purpose
58
+
59
+ # Timestamp of submission to the bank server
60
+ # @return [DateTime]
61
+ attr_accessor :submission_timestamp
62
+
63
+ # Internal creation timestamp on the figo Connect server
64
+ # @return [DateTime]
65
+ attr_accessor :creation_timestamp
66
+
67
+ # Internal modification timestamp on the figo Connect server
68
+ # @return [DateTime]
69
+ attr_accessor :modification_timestamp
70
+
71
+ # ID of the transaction corresponding to this payment. This field is only set if the payment has been matched to a transaction
72
+ # @return [String]
73
+ attr_accessor :transaction_id
74
+ end
75
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "model.rb"
2
+ module Figo
3
+ # Begin process.
4
+ #
5
+ # @param process [Hash] - Process token object
6
+ def start_process(process)
7
+ query_api "/process/start?id=" + process.process_token, nil, "GET"
8
+ end
9
+
10
+ # Create a process.
11
+ #
12
+ # @param proc [Hash] - Process object
13
+ # @return [Hash] - The result parameter is a ProcessToken object of a newly created process.
14
+ def create_process(proc)
15
+ query_api_object ProcessToken, "/client/process", proc.dump(), "POST", nil
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ require_relative "../base.rb"
2
+ module Figo
3
+ ### Object representing a process token
4
+ class ProcessToken < Base
5
+ @dump_attributes = [:process_token];
6
+ def initialize(session, json)
7
+ super(session, json)
8
+ end
9
+
10
+ # Properties:
11
+ # @param process_token [Object] - Process ID
12
+ attr_accessor :process_token
13
+ end
14
+
15
+ ### Object representing a Bsiness Process
16
+ class Process < Base
17
+ @dump_attributes = [:email, :password, :redirect_uri, :state, :steps]
18
+ def initialize(session, json)
19
+ super(session, json)
20
+ end
21
+
22
+ # Properties:
23
+ # @param email [String] - The email of the existing user to use as context or the new user to create beforehand
24
+ attr_accessor :email
25
+ # @param password [String] - The password of the user existing or new user
26
+ attr_accessor :password
27
+ # @param redirect_uri [String] - The authorization code will be sent to this callback URL
28
+ attr_accessor :redirect_uri
29
+ # @param state [String] - Any kind of string that will be forwarded in the callback response message
30
+ attr_accessor :state
31
+ # @param steps [String] - A list of steps definitions
32
+ attr_accessor :steps
33
+ end
34
+ end
@@ -0,0 +1,59 @@
1
+ require_relative "model.rb"
2
+ require 'json'
3
+
4
+ module Figo
5
+ # Retrieve a security.
6
+ #
7
+ # @param account_id [String] - ID of the account the security belongs to
8
+ # @param security_id [String] - ID of the security to retrieve
9
+ # @return [Security] - A single security object.
10
+ def get_security(account_id, security_id)
11
+ query_api_object Security, "/rest/accounts/" + account_id + "/securities/" + security_id, nil, "GET", nil
12
+ end
13
+
14
+ # Retrieve securities of one or all accounts.
15
+ #
16
+ # @param options [Object] - further options (all are optional)
17
+ # @param options.account_id [String] - ID of the account for which to retrieve the securities
18
+ # @param options.accounts [Array] - filter the securities to be only from these accounts
19
+ # @param options.since [Date] - ISO date filtering the returned securities by their creation or last modification date
20
+ # @param options.since_type [String] - defines hot the `since` will be interpreted: `traded`, `created` or `modified`
21
+ # @param options.count [Number] - limit the number of returned transactions
22
+ # @param options.offset [Number] - offset into the implicit list of transactions
23
+ # @return [Security] - An array of `Security` objects.
24
+ def get_securities(options = nil)
25
+ options ||= {}
26
+ options["count"] ||= 1000
27
+ options["offset"] ||= 0
28
+ if(!options["account_id"])
29
+ query_api_object Security, "/rest/securities?" + URI.encode_www_form(options), nil, "GET", 'securities'
30
+ else
31
+ account_id = options["account_id"]
32
+ options.delete("account_id")
33
+ query_api_object Security, "/rest/accounts/" + account_id + "/securities?" + URI.encode_www_form(options), nil, "GET", "securities"
34
+ end
35
+ end
36
+
37
+ # Modify a security.
38
+ # @param account_id [String] - ID of the account the security belongs to
39
+ # @param security_id [String] - ID of the security to change
40
+ # @param visited [Boolean] - a bit showing whether the user has already seen this security or not
41
+
42
+ def modify_security (account_id, security_id, visited)
43
+ data = {:visited => visited}
44
+ query_api "/rest/accounts/" + account_id + "/securities/" + security_id, data, "PUT"
45
+ end
46
+
47
+ # Modify securities of one or all accounts.
48
+ # @param visited [Boolean] - a bit showing whether the user has already seen these securities or not
49
+ # @param account_id [String] - ID of the account securities belongs to (optional)
50
+
51
+ def modify_securities (visited, account_id = nil)
52
+ data = {visited: visited}
53
+ if (account_id)
54
+ query_api "/rest/accounts/" + account_id + "/securities", data, "PUT"
55
+ else
56
+ query_api "/rest/securities", data, "PUT"
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,83 @@
1
+ require_relative "../base.rb"
2
+ module Figo
3
+ # Object representing a Payment
4
+ class Security < Base
5
+ @dump_attributes = [:name, :isin, :wkn, :currency, :quantity, :amount, :amount_original_currency, :exchange_rate, :price, :price_currency, :purchase_price, :purchase_price_currency, :visited]
6
+
7
+ def initialize(session, json)
8
+ super(session, json)
9
+ end
10
+
11
+ # Name of creditor or debtor
12
+ # @return [String]
13
+ attr_accessor :name
14
+
15
+ # Order amount
16
+ # @return [DecNum]
17
+ attr_accessor :amount
18
+
19
+ # Three-character currency code
20
+ # @return [String]
21
+ attr_accessor :currency
22
+
23
+ # Internal figo Connect security ID
24
+ # @return [String]
25
+ attr_accessor :security_id
26
+
27
+ # Internal figo Connect account ID
28
+ # @return [String]
29
+ attr_accessor :account_id
30
+
31
+ # International Securities Identification Number
32
+ # @return [String]
33
+ attr_accessor :isin
34
+
35
+ # Wertpapierkennnummer (if available)
36
+ # @return [String]
37
+ attr_accessor :wkn
38
+
39
+ # Number of pieces or value
40
+ # @return [Number]
41
+ attr_accessor :quantity
42
+
43
+ # Monetary value in trading currency
44
+ # @return [Number]
45
+ attr_accessor :amount_original_currency
46
+
47
+ # Exchange rate between trading and account currency
48
+ # @return [Number]
49
+ attr_accessor :exchange_rate
50
+
51
+ # Current price
52
+ # @return [Number]
53
+ attr_accessor :price
54
+
55
+ # Currency of current price
56
+ # @return [String]
57
+ attr_accessor :price_currency
58
+
59
+ # Purchase price
60
+ # @return [Number]
61
+ attr_accessor :purchase_price
62
+
63
+ # Currency of purchase price
64
+ # @return [String]
65
+ attr_accessor :purchase_price_currency
66
+
67
+ # This flag indicates whether the security has already been marked as visited by the user
68
+ # @return [Boolean]
69
+ attr_accessor :visited
70
+
71
+ # Trading timestamp
72
+ # @return [Date]
73
+ attr_accessor :trade_timestamp
74
+
75
+ # Internal creation timestamp on the figo Connect server
76
+ # @return [Date]
77
+ attr_accessor :creation_timestamp
78
+
79
+ # Internal modification timestamp on the figo
80
+ # @return [Date]
81
+ attr_accessor :modification_timestamp
82
+ end
83
+ end