ofx_for_ruby 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. data/.externalToolBuilders/Rebuild parsers.launch +10 -0
  2. data/.gitignore +9 -0
  3. data/.loadpath +5 -0
  4. data/.project +27 -0
  5. data/COPYING +674 -0
  6. data/Gemfile +2 -0
  7. data/README +47 -0
  8. data/RELEASE_NOTES +45 -0
  9. data/Rakefile +63 -0
  10. data/lib/ofx.rb +60 -0
  11. data/lib/ofx/1.0.2/banking_message_set.rb +261 -0
  12. data/lib/ofx/1.0.2/credit_card_statement_message_set.rb +269 -0
  13. data/lib/ofx/1.0.2/document.rb +34 -0
  14. data/lib/ofx/1.0.2/email_message_set.rb +34 -0
  15. data/lib/ofx/1.0.2/financial_institution_profile_message_set.rb +155 -0
  16. data/lib/ofx/1.0.2/header.rb +48 -0
  17. data/lib/ofx/1.0.2/interbank_funds_transfer_message_set.rb +30 -0
  18. data/lib/ofx/1.0.2/investment_security_list_message_set.rb +30 -0
  19. data/lib/ofx/1.0.2/investment_statement_message_set.rb +30 -0
  20. data/lib/ofx/1.0.2/lexer.rb +135 -0
  21. data/lib/ofx/1.0.2/message_set.rb +165 -0
  22. data/lib/ofx/1.0.2/ofx_102.racc +90 -0
  23. data/lib/ofx/1.0.2/ofx_102.rex +65 -0
  24. data/lib/ofx/1.0.2/parser.rb +215 -0
  25. data/lib/ofx/1.0.2/payment_message_set.rb +30 -0
  26. data/lib/ofx/1.0.2/serializer.rb +114 -0
  27. data/lib/ofx/1.0.2/signon_message_set.rb +121 -0
  28. data/lib/ofx/1.0.2/signup_message_set.rb +186 -0
  29. data/lib/ofx/1.0.2/statements.rb +54 -0
  30. data/lib/ofx/1.0.2/status.rb +30 -0
  31. data/lib/ofx/1.0.2/wire_funds_transfer_message_set.rb +30 -0
  32. data/lib/ofx/banking_message_set.rb +125 -0
  33. data/lib/ofx/credit_card_statement_message_set.rb +104 -0
  34. data/lib/ofx/document.rb +30 -0
  35. data/lib/ofx/email_message_set.rb +42 -0
  36. data/lib/ofx/file_unique_identifier.rb +28 -0
  37. data/lib/ofx/financial_client.rb +76 -0
  38. data/lib/ofx/financial_institution.rb +83 -0
  39. data/lib/ofx/financial_institution_profile_message_set.rb +67 -0
  40. data/lib/ofx/header.rb +115 -0
  41. data/lib/ofx/http/cacert.pem +3509 -0
  42. data/lib/ofx/http/ofx_http_client.rb +84 -0
  43. data/lib/ofx/interbank_funds_transfer_message_set.rb +33 -0
  44. data/lib/ofx/investment_security_list_message_set.rb +33 -0
  45. data/lib/ofx/investment_statement_message_set.rb +33 -0
  46. data/lib/ofx/message_set.rb +78 -0
  47. data/lib/ofx/payment_message_set.rb +33 -0
  48. data/lib/ofx/serializer.rb +39 -0
  49. data/lib/ofx/signon_message_set.rb +141 -0
  50. data/lib/ofx/signup_message_set.rb +84 -0
  51. data/lib/ofx/statements.rb +49 -0
  52. data/lib/ofx/status.rb +100 -0
  53. data/lib/ofx/transaction_unique_identifier.rb +28 -0
  54. data/lib/ofx/version.rb +82 -0
  55. data/lib/ofx/wire_funds_transfer_message_set.rb +33 -0
  56. data/ofx_for_ruby.gemspec +25 -0
  57. data/planning/OFX Specification completion.ods +0 -0
  58. data/test/capital_one/capital_one_helper.rb +77 -0
  59. data/test/capital_one/fixtures/README +10 -0
  60. data/test/capital_one/fixtures/fipid-5599.xml +98 -0
  61. data/test/capital_one/test_banking_statement.rb +108 -0
  62. data/test/capital_one/test_financial_institution_profile.rb +295 -0
  63. data/test/capital_one/test_ofx_http_client.rb +72 -0
  64. data/test/capital_one/test_signup_account_information.rb +100 -0
  65. data/test/citi/citi_helper.rb +77 -0
  66. data/test/citi/fixtures/README +9 -0
  67. data/test/citi/fixtures/fipid-6642.xml +98 -0
  68. data/test/citi/test_credit_card_statement.rb +159 -0
  69. data/test/citi/test_financial_institution_profile.rb +231 -0
  70. data/test/citi/test_ofx_http_client.rb +71 -0
  71. data/test/citi/test_signup_account_information.rb +85 -0
  72. data/test/test_helper.rb +4 -0
  73. data/test/test_ofx_version.rb +141 -0
  74. metadata +210 -0
@@ -0,0 +1,30 @@
1
+ # Copyright © 2007 Chris Guidry <chrisguidry@gmail.com>
2
+ #
3
+ # This file is part of OFX for Ruby.
4
+ #
5
+ # OFX for Ruby is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # OFX for Ruby is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module OFX
19
+ class Document
20
+
21
+ attr_accessor :header
22
+ attr :message_sets
23
+
24
+ def initialize
25
+ @header = OFX::Header.new
26
+ @message_sets = []
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ # Copyright © 2007 Chris Guidry <chrisguidry@gmail.com>
2
+ #
3
+ # This file is part of OFX for Ruby.
4
+ #
5
+ # OFX for Ruby is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # OFX for Ruby is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module OFX
19
+ class EmailMessageSet < MessageSet
20
+ def precedence
21
+ 9
22
+ end
23
+ def version
24
+ 1
25
+ end
26
+ end
27
+
28
+ class EmailMessageSetProfile < MessageSetProfile
29
+ def self.message_set_class
30
+ EmailMessageSet
31
+ end
32
+
33
+ attr_accessor :supports_email
34
+ def supports_email?
35
+ supports_email
36
+ end
37
+ attr_accessor :supports_mime_messages
38
+ def supports_mime_messages?
39
+ supports_mime_messages
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright © 2007 Chris Guidry <chrisguidry@gmail.com>
2
+ #
3
+ # This file is part of OFX for Ruby.
4
+ #
5
+ # OFX for Ruby is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # OFX for Ruby is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module OFX
19
+ class FileUniqueIdentifier
20
+ def initialize
21
+ @timestamp = DateTime.now
22
+ end
23
+
24
+ def to_s
25
+ @timestamp.strftime('%Y%m%d%H%M%S')
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,76 @@
1
+ # Copyright © 2007 Chris Guidry <chrisguidry@gmail.com>
2
+ #
3
+ # This file is part of OFX for Ruby.
4
+ #
5
+ # OFX for Ruby is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # OFX for Ruby is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require 'date'
19
+
20
+ module OFX
21
+ class FinancialClient
22
+
23
+ @financial_institutions_and_credentials = []
24
+
25
+ attr_accessor :date_of_last_profile_update
26
+
27
+ def initialize(financial_institutions_and_credentials)
28
+ @financial_institutions_and_credentials = financial_institutions_and_credentials
29
+ end
30
+
31
+ def financial_institution_identification_for(financial_institution_id)
32
+ @financial_institutions_and_credentials.each do |pair|
33
+ return pair[0] if (pair[0].financial_institution_identifier == financial_institution_id)
34
+ end
35
+ return nil
36
+ end
37
+ def user_identification_for(financial_institution_id)
38
+ @financial_institutions_and_credentials.each do |pair|
39
+ return pair[1] if (pair[0].financial_institution_identifier == financial_institution_id)
40
+ end
41
+ return nil
42
+ end
43
+
44
+ def application_identification
45
+ OFX::ApplicationIdentification.new('OFX', '0010')
46
+ end
47
+
48
+ def create_signon_request_message(financial_institution_id)
49
+ signonMessageSet = OFX::SignonMessageSet.new
50
+
51
+ signonRequest = OFX::SignonRequest.new
52
+ signonRequest.date = DateTime.now
53
+ signonRequest.user_identification = self.user_identification_for(financial_institution_id)
54
+ signonRequest.generate_user_key = false
55
+ signonRequest.language = "ENG"
56
+ signonRequest.financial_institution_identification = self.financial_institution_identification_for(financial_institution_id)
57
+ signonRequest.session_cookie = nil
58
+ signonRequest.application_identification = self.application_identification
59
+ signonMessageSet.requests << signonRequest
60
+
61
+ signonMessageSet
62
+ end
63
+
64
+ def create_profile_update_request_message()
65
+ profileMessageSet = OFX::FinancialInstitutionProfileMessageSet.new
66
+
67
+ profileRequest = OFX::FinancialInstitutionProfileRequest.new
68
+ profileRequest.transaction_identifier = OFX::TransactionUniqueIdentifier.new
69
+ profileRequest.client_routing = 'MSGSET'
70
+ profileRequest.date_of_last_profile_update = self.date_of_last_profile_update
71
+ profileMessageSet.requests << profileRequest
72
+
73
+ profileMessageSet
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,83 @@
1
+ # Copyright © 2007 Chris Guidry <chrisguidry@gmail.com>
2
+ #
3
+ # This file is part of OFX for Ruby.
4
+ #
5
+ # OFX for Ruby is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # OFX for Ruby is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require 'uri'
19
+
20
+ module OFX
21
+ class FinancialInstitution
22
+
23
+ def self.get_institution(financial_institution_name)
24
+ case financial_institution_name
25
+ when 'Capital One'
26
+ FinancialInstitution.new('Capital One',
27
+ URI.parse('https://onlinebanking.capitalone.com/scripts/serverext.dll'),
28
+ OFX::Version.new("1.0.2"))
29
+ when 'Citi'
30
+ FinancialInstitution.new('Citi',
31
+ URI.parse('https://secureofx2.bankhost.com/citi/cgi-forte/ofx_rt?servicename=ofx_rt&pagename=ofx'),
32
+ OFX::Version.new("1.0.2"))
33
+ else
34
+ raise NotImplementedError
35
+ end
36
+ end
37
+
38
+ attr :name
39
+ attr :ofx_uri
40
+ attr :ofx_version
41
+
42
+ def initialize(name, ofx_uri, ofx_version)
43
+ @name = name
44
+ @ofx_uri = ofx_uri
45
+ @ofx_version = ofx_version
46
+ end
47
+
48
+ def create_request_document()
49
+ document = OFX::Document.new
50
+
51
+ case ofx_version
52
+ when OFX::Version.new("1.0.2")
53
+ document.header.header_version = OFX::Version.new("1.0.0")
54
+ document.header.content_type = "OFXSGML"
55
+ document.header.document_version = OFX::Version.new("1.0.2")
56
+ else
57
+ raise NotImplementedError
58
+ end
59
+
60
+ document.header.security = "NONE"
61
+
62
+ document.header.content_encoding = "USASCII"
63
+ document.header.content_character_set = "1252"
64
+
65
+ document.header.compression = "NONE"
66
+
67
+ document.header.previous_unique_identifier = "NONE"
68
+ document.header.unique_identifier = OFX::FileUniqueIdentifier.new
69
+
70
+ document
71
+ end
72
+
73
+ def send(document)
74
+ serializer = OFX::Serializer.get(@ofx_version)
75
+ request_body = serializer.to_http_post_body(document)
76
+
77
+ client = OFX::HTTPClient.new(@ofx_uri)
78
+ response_body = client.send(request_body)
79
+
80
+ return serializer.from_http_response_body(response_body)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,67 @@
1
+ # Copyright © 2007 Chris Guidry <chrisguidry@gmail.com>
2
+ #
3
+ # This file is part of OFX for Ruby.
4
+ #
5
+ # OFX for Ruby is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # OFX for Ruby is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module OFX
19
+ class FinancialInstitutionProfileMessageSet < MessageSet
20
+ def precedence
21
+ 11
22
+ end
23
+ def version
24
+ 1
25
+ end
26
+ end
27
+
28
+ class FinancialInstitutionProfileMessageSetProfile < MessageSetProfile
29
+ def self.message_set_class
30
+ FinancialInstitutionProfileMessageSet
31
+ end
32
+ end
33
+
34
+ class SignonRealm
35
+ attr_accessor :name
36
+ attr_accessor :password_length_constraint
37
+ attr_accessor :password_characters_constraint
38
+ attr_accessor :case_sensitive
39
+ attr_accessor :allows_special_characters
40
+ attr_accessor :allows_spaces
41
+ attr_accessor :supports_pin_changes
42
+ attr_accessor :requires_initial_pin_change
43
+ end
44
+
45
+ class FinancialInstitutionProfileRequest < TransactionalRequest
46
+ attr_accessor :client_routing
47
+ attr_accessor :date_of_last_profile_update
48
+ end
49
+
50
+ class FinancialInstitutionProfileResponse < TransactionalResponse
51
+ attr_accessor :message_sets
52
+ attr_accessor :signon_realms
53
+
54
+ attr_accessor :date_of_last_profile_update
55
+ attr_accessor :financial_institution_name
56
+ attr_accessor :address
57
+ attr_accessor :city
58
+ attr_accessor :state
59
+ attr_accessor :postal_code
60
+ attr_accessor :country
61
+ attr_accessor :customer_service_telephone
62
+ attr_accessor :technical_support_telephone
63
+ attr_accessor :facsimile_telephone
64
+ attr_accessor :url
65
+ attr_accessor :email_address
66
+ end
67
+ end
data/lib/ofx/header.rb ADDED
@@ -0,0 +1,115 @@
1
+ # Copyright © 2007 Chris Guidry <chrisguidry@gmail.com>
2
+ #
3
+ # This file is part of OFX for Ruby.
4
+ #
5
+ # OFX for Ruby is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # OFX for Ruby is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module OFX
19
+
20
+ # = Summary
21
+ # The OFX headers for one message. The headers provide metadata about
22
+ # the OFX request/response, including message versioning, security, and
23
+ # encoding.
24
+ #
25
+ # = Specifications
26
+ # OFX 1.0.2:: 2.2 (pp. 12-14)
27
+ class Header
28
+
29
+ def initialize
30
+ @headers = {}
31
+ end
32
+
33
+ def [](key)
34
+ @headers[key]
35
+ end
36
+
37
+ def []=(key, value)
38
+ @headers[key] = value
39
+ end
40
+
41
+ # The version of this OFX header
42
+ # OFX 1.0.2:: 2.2.1
43
+ # OFX 1.0.3:: 2.2.1
44
+ def header_version
45
+ OFX::Version.new(@headers['OFXHEADER'])
46
+ end
47
+ def header_version=(value)
48
+ @headers['OFXHEADER'] = value
49
+ end
50
+
51
+ # OFX 1.0.2:: 2.2.2
52
+ def content_type
53
+ @headers['DATA']
54
+ end
55
+ def content_type=(value)
56
+ @headers['DATA'] = value
57
+ end
58
+
59
+ # OFX 1.0.2:: 2.2.3
60
+ def document_version
61
+ OFX::Version.new(@headers['VERSION'])
62
+ end
63
+ def document_version=(value)
64
+ @headers['VERSION'] = value
65
+ end
66
+
67
+ # OFX 1.0.2:: 2.2.4
68
+ def security
69
+ @headers['SECURITY']
70
+ end
71
+ def security=(value)
72
+ @headers['SECURITY'] = value
73
+ end
74
+
75
+ # OFX 1.0.2:: 2.2.5
76
+ def content_encoding
77
+ @headers['ENCODING']
78
+ end
79
+ def content_encoding=(value)
80
+ @headers['ENCODING'] = value
81
+ end
82
+
83
+ # OFX 1.0.2:: 2.2.5
84
+ def content_character_set
85
+ @headers['CHARSET']
86
+ end
87
+ def content_character_set=(value)
88
+ @headers['CHARSET'] = value
89
+ end
90
+
91
+ # OFX 1.0.2:: 2.2.6
92
+ def compression
93
+ @headers['COMPRESSION']
94
+ end
95
+ def compression=(value)
96
+ @headers['COMPRESSION'] = value
97
+ end
98
+
99
+ # OFX 1.0.2:: 2.2.7
100
+ def unique_identifier
101
+ @headers['NEWFILEUID']
102
+ end
103
+ def unique_identifier=(value)
104
+ @headers['NEWFILEUID'] = value
105
+ end
106
+
107
+ # OFX 1.0.2:: 2.2.7
108
+ def previous_unique_identifier
109
+ @headers['OLDFILEUID']
110
+ end
111
+ def previous_unique_identifier=(value)
112
+ @headers['OLDFILEUID'] = value
113
+ end
114
+ end
115
+ end