├── .gitignore
├── .rspec
├── .semaphore
└── semaphore.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── bin
├── console
└── setup
├── epics.gemspec
├── lib
├── epics.rb
├── epics
│ ├── azv.rb
│ ├── b2b.rb
│ ├── bka.rb
│ ├── c2s.rb
│ ├── c52.rb
│ ├── c53.rb
│ ├── c54.rb
│ ├── c5n.rb
│ ├── ccs.rb
│ ├── cct.rb
│ ├── cd1.rb
│ ├── cdb.rb
│ ├── cdd.rb
│ ├── cds.rb
│ ├── cdz.rb
│ ├── cip.rb
│ ├── client.rb
│ ├── crz.rb
│ ├── error.rb
│ ├── fdl.rb
│ ├── ful.rb
│ ├── generic_request.rb
│ ├── generic_upload_request.rb
│ ├── haa.rb
│ ├── hac.rb
│ ├── header_request.rb
│ ├── hev.rb
│ ├── hia.rb
│ ├── hkd.rb
│ ├── hpb.rb
│ ├── hpd.rb
│ ├── htd.rb
│ ├── ini.rb
│ ├── key.rb
│ ├── letter_renderer.rb
│ ├── middleware
│ │ ├── parse_ebics.rb
│ │ └── xmlsig.rb
│ ├── ptk.rb
│ ├── response.rb
│ ├── signer.rb
│ ├── sta.rb
│ ├── version.rb
│ ├── vmk.rb
│ ├── wss.rb
│ ├── x_509_certificate.rb
│ ├── xct.rb
│ ├── xds.rb
│ ├── xe2.rb
│ ├── xe3.rb
│ ├── z01.rb
│ ├── z52.rb
│ ├── z53.rb
│ └── z54.rb
└── letter
│ ├── ini.erb
│ ├── ini_with_certs.erb
│ └── locales
│ ├── de.yml
│ ├── en.yml
│ └── fr.yml
└── spec
├── .DS_Store
├── client_spec.rb
├── error_spec.rb
├── fixtures
├── SIZBN001.key
├── a006.pem
├── bank_e.pem
├── e002.pem
├── test.zip
├── test_with_general_purpose_bit_3.zip
├── x002.pem
└── xml
│ ├── cd1.xml
│ ├── cd1_init_response.xml
│ ├── cd1_transfer_response.xml
│ ├── cdb.xml
│ ├── cdb_init_response.xml
│ ├── cdb_transfer_response.xml
│ ├── cip.xml
│ ├── ebics_business_nok.xml
│ ├── ebics_technical_nok.xml
│ ├── haa.xml
│ ├── haa_receipt.xml
│ ├── hia_request_order_data.xml
│ ├── hpb.xml
│ ├── hpb_request.xml
│ ├── hpb_response_ebics_ns.xml
│ ├── hpb_response_order.xml
│ ├── hpb_response_order_without_ns.xml
│ ├── htd_order_data.xml
│ ├── htd_order_data_without_names.xml
│ ├── ini_response_h004_ns.xml
│ ├── jruby
│ ├── hia.xml
│ └── ini.xml
│ ├── ruby
│ ├── hia.xml
│ └── ini.xml
│ ├── signature_pub_key_order_data.xml
│ ├── sta_response.xml
│ ├── sta_response_continued.xml
│ ├── swiss_credit_transfer.xml
│ ├── swiss_direct_debit.xml
│ └── upload_init_response.xml
├── generic_upload_spec.rb
├── hpb_spec.rb
├── key_spec.rb
├── middleware
└── parse_ebics_spec.rb
├── orders
├── azv_spec.rb
├── b2b_spec.rb
├── bka_spec.rb
├── c2s_spec.rb
├── c52_spec.rb
├── c53_spec.rb
├── c54_spec.rb
├── c5n_spec.rb
├── ccs_spec.rb
├── cct_spec.rb
├── cd1_spec.rb
├── cdb_spec.rb
├── cdd_spec.rb
├── cdz_spec.rb
├── cip_spec.rb
├── crz_spec.rb
├── fdl_spec.rb
├── ful_spec.rb
├── haa_spec.rb
├── hac_spec.rb
├── hev_spec.rb
├── hia_spec.rb
├── hkd_spec.rb
├── hpb_spec.rb
├── hpd_spec.rb
├── htd_spec.rb
├── ini_spec.rb
├── ptk_spec.rb
├── sta_spec.rb
├── vmk_spec.rb
├── wss_spec.rb
├── x_509_certificate_spec.rb
├── xds_spec.rb
├── xe2_spec.rb
├── xe3_spec.rb
├── z01_spec.rb
├── z52_spec.rb
├── z53_spec.rb
└── z54_spec.rb
├── response_spec.rb
├── signer_spec.rb
├── spec_helper.rb
├── support
├── ebics_matcher.rb
└── x_509_crt_generator.rb
└── xsd
├── ebics_H004.xsd
├── ebics_hev.xsd
├── ebics_keymgmt_request_H004.xsd
├── ebics_keymgmt_response_H004.xsd
├── ebics_orders_H004.xsd
├── ebics_request_H004.xsd
├── ebics_response_H004.xsd
├── ebics_signature.xsd
├── ebics_types_H004.xsd
└── xmldsig-core-schema.xsd
/.gitignore:
--------------------------------------------------------------------------------
1 | /.bundle/
2 | /.yardoc
3 | /Gemfile.lock
4 | /_yardoc/
5 | /coverage/
6 | /doc/
7 | /pkg/
8 | /spec/reports/
9 | /tmp/
10 | *.bundle
11 | *.so
12 | *.o
13 | *.a
14 | mkmf.log
15 | /ebics_playground
16 | .DS_Store
17 | sbk.key
18 | /mt940
19 | *.key
20 | .idea/
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --color
2 | --require spec_helper
3 |
--------------------------------------------------------------------------------
/.semaphore/semaphore.yml:
--------------------------------------------------------------------------------
1 | version: v1.0
2 | name: Test
3 | agent:
4 | machine:
5 | type: e1-standard-2
6 | os_image: ubuntu2004
7 | blocks:
8 | - name: Setup
9 | task:
10 | jobs:
11 | - name: "Checkout"
12 | commands:
13 | - checkout
14 | - ls
15 | - rm -f .rbenv-version .ruby-version
16 | - name: Spec versions
17 | task:
18 | jobs:
19 | - name: "3.1"
20 | commands:
21 | - checkout
22 | - sem-version ruby 3.1
23 | - cache restore
24 | - gem install bundler:2.5.19
25 | - bundle install
26 | - cache store
27 | - bundle exec rspec
28 | - name: "3.2"
29 | commands:
30 | - checkout
31 | - sem-version ruby 3.2
32 | - cache restore
33 | - gem install bundler:2.5.19
34 | - bundle install
35 | - cache store
36 | - bundle exec rspec
37 | - name: "3.3"
38 | commands:
39 | - checkout
40 | - sem-version ruby 3.3
41 | - cache restore
42 | - gem install bundler:2.5.19
43 | - bundle install
44 | - cache store
45 | - bundle exec rspec
46 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### Unreleased
2 |
3 | ### 2.11.0
4 |
5 | - [ENHANCEMENT] Added FUL order type (thanks to @scollon-pl)
6 |
7 | ### 2.10.0
8 |
9 | - [ENHANCEMENT] Added X.509 certificates support for INI and HIA (thanks to @vnoviskyi)
10 | - [ENHANCEMENT] Added Z01 order type (thanks to @Nymuxyzo)
11 |
12 | ### 2.9.0
13 |
14 | - [ENHANCEMENT] Added HEV order type (thanks to @jplot)
15 |
16 | ### 2.8.0
17 |
18 | - [ENHANCEMENT] Added BKA order type
19 |
20 | ### 2.7.0
21 |
22 | - [ENHANCEMENT] Added FDL order type (thanks to @frantisekrokusek)
23 | - [ENHANCEMENT] Added support for configuring locale and client/product name on initialization (thanks to @frantisekrokusek)
24 |
25 | ### 2.6.0
26 |
27 | - [ENHANCEMENT] Added CIP order type (instant transfers)
28 | - [ENHANCEMENT] Added gem metadata (thanks to @Nymuxyzo)
29 |
30 | ### 2.5.0
31 |
32 | - [HOUSEKEEPING] Bump XML dependency requirements to more recent versions
33 | - [HOUSEKEEPING] Bump bundler version to 2.5.19
34 | - [HOUSEKEEPING] Bump ruby required version from 2.7 to 3.1
35 | - [ENHANCEMENT] Request Header generation more generalized (thanks to @jplot)
36 | - [ENHANCEMENT] Multi language support for initialization letter (thanks to @jplot)
37 | - [ENHANCEMENT] Added support for WSS and C5N order types (thanks to @kostja93)
38 |
39 | ### 2.4.0
40 |
41 | - [ENHANCEMENT] Adds XE2 and XE3 order type (CCT and CDD for swiss banks)
42 |
43 | ### 2.3.0
44 |
45 | - [ENHANCEMENT] Adds Z52, Z53, Z54 order type (C52, C53, C54 for swiss banks)
46 |
47 | ### 2.2.0
48 |
49 | - [ENHANCEMENT] Adds C2S order type
50 | - [HOUSEKEEPING] updates nokogiri dependency
51 | - [HOUSEKEEPING] updates rexml dependency
52 | - [HOUSEKEEPING] adds Ruby 3.3 to CI
53 |
54 | ### 2.1.2
55 |
56 | - [BUGFIX] Fix order data encryption for OpenSSL 3
57 |
58 | ### 2.1.1
59 |
60 | - [HOUSEKEEPING] update Bank public key initialization for OpenSSL 3
61 |
62 | ### 2.1.0
63 |
64 | - [HOUSEKEEPING] updates Nokogiri dependencies
65 | - [HOUSEKEEPING] updates Bundler dependency
66 | - [HOUSEKEEPING] updates Gemfile bundler version
67 | - [HOUSEKEEPING] Bump ruby required version from 2.6 to 2.7
68 |
69 | ### 2.0.0
70 | - [BUGFIX] Add Openssl 3.0 support
71 | - [BUGFIX] Update CDZ to download data, not upload it
72 | - [BUGFIX] Support signature for keys later than 2048 bit
73 | - [HOUSEKEEPING] Open rubyzip dependency to allow newer versions and update it
74 | - [HOUSEKEEPING] Update supported ruby versions to 2.6+
75 | - [HOUSEKEEPING] Update faraday, nokogiri, and development dependencies
76 | - [HOUSEKEEPING] Remove JRuby test execution due to failing tests - needs to be re-added if required
77 | - [ENHANCEMENT] Adds CRZ order type
78 | - [ENHANCEMENT] Make date period optional for CDZ order type
79 |
80 | ### 1.8.1
81 | - [BUGFIX] Remove masking of transport client errors
82 |
83 | ### 1.8.0
84 |
85 | - [HOUSEKEEPING] updates faraday and rubyzip
86 | - [HOUSEKEEPING] as a result: bump required ruby version to 2.4+
87 |
88 | ### 1.7.2
89 |
90 | - [FEATURE] adds XCT order type (thanks to @punkle64)
91 |
92 | ### 1.7.1
93 |
94 | - [HOUSEKEEPING] sets headers for requests to text/xml
95 | - [HOUSEKEEPING] updates Nokogiri dependencies
96 |
97 | ### 1.7.0
98 |
99 | - [ENHANCEMENT] adds CDB (thanks to @romanlehnert)
100 | - [BUGFIX] fixes CCS order type and attribute (thanks to @gadimbaylisahil)
101 | - [BUGFIX] make CDZ callable via client
102 |
103 | ### 1.6.0
104 |
105 | - [BUGFIX] allow unstreamable zipfile handling
106 | - [ENHANCEMENT] adds CDZ order type
107 | - updates dependencies
108 |
109 | ### 1.5.2
110 |
111 | - [COMPATIBILITY] be removing the `goyku` dependency we're more recilent against old versions of that gem
112 | - [ENHANCEMENT] #order_type gives you more complete overview which order types to current client is entitled
113 | to use, there was already `HAA` which isn't as complete as this, which gets its info from `HTD`
114 |
115 | ### 1.5.1
116 |
117 | - [ENHANCEMENT] some banks are not returning the order_id in the second upload phase, we now fetch it already
118 | from the first response to handle this different behaviour.
119 | - [ENHANCEMENT] New order types: `AZV` (Auslandszahlungsverkehr). `CDS` and `CCS` for submitting SEPA credits/debits
120 | as SRZ (Service Rechen Zentrum)
121 |
122 | ### 1.5.0
123 |
124 | - [ENHANCEMENT] support for fetching the C54 order type
125 | - [ENHANCEMENT] Exceptions expose their internal code via `code`
126 | - [HOUSEKEEPING] Added Ruby 2.4 compatibility
127 | - [HOUSEKEEPING] Drop Ruby 2.0.0
128 |
129 | ### 1.4.1
130 |
131 | - [ENHANCEMENT] support for fetching the VMK order type
132 |
133 | ### 1.4.0
134 |
135 | - [ENHANCEMENT] STA without date range to fetch all statements which have not yet been fetched
136 | - [ENHANCEMENT] HAC without date range to fetch all transaction logs which have not yet been fetched
137 |
138 | ### 1.3.1
139 |
140 | - [ENHANCEMENT] make xpath namespaces explicit, so we can cover a wider
141 | rage of responses
142 |
143 | ### 1.3.0
144 |
145 | - [BUGFIX] unzip C5X payloads
146 | - [ENHANCEMENT] B2B direct debits
147 |
148 | ### 1.2.2
149 |
150 | - [BUGFIX] HPB namespaces are unpredictable so be ignore them
151 |
152 | ### 1.2.1
153 |
154 | - [BUGFIX] fixing wrong variable bind within `credit`, `debit` and `statements`
155 |
156 | ### 1.2.0
157 |
158 | - [ENHANCEMENT] uploads will return both ebics_order_id and ebics_transaction_id
159 |
160 | ### 1.1.2
161 |
162 | - [BUGFIX] missing require statements for `zlib`
163 | - [BUGFIX] #16 `setup` tried to initialize wrong class
164 |
165 | ### 1.1.1
166 |
167 | - [BUGFIX] CCT order was submited as CD1
168 | - [BUGFIX] padding was calculated against the wrong block size
169 | - [BUGFIX] double encoding of the signature
170 |
171 | ### 1.1.0
172 |
173 | - [BUGFIX] Sending `Receipts` after downloading data, to circumvent download locks
174 | - [BUGFIX] adding missing require statements
175 | - adding HAC, HKD, C52 and C53 support
176 | - less verbose object inspection for `Epics::Client`
177 | - readme polishing
178 |
179 | ### 1.0.0
180 |
181 | - first release
182 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Individual Contributor Non-Exclusive License Agreement
2 |
3 | Note: This CLA is for Individual Copyright owner only. If You would like to submit your Contribution as part of your employment or as Legal Entity, please contact Us at team@railslove.com first.
4 |
5 | Thank you for your interest in contributing to the project **„epics - EBICS client for Ruby“ from Railslove GmbH, An der Bottmuehle 5, 50678 Cologne, Germany (“We” or “Us”).**
6 | The purpose of this contributor agreement (**“Agreement”**) is to clarify and document the rights granted by contributors to Us.
7 |
8 | ### 1. DEFINITIONS
9 | **“You”** means the Individual Copyright owner who submits a Contribution to Us. If You are either a Legal Entity or submit the Contribution as part of your employment, please contact Us at team@railslove.com first.
10 | **“Contribution”** means any original work of authorship (software and/or documentation) including any modifications or additions to an existing work, Submitted by You to Us, in which You own the Copyright. If You do not own the Copyright in the entire work of authorship, please contact Us at team@railslove.com.
11 | **“Copyright”** means all rights protecting works of authorship owned or controlled by You, including copyright, moral and neighboring rights, as appropriate, for the full term of their existence including any extensions by You.
12 | **“Material”** means the software or documentation made available by Us to third parties. When this Agreement covers more than one software project, the Material means the software or documentation to which the Contribution was Submitted. After You Submit the Contribution, it may be included in the Material.
13 | **“Submit”** means any form of physical, electronic, or written communication sent to Us, including but not limited to electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, Us, but excluding communication that is conspicuously marked or otherwise designated in writing by You as “Not a Contribution.”
14 | **“Submission Date”** means the date You Submit a Contribution to Us.
15 | **“Documentation”** means any non-software portion of a Contribution.
16 |
17 | ### 2. LICENSE GRANT
18 | 2.1 Copyright License to Us
19 | Subject to the terms and conditions of this Agreement, You hereby grant to Us a worldwide, royalty-free, NON-exclusive, perpetual and irrevocable license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, under the Copyright covering the Contribution to use the Contribution by all means, including, but not limited to:
20 | - to publish the Contribution,
21 | - to modify the Contribution, to prepare derivative works based upon or containing the Contribution and to combine the Contribution with other software code,
22 | - to reproduce the Contribution in original or modified form,
23 | - to distribute, to make the Contribution available to the public, display and publicly perform the Contribution in original or modified form.
24 |
25 | 2.2 Moral Rights remain unaffected to the extent they are recognized and not waivable by applicable law. Notwithstanding, You may add your name in the header of the source code files of Your Contribution and We will respect this attribution when using Your Contribution.
26 |
27 | ### 3. DISCLAIMER
28 | THE CONTRIBUTION IS PROVIDED “AS IS”. MORE PARTICULARLY, ALL EXPRESS OR IMPLIED WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY DISCLAIMED BY YOU TO US AND BY US TO YOU. TO THE EXTENT THAT ANY SUCH WARRANTIES CANNOT BE DISCLAIMED, SUCH WARRANTY IS LIMITED IN DURATION TO THE MINIMUM PERIOD PERMITTED BY LAW.
29 |
30 | ### 4. Consequential Damage Waiver
31 | TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL YOU OR US BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF ANTICIPATED SAVINGS, LOSS OF DATA, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL AND EXEMPLARY DAMAGES ARISING OUT OF THIS AGREEMENT REGARDLESS OF THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED.
32 |
33 | ### 5. Approximation of Disclaimer and Damage Waiver
34 | IF THE DISCLAIMER AND DAMAGE WAIVER MENTIONED IN SECTION 3 AND SECTION 4 CANNOT BE GIVEN LEGAL EFFECT UNDER APPLICABLE LOCAL LAW, REVIEWING COURTS SHALL APPLY LOCAL LAW THAT MOST CLOSELY APPROXIMATES AN ABSOLUTE WAIVER OF ALL CIVIL LIABILITY IN CONNECTION WITH THE CONTRIBUTION.
35 |
36 | ### 6. Term
37 | 6.1 This Agreement shall come into effect upon Your acceptance of the terms and conditions.
38 | 6.2 In the event of a termination of this Agreement Sections 3, 4, 5, 6 and 7 shall survive such termination and shall remain in full force thereafter. For the avoidance of doubt, Contributions that are already licensed under a free and open source license at the date of the termination shall remain in full force after the termination of this Agreement.
39 |
40 | ### 7. Miscellaneous
41 | 7.1 This Agreement and all disputes, claims, actions, suits or other proceedings arising out of this agreement or relating in any way to it shall be governed by the laws of Germany excluding its private international law provisions.
42 | 7.2 This Agreement sets out the entire agreement between You and Us for Your Contributions to Us and overrides all other agreements or understandings.
43 | 7.3 If any provision of this Agreement is found void and unenforceable, such provision will be replaced to the extent possible with a provision that comes closest to the meaning of the original provision and that is enforceable. The terms and conditions set forth in this Agreement shall apply notwithstanding any failure of essential purpose of this Agreement or any limited remedy to the maximum extent possible under law.
44 | 7.4 You agree to notify Us of any facts or circumstances of which you become aware that would make this Agreement inaccurate in any respect.
45 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # Specify your gem's dependencies in epics.gemspec
4 | gemspec
5 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require "bundler/gem_tasks"
2 | require 'rspec/core/rake_task'
3 |
4 | RSpec::Core::RakeTask.new(:spec)
5 |
6 | task default: :spec
7 |
8 |
--------------------------------------------------------------------------------
/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require "bundler/setup"
5 | require "epics"
6 |
7 | require "irb"
8 | IRB.start(__FILE__)
9 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -euo pipefail
3 | IFS=$'\n\t'
4 | set -vx
5 |
6 | bundle install
--------------------------------------------------------------------------------
/epics.gemspec:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | lib = File.expand_path('lib', __dir__)
4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5 | require 'epics/version'
6 |
7 | Gem::Specification.new do |spec|
8 | spec.name = 'epics'
9 | spec.version = Epics::VERSION
10 | spec.authors = ['Lars Brillert']
11 | spec.email = ['lars@railslove.com']
12 | spec.summary = 'a ruby implementation of the EBICS protocol'
13 | spec.description = <<-description
14 | Epics is a ruby implementation of the EBIC standard (H004)
15 |
16 | It supports the complete initialization process comprising INI, HIA and HPB
17 | including the INI letter generation.
18 |
19 | Furthermore it offers support for the most common download types:
20 | STA HAA HTD HPD PKT HAC HKD C52 C53 C54
21 |
22 | And the following upload orders:
23 | CD1 CDD CCT CDB CDS CCS CDZ CRZ
24 | description
25 |
26 | spec.homepage = 'https://github.com/railslove/epics'
27 | spec.license = 'LGPL-3.0'
28 |
29 | spec.required_ruby_version = '>= 3.1'
30 |
31 | spec.files = `git ls-files -z`.split("\x0")
32 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
33 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
34 | spec.require_paths = ['lib']
35 |
36 | spec.metadata['changelog_uri'] = 'https://github.com/railslove/epics/blob/master/CHANGELOG.md'
37 | spec.metadata['source_code_uri'] = 'https://github.com/railslove/epics'
38 | spec.metadata['bug_tracker_uri'] = 'https://github.com/railslove/epics/issues'
39 |
40 | spec.post_install_message = "\n\e[32m" + ('*' * 60) + "\n\e[0m"
41 | spec.post_install_message += "Thanks for using Epics - your epic EBICS client!\n"
42 | spec.post_install_message += "Epics provides a full production-tested implementation of the Electronic Banking Internet Communication Standard.\n"
43 | spec.post_install_message += "Railslove as the maintainer is commited to provide extensive developer tools to make integrating financial institutions fun and easy.\n"
44 | spec.post_install_message += "Please create an issue on github (railslove/epics) if anything does not work as expected. And contact team@railslove.com if you are looking for support with your integration.\n"
45 | spec.post_install_message += "\e[32m" + ('*' * 60) + "\n\e[0m"
46 |
47 | spec.add_dependency 'base64'
48 | spec.add_dependency 'bigdecimal'
49 | spec.add_dependency 'faraday', '>= 1.10.0'
50 | spec.add_dependency 'i18n', '>= 1.1.0'
51 | spec.add_dependency 'nokogiri', '>= 1.16.7'
52 | spec.add_dependency 'rubyzip', '>= 2.3.2'
53 | spec.add_dependency 'rexml', '>= 3.3.7'
54 |
55 | spec.add_development_dependency 'bundler', '>= 2.5.19'
56 | spec.add_development_dependency 'equivalent-xml'
57 | spec.add_development_dependency 'pry'
58 | spec.add_development_dependency 'rake', '~> 13.0'
59 | spec.add_development_dependency 'rspec'
60 | spec.add_development_dependency 'webmock'
61 | end
62 |
--------------------------------------------------------------------------------
/lib/epics.rb:
--------------------------------------------------------------------------------
1 | require 'openssl'
2 | require 'base64'
3 | require 'erb'
4 | require 'i18n'
5 | require 'json'
6 | require 'zlib'
7 | require 'zip'
8 | require 'nokogiri'
9 | require 'faraday'
10 | require 'securerandom'
11 | require 'time'
12 | require "epics/version"
13 | require "epics/key"
14 | require "epics/response"
15 | require "epics/error"
16 | require 'epics/letter_renderer'
17 | require "epics/middleware/xmlsig"
18 | require "epics/middleware/parse_ebics"
19 | require "epics/generic_request"
20 | require "epics/generic_upload_request"
21 | require "epics/header_request"
22 | require "epics/azv"
23 | require "epics/hpb"
24 | require "epics/hkd"
25 | require "epics/htd"
26 | require "epics/haa"
27 | require "epics/sta"
28 | require "epics/fdl"
29 | require "epics/ful"
30 | require "epics/vmk"
31 | require "epics/bka"
32 | require "epics/c52"
33 | require "epics/c53"
34 | require "epics/c54"
35 | require "epics/c5n"
36 | require "epics/z01"
37 | require "epics/z52"
38 | require "epics/z53"
39 | require "epics/z54"
40 | require "epics/ptk"
41 | require "epics/hac"
42 | require "epics/wss"
43 | require "epics/hpd"
44 | require "epics/cd1"
45 | require "epics/cct"
46 | require "epics/ccs"
47 | require "epics/cip"
48 | require "epics/cdb"
49 | require "epics/cdd"
50 | require "epics/xe2"
51 | require "epics/xe3"
52 | require "epics/b2b"
53 | require "epics/xds"
54 | require "epics/cds"
55 | require "epics/c2s"
56 | require "epics/cdz"
57 | require "epics/crz"
58 | require "epics/xct"
59 | require "epics/hia"
60 | require "epics/ini"
61 | require "epics/hev"
62 | require "epics/signer"
63 | require "epics/x_509_certificate"
64 | require "epics/client"
65 |
66 | I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'letter/locales', '*.yml')]
67 |
68 | module Epics
69 | DEFAULT_PRODUCT_NAME = 'EPICS - a ruby ebics kernel'
70 | DEFAULT_LOCALE = :de
71 | end
72 |
73 | Ebics = Epics
74 |
--------------------------------------------------------------------------------
/lib/epics/azv.rb:
--------------------------------------------------------------------------------
1 | class Epics::AZV < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'CD1',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/b2b.rb:
--------------------------------------------------------------------------------
1 | class Epics::B2B < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'B2B',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/bka.rb:
--------------------------------------------------------------------------------
1 | class Epics::BKA < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'BKA',
7 | order_attribute: 'DZHNN',
8 | order_params: {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | },
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/c2s.rb:
--------------------------------------------------------------------------------
1 | class Epics::C2S < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'C2S',
7 | order_attribute: 'DZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/c52.rb:
--------------------------------------------------------------------------------
1 | class Epics::C52 < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'C52',
7 | order_attribute: 'DZHNN',
8 | order_params: {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | },
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/c53.rb:
--------------------------------------------------------------------------------
1 | class Epics::C53 < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'C53',
7 | order_attribute: 'DZHNN',
8 | order_params: {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | },
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/c54.rb:
--------------------------------------------------------------------------------
1 | class Epics::C54 < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'C54',
7 | order_attribute: 'DZHNN',
8 | order_params: {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | },
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/c5n.rb:
--------------------------------------------------------------------------------
1 | class Epics::C5N < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'C5N',
7 | order_attribute: 'DZHNN',
8 | order_params: {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | },
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/ccs.rb:
--------------------------------------------------------------------------------
1 | class Epics::CCS < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'CCS',
7 | order_attribute: 'DZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/cct.rb:
--------------------------------------------------------------------------------
1 | class Epics::CCT < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'CCT',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/cd1.rb:
--------------------------------------------------------------------------------
1 | class Epics::CD1 < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'CD1',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/cdb.rb:
--------------------------------------------------------------------------------
1 | class Epics::CDB < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'CDB',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/cdd.rb:
--------------------------------------------------------------------------------
1 | class Epics::CDD < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'CDD',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/cds.rb:
--------------------------------------------------------------------------------
1 | class Epics::CDS < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'CDS',
7 | order_attribute: 'DZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/cdz.rb:
--------------------------------------------------------------------------------
1 | class Epics::CDZ < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'CDZ',
7 | order_attribute: 'DZHNN',
8 | order_params: !!options[:from] && !!options[:to] ? {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | } : {},
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/cip.rb:
--------------------------------------------------------------------------------
1 | class Epics::CIP < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'CIP',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/crz.rb:
--------------------------------------------------------------------------------
1 | class Epics::CRZ < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'CRZ',
7 | order_attribute: 'DZHNN',
8 | order_params: !!options[:from] && !!options[:to] ? {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | } : {},
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/fdl.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Epics::FDL < Epics::GenericRequest
4 | def header
5 | fdl_order_params = Hash.new.tap do |params|
6 | params[:DateRange] = {
7 | Start: options[:from],
8 | End: options[:to],
9 | } if options[:from] && options[:to]
10 | params[:FileFormat] = options[:file_format]
11 | end
12 |
13 | client.header_request.build(
14 | nonce: nonce,
15 | timestamp: timestamp,
16 | order_type: 'FDL',
17 | order_attribute: 'DZHNN',
18 | order_id: 'A00A',
19 | custom_order_params: { FDLOrderParams: fdl_order_params },
20 | mutable: { TransactionPhase: 'Initialisation' }
21 | )
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/lib/epics/ful.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Epics::FUL < Epics::GenericUploadRequest
4 | def header
5 | ful_order_params = Hash.new.tap do |params|
6 | params[:FileFormat] = options[:file_format]
7 | end
8 |
9 | client.header_request.build(
10 | nonce: nonce,
11 | timestamp: timestamp,
12 | order_type: 'FUL',
13 | order_attribute: 'DZHNN',
14 | custom_order_params: { FULOrderParams: ful_order_params },
15 | mutable: { TransactionPhase: 'Initialisation' }
16 | )
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/lib/epics/generic_request.rb:
--------------------------------------------------------------------------------
1 | class Epics::GenericRequest
2 | extend Forwardable
3 | attr_reader :client, :options
4 | attr_accessor :transaction_id
5 |
6 | def initialize(client, **options)
7 | @client = client
8 | @options = options
9 | end
10 |
11 | def nonce
12 | SecureRandom.hex(16)
13 | end
14 |
15 | def timestamp
16 | Time.now.utc.iso8601
17 | end
18 |
19 | def_delegators :client, :host_id, :user_id, :partner_id
20 |
21 | def root
22 | "ebicsRequest"
23 | end
24 |
25 | def body
26 | Nokogiri::XML::Builder.new do |xml|
27 | xml.body
28 | end.doc.root
29 | end
30 |
31 | def header
32 | raise NotImplementedError
33 | end
34 |
35 | def auth_signature
36 | Nokogiri::XML::Builder.new do |xml|
37 | xml.AuthSignature{
38 | xml.send('ds:SignedInfo') {
39 | xml.send('ds:CanonicalizationMethod', '', Algorithm: "http://www.w3.org/TR/2001/REC-xml-c14n-20010315")
40 | xml.send('ds:SignatureMethod', '', Algorithm: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")
41 | xml.send('ds:Reference', '', URI: "#xpointer(//*[@authenticate='true'])") {
42 | xml.send('ds:Transforms') {
43 | xml.send('ds:Transform', '', Algorithm: "http://www.w3.org/TR/2001/REC-xml-c14n-20010315")
44 | }
45 | xml.send('ds:DigestMethod', '', Algorithm: "http://www.w3.org/2001/04/xmlenc#sha256")
46 | xml.send('ds:DigestValue', '')
47 | }
48 | }
49 | xml.send('ds:SignatureValue', '')
50 | }
51 | end.doc.root
52 | end
53 |
54 | def to_transfer_xml
55 | Nokogiri::XML::Builder.new do |xml|
56 | xml.send(root, 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004', 'Version' => 'H004', 'Revision' => '1') {
57 | xml.header(authenticate: true) {
58 | xml.static {
59 | xml.HostID host_id
60 | xml.TransactionID transaction_id
61 | }
62 | xml.mutable {
63 | xml.TransactionPhase 'Transfer'
64 | xml.SegmentNumber(1, lastSegment: true)
65 | }
66 | }
67 | xml.parent.add_child(auth_signature)
68 | xml.body {
69 | xml.DataTransfer {
70 | xml.OrderData encrypted_order_data
71 | }
72 | }
73 | }
74 | end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
75 | end
76 |
77 | def to_receipt_xml
78 | Nokogiri::XML::Builder.new do |xml|
79 | xml.send(root, 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004', 'Version' => 'H004', 'Revision' => '1') {
80 | xml.header(authenticate: true) {
81 | xml.static {
82 | xml.HostID host_id
83 | xml.TransactionID(transaction_id)
84 | }
85 | xml.mutable {
86 | xml.TransactionPhase 'Receipt'
87 | }
88 | }
89 | xml.parent.add_child(auth_signature)
90 | xml.body {
91 | xml.TransferReceipt(authenticate: true) {
92 | xml.ReceiptCode 0
93 | }
94 | }
95 | }
96 | end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
97 | end
98 |
99 | def to_xml
100 | Nokogiri::XML::Builder.new do |xml|
101 | xml.send(root, 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004', 'Version' => 'H004', 'Revision'=> '1') {
102 | xml.parent.add_child(header)
103 | xml.parent.add_child(auth_signature)
104 | xml.parent.add_child(body)
105 | }
106 | end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
107 | end
108 |
109 | private
110 |
111 | def x509_data_xml(xml, x_509_certificate)
112 | return unless x_509_certificate
113 |
114 | xml.send('ds:X509Data') do
115 | xml.send('ds:X509IssuerSerial') do
116 | xml.send('ds:X509IssuerName', x_509_certificate.issuer)
117 | xml.send('ds:X509SerialNumber', x_509_certificate.version)
118 | end
119 | xml.send('ds:X509Certificate', x_509_certificate.data)
120 | end
121 | end
122 | end
123 |
--------------------------------------------------------------------------------
/lib/epics/generic_upload_request.rb:
--------------------------------------------------------------------------------
1 | class Epics::GenericUploadRequest < Epics::GenericRequest
2 | attr_accessor :key
3 | attr_accessor :iv
4 | attr_accessor :document
5 |
6 | def initialize(client, document, **options)
7 | super(client, **options)
8 | self.document = document
9 | self.key = cipher.random_key
10 | self.iv = 0.chr * cipher.iv_len
11 | end
12 |
13 | def cipher
14 | @cipher ||= OpenSSL::Cipher.new("aes-128-cbc").tap { |cipher| cipher.encrypt }
15 | end
16 |
17 | def digester
18 | @digester ||= OpenSSL::Digest::SHA256.new
19 | end
20 |
21 | def body
22 | Nokogiri::XML::Builder.new do |xml|
23 | xml.body {
24 | xml.DataTransfer {
25 | xml.DataEncryptionInfo(authenticate: true) {
26 | xml.EncryptionPubKeyDigest(client.bank_e.public_digest, Version: 'E002', Algorithm: "http://www.w3.org/2001/04/xmlenc#sha256")
27 | xml.TransactionKey Base64.encode64(client.bank_e.key.public_encrypt(self.key)).gsub(/\n/,'')
28 | }
29 | xml.SignatureData(encrypted_order_signature, authenticate: true)
30 | }
31 | }
32 | end.doc.root
33 | end
34 |
35 | def order_signature
36 | Nokogiri::XML::Builder.new do |xml|
37 | xml.UserSignatureData('xmlns' => 'http://www.ebics.org/S001', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'http://www.ebics.org/S001 http://www.ebics.org/S001/ebics_signature.xsd') {
38 | xml.OrderSignatureData {
39 | xml.SignatureVersion "A006"
40 | xml.SignatureValue signature_value
41 | xml.PartnerID partner_id
42 | xml.UserID user_id
43 | }
44 | }
45 | end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
46 | end
47 |
48 | def signature_value
49 | client.a.sign( digester.digest(document.gsub(/\n|\r/, "")) )
50 | end
51 |
52 | def encrypt(d)
53 | cipher.reset
54 | cipher.padding = 0
55 | cipher.key = self.key
56 | cipher.iv = self.iv
57 | (cipher.update(pad(d)) + cipher.final)
58 | end
59 |
60 | def encrypted_order_data
61 | dst = Zlib::Deflate.deflate(document)
62 |
63 | Base64.encode64(encrypt(dst)).gsub(/\n/,'')
64 | end
65 |
66 | def encrypted_order_signature
67 | dst = Zlib::Deflate.deflate(order_signature)
68 |
69 | Base64.encode64(encrypt(dst)).gsub(/\n/,'')
70 | end
71 |
72 | def pad(d)
73 | len = cipher.block_size*((d.size / cipher.block_size)+1)
74 |
75 | d.ljust(len, [0].pack("C*")).tap do |padded|
76 | padded[-1] = [len - d.size].pack("C*")
77 | end
78 | end
79 |
80 | end
81 |
--------------------------------------------------------------------------------
/lib/epics/haa.rb:
--------------------------------------------------------------------------------
1 | class Epics::HAA < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'HAA',
7 | order_attribute: 'DZHNN',
8 | order_params: {},
9 | mutable: { TransactionPhase: 'Initialisation' }
10 | )
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/epics/hac.rb:
--------------------------------------------------------------------------------
1 | class Epics::HAC < Epics::GenericRequest
2 | # By default HAC only returns data for transactions which have not yet been fetched. Therefore,
3 | # most applications not not have to specify a date range, but can simply fetch the status and
4 | # be done
5 | def header
6 | client.header_request.build(
7 | nonce: nonce,
8 | timestamp: timestamp,
9 | order_type: 'HAC',
10 | order_attribute: 'DZHNN',
11 | order_params: !!options[:from] && !!options[:to] ? {
12 | DateRange: {
13 | Start: options[:from],
14 | End: options[:to]
15 | }
16 | } : {},
17 | mutable: { TransactionPhase: 'Initialisation' }
18 | )
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/lib/epics/header_request.rb:
--------------------------------------------------------------------------------
1 | class Epics::HeaderRequest
2 | extend Forwardable
3 | attr_accessor :client
4 |
5 | def initialize(client)
6 | self.client = client
7 | end
8 |
9 | def_delegators :client, :host_id, :user_id, :partner_id
10 |
11 | def build(options = {})
12 | options[:with_bank_pubkey_digests] = true if options[:with_bank_pubkey_digests].nil?
13 |
14 | Nokogiri::XML::Builder.new do |xml|
15 | xml.header(authenticate: true) {
16 | xml.static {
17 | xml.HostID host_id
18 | xml.Nonce options[:nonce] if options[:nonce]
19 | xml.Timestamp options[:timestamp] if options[:timestamp]
20 | xml.PartnerID partner_id
21 | xml.UserID user_id
22 | xml.Product(client.product_name, 'Language' => client.locale)
23 | xml.OrderDetails {
24 | xml.OrderType options[:order_type]
25 | xml.OrderAttribute options[:order_attribute]
26 | xml.StandardOrderParams {
27 | build_attributes(xml, options[:order_params])
28 | } if options[:order_params]
29 | build_attributes(xml, options[:custom_order_params]) if options[:custom_order_params]
30 | }
31 | xml.BankPubKeyDigests {
32 | xml.Authentication(client.bank_x.public_digest, Version: 'X002', Algorithm: 'http://www.w3.org/2001/04/xmlenc#sha256')
33 | xml.Encryption(client.bank_e.public_digest, Version: 'E002', Algorithm: 'http://www.w3.org/2001/04/xmlenc#sha256')
34 | } if options[:with_bank_pubkey_digests]
35 | xml.SecurityMedium '0000'
36 | xml.NumSegments options[:num_segments] if options[:num_segments]
37 | }
38 | xml.mutable {
39 | build_attributes(xml, options[:mutable])
40 | } if options[:mutable]
41 | }
42 | end.doc.root
43 | end
44 |
45 | private
46 |
47 | def build_attributes(xml, attributes)
48 | attributes.each do |key, value|
49 | if value.is_a?(Hash)
50 | xml.send(key) {
51 | build_attributes(xml, value)
52 | }
53 | else
54 | xml.send(key, value)
55 | end
56 | end
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/lib/epics/hev.rb:
--------------------------------------------------------------------------------
1 | class Epics::HEV < Epics::GenericRequest
2 | def root
3 | "ebicsHEVRequest"
4 | end
5 |
6 | def body
7 | Nokogiri::XML::Builder.new do |xml|
8 | xml.HostID host_id
9 | end.doc.root
10 | end
11 |
12 | def to_xml
13 | Nokogiri::XML::Builder.new do |xml|
14 | xml.send(root, 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'http://www.ebics.org/H000 http://www.ebics.org/H000/ebics_hev.xsd', 'xmlns' => 'http://www.ebics.org/H000') {
15 | xml.parent.add_child(body)
16 | }
17 | end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/epics/hia.rb:
--------------------------------------------------------------------------------
1 | class Epics::HIA < Epics::GenericRequest
2 | def root
3 | "ebicsUnsecuredRequest"
4 | end
5 |
6 | def header
7 | client.header_request.build(
8 | order_type: 'HIA',
9 | order_attribute: 'DZNNN',
10 | with_bank_pubkey_digests: false,
11 | mutable: {}
12 | )
13 | end
14 |
15 | def body
16 | Nokogiri::XML::Builder.new do |xml|
17 | xml.body{
18 | xml.DataTransfer {
19 | xml.OrderData Base64.strict_encode64(Zlib::Deflate.deflate(order_data))
20 | }
21 | }
22 | end.doc.root
23 | end
24 |
25 | def order_data
26 | Nokogiri::XML::Builder.new do |xml|
27 | xml.HIARequestOrderData('xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004') {
28 | xml.AuthenticationPubKeyInfo {
29 | x509_data_xml(xml, client.x_509_certificate(:x))
30 | xml.PubKeyValue {
31 | xml.send('ds:RSAKeyValue') {
32 | xml.send('ds:Modulus', Base64.strict_encode64([client.x.n].pack("H*")))
33 | xml.send('ds:Exponent', Base64.strict_encode64(client.x.key.e.to_s(2)))
34 | }
35 | }
36 | xml.AuthenticationVersion 'X002'
37 | }
38 | xml.EncryptionPubKeyInfo{
39 | x509_data_xml(xml, client.x_509_certificate(:e))
40 | xml.PubKeyValue {
41 | xml.send('ds:RSAKeyValue') {
42 | xml.send('ds:Modulus', Base64.strict_encode64([client.e.n].pack("H*")))
43 | xml.send('ds:Exponent', Base64.strict_encode64(client.e.key.e.to_s(2)))
44 | }
45 | }
46 | xml.EncryptionVersion 'E002'
47 | }
48 | xml.PartnerID partner_id
49 | xml.UserID user_id
50 | }
51 | end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
52 | end
53 |
54 | def to_xml
55 | Nokogiri::XML::Builder.new do |xml|
56 | xml.send(root, 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004', 'Version' => 'H004', 'Revision' => '1') {
57 | xml.parent.add_child(header)
58 | xml.parent.add_child(body)
59 | }
60 | end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
61 | end
62 | end
63 |
--------------------------------------------------------------------------------
/lib/epics/hkd.rb:
--------------------------------------------------------------------------------
1 | class Epics::HKD < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'HKD',
7 | order_attribute: 'DZHNN',
8 | order_params: {},
9 | mutable: { TransactionPhase: 'Initialisation' }
10 | )
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/epics/hpb.rb:
--------------------------------------------------------------------------------
1 | class Epics::HPB < Epics::GenericRequest
2 | def root
3 | "ebicsNoPubKeyDigestsRequest"
4 | end
5 |
6 | def header
7 | client.header_request.build(
8 | nonce: nonce,
9 | timestamp: timestamp,
10 | order_type: 'HPB',
11 | order_attribute: 'DZHNN',
12 | with_bank_pubkey_digests: false,
13 | mutable: {}
14 | )
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/epics/hpd.rb:
--------------------------------------------------------------------------------
1 | class Epics::HPD < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'HPD',
7 | order_attribute: 'DZHNN',
8 | order_params: {},
9 | mutable: { TransactionPhase: 'Initialisation' }
10 | )
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/epics/htd.rb:
--------------------------------------------------------------------------------
1 | class Epics::HTD < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'HTD',
7 | order_attribute: 'DZHNN',
8 | order_params: {},
9 | mutable: { TransactionPhase: 'Initialisation' }
10 | )
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/epics/ini.rb:
--------------------------------------------------------------------------------
1 | class Epics::INI < Epics::GenericRequest
2 | def root
3 | "ebicsUnsecuredRequest"
4 | end
5 |
6 | def header
7 | client.header_request.build(
8 | order_type: 'INI',
9 | order_attribute: 'DZNNN',
10 | with_bank_pubkey_digests: false,
11 | mutable: {},
12 | )
13 | end
14 |
15 | def body
16 | Nokogiri::XML::Builder.new do |xml|
17 | xml.body{
18 | xml.DataTransfer {
19 | xml.OrderData Base64.strict_encode64(Zlib::Deflate.deflate(key_signature))
20 | }
21 | }
22 | end.doc.root
23 | end
24 |
25 | def key_signature
26 | Nokogiri::XML::Builder.new do |xml|
27 | xml.SignaturePubKeyOrderData('xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'http://www.ebics.org/S001') {
28 | xml.SignaturePubKeyInfo {
29 | x509_data_xml(xml, client.x_509_certificate(:a))
30 | xml.PubKeyValue {
31 | xml.send('ds:RSAKeyValue') {
32 | xml.send('ds:Modulus', Base64.strict_encode64([client.a.n].pack("H*")))
33 | xml.send('ds:Exponent', Base64.strict_encode64(client.a.key.e.to_s(2)))
34 | }
35 | xml.TimeStamp timestamp
36 | }
37 | xml.SignatureVersion 'A006'
38 | }
39 | xml.PartnerID partner_id
40 | xml.UserID user_id
41 | }
42 | end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
43 | end
44 |
45 | def to_xml
46 | Nokogiri::XML::Builder.new do |xml|
47 | xml.send(root, 'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004', 'Version' => 'H004', 'Revision' => '1') {
48 | xml.parent.add_child(header)
49 | xml.parent.add_child(body)
50 | }
51 | end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/lib/epics/key.rb:
--------------------------------------------------------------------------------
1 | class Epics::Key
2 | attr_accessor :key
3 |
4 | def initialize(encoded_key, passphrase = nil)
5 | if encoded_key.kind_of?(OpenSSL::PKey::RSA)
6 | self.key = encoded_key
7 | else
8 | self.key = OpenSSL::PKey::RSA.new(encoded_key)
9 | end
10 | end
11 |
12 | ###
13 | # concat the exponent and modulus (hex representation) with a single whitespace
14 | # remove leading zeros from both
15 | # calculate digest (SHA256)
16 | # encode as Base64
17 | ####
18 | def public_digest
19 | c = [ e.gsub(/^0*/,''), n.gsub(/^0*/,'') ].map(&:downcase).join(" ")
20 |
21 | Base64.encode64(digester.digest(c)).strip
22 | end
23 |
24 | def n
25 | self.key.n.to_s(16)
26 | end
27 |
28 | def e
29 | self.key.e.to_s(16)
30 | end
31 |
32 | def sign(msg)
33 | Base64.encode64(
34 | key.sign_pss(
35 | 'SHA256',
36 | msg,
37 | salt_length: :digest,
38 | mgf1_hash: 'SHA256',
39 | ),
40 | ).gsub("\n", '')
41 | end
42 |
43 | def digester
44 | @digester ||= OpenSSL::Digest::SHA256.new
45 | end
46 |
47 | end
48 |
--------------------------------------------------------------------------------
/lib/epics/letter_renderer.rb:
--------------------------------------------------------------------------------
1 | class Epics::LetterRenderer
2 | extend Forwardable
3 |
4 | I18N_SCOPE = 'epics.letter'
5 |
6 | def initialize(client)
7 | @client = client
8 | end
9 |
10 | def translate(key, **options)
11 | I18n.translate(key, **{ locale: @client.locale, scope: I18N_SCOPE }.merge(options))
12 | end
13 |
14 | alias t translate
15 |
16 | def_delegators :@client, :host_id, :user_id, :partner_id, :a, :x, :e
17 |
18 | def render(bankname)
19 | template_path = File.join(File.dirname(__FILE__), '../letter/', template_filename)
20 | ERB.new(File.read(template_path)).result(binding)
21 | end
22 |
23 | def template_filename
24 | use_x_509_certificate_template? ? 'ini_with_certs.erb' : 'ini.erb'
25 | end
26 |
27 | def use_x_509_certificate_template?
28 | x_509_certificate_a_hash && x_509_certificate_x_hash && x_509_certificate_e_hash
29 | end
30 |
31 | def x_509_certificate_a_hash
32 | @client.x_509_certificate_hash(:a)
33 | end
34 |
35 | def x_509_certificate_x_hash
36 | @client.x_509_certificate_hash(:x)
37 | end
38 |
39 | def x_509_certificate_e_hash
40 | @client.x_509_certificate_hash(:e)
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/lib/epics/middleware/parse_ebics.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Epics::ParseEbics < Faraday::Middleware
4 | def initialize(app = nil, options = {})
5 | super(app)
6 | @client = options[:client]
7 | end
8 |
9 | def call(env)
10 | @app.call(env).on_complete do |response|
11 | response.body = ::Epics::Response.new(@client, response.body)
12 | raise(Epics::Error::TechnicalError, response.body.technical_code) if response.body.technical_error?
13 | raise(Epics::Error::BusinessError, response.body.business_code) if response.body.business_error?
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/epics/middleware/xmlsig.rb:
--------------------------------------------------------------------------------
1 | class Epics::XMLSIG < Faraday::Middleware
2 |
3 | def initialize(app, options = {})
4 | super(app)
5 | @client = options[:client]
6 | end
7 |
8 | def call(env)
9 | @signer = Epics::Signer.new(@client, env.request_body)
10 | @signer.digest!
11 | @signer.sign!
12 |
13 | env.request_body = @signer.doc.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
14 | @app.call(env)
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/epics/ptk.rb:
--------------------------------------------------------------------------------
1 | class Epics::PTK < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'PTK',
7 | order_attribute: 'DZHNN',
8 | order_params: !!options[:from] && !!options[:to] ? {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | } : {},
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/response.rb:
--------------------------------------------------------------------------------
1 | class Epics::Response
2 | attr_accessor :doc
3 | attr_accessor :client
4 |
5 | def initialize(client, xml)
6 | self.doc = Nokogiri::XML.parse(xml)
7 | self.client = client
8 | end
9 |
10 | def technical_error?
11 | !["011000", "000000"].include?(technical_code)
12 | end
13 |
14 | def technical_code
15 | mutable_return_code.empty? ? system_return_code : mutable_return_code
16 | end
17 |
18 | def mutable_return_code
19 | doc.xpath("//xmlns:header/xmlns:mutable/xmlns:ReturnCode", xmlns: "urn:org:ebics:H004").text
20 | end
21 |
22 | def system_return_code
23 | doc.xpath("//xmlns:SystemReturnCode/xmlns:ReturnCode", xmlns: 'http://www.ebics.org/H000').text
24 | end
25 |
26 | def business_error?
27 | !["", "000000"].include?(business_code)
28 | end
29 |
30 | def business_code
31 | doc.xpath("//xmlns:body/xmlns:ReturnCode", xmlns: "urn:org:ebics:H004").text
32 | end
33 |
34 | def ok?
35 | !technical_error? & !business_error?
36 | end
37 |
38 | def last_segment?
39 | !!doc.at_xpath("//xmlns:header/xmlns:mutable/*[@lastSegment='true']", xmlns: "urn:org:ebics:H004")
40 | end
41 |
42 | def segmented?
43 | !!doc.at_xpath("//xmlns:header/xmlns:mutable/xmlns:SegmentNumber", xmlns: "urn:org:ebics:H004")
44 | end
45 |
46 | def return_code
47 | doc.xpath("//xmlns:ReturnCode", xmlns: "urn:org:ebics:H004").last.content
48 | rescue NoMethodError
49 | nil
50 | end
51 |
52 | def report_text
53 | doc.xpath("//xmlns:ReportText", xmlns: "urn:org:ebics:H004").first.content
54 | end
55 |
56 | def transaction_id
57 | doc.xpath("//xmlns:header/xmlns:static/xmlns:TransactionID", xmlns: 'urn:org:ebics:H004').text
58 | end
59 |
60 | def order_id
61 | doc.xpath("//xmlns:header/xmlns:mutable/xmlns:OrderID", xmlns: "urn:org:ebics:H004").text
62 | end
63 |
64 | def digest_valid?
65 | authenticated = doc.xpath("//*[@authenticate='true']").map(&:canonicalize).join
66 | digest_value = doc.xpath("//ds:DigestValue", ds: "http://www.w3.org/2000/09/xmldsig#").first
67 |
68 | digest = Base64.encode64(digester.digest(authenticated)).strip
69 |
70 | digest == digest_value.content
71 | end
72 |
73 | def signature_valid?
74 | signature = doc.xpath("//ds:SignedInfo", ds: "http://www.w3.org/2000/09/xmldsig#").first.canonicalize
75 | signature_value = doc.xpath("//ds:SignatureValue", ds: "http://www.w3.org/2000/09/xmldsig#").first
76 |
77 | client.bank_x.key.verify(digester, Base64.decode64(signature_value.content), signature)
78 | end
79 |
80 | def public_digest_valid?
81 | encryption_pub_key_digest = doc.xpath("//xmlns:EncryptionPubKeyDigest", xmlns: 'urn:org:ebics:H004').first
82 |
83 | client.e.public_digest == encryption_pub_key_digest.content
84 | end
85 |
86 | def order_data
87 | order_data_encrypted = Base64.decode64(doc.xpath("//xmlns:OrderData", xmlns: 'urn:org:ebics:H004').first.content)
88 |
89 | data = (cipher.update(order_data_encrypted) + cipher.final)
90 |
91 | Zlib::Inflate.new.inflate(data)
92 | end
93 |
94 | def cipher
95 | cipher = OpenSSL::Cipher.new("aes-128-cbc")
96 |
97 | cipher.decrypt
98 | cipher.padding = 0
99 | cipher.key = transaction_key
100 | cipher
101 | end
102 |
103 | def transaction_key
104 | transaction_key_encrypted = Base64.decode64(doc.xpath("//xmlns:TransactionKey", xmlns: 'urn:org:ebics:H004').first.content)
105 |
106 | @transaction_key ||= client.e.key.private_decrypt(transaction_key_encrypted)
107 | end
108 |
109 | def digester
110 | @digester ||= OpenSSL::Digest::SHA256.new
111 | end
112 |
113 | end
114 |
--------------------------------------------------------------------------------
/lib/epics/signer.rb:
--------------------------------------------------------------------------------
1 | class Epics::Signer
2 | attr_accessor :doc, :client
3 |
4 | def initialize(client, doc = nil)
5 | self.doc = Nokogiri::XML.parse(doc) if doc
6 | self.client = client
7 | end
8 |
9 | def digest!
10 | content_to_digest = Base64.encode64(digester.digest(doc.xpath("//*[@authenticate='true']").map(&:canonicalize).join)).strip
11 |
12 | if digest_node
13 | digest_node.content = content_to_digest
14 | end
15 |
16 | doc
17 | end
18 |
19 | def sign!
20 | signature_value_node = doc.xpath("//ds:SignatureValue", ds: "http://www.w3.org/2000/09/xmldsig#").first
21 |
22 | if signature_node
23 | signature_value_node.content = Base64.encode64(client.x.key.sign(digester, signature_node.canonicalize)).gsub(/\n/,'')
24 | end
25 |
26 | doc
27 | end
28 |
29 | def digest_node
30 | @d ||= doc.xpath("//ds:DigestValue", ds: "http://www.w3.org/2000/09/xmldsig#").first
31 | end
32 |
33 | def signature_node
34 | @s ||= doc.xpath("//ds:SignedInfo", ds: "http://www.w3.org/2000/09/xmldsig#").first
35 | end
36 |
37 | def digester
38 | OpenSSL::Digest::SHA256.new
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/lib/epics/sta.rb:
--------------------------------------------------------------------------------
1 | class Epics::STA < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'STA',
7 | order_attribute: 'DZHNN',
8 | order_params: !!options[:from] && !!options[:to] ? {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | } : {},
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Epics
4 | VERSION = '2.11.0'
5 | end
6 |
--------------------------------------------------------------------------------
/lib/epics/vmk.rb:
--------------------------------------------------------------------------------
1 | class Epics::VMK < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'VMK',
7 | order_attribute: 'DZHNN',
8 | order_params: !!options[:from] && !!options[:to] ? {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | } : {},
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/wss.rb:
--------------------------------------------------------------------------------
1 | class Epics::WSS < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'WSS',
7 | order_attribute: 'DZHNN',
8 | order_params: {},
9 | mutable: { TransactionPhase: 'Initialisation' }
10 | )
11 | end
12 | end
13 |
14 |
--------------------------------------------------------------------------------
/lib/epics/x_509_certificate.rb:
--------------------------------------------------------------------------------
1 | class Epics::X509Certificate
2 | extend Forwardable
3 |
4 | attr_reader :certificate
5 |
6 | def_delegators :certificate, :issuer, :version
7 |
8 | def initialize(crt_content)
9 | @certificate = OpenSSL::X509::Certificate.new(crt_content)
10 | end
11 |
12 | def data
13 | Base64.strict_encode64(@certificate.to_der)
14 | end
15 | end
--------------------------------------------------------------------------------
/lib/epics/xct.rb:
--------------------------------------------------------------------------------
1 | class Epics::XCT < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'XCT',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/xds.rb:
--------------------------------------------------------------------------------
1 | class Epics::XDS < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'XDS',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/xe2.rb:
--------------------------------------------------------------------------------
1 | class Epics::XE2 < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'XE2',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/xe3.rb:
--------------------------------------------------------------------------------
1 | class Epics::XE3 < Epics::GenericUploadRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'XE3',
7 | order_attribute: 'OZHNN',
8 | order_params: {},
9 | num_segments: 1,
10 | mutable: { TransactionPhase: 'Initialisation' }
11 | )
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/epics/z01.rb:
--------------------------------------------------------------------------------
1 | class Epics::Z01 < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'Z01',
7 | order_attribute: 'DZHNN',
8 | order_params: {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | },
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/z52.rb:
--------------------------------------------------------------------------------
1 | class Epics::Z52 < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'Z52',
7 | order_attribute: 'DZHNN',
8 | order_params: {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | },
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/z53.rb:
--------------------------------------------------------------------------------
1 | class Epics::Z53 < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'Z53',
7 | order_attribute: 'DZHNN',
8 | order_params: {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | },
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/epics/z54.rb:
--------------------------------------------------------------------------------
1 | class Epics::Z54 < Epics::GenericRequest
2 | def header
3 | client.header_request.build(
4 | nonce: nonce,
5 | timestamp: timestamp,
6 | order_type: 'Z54',
7 | order_attribute: 'DZHNN',
8 | order_params: {
9 | DateRange: {
10 | Start: options[:from],
11 | End: options[:to]
12 | }
13 | },
14 | mutable: { TransactionPhase: 'Initialisation' }
15 | )
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/letter/locales/de.yml:
--------------------------------------------------------------------------------
1 | de:
2 | epics:
3 | letter:
4 | date: Datum
5 | time: Uhrzeit
6 | recipient: Empfänger
7 | signature: Unterschrift
8 | version: Version
9 | exponent: Exponent
10 | modulus: Modulus
11 | hash: Hash
12 | certificate: Zertifikat
13 | bit: '%{bit} Bit'
14 | issued_in: Ort/Datum
15 | name: Name/Firma
16 | confirmation: Ich bestätige hiermit den obigen öffentlichen Schlüssel für meine elektronische Unterschrift.
17 | initialization_letter:
18 | a: Initialisierungsbrief für SIGNATUR-Zertifikat (INI)
19 | x: Initialisierungsbrief für AUTHENTIFIZIERUNGS-Zertifikat (HIA)
20 | e: Initialisierungsbrief für VERSCHLÜSSELUNGS-Zertifikat (HIA)
21 |
--------------------------------------------------------------------------------
/lib/letter/locales/en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | epics:
3 | letter:
4 | date: Date
5 | time: Time
6 | recipient: Recipient
7 | signature: Signature
8 | version: Version
9 | exponent: Exponent
10 | modulus: Modulus
11 | hash: Hash
12 | certificate: Certificate
13 | bit: '%{bit} Bit'
14 | issued_in: Location/Date
15 | name: Name/Company
16 | confirmation: I hearby confirm the public key above for my electronic signature.
17 | initialization_letter:
18 | a: Initialization letter for SIGNATURE certificate (INI)
19 | x: Initialization letter for AUTHENTICATION certificate (HIA)
20 | e: Initialization letter for ENCRYPTION certificate (HIA)
21 |
--------------------------------------------------------------------------------
/lib/letter/locales/fr.yml:
--------------------------------------------------------------------------------
1 | fr:
2 | epics:
3 | letter:
4 | date: Date
5 | time: Heure
6 | recipient: Destinataire
7 | signature: Signature
8 | version: Version
9 | exponent: Exponent
10 | modulus: Modulus
11 | hash: Hash
12 | certificate: Certificat
13 | bit: '%{bit} Bit'
14 | issued_in: Lieu/Date
15 | name: Nom/Société
16 | confirmation: Je confirme par la présente la clé publique ci-dessus pour ma signature électronique.
17 | initialization_letter:
18 | a: Lettre d'initialization du certificat de SIGNATURE (INI)
19 | x: Lettre d'initialization du certificat d'AUTHENTIFICATION (HIA)
20 | e: Lettre d'initialization du certificat de CHIFFREMENT (HIA)
21 |
--------------------------------------------------------------------------------
/spec/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railslove/epics/6ab966f1618baa0718a20b93bc2fe25589750693/spec/.DS_Store
--------------------------------------------------------------------------------
/spec/error_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Epics::Error::BusinessError do
4 |
5 | subject { Epics::Error::BusinessError.new(code) }
6 |
7 | before do
8 | stub_const("Epics::Error::BusinessError::ERRORS", {
9 | "123" => {
10 | "symbol" => "BOTTMUEHLE",
11 | "short_text" => "home of awesome",
12 | }
13 | })
14 | end
15 |
16 | let(:code) { '123' }
17 |
18 | describe '#to_s' do
19 |
20 | it 'returns a message composed of symbol and short text' do
21 | expect(subject.to_s).to eql('BOTTMUEHLE - home of awesome')
22 | end
23 | end
24 |
25 | describe '#code' do
26 | it 'returns the code' do
27 | expect(subject.code).to eql('123')
28 | end
29 | end
30 |
31 | describe '#symbol' do
32 | it 'returns the symbol' do
33 | expect(subject.symbol).to eql('BOTTMUEHLE')
34 | end
35 | end
36 |
37 | describe '#short_text' do
38 | it 'returns the short text' do
39 | expect(subject.short_text).to eql('home of awesome')
40 | end
41 | end
42 |
43 | end
44 |
--------------------------------------------------------------------------------
/spec/fixtures/SIZBN001.key:
--------------------------------------------------------------------------------
1 | {
2 | "SIZBN001.E002": "T0DbJARPNfDbx3x+pooRViwBpL8so7i/vFPN/s91Fd6/KuvJbbbTPRPrNpK3TDt0VxiPYn8VO7comHesifUUUYm+WJm73cFEjvKzelejz7WvBKaIVHii519bQ8J3TuFPiIReB1Ex/RYcBsEHBGqhRkcUsLALDdBvbfrQ8+L+OKijM0C8OadHWzrl4BKivua5uydkkw2hv0FIi0oJinXXKM0CBU6Id/lGXKCgrM0/yEmu3XLRVxR6Fqw9zUJc1efuS+88WgXqQoArTZphcGExunAvePV7BBiPI0SshyzmyTVOY5pJDHptw/gwT7eqCTWPn7kvOJ7beGVF4cnOuMJWo++0P7vqb5oeSt+RhUtgyWHktofm8UVxMYej27hEi3UmIcaiy9MwtZc=",
3 | "SIZBN001.X002": "E9Lx/LgcG2zCaEtpk2nsz7ix9LioI7utENsMhx9xDet3APsg9mg2wpaLK4WYGHxVlfRBmqwKcVyQJxbkkfupasCL6GChsIrgeavCmSX3fMFr6Z5VpcLXauar5BMZLXp1HvKwheI6iZwwYCyGpChMeY5Di6fN8EcxG2vP8oPQYoLs0COwl5kZ0PVfSFSCK1SWrcNSOeHbrrf0YViYWoVt6D9zTHBf/F3DznicJkgkhVTCVvq/+RpKoK/4YDMjAEheMf0PLvmqUk0HHsAKtFPWe4Q9SVqXmK59h+ZcJweDSkox95nWb67j9Hyw21D0PisgWTx4o7YqcCiEn9yb08EfmQrQUCHzaQHdryMaWNhLcHuTVneGOFpCmcMJsfwUhcOklsqxMbvJu1M=",
4 | "X002": "RYnfScoGWcVvmFWZbqbwc+9yr1TkLiK9EMUOkPbfJkD1kX7f4zPzJv0CtO3jJPvhbCTVC7Cl4Zk10JTPxLUztqZkU6rfGGxi4/Da28SSBr4XHaHmso53sWoA4qIdilb6ibQdZX6nfmBYqQ3Ynd8KanThSyWj39CWECcve7all7ShB9C4+8z7sS57FhAr+XJ/nIiEPxuQ8sajV4urfxiFM+b2tWc3WDckyJ+l+6T0FH+3ZM70GOy8hwwxjN7MyJpPZ5ToqTLUkOlxpOhnzSwlsQErb97Rp3vq/hvfb3S6f6GHE/znZJr/xYo4jaNo41T95efSbpOI5XjPAwsAbjxGEu8DwUBKaUh62mqE9TukJRK2m0kMFI7EgKTTL3N/BNp8vPhmUhWmWKZHUBZIXZNjnjGRRzSvSxS25s2xcNXedfO2AN8w0gcfklLgk32xCFcvAW7VOMWCmRk6V0efeKxn9m1Dk5OZT75nih5DsYWAyx5I7tEig/7K1p3jUh55iRDacjsFwmFdRnpXifAsTn2qIZ88VuHO9QluBhXw7+W3A2Xf3Yrkr75fsTP+uQlpxx43cOLKjTkx9wPt0r6kQhm2Kiy3EtP7oyVOhbe4ahDLFlIkaumhcKedx5ds4cytEx7/0obHxx36c2ldbSYrbdndh7rpdlonC1GKqlPiB2bcQGH43XRfMjee8JLNVHPO2lGMkZlE/L9NMkN8TQ6x8hixekWm0odb4ZVZMneCqFzynv+xbqdWw9ysR6z+viNJbqqTJC0s0Xdx3xRMUK9pjyqH5pl03IFoozfOrBKblW/QMxdUIiRhlu0j9Lq5VVOajwUx/v3bRI7EFXRW8IDnLYjKCKj5Wh2IsI246jTDvAULNc/Cv44bNA2Sj/gen7YA5EmuH18DqibV7AL2ROSH4VKAjW2tcRyyGm4gtDU9iF+jdk0kNcv/IYLqa943EU15JmiVdj3ciEKWxr4YuK4Y1BhZPmRSdGJFWQoqm2QoxmSayNePww8eYt6JsMtFm+BREZwHM0/Jfy6DgpiEPx4Gw5zg636+lLffv81CHlbzcySsKIRx6RdAjKwf5ixHqxYeZx0xhEuJ1KCmsCnJvyC7UBwgxA9ZrBHmq6ijuGsfboOPqYONQOVPjXgiOypyTVSrzt0D3CMQFs4juOM2NSSjx6oLVOe3QIbPDE25wyjQYLHmPhQS5+UqPuocqCo0Z6jLlcIJ/2VkquT1ORdUAcHXk9qp1zPfvFGZbA2OX5Qn27oAVVJA2iGD49/K2aXa1xFrKgha0HkEJSFjCQrs66P7Ku2JHOTkkBJnnE/ZnJ4uiEaNDzXXls7SEMdfxyqKbX0ooONxqv7PbzILgTzN0Dk1b+8Lnnq5CDyQ/BbA1ZcuilsGenGXvqPvIjDzhwe4MrF2A/T3OCAhqiKmqWeyhLNzO9APY2knK9Hq2+nj+FZuQ84uzdRdGPbOFI/1qJm1C+UyB5J00pg/2Glb4HnruAp9eoBbVHZH4XoMVGnOk2KQRsXUvoUZj19XoaX4+eurrIE/hmKrXnwegGLi8d4VYlOdU65bqRhoBytL8FywfXgxPDet/nOFip4D1g612poFSsMlFvof2I1HSW9K3JiPypH4eipSzkOC6bNniA98CjnRGInEXvf5DAP/xc5DPGi9LV45mUfWBNpGhgxfI32YLmE3ENx2aLZKjhYwZq9Dv5kwrRM3NZGKLFMVXPWZsspKwwUfg1tqR729r5s3HiJ2bQ4F1TD8hBx38uGlizX7oDDgbkFUWrrNLUOSGJsGeXFmzOrvBvzAkCVwHNZ/QgXk95J8LEW10JAqSptdJD3hzbG+17PUDFOazw6AebRo9QjUIuk92KDXDP9F/sHPnUZdEJf7UkpH7FTfSGCkcaNi4e4DrxfHVMMOcf66nv0+B2Z1+84/DdBXVGwGsYQw0IH0fL0X8FRflp+CMO6SwwvvCYCTYufCXxB7modxBoj6dUk+NZPdwYkPdQ9xQmmuzwddGi+5TM5LjlnDam3G3ucuisyN7ZIRErnS3uE0MniZrp4la8mJ10G4cX5KO1Ar96+9JoRANYoz1eRTHh6VA4G/pMM4PiOeoPd8KNK4bsOk7RjnoDih685mHbfTn/qj2n9EbAP+H+FhoILNJY/12tQNIzzH76xX/W82V1WPz964wotOSKO1sg9qwNCSu5rt62JQchvmjuCVvZGz3P+iIZilOTjklaaIkrdxHWGSVf99xOxwr3j2VyjThcl8u0MIDZc=",
5 | "A006": "PKftcKEEuAfvNMRkM/E62+8ELgd1+uiUVXLf+2YaXO0yayPYz5JdPQB5pfVFAfmQfS034lj18q2cOefk2gBceiBHCEmW3hSLLZOCvbuafi0YAMCFXrovQuil0QlP1XIjcZ1x9eBRB37Hbkff4tKSHjjj1ex5M0uGtZ9Kf78BGvO8VewPVtifim6XrLSvz8AXVv8TE2VfK4z2jYG5toUO9MqEZV+NA2SscSaFSTOo+8frm0HSAYC9NxWEJCFA4KVQWP4lTAQDv4pjJ83p1cdy6jipzKYraSHZGjGKb1Hzrvt9KXa7+JyzetiaCz2q9iOYoz6WZPmn87rjmqq/8fnck/IfqhH6ESMuaAEWeaA7mkivGB2zxIQSb6E+d7cenSbZmKLSVnGThylKzzzRjoDmwNixyKLqPOtogS4bPKo7eiPSLmla2xVTmlO9pemMMtBmOKYpRYMnmldpFHcCGxqu3gUhq+bT6ry3cMeAOoyimmTO0J1IzIHcuG/mcN7pr3ZZFODe4B/6ca2HslWbUDWfAw76HGatzEmVfJijFQ5bKSQ3Jp4MmlcWzfLRr/3rELzDgH27sYJyaVAJd4NR7BTtXN1o1Ytgj8mYvRvsWW1Z1Vjwwa7vzomcSkcV7TAYsJ3J75us4lsNwStAOLln59gGSMPAvI69tWSKOpy+5zm7Ph0wVY7yr0FE0ZgZFWmnZNMI+jcxfpCuuP80ar+HqyPQAltocgSbylANvXW4cDhg3umzVxkmEB87Xswmx+iKWOiyOLj0gbpNoe4OHYxR7nPkpMJpSr2JmtgIcdDI2c4jZax+3Lh9bq+89V4DvROjna2KWsxdY1t0Dl1F/nGRdnKdR/EpJYATeztMmdLOIxF8vjvkYVkrDhTj1sBOTP8tSFoDBn2NSECRPGnM1lpmdX6TZEXN7hDeb/ZEF1XCfXRuvoH0AZknp/u+9Yv8PC7ORc2VCHEJydg4g+N0U1i7iRPrQ8YXFNZGCRMlEjSnp+oPiMAF78qD2Vcz9lHB1wuPnZ4cPDOQq1WbpdH1TaQmDUQbTBVImxl/iiN3Qwt9STyZ7fKJ3rdC4gBENJ7wSxDYuOEFRpPPtECarhzMb+dzfrA/GB8XRkdl4o9V7XAnCnSr0nC4rEDfgNRbn3Px01LpbLa0aNjZcU1SoIsIDuyraB2ptyTjcdLti8znn0tcb6FSoxtVsk73xs4y+VbV/tUqG9+aHsFiHIV4PqFDqzEKUUTV4LyHctZRyEkIVi6TbfABFRWfWxtK+w/D9QFuI4MVG3DNG+KxWkOiPgi9smMtwV6fCjIaqYcUJgCdV79kfY9hVSJbMcLcNhXTnIAhZgos6GPTSKHMuspUFbpxsSVupwmXtFQMdyIpMn65dJ0iEuzLy2rq469egGeAJAmfofJ1NJgP2dWqKyMHvic8n6wn7ZM0GXmsdgbZPagSB11kwLbo7t9eS068i9Il+dyH56WCzS9N/eBJhr34OdKhwTFVAFZnJR07Oxo5QDTxtw8o4tzcxbQtDca+8Qd9U0C7FPfqsHC4o/JRyuEzu0Q4M8Ln8MLE5W0886kWpuHHwuycQvTYiNAyPNsOOQfR/jLlOyZ9ycp/1HITLYzwfV6L+HRkzy/gcS5PmusxnUHkDqfqcbM97Uaxg6Oq+GY/umFz08TxQ0/8rU4UOuaHqronB/SbvxF9u9WC9uIj0H0RKlaRT6G5xhWpUUlVughsEjEfnRL3dOvgI2HhFpVlIhuQHWA3AuQ/JBS1l9mzfqZOz8BIUVpSvg8esti2BwRZp4+a3uj+xeld7bw9jrn4mlveZP6Jo23KOt5SQ5HWb8dEdj44vpe7J+QeSl1lOu6eD2eVw4Mth9BVREHPLvsOd4Ja3o35mkZHjQl3Q3cxJRPGbXXzSwPDKNaMbq36eBgt2ygNCRg5zlHlfmGoBgVtwMc9ApeIt9lLuXw99XGdpImpe70dAPMn7pSStStMusPIReigHIT3zRVDMwz1nku6paKaGOnES98RAc0PCFlymae+WdWvG5BtBTs255pcvihxq4QLhfofUyKGgKWwcOkqz9pOsOSxSLPlHy1lIreeyQHkRbNkqFhha/kWiWYxrwO3GfWPLotarpvmfvEy2CTIA2R61VWqoNQmETh1ZhNe6d5g0tcIZRmIzMMZOpg4aGZyrPM4XeTyhhq+BjvUgXqzjSzBCQJG0wEuo/cJvAPfJauOqPz2z2LabTa0TvOCPOGtB1jFU58EBa2sCx9E5aGHiV4=",
6 | "E002": "oGTx5v7voHOTcUVVJlMwz7mKUVM9NJzNzLUX8W9c14DjupMSNyMDgqy6m6tUt/p71tUFQpVkztx2VqP9kgnpN67sG9IW2u9nLzAZyL+buZwTUC4KFDuRcYbCaYaXUAd6GD1vL1X5sGGvwhZaZjOQX8A1sRI0+PVVu+hkRHZXwGBMmmzF0QR+tf44d40hb8MjSlUFT4LXny6qgWgQ5jhnZ/+fB/V38GgNsSsaU2pdIL6p0qefRVAtUw9PWbQdZ0ijoPMGc4qtWqy80goKN/YCwmsBO6RyA1VKiYe3v0SsLJ3i3hQEtaaqguBmzLScsGW4ytROhNOaQmW2q/XAZHN6s2NnObcy5VVWR7Vz9ayHP9gqUMZTT+1yhokcPV7Akxg9vS8oWDszxncJbi4i+HWbG3ZtWvkwcBxINYTqf5m6OcA0MEzKXZEIwJwD1jk3eq5Y78pHYStPOzUuInKBjXWLv4tbeHeuKJ+Dd/4Pd/hd3ENLKOiV3cSsRvQW+zE2ST0B3Nv0AqM2SNcj7odiZc9oXZojc3HUI0NNh4s2zaXrs+xrVd/PBNqQy9JBPJhgFGJyMhB0prauV+8Z0HfUyv2V/T/Lc4hOoUAGexWVM5HiE81+LPSMsXZZV9NuUqedMZ2P+ayv6U/yegbOt7prk6EGtvOHYG0mjomebY8SWpPjPB3vwJ2d4bjfedWr3iNfTVjDvqhPw7d54kC3HEbkE82Wb32xM2gCQMu3OLiUgxEP2d+ps31Z562TeudQkPaCB0FRfjV0cmrLcCYYlKYiwJYTyVGtq/7j0hysWjY2hglmag8BBiUE0ZS4+H65ntYwYyPIMN0F0TvC3/p+bmDx1qowbyFp03Lbquld/8HlAcDdSFFF5FqcTuYERTBhU4m0W5cVmw/jm0jLJMCwerj3NLhw3l8WNrB7J1GFjVPSZOuQmBJce4oUX+AjpZASXNPzfL6w7H0kMVnoC4ObMecUnoAKNJLjhCG8h2yswM8YP5xHG0vPKKO145i9+nMMbkbc5ltMiVdHemcDd6h0BM6H3TGcSCPEh/Hx4CDYsyu6qrqT4eFCE3vuGmpNlLJ9CclQZipHVp90bbuHWn6mIlkmJMcR0EWzi6yBWdAz2KiXMp8OsTgcF6qNi13a3wt7kRESjXRYxkixvglggu1f82fSTc0njzHzx3+Vk4BxQmLfx79FB+1V9uJuZ6sDXjXr/oH5sUbJa9oLGBjiwez9r5Vg9fNcy9O3L3OQAYejgPJlI8uFTEGYHJaLZSIR2kr/9jV4bW7MxHcdc0gONvLGiCg+YjFA065xF9kg5RTaWkOC0/wbh9fISgXsv8txOo228n2ukrt31V8lfM/W+TAdg9v+xc1+BfZXUY2fZzlU8gpmwcE9EYP2YpE65CaGuroxkVEu94TfxSdkEwjlMkNVXOSPo1uZOXwzJhn5fgIGFMU+z7pYwp7X41C7LA6DY5afAsxCof1x646m2dAQ3Fz/Dqkzq4bLwq1b0Kas0S8DHDL/V3kz3WrjLDLhUfSRwDgUMQoFseUqC7Hc8X5oiJutvN5aVgoBxTTvj5F5o3jrq47da2WzYuO24YSEQ+fHdHUMZ7uIxzS7aZs6bOi53fpTHMRYWC2JqT/VwuAhppG9Yc/qDZ7a63w209jRvRSFQoYnsMN9lGJ3N+hdXK+qBLn0YjBNuW65uAulzQ94dliQNYUlEaPPKtzJcNhbMGBokMwZDxGJJL5oozY+gAZ+LiTrssMAZrxku294AwftgqckxEdX7/eu1bL2d4I1xlrkAc6cFo4Te0uT5OKsGjGW6KTobSSx3mpOvc2V2YjSbBkJzNJ4s50ywCyFVddBbsn9QjDJQBUQN+149zbHU8HbkoPYq9TTfM5Q4Y0cGNihoyIpfvr4Tt1mzYbTkrjMq39Tgoe7bN4ehyfza/5J9037BKUKSw1wQtFztw4OCQZxQ63WdKKJOFLaMwu9YRucQ0OdT9mr6/pZU1tP9lMyZKwky+BV6A8hFnkaR6ZYf247kMKEaUPaNIUk/71UMoi4aF0ULbc9IGG0aKUaIQECbTPGL8Xql5xTJdrSTla9au+4UuHLLM+rTfJWyf7VFLpf6l7d0ms3RwdHYjgPi+HLPpExrBrxpnBBlSQm+Sp6Ky9yeA5qlVaJU4oXvGyK2F0Gk38fEiL/uH5VdbblN90Sz6LNM29CftiLXDNGf+/LdM/W8qp3rKrhxXJeficHm3hNOK/bgW4KmTd2zAELOQ/ukMauzdw="
7 | }
--------------------------------------------------------------------------------
/spec/fixtures/a006.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDXjmjtnx5eemu2
3 | 3EuBQJ308rxoom5osnnfScdcInwqI7s8y6Z0lVp2w5tsMgdf2FytVf3JZSviwq2r
4 | +PMTJ6IGtGkXFca0graQFvjwelp9YSpDVtpv8CLj9VYPiwdhALAFbwojKwqchilF
5 | BjUOcdD4fdd8WFIGeNUavwjSdsOALbgoG6+Sr0U8LyhL+CRCeaspnnat2MtZLere
6 | R20JC8zKTDgbTC81AYmVL9bEwKRLSt/QnQiPBgBLGXVuXj0na++8tKrAO0Ak8VpY
7 | i6TQwceATrmCc/SHXo6rTU+MwA+7EAemGoueC8ydJaR5gN22it/2N4ASasQt1h0g
8 | X+vMeuonAgMBAAECggEAKXjTxUwE6saA7Nirij2lZlhBWZxOw8P64LPwMFDONMlV
9 | H9hKuUl28zylLYbellkpU4wk3NejPuiXw2uNUNUiPkn9ohxlc5tmhoh08seHm3HT
10 | UMtoEXtRKyyrlyf3jnk0ZIc9mxCP5ReG3ynXkWTigLytddYESgx7a77vcpa4/HL0
11 | 9QEkrZCG92m4ga4/rvwSR/V/UcwNarf96/W4leKlmgfXuz0V7Md6tfoubc3pnfI8
12 | I9D7Xp9eRRxWLqLNhpJ5R5JJOsC8qIwuvN/2qjtT8ClAzg85DSu7hUxv8cVqxcWe
13 | jy+hYpnnolDaTt29Htg5Qo0+K6DMaBA/oisPsz2t4QKBgQDzimHfoaNo8LcXPkr7
14 | eQt/HQvvkkrppfoktMQes142YtaM1e2lWNgtVXG9mwFKI/GrSJ6yJVCC4CGa3zX7
15 | euWEUVuWxmpEpH8Tvi0G3389MIECWLxgkWNN4knmC2IwBM6oD4ihd819wWzwsPpn
16 | a+5Df3yL4/FflhttJCNCUoJR0QKBgQDilYV6ShIVL1XgyP8YPDU8t5vm7n6RoTnP
17 | tJ2gu2lW4fqeHO30jgcPBw8UG6FGYalcCixxGVrrrGmgJe1lHYLUOOdn4x5JqZAn
18 | 7I/hm7QSK1C1+qJMWCaQxzo+2DclJOs4oXgES35RiKb3ErDlQW2GyOgNZoLQFFCx
19 | HSJKiJ9CdwKBgFFSmDQQyXw1RS4hwvAOD2S20lGBTDqRDeJL6mFGC+OlRXdpyB06
20 | eZVJvt1NcTTMo9pKOZPLGgNZzF7mwiPjedihQjAquTmKpFR3YJm278oC9FFQSDcG
21 | 1V4gfgSvMG5QbKF57mnck2W2vSXyMutuAvXPEEu2JdeBTE85jfyLiLDBAoGARcse
22 | yVNljIb/IfVntjRdha1c5V5TOFJ8N0GASFFSGkQTaX6pwWm6POPEvkHghIhynXo4
23 | xEG2IuABzSXBoSLc+Lfqd7Ka0r/bOqEAlNLcPbh/7P4d3fxNLM1hYJhDLDraBaCf
24 | EluatkyseXCVcpibvyfFatNHugZ38IZz2JeKzvMCgYBdz52dlr4TSMigbI93B6Ox
25 | 4bBsu/kue+eL1kcOBEBa/uMQLEWgQLWpHkskVpRzpbyu2drSozW6wOx6EBt7HlRV
26 | eG8rYi6P6SOiUoaLWcRqnaFCL5JgzGMlgmcIhwA9ABCdo6gMWJFXkkrIyKBm2FsQ
27 | KfJIQL6xXtLW1h+56l93XA==
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/spec/fixtures/bank_e.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdv9DqCGcnW/bICm4sKg3MANDb
3 | XFDCGIuhiuz6qEbM7tbsrRp8SY0IRretpDLJVry4Hm1EsHav092MhrGtykHiBmlF
4 | J/YqsrtwaDTjHaNgyzeDXRjGNVkfx22ESkdyR8lEYUwSsNuyknEUXShpeo2PlXF3
5 | EyiS/D41zEB+XA+hswIDAQAB
6 | -----END PUBLIC KEY-----
--------------------------------------------------------------------------------
/spec/fixtures/e002.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDWuSNkXpPgLrr3
3 | gKaI5unAj3yTieBqoN4GkhBXyafb9EQCsSOeDBqcklt03nWkLL9KfXRmK2o+yziY
4 | +nKRxMnI0PE7N1mTXbB3MiihOLLIwmgjw36xNYFaUa9PwRHZkQc5tkkAZaoHqw5G
5 | NMRE+qqxDz6xQ1xKhJd9ycxWtuCltVL8uyBDCWeramaxGrfkORV/7TdSFizdCSm3
6 | OFpBcYWZsMNviilPGnVmAmrOXof4YMOEUDn7HPULk9rg4vaM04LK5G7rTDKYfWBz
7 | pw6Ze9hMrIJJVj6Tz/A92rqsXXKVpxMRYWFuL7VkDxFUk+pDM57qBfExcUWgpN6f
8 | VO2SBebpAgMBAAECggEBAJb7Q1mV7yDZevoBahglVgPiYNRVRIl1Z+jy168Cypcs
9 | 4I2MBOFi3WtutgQtUEcKd89m+2vD50cUGk3m/Jxm5QPhd14OA1xNqoGFsW/7sCre
10 | F9/d3L26Q6RAf6byuRxkj9ISzK4MzkvqCXVwMPnX0CID+C8okEKNjQAT3yyyFrAs
11 | z99pAoPD7xfGyZDbpSpdzmm62z69znCZjej1QrknVNmi27/8blat+wHIzTBiyiav
12 | jhcCbZ2YQFghE/Lb1B8dCJvj7eihwTiNWdc61u9U3zCN/AyxV4rl97/NG/bT5jeK
13 | fwkd3yCFSMLBTi0+3GyCv9gN7kokBdFEbkd1oyl43SECgYEA62RFlP2DdAZZMxn6
14 | Q/O8yAncIgLZ+2RlSLn4BWdBHM+O4DGAdXSMjb4BG30UxLZyEwHodSKfolMJdMS/
15 | UNQXffOTJmNRgbT75iCi+3QYHa+ZXPKUs0YUyWTxH6IlX0soHtAXQBz6TZgj1Alx
16 | hRZ33xdAfOt+yrjebIySWxW6hd0CgYEA6YWiAlnaa8v3VvJCshpx68HEeyyKukvg
17 | HiwyxGO9BoK8sgou/8cQgxhj45foTBwuGspgiyXl5Y6Lr/C+C9s81kskkGzIRZHF
18 | 1t9iQjiIxNaqb5k7+2LmR5ScV/ckkgWd/nfFY94iMCSovLUGJIleB3infKZ2pwHl
19 | F1sI/8CdEn0CgYEAiZTc+p1GVO1U+4JGfasbfwwMRzDFeaMPc/eGWJomO5GxH6av
20 | P3d0o3AXs5pjJirA+A0YckZfaYABOee5LqQYavyP2FMak6ZVyQbwW+paIhe9ms8K
21 | TNI8Wg4OxP9/unfyJjhYLpgBUJMI9ejjGfes7o7nmVwHirONBYMQE/7aO10CgYEA
22 | pkfbhqUInL2OD8FNsJiYCfHdwH+FAQbKPXHnbGRA0wQA7R3HPaY3ocGaTxN5+8gN
23 | JFJ60FpaC02nNc7M5JBmD4lOLfDn4nHcWBaUVub+rHrWvcR1K5nOs6WkdharWbba
24 | O7p5OZWQ7osMA+M6zoVqCRPm3yGBV4ZH5IuUKtiyf9kCgYEAqvbm6V0fu/sphEqj
25 | TxoAG6c/Q7aFu7TD3a6znnnml7gTyuWG88Kt8xwUILKhUJpdf3cpeu+FJ0MTn45q
26 | cbjkhO/fZMVaGzO9IIuu0L3T61fyVhUGB/MNjFGAs8iL0trcrw6/sKFSXm/wuax5
27 | 7YFHryPYM/JT+Ob4xvB6F+1FD6Q=
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/spec/fixtures/test.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railslove/epics/6ab966f1618baa0718a20b93bc2fe25589750693/spec/fixtures/test.zip
--------------------------------------------------------------------------------
/spec/fixtures/test_with_general_purpose_bit_3.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/railslove/epics/6ab966f1618baa0718a20b93bc2fe25589750693/spec/fixtures/test_with_general_purpose_bit_3.zip
--------------------------------------------------------------------------------
/spec/fixtures/x002.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQCmF+Dka//jCuwa
3 | 07aajfdTFyIL8NKbDRF1sGELm9U+yqCa+UOBnVumwZbCxc6IFTkHGlsI2+0EtLuN
4 | H/i1KA2IOtaYk8szTnKAUrOHKH/w13aq1kK38lpC6exJ82kgub5v2HVmK5BGcI6y
5 | +wmrt5QKuomdTkt/8BZYTmD0+Vo5xTTU1GoloxHA4jgj7m7TUvUl0n3rytcCSGCU
6 | gtLDDTK4p2jmpP8KQ48Dq7h7iLM/G8c8Ynnp13rWtF88q92u9K67qAQ7OiVLozq5
7 | 6sYPqsgyKQyG5B/tHUIblwsKMZAoMMOnY1qp7NYDWsPfRHFshgvbertUs5XSfrve
8 | +OIOVqtdAgMBAAECggEAL4QzTYXsLcsJIt+gpPSqZfX/QoVB6yPA8/divAx35D/Z
9 | 1JwtCN64wqstc0ldvaa8quCKXK12UFtYMJaN812jCW8zx3C4uFPgBAAk5iza9U7e
10 | 3x7u9Wr7EZuUgs+FKtyYs6ysYW9jFhPLbz7MVHjvfGZDSmKEzPQloFvD9zGC83WV
11 | /ns+UYnwVTXRvSe68idMhuyzRdl/T//FiAPVr0oq6BIAJ+YfBcGX4NA9Whcnij6Y
12 | /qHyEL3kPJGl6u8O9NwyVIPIX50/060dJabV9g28R3BRmldlKARYZtOto/PMp0eB
13 | D1a/4F/Ak18IX+XUUF796AInCtQ/mA5vM2gyrLJXbQKBgQDkax3FLFT9frmDMujK
14 | 4IzmrAfm1qM+mgNj1kRYpJVcmRr4AMGBYkDfmw5pRrMa76Ms8KaqujhNQVLqxIxb
15 | rrXRK3vjiMnb6b7Sm8fqr4us5q3jUq/u7L0KjhvUXWv6rvnc03htIviTalkC8TsA
16 | WK2dy1Es56mF+YcDt38aP22OuwKBgQC6JinfsHUCNKquNdwB/8Tb/l6D/JuZGM07
17 | 4edJSlczVhWNUD//iQ/dyTOja42MKqFs0x1Nrnf2wZSYr32ZdbIaaNxcun/qHngh
18 | 5eiyJ8Z8ulSL9GmA9DsEguz1jNC3ooeNNGZfC5vBVT9BR2ngoONA+jgt3VqIfZui
19 | Am1CNGaoxwKBgQC+W8qmnMiDrg26mj3JfZPPVYUMSsonDMFQfavd1+OmFO6VykN5
20 | qUF5WEaNU99FznpFpJSxaZosQAlzH7P9YD+j/0IzILdhb46ZBDx6iCu2P1ShQzLd
21 | wivVVRM6S1UGyLXw48fT5DYW3KUrv5A1PLIL8/pFmxb7UTXE0jK51CxgqwKBgGWn
22 | Y6SZSzyaID8kgHHDB/EPVvQC5cHUTneOJOzcIQSS1RAnq9tTMQvvzThICrNpsF+q
23 | Zk0+opppGknLQ+6i3FEZxIUK/8GNRBNW5x0rJXSFmJgZL+hQ902+ZcKuVGiD5DxT
24 | SjhLMZKBiBqQ8hvOIGwieL1rLP5ugagWZS4LSaiPAn9v//cCKLmAJT31VP1vqTOE
25 | 5b0/dFiWil+mpWifk6DpPiuNr1XpCuAK1MpBqPZpBlsDglL8lo57MklIvPixJAtg
26 | NfGFBDi5tQEOm0WpAQ9NAlxpbDKGaY+jdW+gEQOsHzO5Fj/IiCKOhMkljMbX7PYi
27 | 5wdINkqx9+DJp1dQg7cg
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/cd1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 3BUCAQDZPOQEYFB4
6 | 2014-10-07T16:10:25Z
7 | 1
8 | 10.00
9 |
10 | Max Mustermann
11 |
12 |
13 |
14 | 3BUCAQDZPOQEYFB4-FRJ5-CORE-FRST
15 | DD
16 | true
17 | 1
18 | 10.00
19 |
20 |
21 | SEPA
22 |
23 |
24 | CORE
25 |
26 | FRST
27 |
28 | 2014-10-15
29 |
30 | Max Mustermann
31 |
32 |
33 |
34 | DE89370400440532013000
35 |
36 |
37 |
38 |
39 | COBADEFFXXX
40 |
41 |
42 | SLEV
43 |
44 |
45 |
46 |
47 | DE98ZZZ09999999999
48 |
49 | SEPA
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | 95853B700796473D88F1009A40B4DC18
58 | NOTPROVIDED
59 |
60 | 10.00
61 |
62 |
63 | M00123456
64 | 2014-02-01
65 | false
66 |
67 |
68 |
69 |
70 | BKAUATWW
71 |
72 |
73 |
74 | Maria Musterfrau
75 |
76 |
77 |
78 | AT611904300234573201
79 |
80 |
81 |
82 | Purpose
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/cd1_init_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 387B7BE88FE33B0F4B60AC64A63F18E2
5 |
6 |
7 | Initialisation
8 | N00L
9 | 000000
10 | [EBICS_OK] OK
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | hSf/fZURBW6ihKUUZDMRpqc3kloVZZRjw+DTBxjS7AM=
23 |
24 |
25 | IFHzo6jch33gA0Ovxh4VWtAwJOJRdxffMy7Yi+a+UUWPM/ekNqcewCWxgjbcWgD/LiH6eQc58iKcZdNKpaKfplQ09CJi1VBry5sd97i4tlCAhoM95JTrJjp2O6PhswAo+a6dpuXmA11u57BK0/nHENMIh4+Qw3aGszn21Ft8qwo=
26 |
27 |
28 | 000000
29 | 2007-10-19T14:58:39.467Z
30 |
31 |
32 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/cd1_transfer_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 387B7BE88FE33B0F4B60AC64A63F18E2
5 |
6 |
7 | Transfer
8 | 1
9 | N00L
10 | 000000
11 | [EBICS_OK] OK
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 000000
30 | 2007-10-19T14:58:39.467Z
31 |
32 |
33 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/cdb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 1434018161
6 | 2015-06-11T12:22:41+02:00
7 | 1
8 | 1.12
9 |
10 | Max Musterman
11 |
12 |
13 |
14 | 1434018161/1
15 | DD
16 | true
17 | 1
18 | 1.12
19 |
20 |
21 | SEPA
22 |
23 |
24 | B2B
25 |
26 | RCUR
27 |
28 | 2015-06-15
29 |
30 | Max Mustermann
31 |
32 |
33 |
34 | DE89370400440532013000
35 |
36 |
37 |
38 |
39 | COBADEFFXXX
40 |
41 |
42 | SLEV
43 |
44 |
45 |
46 |
47 | DE98ZZZ09999999999
48 |
49 | SEPA
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | 86
58 |
59 | 1.12
60 |
61 |
62 | M123123
63 | 2015-06-01
64 |
65 |
66 |
67 |
68 | BKAUATWW
69 |
70 |
71 |
72 | Maria Musterfrau
73 |
74 |
75 |
76 | AT611904300234573201
77 |
78 |
79 |
80 | Purpose
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/cdb_init_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 387B7BE88FE33B0F4B60AC64A63F18E2
5 |
6 |
7 | Initialisation
8 | N00L
9 | 000000
10 | [EBICS_OK] OK
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | hSf/fZURBW6ihKUUZDMRpqc3kloVZZRjw+DTBxjS7AM=
23 |
24 |
25 | IFHzo6jch33gA0Ovxh4VWtAwJOJRdxffMy7Yi+a+UUWPM/ekNqcewCWxgjbcWgD/LiH6eQc58iKcZdNKpaKfplQ09CJi1VBry5sd97i4tlCAhoM95JTrJjp2O6PhswAo+a6dpuXmA11u57BK0/nHENMIh4+Qw3aGszn21Ft8qwo=
26 |
27 |
28 | 000000
29 | 2007-10-19T14:58:39.467Z
30 |
31 |
32 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/cdb_transfer_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 387B7BE88FE33B0F4B60AC64A63F18E2
5 |
6 |
7 | Transfer
8 | 1
9 | N00L
10 | 000000
11 | [EBICS_OK] OK
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 000000
30 | 2007-10-19T14:58:39.467Z
31 |
32 |
33 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/cip.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Message-ID-0815
6 | 2022-09-15T09:31:39.000Z
7 | 2
8 | 1122.33
9 |
10 | Initiator Name
11 |
12 |
13 |
14 | Payment-Information-ID-0815
15 | TRF
16 | true
17 | 2
18 | 1122.33
19 |
20 |
21 | SEPA
22 |
23 |
24 | INST
25 |
26 |
27 |
28 | 2022-09-16T10:00:00
29 |
30 |
31 | Herr Schnellzahler
32 |
33 |
34 |
35 | DE89370400440532013000
36 |
37 |
38 |
39 |
40 |
41 | NOTPROVIDED
42 |
43 |
44 |
45 | SLEV
46 |
47 |
48 | OriginID1
49 |
50 |
51 | 1022.00
52 |
53 |
54 | John Dough
55 |
56 |
57 |
58 | AT611904300234573201
59 |
60 |
61 |
62 | Unstructured Remittance Information
63 |
64 |
65 |
66 |
67 | OriginID2
68 |
69 |
70 | 100.33
71 |
72 |
73 | Cookie Cutter
74 |
75 |
76 |
77 | AT611904300234573201
78 |
79 |
80 |
81 | Unstructured Remittance Information
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/ebics_business_nok.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 000000
6 | [EBICS_OK] OK
7 |
8 |
9 |
10 |
11 |
12 | rwIxSUJAVEFDQ0sdYe+CybdspMllDG6ArNtdCzUbT1E=
13 | CPdd6ODXrCxHWpYrwS/5a3NIZ1R2SDscHHJSONc2I7g8ara7qv5Ra7H03W+336DPQLZQxH+EBRWdE2FQ1vrVTcypK6fkFarmO1dEtQt6Ka89AozC7aQMyp4yGl+zlF+XvFkJXZbRXgoEOPsgcG0xM6nKLXnr1ThYRFOoAasigLDGwqxliyhoR94F9dL7YB8Le/uZeRj78mNp4smkE5ZKKyPhwVx+0IW78YuVCSC2c2qbsMmm4evAvycdpLfuuoG4KVlNMIlvkKeBfMZFELcmeKKm85D2zPYkZ7cqG2IfAAp5qdS6K8P7RY4gtjUhOtP5mi8bZt/ZcjioUmIR9dAMnA==
14 |
15 | lJ/v1HvOYAZKTPkxULH4mOcUy01+EaAsxLzCPhtieAo9m5AtU5URdyBVfmclHbtWe3ELb02lR37bChynq0Esqpljxx7CiB+kl/bVs7XkNQQmtGPlh08O7ApJ7AHdKPFFvE+SM2OWpSwUrqJGtmyaU6s+RM66o/3Q0wvKi4y3+Q2jm8nkiWZpPfNt52g4ReE9Ge86o+L+EBOBgZm634L5Z/i6pq908mXBAklPdk1ERdEgWONaOeYYmB70FToplR1gINJEF2CnfAtD/wV+DuQFPDth+EWHqhe3a4xO0d9eJ55ou2QCYOPUC2g/qz1sp7GR74W7P5IWJdmnUEuPFsKJ6OvM+1V8S06jZGDa/QhUGDK8F3G/TMP09W1MsrlQTRr3YQ5H43+pMY7I6Jysze+X9OKZZTTpv4GmYm1USjmraGyMuPF3j9hrlmpttK+1gg2WzytCJO44YsZp9ckls8JNK4bT5uwTuomKZoRgmiIOTcMh4VP7V28TWj2XdF+T6rBFILTvQyXMOzvbe1kLwg2O31JDBdJ8X1fHCYJxKsIrYCSDPz4sha8h7QmHrCSFmjoXb+LUElnbLXZVRkY5/Dc73EM6Es3wAgjwSJK2asRqdqU0PhbS5qpIlgYKsNcb+Wes
16 |
17 | 091116
18 | 2007-10-19T14:58:39.467Z
19 |
20 |
21 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/ebics_technical_nok.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 061001
7 | [EBICS_AUTHENTICATION_FAILED] Authentication signature error
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/haa.xml:
--------------------------------------------------------------------------------
1 |
2 | SIZBN00195149241ead8ae7dbb72cabe966bf0e32017-10-17T19:56:33ZEBICSEBIXEPICS - a ruby ebics kernelHAADZHNNdFAYe281vj9NB7w+VoWIdfHnjY9hNbZLbHsDOu76QAE=dFAYe281vj9NB7w+VoWIdfHnjY9hNbZLbHsDOu76QAE=0000Initialisation
3 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/haa_receipt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SIZBN001
6 |
7 |
8 |
9 | Receipt
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | 0
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/hia_request_order_data.xml:
--------------------------------------------------------------------------------
1 |
2 | phfg5Gv/4wrsGtO2mo33UxciC/DSmw0RdbBhC5vVPsqgmvlDgZ1bpsGWwsXOiBU5BxpbCNvtBLS7jR/4tSgNiDrWmJPLM05ygFKzhyh/8Nd2qtZCt/JaQunsSfNpILm+b9h1ZiuQRnCOsvsJq7eUCrqJnU5Lf/AWWE5g9PlaOcU01NRqJaMRwOI4I+5u01L1JdJ968rXAkhglILSww0yuKdo5qT/CkOPA6u4e4izPxvHPGJ56dd61rRfPKvdrvSuu6gEOzolS6M6uerGD6rIMikMhuQf7R1CG5cLCjGQKDDDp2NaqezWA1rD30RxbIYL23q7VLOV0n673vjiDlarXQ==AQABX0021rkjZF6T4C6694CmiObpwI98k4ngaqDeBpIQV8mn2/REArEjngwanJJbdN51pCy/Sn10ZitqPss4mPpykcTJyNDxOzdZk12wdzIooTiyyMJoI8N+sTWBWlGvT8ER2ZEHObZJAGWqB6sORjTERPqqsQ8+sUNcSoSXfcnMVrbgpbVS/LsgQwlnq2pmsRq35DkVf+03UhYs3QkptzhaQXGFmbDDb4opTxp1ZgJqzl6H+GDDhFA5+xz1C5Pa4OL2jNOCyuRu60wymH1gc6cOmXvYTKyCSVY+k8/wPdq6rF1ylacTEWFhbi+1ZA8RVJPqQzOe6gXxMXFFoKTen1TtkgXm6Q==AQABE002EBICSEBIX
--------------------------------------------------------------------------------
/spec/fixtures/xml/hpb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HOST
6 |
7 |
8 | PARTNER
9 | USER
10 | EPICS - a ruby ebics kernel
11 |
12 | HPB
13 | DZHNN
14 |
15 | 0000
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/hpb_request.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HOST
6 | 014a82626a51ee1cab547bbaf18a13a0
7 | 2014-09-09T09:33:12Z
8 | PARTNER
9 | USER
10 | EPICS - a ruby ebics kernel
11 |
12 | HPB
13 | DZHNN
14 |
15 | 0000
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | 5PL08o8acS8kewViTEeVqSiWZshzNG3QgZehRk1EJgg=
29 |
30 |
31 | d+qgWNti7uCsB/CWreyw9AGQOJiqU+CPPrpgdcisauUvJhFszEJasBeky9TsJXgxVsT27fZaHGnV2pO1YwlBmSuJSGRg5ijHCxbG+XyisIwVAVXY7mlkaO5Ms4eznaW2GCPhiwmIJZOcvzYZwzxtrCbAQFoKA+QgBaAytBtWJiOe8nErnb5s7OEg2D0NvWG4hV+NdcXPlUEKiY5Rw4qCukGXnpZmwMw/L+TB1v47eOLpQa/Dl2oJCjZgV4og3Q2o88adpErnKtIdKic8mb5FLXa2gFK63fmpCcwvs8FPb3kR7/QLWSs4WYycKcXDmgDKnVwYYcBfANEq1yFgReRjzQ==
32 |
33 |
34 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/hpb_response_ebics_ns.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 000000
6 | [EBICS_OK] OK
7 |
8 |
9 |
10 |
11 |
12 | rwIxSUJAVEFDQ0sdYe+CybdspMllDG6ArNtdCzUbT1E=
13 | CPdd6ODXrCxHWpYrwS/5a3NIZ1R2SDscHHJSONc2I7g8ara7qv5Ra7H03W+336DPQLZQxH+EBRWdE2FQ1vrVTcypK6fkFarmO1dEtQt6Ka89AozC7aQMyp4yGl+zlF+XvFkJXZbRXgoEOPsgcG0xM6nKLXnr1ThYRFOoAasigLDGwqxliyhoR94F9dL7YB8Le/uZeRj78mNp4smkE5ZKKyPhwVx+0IW78YuVCSC2c2qbsMmm4evAvycdpLfuuoG4KVlNMIlvkKeBfMZFELcmeKKm85D2zPYkZ7cqG2IfAAp5qdS6K8P7RY4gtjUhOtP5mi8bZt/ZcjioUmIR9dAMnA==
14 |
15 | tPp8sZbGSkjaUy4IoNektKEK1KekTQxLwIZ+AYhyuL99erg26xK1ZcvXd+vJwSfl5TV21qQHybID5CnnP5ZvjcxBdwrK0hyMyp2FYJAY16wLAt++Esydx55XSBvutQASBEnPd01uq3Gd4tPLLbrlBGCDEtqJcfbLEOyWvxYFNDb/HU6RpOCD7JN3jL+LRLsFfrZEK96QO8IzpCtiAYBJ6C3OaHsETt0wBx1lYy7JBSw+nIEEzE6+N3EjJjE3++9BfCDE0ca7kpWCSJ666dUuelPuIS45LjcFbTGROdZ1BTJc6F39Zjxud2yUJIEJINQUZA2O8628gVi2GvoUZuILFx1TsCik1T2ims7EVqkfSNEBpKCa3mtmNMEFepdXNTBm3Kf+J+5ATnqq1EJrYBkGpDPii4jgvVPNIkXJlx5DqqhgUUCShnCLOingwrE+z5ekRM5091iHl1C4APfR05gl0Q81D5HiV9m4CuMjx4Lp7mm0vdgP1LNiaA1BnKIeFob+4SN4Kv7AoP7nxk+3nINMd0yGujsnMx6WgGFn4lvv7IH250+LUZJM4rkdVx9FacxU+P+B6+GDHpLKZyT84WKvPXWnoIhPpykR/Pbysoe+WdAf7cMVp9K5Q5QhfPaMu2eIZjR5+IRIUXxhTo8k2vDG4XBcjgVygP5GJAN83pjXuwdo5JRxyGZAOqvBr7cHmmCG
16 |
17 | 000000
18 | 2007-10-19T14:58:39.467Z
19 |
20 |
21 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/hpb_response_order.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AJ2/0OoIZydb9sgKbiwqDcwA0NtcUMIYi6GK7PqoRszu1uytGnxJjQhGt62kMslWvLgebUSwdq/T3YyGsa3KQeIGaUUn9iqyu3BoNOMdo2DLN4NdGMY1WR/HbYRKR3JHyURhTBKw27KScRRdKGl6jY+VcXcTKJL8PjXMQH5cD6Gz
7 | AQAB
8 |
9 | 2007-03-13T11:33:16.616Z
10 |
11 | X002
12 |
13 |
14 |
15 |
16 | AJ2/0OoIZydb9sgKbiwqDcwA0NtcUMIYi6GK7PqoRszu1uytGnxJjQhGt62kMslWvLgebUSwdq/T3YyGsa3KQeIGaUUn9iqyu3BoNOMdo2DLN4NdGMY1WR/HbYRKR3JHyURhTBKw27KScRRdKGl6jY+VcXcTKJL8PjXMQH5cD6Gz
17 | AQAB
18 |
19 | 2007-03-13T11:33:16.616Z
20 |
21 | E002
22 |
23 | SIZBN001
24 |
25 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/hpb_response_order_without_ns.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | AJ2/0OoIZydb9sgKbiwqDcwA0NtcUMIYi6GK7PqoRszu1uytGnxJjQhGt62kMslWvLgebUSwdq/T3YyGsa3KQeIGaUUn9iqyu3BoNOMdo2DLN4NdGMY1WR/HbYRKR3JHyURhTBKw27KScRRdKGl6jY+VcXcTKJL8PjXMQH5cD6Gz
7 | AQAB
8 |
9 | 2007-03-13T11:33:16.616Z
10 |
11 | X002
12 |
13 |
14 |
15 |
16 | AJ2/0OoIZydb9sgKbiwqDcwA0NtcUMIYi6GK7PqoRszu1uytGnxJjQhGt62kMslWvLgebUSwdq/T3YyGsa3KQeIGaUUn9iqyu3BoNOMdo2DLN4NdGMY1WR/HbYRKR3JHyURhTBKw27KScRRdKGl6jY+VcXcTKJL8PjXMQH5cD6Gz
17 | AQAB
18 |
19 | 2007-03-13T11:33:16.682Z
20 |
21 | E002
22 |
23 | SIZBN001
24 |
25 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/htd_order_data.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Railslove GmbH
6 | Deutschland
7 |
8 |
9 | SIZBN001
10 |
11 |
12 | 1929807319
13 | DE51370501981929807319
14 | 37050198
15 | COLSDE33XXX
16 |
17 |
18 | HTD
19 | Download
20 | Kunden- und Teilnehmerdaten abholen
21 |
22 |
23 | STA
24 | Download
25 | Abholen SWIFT-Tagesauszüge
26 |
27 |
28 | PTK
29 | Download
30 | Abholen Kundenprotokoll
31 |
32 |
33 | HPD
34 | Download
35 | Bankparameter abholen
36 |
37 |
38 | HAC
39 | Download
40 | HAC
41 |
42 |
43 | HAA
44 | Download
45 | Abrufbare Auftragsarten abholen
46 |
47 |
48 | HVT
49 | Download
50 | VEU-Transaktionsdetails abrufen
51 |
52 |
53 | HVU
54 | Download
55 | VEU-Übersicht abholen
56 |
57 |
58 | HVD
59 | Download
60 | VEU-Status abrufen
61 |
62 |
63 | HPB
64 | Download
65 | Abholen Public-Keys der Bank
66 |
67 |
68 | HVZ
69 | Download
70 | VEU-Übersicht mit Zusatzinformationen abholen
71 |
72 |
73 | CCS
74 | Upload
75 | CCS
76 | 1
77 |
78 |
79 | INI
80 | Upload
81 | Passwort-Initialisierung
82 | 1
83 |
84 |
85 | HIA
86 | Upload
87 | Initiales Senden Public Key
88 |
89 |
90 | HCA
91 | Upload
92 | Senden Public Key
93 | 1
94 |
95 |
96 | HSA
97 | Upload
98 | Initiales Senden Public Key
99 | 1
100 |
101 |
102 | SPR
103 | Upload
104 | Sperren der Zugangsberechtigung
105 |
106 |
107 | PUB
108 | Upload
109 | Senden Public Key zur Unterschrift
110 | 1
111 |
112 |
113 | HVE
114 | Upload
115 | VEU-Unterschrift hinzufügen
116 | 1
117 |
118 |
119 | HVS
120 | Upload
121 | VEU-Storno
122 | 1
123 |
124 |
125 | CCT
126 | Upload
127 | Credit Transfer Initiation
128 | 1
129 |
130 |
131 | CIP
132 | Upload
133 | Instant Credit Transfer Initiation
134 | 1
135 |
136 |
137 | CD1
138 | Upload
139 | CD1
140 | 1
141 |
142 |
143 | CDB
144 | Upload
145 | CDB
146 | 1
147 |
148 |
149 | CDD
150 | Upload
151 | Direct Debit Initiation
152 | 1
153 |
154 |
155 |
156 | EBIX
157 | Ebi, Epics
158 |
159 | PTK HPD HTD STA HVD HPB HAA HVT HVU HVZ
160 |
161 |
162 | INI SPR PUB HIA HCA HSA HVE HVS CCS CCT CIP CD1 CDB CDD
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/htd_order_data_without_names.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Railslove GmbH
6 | Deutschland
7 |
8 |
9 | SIZBN001
10 |
11 |
12 | HTD
13 | Download
14 | Kunden- und Teilnehmerdaten abholen
15 |
16 |
17 |
18 | EBIX
19 | Ebi, Epics
20 |
21 | HTD
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/ini_response_h004_ns.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | B004
6 | 000000
7 | [EBICS_OK] OK
8 |
9 |
10 |
11 | 000000
12 |
13 |
14 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/jruby/hia.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | SIZBN001
8 | EBICS
9 | EBIX
10 | EPICS - a ruby ebics kernel
11 |
12 | HIA
13 | DZNNN
14 |
15 | 0000
16 |
17 |
18 |
19 |
20 |
21 | eJzNlEuTqkgQhffzKzqcpTHNQ0A0bG8gIILIW6Td8RIQKKCKh/jrx+ients9cze9mtlVnpMnqyLyi1r9uJXFUx9DlFXgZUI845OnGIRVlIHkZdK1lz/YyY/1b6udzFlx08Wo1WEUQ8Fv/adHEqBHEwTLCibLOMhCtNzhODV5t5bRw03btl5i2DAMz8Ps+dGHkTiOY/gCe/REKEt+n6xXXNemMWiz0G8fzzC6YB+PMrhU69X72fWLLl6vIrS0bO6j/u4lj/ShirqiQ99M1ukloaUeowaIpFYny2o2O97CjMcEuxxwKwo2KU/3roGapOwLITkTQY2k04A8Pdsc6c2tDnitbzeqPb9aGNXaiZYJ8FQqhnrA6THZ7u/pmGKsFpFNe+ZbTPHNDiD7otWyWk6DRUqcs860AK+jHinNPD7ysFHAkVYvGHc6iXSyMApfD484oVmN4h+sQZcpeUp3OKESSqQsGBZ6XJ4mhazaw4CP3T6q6MbB+Fw3OKajYiq7G7d+Z0gKzUQRQ0DrYuz7CPZ21zGJqN+rwmYOTBdDSWCgfMjyQ9qZl7lF8BIdqvxVMveCINSk5jfx/cQRUJjh1i2QX1Vy1sxdVXdxwMxn/TUTCh965svLCvu5krf1iLe6Ag8OvrkfzuQ2b7M+8uu36hMqD+ELSF95c9/pX3s4Tq6wX3v/1D8zKoIQjvX/kVwC5tfzlnEonmEWFF9melAP8oLNKZD4jRBvatl02RKQmCVyULyCZPCBogSRRhM1P2I2IPBz1jYGQlRp1GMeOsqoCTf9Hp1zghyiu1xVTjaOB6WSWW2KnNPmVEi9w4oWeRZ3enBWOOnUbBikW1dHtIymQSY7RUcttCvbu4Tg4MIgqQPXxlSUmEMBGrIukdXMaCF3L1N8dkxf0czM6/ae+qYnbctAEAKqqp1bTZwTpbkXzG4qCUK65ejp7U7wtOFTukpeNZ0fO6tj8GEsd0QSMqFeev2rsx95232d5iw2GFHDwC0xFn7oiKdtGmRT4syxlqsYjXnXYybxbgdvu632TgwIp80Tr2T+U3J/svZBpvhG7b/1z9oXLn3YghjKwlrcyLz9mP+3sDqiD8NbYX8VK+wXf//6T/odHps=
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/jruby/ini.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | SIZBN001
8 | EBICS
9 | EBIX
10 | EPICS - a ruby ebics kernel
11 |
12 | INI
13 | DZNNN
14 |
15 | 0000
16 |
17 |
18 |
19 |
20 |
21 | eJyVU8tyokAU3c9XpJjl1KQbRQMWkuKlPGSEkAhmB+kWEW2gaUDz9WOZyWuySlUv+p57zrmLe658ezzsrzpMm7wkU46/htwVJk8lykk25Vq2+S1yt8oPOcwzkrCWYr9NXXxaUoSpkbDk6iwnzZTbMlZNAOj7/hqn+VNzXdIMhBDy3Atjgj6T+uGFMYAQAiiBMwc1efaTU/6fZJNNqcgv/1Wyb7Eio2ZyF6qv9Xf9z2qvRO2+bb6p5IVRefMo4phUlLHjInvQkeS7YuI6bbJwRkNIrFh3RDdf3vhee0DOKkHNMk0N24ql7RNdxdIpeqBC47Ia7J7NE841elfNjvGc2e6g0FJBtKpkE5l1wKdJCtRcAKvIEBprHei9FomufWpcYq+ru2DNG8QKflnDeDPbhhrZreZUtCFJjUwfCK7WdkUtzXxdLEOQFQE5UPdxNKBot4jCYT0sENODzjsVvTCHffcnmDv7EERHTy9CSDfQgfauX6vhcc+ne0FyBl3XLcK6N5jq+LMkstsCepaVmeNRRny45cfLGvL+zlP99qha1bZekKzzSBgVeG0gVtKNtMOqeaDmAq2RPQP02aK100+nMnhfyWU95rEqCSbsm/tRA1W7eL3qlUv1ISqKfJ8fcMiSQ6UMIC/85uH53fP8hB9PIHyUwXtfBp8y95bK1cupKCqEYxl8gT9An/KbUEYwtQ3F1Gw9PJu/AfJD89qIZfCv+GLzdnDKX0j2PtE=
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/ruby/hia.xml:
--------------------------------------------------------------------------------
1 |
2 | SIZBN001EBICSEBIXEPICS - a ruby ebics kernelHIADZNNN0000eJytlEuTokgUhff9KyqcpTGVgECpYdmBgAgib5Fyx0tAIIFMHuKvH6dquqdqplcTs8t7zs0bGfd8kavvt7J46mOEswq+TshnYvIUw7CKMpi8Trr28vt88n39bbWTOStuuhi3OopiJPit//S4CfEywq+TtG3rJQDDMDwPs+cKJYAiCAIQC/DoiXCW/Db56H6MRHD5aFjGQRbi5Y4g6Ml6xXVtGsM2C/328QyjC/bxKMNLtV59nF2/6OL1KsJLy+a+1Icq6ooOr+v0kjBSD+gBYanVqbKazY63MOOBYJcDYUXBJuWZ3jVwk5R9ISRnMqixdBqwp2ebI7O51QGv9e1GtV+uFqBbO9EyAZ1KxVAPBDMm2/09HVMw1yKqac98CxTf7CC2L1otq+U0WKTkOetMC/I67rHSvMRHHjUKPDLqBXCnk8gkC6Pw9fBIkJrVKP7BGnSZlqdMR5AqqUTKgp0jj8vTpJBVexiIsdtHFdM4gM91g2M7Oqazu3Hrd4akMGwUsSSyLsa+j1Bvdx2biPq9Kmz2wHYxkgQWyYcsP6SdeXmxSF5iQpW/SuZeEISa0vwmvp84EgkzwroF8ptKzZoXV9VdArIvs/6aCYWPPPP1dQU+LfnPhYu3uoKPrNacyW3e3Z/Ke/UlIPAlvq8pux/MrT2CoFbg194/9c9kiDBEY/1feSFRfj1vWYfmWXZB82WmB/UgL+Y5DRO/EeJNLZvuvIQUsEQOiVeYDD5UlCDSGLLmR2BDkjhnbWNgTJdGPeaho4yacNPv0TknqSG6y1XlZON4UCp5rk2xc9qcCql35qJFncWdHpwVTjo1Gxbr1tURLaNpsDmf4qMW2pXtXUJ4cFGQ1IFrAxUn5lDAhqpLbDUzRsjdy5SYHdM3PDPzur2nvulJ2zIQhICuaudWk+dEae4Fu5tKgpBuOWZ6u5M8Y/i0rlJXTefHzupYYhjLHZmEbKiXXv/m7Efedt+m+RwMRtSwaEuOhR864mmbBtmUPHNzy1WMxrzrMZt4t4O33VZ7J4ak0+aJV7L/My9/J/yDB/GdlX/rn7UvNPiohTGShbW4kXn7Mf+nsDriH4a3An8VK/CLf2797Q98eMYK
3 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/ruby/ini.xml:
--------------------------------------------------------------------------------
1 |
2 | SIZBN001EBICSEBIXEPICS - a ruby ebics kernelINIDZNNN0000eJxlUltzmkAUfs+vyNDHTrOLogEHyXBTLlIhJIJ5g+yKiC6wLKD59bVJa2Mzcx72u5yzM+d88sPxsL/tMG3ykkw5/g5yt5i8lign2ZRr2eaHyD0oN3KYZyRhLcV+m7r4tKQIUyNhye25nTQT1Ey5LWPVBIC+7+/64V1JMzCAEAIogbMHNXn2jftwX1lxmr827+4QQp5T/v/JJptSkT/eq2TfYkVGzeQxVK+wV6J23zYKL4zK+xcRx6SijB0X2bOOJN8VE9dpk4UzGkJixbojuvny3vfaA3JWCWqWaWrYVixtX+kqlk7RMxUal9Vg92aecK7Rx2p2jOfMdgeFlgqiVSWbyKwDPk1SoOYCWEWG0FjrQO+1SHTtU+MSe109BmveIFbw3RrGm9k21MhuNaeiDUlqZPpAcLW2K2pp5utiGYKsCMiBui+jAUW7RRQO62GBmB503qnohTnsu5/B3NmHIDp6ehFCuoEOtHf9Wg2Pez7dC5Iz6LpuEda9wVTHnyWR3RbQs6zMHI8y4sMtP17WkPd3nuq3R9WqtvWCZJ1HwqjAawOxkm6kHVbNAzUXaI3sGaBvFq2dfjqVwacl/164eaxKgglT1EDV3tUL846uDvSUH3DIkkOlDCAv/ODhuZ54fsKPJxC+yOCfLoOrS1+ysPoIqKJCOJbBF/oTdZWahDKCqW0opmbr4Xn4hZCfm79CLIM/4MuYS8yVm1/X5hKV
3 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/signature_pub_key_order_data.xml:
--------------------------------------------------------------------------------
1 |
2 | 145o7Z8eXnprttxLgUCd9PK8aKJuaLJ530nHXCJ8KiO7PMumdJVadsObbDIHX9hcrVX9yWUr4sKtq/jzEyeiBrRpFxXGtIK2kBb48HpafWEqQ1bab/Ai4/VWD4sHYQCwBW8KIysKnIYpRQY1DnHQ+H3XfFhSBnjVGr8I0nbDgC24KBuvkq9FPC8oS/gkQnmrKZ52rdjLWS3q3kdtCQvMykw4G0wvNQGJlS/WxMCkS0rf0J0IjwYASxl1bl49J2vvvLSqwDtAJPFaWIuk0MHHgE65gnP0h16Oq01PjMAPuxAHphqLngvMnSWkeYDdtorf9jeAEmrELdYdIF/rzHrqJw==AQAB2014-10-10T11:16:00ZA006EBICSEBIX
--------------------------------------------------------------------------------
/spec/fixtures/xml/sta_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ECD6F062AAEDFA77250526A68CBEC549
6 | 1
7 |
8 |
9 | Initialisation
10 | 1
11 | 000000
12 | [EBICS_OK] OK
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | OnY4VczV+1XfplpMS/SCKFWn+FDMge40X8TJ9pA6HEI=
25 |
26 |
27 | Qiz8clr/Ym+wLpB8CzTuxKP5rgIR2P4SaX8O4gGZx0Di8Lzd4hsBO3koqIuX11NRZo0RYA5E/IKQCoYLepkcM4QHvLT37YidbrXsTZe6cml/yF8OdyRAcd/9U7AoA9GKENFk4lnBFfZYmM4ADK6wVOCE/ABaOk0NeCDDbxrKA75tfTxwxTvQBfUOHZ87LrZxuQf//L9pzmtI07/7GbsQX8ZceQq40SpBFZn/oRvT/Q38Qu2ZO59MZexJn+BTzlhpfv9fQGF/sgXkdhUkPTEW3nL4j7ehasq3CtySGO2RnEppohEvJ4m07RDtEY3OWyAAZoPFVpvnECM6pOLbIuR40w==
28 |
29 |
30 |
31 |
32 | IUW05JB5cuCzRYYa4kIAZ2ehYVrLI3lKvxZvo1uP+ug=
33 | CPdd6ODXrCxHWpYrwS/5a3NIZ1R2SDscHHJSONc2I7g8ara7qv5Ra7H03W+336DPQLZQxH+EBRWdE2FQ1vrVTcypK6fkFarmO1dEtQt6Ka89AozC7aQMyp4yGl+zlF+XvFkJXZbRXgoEOPsgcG0xM6nKLXnr1ThYRFOoAasigLDGwqxliyhoR94F9dL7YB8Le/uZeRj78mNp4smkE5ZKKyPhwVx+0IW78YuVCSC2c2qbsMmm4evAvycdpLfuuoG4KVlNMIlvkKeBfMZFELcmeKKm85D2zPYkZ7cqG2IfAAp5qdS6K8P7RY4gtjUhOtP5mi8bZt/ZcjioUmIR9dAMnA==
34 |
35 | lJ/v1HvOYAZKTPkxULH4mOcUy01+EaAsxLzCPhtieAo9m5AtU5URdyBVfmclHbtWe3ELb02lR37bChynq0Esqpljxx7CiB+kl/bVs7XkNQQmtGPlh08O7ApJ7AHdKPFFvE+SM2OWpSwUrqJGtmyaU6s+RM66o/3Q0wvKi4y3+Q2jm8nkiWZpPfNt52g4ReE9Ge86o+L+EBOBgZm634L5Z/i6pq908mXBAklPdk1ERdEgWONaOeYYmB70FToplR1gINJEF2CnfAtD/wV+DuQFPDth+EWHqhe3a4xO0d9eJ55ou2QCYOPUC2g/qz1sp7GR74W7P5IWJdmnUEuPFsKJ6OvM+1V8S06jZGDa/QhUGDK8F3G/TMP09W1MsrlQTRr3YQ5H43+pMY7I6Jysze+X9OKZZTTpv4GmYm1USjmraGyMuPF3j9hrlmpttK+1gg2WzytCJO44YsZp9ckls8JNK4bT5uwTuomKZoRgmiIOTcMh4VP7V28TWj2XdF+T6rBFILTvQyXMOzvbe1kLwg2O31JDBdJ8X1fHCYJxKsIrYCSDPz4sha8h7QmHrCSFmjoXb+LUElnbLXZVRkY5/Dc73EM6Es3wAgjwSJK2asRqdqU0PhbS5qpIlgYKsNcb+Wes
36 |
37 | 000000
38 | 2013-12-09T15:14:30.000Z
39 |
40 |
41 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/sta_response_continued.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ECD6F062AAEDFA77250526A68CBEC549
6 | 2
7 |
8 |
9 | Initialisation
10 | 1
11 | 000000
12 | [EBICS_OK] OK
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | OnY4VczV+1XfplpMS/SCKFWn+FDMge40X8TJ9pA6HEI=
25 |
26 |
27 | Qiz8clr/Ym+wLpB8CzTuxKP5rgIR2P4SaX8O4gGZx0Di8Lzd4hsBO3koqIuX11NRZo0RYA5E/IKQCoYLepkcM4QHvLT37YidbrXsTZe6cml/yF8OdyRAcd/9U7AoA9GKENFk4lnBFfZYmM4ADK6wVOCE/ABaOk0NeCDDbxrKA75tfTxwxTvQBfUOHZ87LrZxuQf//L9pzmtI07/7GbsQX8ZceQq40SpBFZn/oRvT/Q38Qu2ZO59MZexJn+BTzlhpfv9fQGF/sgXkdhUkPTEW3nL4j7ehasq3CtySGO2RnEppohEvJ4m07RDtEY3OWyAAZoPFVpvnECM6pOLbIuR40w==
28 |
29 |
30 |
31 |
32 | IUW05JB5cuCzRYYa4kIAZ2ehYVrLI3lKvxZvo1uP+ug=
33 | CPdd6ODXrCxHWpYrwS/5a3NIZ1R2SDscHHJSONc2I7g8ara7qv5Ra7H03W+336DPQLZQxH+EBRWdE2FQ1vrVTcypK6fkFarmO1dEtQt6Ka89AozC7aQMyp4yGl+zlF+XvFkJXZbRXgoEOPsgcG0xM6nKLXnr1ThYRFOoAasigLDGwqxliyhoR94F9dL7YB8Le/uZeRj78mNp4smkE5ZKKyPhwVx+0IW78YuVCSC2c2qbsMmm4evAvycdpLfuuoG4KVlNMIlvkKeBfMZFELcmeKKm85D2zPYkZ7cqG2IfAAp5qdS6K8P7RY4gtjUhOtP5mi8bZt/ZcjioUmIR9dAMnA==
34 |
35 | lJ/v1HvOYAZKTPkxULH4mOcUy01+EaAsxLzCPhtieAo9m5AtU5URdyBVfmclHbtWe3ELb02lR37bChynq0Esqpljxx7CiB+kl/bVs7XkNQQmtGPlh08O7ApJ7AHdKPFFvE+SM2OWpSwUrqJGtmyaU6s+RM66o/3Q0wvKi4y3+Q2jm8nkiWZpPfNt52g4ReE9Ge86o+L+EBOBgZm634L5Z/i6pq908mXBAklPdk1ERdEgWONaOeYYmB70FToplR1gINJEF2CnfAtD/wV+DuQFPDth+EWHqhe3a4xO0d9eJ55ou2QCYOPUC2g/qz1sp7GR74W7P5IWJdmnUEuPFsKJ6OvM+1V8S06jZGDa/QhUGDK8F3G/TMP09W1MsrlQTRr3YQ5H43+pMY7I6Jysze+X9OKZZTTpv4GmYm1USjmraGyMuPF3j9hrlmpttK+1gg2WzytCJO44YsZp9ckls8JNK4bT5uwTuomKZoRgmiIOTcMh4VP7V28TWj2XdF+T6rBFILTvQyXMOzvbe1kLwg2O31JDBdJ8X1fHCYJxKsIrYCSDPz4sha8h7QmHrCSFmjoXb+LUElnbLXZVRkY5/Dc73EM6Es3wAgjwSJK2asRqdqU0PhbS5qpIlgYKsNcb+Wes
36 |
37 | 000000
38 | 2013-12-09T15:14:30.000Z
39 |
40 |
41 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/swiss_credit_transfer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SPS-KING/7c332aeb9ec40d29232691
6 | 2024-06-20T17:27:56+02:00
7 | 1
8 | 102.50
9 |
10 | Schuldner GmbH
11 |
12 |
13 |
14 | SPS-KING/7c332aeb9ec40d29232691/1
15 | TRF
16 | false
17 | 1
18 | 102.50
19 |
20 |
21 | SEPA
22 |
23 |
24 | 1999-01-01
25 |
26 | Schuldner GmbH
27 |
28 |
29 |
30 | CH5481230000001998736
31 |
32 |
33 |
34 |
35 | RAIFCH22
36 |
37 |
38 | SLEV
39 |
40 |
41 | NOTPROVIDED
42 |
43 |
44 | 102.50
45 |
46 |
47 |
48 | CRESCHZZ80A
49 |
50 |
51 |
52 | Contoso AG
53 |
54 | Mustergasse
55 | 123a
56 | 1234
57 | Musterstadt
58 | CH
59 |
60 |
61 |
62 |
63 | CH9300762011623852957
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/swiss_direct_debit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SPS-KING/c1e3bcc1a22c941e6c631b
6 | 2024-06-20T17:43:31+02:00
7 | 1
8 | 39.99
9 |
10 | Glaubiger GmbH
11 |
12 |
13 |
14 | ABC1W
15 |
16 |
17 |
18 |
19 |
20 |
21 | SPS-KING/c1e3bcc1a22c941e6c631b/1
22 | DD
23 |
24 |
25 | CHTA
26 |
27 |
28 | LSV+
29 |
30 |
31 | 1999-01-01
32 |
33 | Glaubiger GmbH
34 |
35 |
36 |
37 | CH7081232000001998736
38 |
39 |
40 |
41 |
42 |
43 | 81232
44 |
45 |
46 | 010001456
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | ABC1W
55 |
56 | CHLS
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | 12345
65 | XYZ/2013-08-ABO/6789
66 |
67 | 39.99
68 |
69 |
70 |
71 | 4835
72 |
73 |
74 |
75 |
76 | Zahlemann Soehne GbR
77 |
78 | Mustergasse
79 | 1234
80 | Musterstadt
81 | CH
82 |
83 |
84 |
85 |
86 | CH9804835011062385295
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | ESR
95 |
96 |
97 | [609323234234234353453423423]
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/spec/fixtures/xml/upload_init_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ABF70F5E704E03CFE5B50692BEE55ABA
6 |
7 |
8 | Initialisation
9 | 000000
10 | [EBICS_OK] OK
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | 0/3J0Cne3ncZmTUNZuD8S8HOKI95bo9fP1AvVyVZDfc=
23 |
24 |
25 | J1vtnW2TX3sY9IWnWDcYA2SiZcPwSKq8ap7ESJEfHjDsqDhJV5A3dOo/R4v3LwoMe7CdbWc0AX+KMrcL4FSeQ+CnM776ncQV3OELS83ZkHZzbp15B0cJ9pf3lY9JiEDxKLMeoRjNJlc97Io2iJOW6dO2ZoSPXjF2G4ukQ81P7P8=
26 |
27 |
28 | 000000
29 | 2009-06-16T17:56:05.698+02:00
30 |
31 |
32 |
--------------------------------------------------------------------------------
/spec/generic_upload_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::GenericUploadRequest do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 | let(:document) { "\x01" * 12 }
4 | subject { described_class.new(client, document) }
5 |
6 | describe '#pad' do
7 |
8 | it 'will complete the block to the next 16byte' do
9 | expect(subject.pad("\x01" * 13).size).to eq(16)
10 | end
11 |
12 | it 'will pad a complete block if the size is a multiple of 16' do
13 | expect(subject.pad("\x01" * 16).size).to eq(32)
14 | end
15 |
16 | it 'will set the last byte to the padding length' do
17 | expect(subject.pad("\x01" * 13)[-1]).to eq([3].pack("C*"))
18 | end
19 | end
20 |
21 | describe '#signature_value' do
22 | before { allow(OpenSSL::Random).to receive(:random_bytes).with(16).and_return("\x01" * 16) } # fake random_key requires a 16byte lenght but is not used in this test
23 | before { allow(OpenSSL::Random).to receive(:random_bytes).with(32).and_return(Base64.strict_decode64("7wtROfiX4tyN60cygJUSsHkhzxX1RVJa8vGNYnflvKc=")) } # digest requires 32 bytes
24 |
25 | it 'will be the signed document' do
26 | key = subject.client.a.key
27 |
28 | verification_result = key.verify_pss(
29 | 'SHA256',
30 | Base64.decode64(subject.signature_value),
31 | OpenSSL::Digest::SHA256.new.digest(document),
32 | salt_length: :digest,
33 | mgf1_hash: 'SHA256',
34 | )
35 |
36 | expect(verification_result).to eq(true)
37 | end
38 | end
39 |
40 | describe '#order_signature' do
41 | before { allow(subject).to receive(:signature_value).and_return("FOOBAR") }
42 | let(:signature) { Nokogiri::XML(subject.order_signature) }
43 |
44 | it 'contains the untouched signature_value ' do
45 | expect(signature.at_xpath('//xmlns:SignatureValue').text).to eq("FOOBAR")
46 | end
47 |
48 | end
49 |
50 | describe '#encrypted_order_data' do
51 | it 'returns the same data every time' do
52 | data_1 = subject.encrypted_order_data
53 | data_2 = subject.encrypted_order_data
54 |
55 | expect(data_1).to eq(data_2)
56 | end
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/spec/hpb_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::HPB do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 | describe '#to_xml' do
4 | subject { Nokogiri::XML.parse(described_class.new(client).to_xml) }
5 |
6 | specify do
7 | expect(subject.xpath("//xmlns:Timestamp").first.content).to_not be_nil
8 | expect(subject.xpath("//xmlns:Nonce").first.content).to_not be_nil
9 | expect(subject.xpath("//xmlns:HostID").first.content).to eq("SIZBN001")
10 | expect(subject.xpath("//xmlns:UserID").first.content).to eq("EBIX")
11 | expect(subject.xpath("//xmlns:PartnerID").first.content).to eq("EBICS")
12 | end
13 | end
14 |
15 | end
16 |
--------------------------------------------------------------------------------
/spec/key_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::Key do
2 |
3 | subject { described_class.new( File.read(File.join( File.dirname(__FILE__), 'fixtures', 'e002.pem'))) }
4 |
5 | describe '#public_digest' do
6 |
7 | it 'will calculate the digest as the specification suggests' do
8 | expect(subject.public_digest).to eq("rwIxSUJAVEFDQ0sdYe+CybdspMllDG6ArNtdCzUbT1E=")
9 | end
10 | end
11 |
12 |
13 | describe '#sign' do
14 | let(:dsi) { OpenSSL::Digest::SHA256.new.digest("ruby is great") }
15 |
16 | it 'will generated a digest that can be verified with openssl key.verify_pss' do
17 | signed_digest = subject.sign(dsi)
18 |
19 | key = subject.key
20 |
21 | verification_result = key.verify_pss(
22 | 'SHA256',
23 | Base64.decode64(signed_digest),
24 | dsi,
25 | salt_length: :digest,
26 | mgf1_hash: 'SHA256',
27 | )
28 |
29 | expect(verification_result).to eq(true)
30 | end
31 |
32 | end
33 |
34 |
35 | end
36 |
--------------------------------------------------------------------------------
/spec/middleware/parse_ebics_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | RSpec.describe Epics::ParseEbics do
4 | subject do
5 | Faraday.new do |builder|
6 | builder.use Epics::ParseEbics
7 | builder.adapter :test, Faraday::Adapter::Test::Stubs.new do |stub|
8 | stub.post('/business_nok') { [200, {}, File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'xml', 'ebics_business_nok.xml'))] }
9 | stub.post('/technical_nok') { [200, {}, File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'xml', 'ebics_technical_nok.xml'))] }
10 | stub.post('/ok') { [200, {}, File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'xml', 'hpb_response_ebics_ns.xml'))] }
11 | stub.post('/timeout') { raise Faraday::TimeoutError }
12 | stub.post('/no_connection') { raise Faraday::ConnectionFailed, 'peer has finished all lan parties and gone home' }
13 | end
14 | end
15 | end
16 |
17 | it 'will handle errornous response with raising the related error class' do
18 | expect { subject.post('/business_nok') }.to raise_error(Epics::Error::BusinessError, 'EBICS_PROCESSING_ERROR - During processing of the EBICS request, other business-related errors have ocurred')
19 | expect { subject.post('/technical_nok') }.to raise_error(Epics::Error::TechnicalError, 'EBICS_AUTHENTICATION_FAILED - Authentication signature error')
20 | end
21 |
22 | it 'will parsed as Epics::Response' do
23 | expect(subject.post('/ok').body).to be_kind_of(Epics::Response)
24 | end
25 |
26 | context 'failures' do
27 | it 'will raise a timeout correctly' do
28 | expect { subject.post('/timeout') }.to raise_error(Faraday::TimeoutError, 'timeout')
29 | end
30 |
31 | it 'will properly raise non-epics errors' do
32 | expect { subject.post('/no_connection') }.to raise_error(Faraday::ConnectionFailed, 'peer has finished all lan parties and gone home')
33 | end
34 | end
35 | end
36 |
--------------------------------------------------------------------------------
/spec/orders/azv_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::AZV do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 | let(:document) { 'DTAZV' }
5 |
6 | subject { described_class.new(client, document) }
7 |
8 | describe '#to_xml' do
9 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
10 | end
11 |
12 | describe '#to_transfer_xml' do
13 | before { subject.transaction_id = SecureRandom.hex(16) }
14 |
15 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
16 | end
17 |
18 | end
19 |
--------------------------------------------------------------------------------
/spec/orders/b2b_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::B2B do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cd1.xml') ) }
4 | subject { described_class.new(client, document) }
5 |
6 | describe '#to_xml' do
7 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/orders/bka_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::BKA do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | end
12 |
--------------------------------------------------------------------------------
/spec/orders/c2s_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::C2S do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cdb.xml') ) }
5 | subject { described_class.new(client, document) }
6 |
7 | describe 'order attributes' do
8 | it { expect(subject.header.to_s).to include('DZHNN') }
9 | it { expect(subject.header.to_s).to include('C2S') }
10 | end
11 |
12 | describe '#to_xml' do
13 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
14 | end
15 |
16 | describe '#to_transfer_xml' do
17 | before { subject.transaction_id = SecureRandom.hex(16) }
18 |
19 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/spec/orders/c52_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::C52 do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | end
--------------------------------------------------------------------------------
/spec/orders/c53_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::C53 do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | end
--------------------------------------------------------------------------------
/spec/orders/c54_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::C54 do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 |
4 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
5 |
6 | describe '#to_xml' do
7 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/orders/c5n_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::C5N do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 |
4 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-01") }
5 |
6 | describe '#to_xml' do
7 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/orders/ccs_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::CCS do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cd1.xml') ) }
5 | subject { described_class.new(client, document) }
6 |
7 | describe 'order attributes' do
8 | it { expect(subject.header.to_s).to include('DZHNN') }
9 | it { expect(subject.header.to_s).to include('CCS') }
10 | end
11 |
12 | describe '#to_xml' do
13 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
14 | end
15 |
16 | describe '#to_transfer_xml' do
17 | before { subject.transaction_id = SecureRandom.hex(16) }
18 |
19 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/spec/orders/cct_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::CCT do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cd1.xml') ) }
5 | subject { described_class.new(client, document) }
6 |
7 | describe 'order attributes' do
8 | it { expect(subject.header.to_s).to include('OZHNN') }
9 | it { expect(subject.header.to_s).to include('CCT') }
10 | end
11 |
12 | describe '#to_xml' do
13 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
14 | end
15 |
16 | describe '#to_transfer_xml' do
17 | before { subject.transaction_id = SecureRandom.hex(16) }
18 |
19 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/spec/orders/cd1_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::CD1 do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cd1.xml') ) }
5 | subject { described_class.new(client, document) }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | describe '#to_transfer_xml' do
12 | before { subject.transaction_id = SecureRandom.hex(16) }
13 |
14 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
15 | end
16 |
17 | end
--------------------------------------------------------------------------------
/spec/orders/cdb_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::CDB do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cdb.xml') ) }
5 | subject { described_class.new(client, document) }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | describe '#to_transfer_xml' do
12 | before { subject.transaction_id = SecureRandom.hex(16) }
13 |
14 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
15 | end
16 |
17 | end
18 |
--------------------------------------------------------------------------------
/spec/orders/cdd_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::CDD do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cd1.xml') ) }
5 | subject { described_class.new(client, document) }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | describe '#to_transfer_xml' do
12 | before { subject.transaction_id = SecureRandom.hex(16) }
13 |
14 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
15 | end
16 |
17 | end
--------------------------------------------------------------------------------
/spec/orders/cdz_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::CDZ do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 |
4 | context 'with date range' do
5 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 |
10 | it 'does includes a date range as standard order parameter' do
11 | expect(subject.to_xml).to include('2014-09-012014-09-30')
12 | end
13 | end
14 | end
15 |
16 | context 'without date range' do
17 | subject { described_class.new(client) }
18 |
19 | describe '#to_xml' do
20 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
21 |
22 | it 'does not include a standard order parameter' do
23 | expect(subject.to_xml).to include('')
24 | end
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/spec/orders/cip_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::CIP do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cip.xml') ) }
5 | subject { described_class.new(client, document) }
6 |
7 | describe 'order attributes' do
8 | it { expect(subject.header.to_s).to include('OZHNN') }
9 | it { expect(subject.header.to_s).to include('CIP') }
10 | end
11 |
12 | describe '#to_xml' do
13 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
14 | end
15 |
16 | describe '#to_transfer_xml' do
17 | before { subject.transaction_id = SecureRandom.hex(16) }
18 |
19 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
20 | end
21 |
22 | end
23 |
24 |
--------------------------------------------------------------------------------
/spec/orders/crz_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::CRZ do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 |
4 | context 'with date range' do
5 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 |
10 | it 'does includes a date range as standard order parameter' do
11 | expect(subject.to_xml).to include('2014-09-012014-09-30')
12 | end
13 | end
14 | end
15 |
16 | context 'without date range' do
17 | subject { described_class.new(client) }
18 |
19 | describe '#to_xml' do
20 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
21 |
22 | it 'does not include a standard order parameter' do
23 | expect(subject.to_xml).to include('')
24 | end
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/spec/orders/fdl_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::FDL do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 | let(:file_format) { 'camt.xxx.cfonb120.stm.Oby' }
4 |
5 | context 'with file_format' do
6 | subject(:order) { described_class.new(client, file_format: file_format) }
7 |
8 | describe '#to_xml' do
9 | specify { expect(order.to_xml).to be_a_valid_ebics_doc }
10 |
11 | it 'does includes a date range as standard order parameter' do
12 | expect(order.to_xml).to include('camt.xxx.cfonb120.stm.Oby')
13 | end
14 | end
15 |
16 | describe '#to_receipt_xml' do
17 | before { order.transaction_id = SecureRandom.hex(16) }
18 |
19 | specify { expect(order.to_receipt_xml).to be_a_valid_ebics_doc }
20 | end
21 |
22 | context 'with DateRange' do
23 | subject(:order) { described_class.new(client, file_format: file_format, from: Date.new(2024, 1, 1), to: Date.new(2024, 1, 2)) }
24 |
25 | describe '#to_xml' do
26 | specify { expect(order.to_xml).to be_a_valid_ebics_doc }
27 |
28 | it 'does includes a date range as optional order parameter' do
29 | expect(order.to_xml).to include('2024-01-012024-01-02camt.xxx.cfonb120.stm.Oby')
30 | end
31 | end
32 |
33 | describe '#to_receipt_xml' do
34 | before { order.transaction_id = SecureRandom.hex(16) }
35 |
36 | specify { expect(order.to_receipt_xml).to be_a_valid_ebics_doc }
37 | end
38 | end
39 | end
40 |
41 | context 'without file_format' do
42 | subject(:order) { described_class.new(client) }
43 |
44 | describe '#to_xml' do
45 | specify { expect(order.to_xml).to be_a_valid_ebics_doc }
46 |
47 | it 'does not include a standard order parameter' do
48 | expect(order.to_xml).to include('')
49 | end
50 | end
51 |
52 | describe '#to_receipt_xml' do
53 | before { order.transaction_id = SecureRandom.hex(16) }
54 |
55 | specify { expect(order.to_receipt_xml).to be_a_valid_ebics_doc }
56 | end
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/spec/orders/ful_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::FUL do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cd1.xml') ) }
4 |
5 | subject { described_class.new(client, document, file_format: 'pain.001.001.02') }
6 |
7 | describe 'order attributes' do
8 | it { expect(subject.header.to_s).to include('DZHNN') }
9 | it { expect(subject.header.to_s).to include('FUL') }
10 | it { expect(subject.header.to_s).to include('pain.001.001.02') }
11 | end
12 |
13 | describe '#to_xml' do
14 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
15 | end
16 |
17 | describe '#to_transfer_xml' do
18 | before { subject.transaction_id = SecureRandom.hex(16) }
19 |
20 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
21 | end
22 | end
--------------------------------------------------------------------------------
/spec/orders/haa_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::HAA do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client) }
6 |
7 | before do
8 | allow(subject).to receive(:nonce) { "95149241ead8ae7dbb72cabe966bf0e3" }
9 | allow(subject).to receive(:timestamp) { "2017-10-17T19:56:33Z" }
10 | end
11 |
12 | describe '#to_xml' do
13 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
14 |
15 | describe 'validate against fixture' do
16 | let(:signature_order_data) { Nokogiri::XML(File.read(File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'haa.xml'))) }
17 |
18 | it "will match exactly" do
19 | expect(Nokogiri::XML(subject.to_xml)).to be_equivalent_to(signature_order_data)
20 | end
21 | end
22 | end
23 |
24 | describe '#to_receipt_xml' do
25 | describe 'validate against fixture' do
26 | let(:signature_order_data) { Nokogiri::XML(File.read(File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'haa_receipt.xml'))) }
27 |
28 | it "will match exactly" do
29 | expect(Nokogiri::XML(subject.to_receipt_xml)).to be_equivalent_to(signature_order_data)
30 | end
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/spec/orders/hac_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::HAC do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 |
4 | context 'with date range' do
5 | subject(:order) { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
6 |
7 | describe '#to_xml' do
8 | specify { expect(order.to_xml).to be_a_valid_ebics_doc }
9 |
10 | it 'does includes a date range as standard order parameter' do
11 | expect(order.to_xml).to include('2014-09-012014-09-30')
12 | end
13 | end
14 |
15 | describe '#to_receipt_xml' do
16 | before { order.transaction_id = SecureRandom.hex(16) }
17 |
18 | specify { expect(order.to_receipt_xml).to be_a_valid_ebics_doc }
19 | end
20 | end
21 |
22 | context 'without date range' do
23 | subject(:order) { described_class.new(client) }
24 |
25 | describe '#to_xml' do
26 | specify { expect(order.to_xml).to be_a_valid_ebics_doc }
27 |
28 | it 'does not include a standard order parameter' do
29 | expect(order.to_xml).to include('')
30 | end
31 | end
32 |
33 | describe '#to_receipt_xml' do
34 | before { order.transaction_id = SecureRandom.hex(16) }
35 |
36 | specify { expect(order.to_receipt_xml).to be_a_valid_ebics_doc }
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/spec/orders/hev_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::HEV do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | let(:xsd) { Nokogiri::XML::Schema(File.open( File.join( File.dirname(__FILE__), '..', 'xsd', 'ebics_hev.xsd') )) }
6 | let(:validator) { xsd.valid?(Nokogiri::XML(subject.to_xml)) }
7 |
8 | subject { described_class.new(client) }
9 |
10 | describe '#to_xml' do
11 | specify { expect(validator).to be_truthy }
12 | end
13 |
14 | end
15 |
--------------------------------------------------------------------------------
/spec/orders/hia_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::HIA do
2 | let(:client) { Epics::Client.new(key, 'secret', 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 | let(:key) { File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')) }
4 |
5 | subject { described_class.new(client) }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 |
10 | describe 'validate against fixture' do
11 | let(:hia) do
12 | Nokogiri::XML(File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'xml', RUBY_ENGINE, 'hia.xml')))
13 | end
14 |
15 | it 'will match exactly' do
16 | expect(Nokogiri::XML(subject.to_xml)).to be_equivalent_to(hia)
17 | end
18 | end
19 | end
20 |
21 | describe '#order_data' do
22 | specify { expect(subject.order_data).to be_a_valid_ebics_doc }
23 |
24 | describe 'validate against fixture' do
25 | let(:hia_request_order_data) do
26 | Nokogiri::XML(File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'xml',
27 | 'hia_request_order_data.xml')))
28 | end
29 |
30 | it 'will match exactly' do
31 | expect(Nokogiri::XML(subject.order_data)).to be_equivalent_to(hia_request_order_data)
32 | end
33 | end
34 |
35 | context 'with x509 certificate' do
36 | let(:client) do
37 | client = Epics::Client.new(key, 'secret', 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS')
38 | client.x_509_certificates_content = {
39 | x: generate_x_509_crt(client.x.key, '/C=GB/O=TestOrg/CN=test.example.org'),
40 | e: generate_x_509_crt(client.e.key, '/C=GB/O=TestOrg/CN=test.example.org')
41 | }
42 | client
43 | end
44 |
45 | it 'includes x509 certificate' do
46 | x_crt = Epics::X509Certificate.new(client.x_509_certificates_content[:x])
47 | e_crt = Epics::X509Certificate.new(client.x_509_certificates_content[:e])
48 | expect(subject.order_data).to include('/C=GB/O=TestOrg/CN=test.example.org')
49 | expect(subject.order_data).to include('2')
50 | expect(subject.order_data).to include("#{x_crt.data}")
51 | expect(subject.order_data).to include("#{e_crt.data}")
52 | end
53 | end
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/spec/orders/hkd_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::HKD do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client) }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | end
--------------------------------------------------------------------------------
/spec/orders/hpb_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::HPB do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client) }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | end
--------------------------------------------------------------------------------
/spec/orders/hpd_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::HPD do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client) }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | end
--------------------------------------------------------------------------------
/spec/orders/htd_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::HTD do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client) }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | end
--------------------------------------------------------------------------------
/spec/orders/ini_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::INI do
2 | let(:client) { Epics::Client.new(key, 'secret', 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 | let(:key) { File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')) }
4 | before { allow(subject).to receive(:timestamp) { '2014-10-10T11:16:00Z' } }
5 |
6 | subject { described_class.new(client) }
7 |
8 | describe '#to_xml' do
9 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
10 |
11 | describe 'validate against fixture' do
12 | let(:signature_order_data) do
13 | Nokogiri::XML(File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'xml', RUBY_ENGINE, 'ini.xml')))
14 | end
15 |
16 | it 'will match exactly' do
17 | expect(Nokogiri::XML(subject.to_xml)).to be_equivalent_to(signature_order_data)
18 | end
19 | end
20 | end
21 |
22 | describe '#key_signature' do
23 | specify { expect(subject.key_signature).to be_a_valid_ebics_doc }
24 |
25 | describe 'validate against fixture' do
26 | let(:signature_order_data) do
27 | Nokogiri::XML(File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', 'xml',
28 | 'signature_pub_key_order_data.xml')))
29 | end
30 |
31 | it 'will match exactly' do
32 | expect(Nokogiri::XML(subject.key_signature)).to be_equivalent_to(signature_order_data)
33 | end
34 | end
35 |
36 | context 'with x509 certificate' do
37 | let(:client) do
38 | client = Epics::Client.new(key, 'secret', 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS')
39 | client.x_509_certificates_content = {a: generate_x_509_crt(client.a.key, '/C=GB/O=TestOrg/CN=test.example.org')}
40 | client
41 | end
42 |
43 | it 'includes x509 certificate' do
44 | a_crt = Epics::X509Certificate.new(client.x_509_certificates_content[:a])
45 | expect(subject.key_signature).to include('/C=GB/O=TestOrg/CN=test.example.org')
46 | expect(subject.key_signature).to include('2')
47 | expect(subject.key_signature).to include("#{a_crt.data}")
48 | end
49 | end
50 | end
51 | end
52 |
--------------------------------------------------------------------------------
/spec/orders/ptk_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::PTK do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 |
4 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
5 |
6 | describe '#to_xml' do
7 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/orders/sta_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::STA do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 |
4 | context 'with date range' do
5 | subject(:order) { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
6 |
7 | describe '#to_xml' do
8 | specify { expect(order.to_xml).to be_a_valid_ebics_doc }
9 |
10 | it 'does includes a date range as standard order parameter' do
11 | expect(order.to_xml).to include('2014-09-012014-09-30')
12 | end
13 | end
14 |
15 | describe '#to_receipt_xml' do
16 | before { order.transaction_id = SecureRandom.hex(16) }
17 |
18 | specify { expect(order.to_receipt_xml).to be_a_valid_ebics_doc }
19 | end
20 | end
21 |
22 | context 'without date range' do
23 | subject(:order) { described_class.new(client) }
24 |
25 | describe '#to_xml' do
26 | specify { expect(order.to_xml).to be_a_valid_ebics_doc }
27 |
28 | it 'does not include a standard order parameter' do
29 | expect(order.to_xml).to include('')
30 | end
31 | end
32 |
33 | describe '#to_receipt_xml' do
34 | before { order.transaction_id = SecureRandom.hex(16) }
35 |
36 | specify { expect(order.to_receipt_xml).to be_a_valid_ebics_doc }
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/spec/orders/vmk_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::VMK do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 |
4 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
5 |
6 | describe '#to_xml' do
7 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/orders/wss_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::WSS do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 |
4 | subject { described_class.new(client) }
5 |
6 | describe '#to_xml' do
7 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/orders/x_509_certificate_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::X509Certificate do
2 | subject(:x_509_certificate) { described_class.new(crt_content) }
3 |
4 | let(:key) { OpenSSL::PKey::RSA.new(2048) }
5 | let(:crt_content) { generate_x_509_crt(key, distinguished_name) }
6 | let(:distinguished_name) { '/C=GB/O=TestOrg/CN=test.example.org' }
7 |
8 | describe '#issuer' do
9 | it 'returns the issuer of the certificate' do
10 | expect(x_509_certificate.issuer.to_s).to eq(distinguished_name)
11 | end
12 | end
13 |
14 | describe '#version' do
15 | it 'returns the version of the certificate' do
16 | expect(x_509_certificate.version).to eq(2)
17 | end
18 | end
19 |
20 | describe '#data' do
21 | it 'returns the base64 encoded certificate data' do
22 | expect(x_509_certificate.data).to start_with('MIIDDzCCAfegAwIBAgIBATANBgkqhkiG9w0BA')
23 | expect(x_509_certificate.data).to end_with('==')
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/spec/orders/xds_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::XDS do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'cd1.xml') ) }
4 | subject { described_class.new(client, document) }
5 |
6 | describe '#to_xml' do
7 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
8 | end
9 |
10 | describe '#to_transfer_xml' do
11 | before { subject.transaction_id = SecureRandom.hex(16) }
12 |
13 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/orders/xe2_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::XE2 do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'swiss_credit_transfer.xml') ) }
5 | subject { described_class.new(client, document) }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | describe '#to_transfer_xml' do
12 | before { subject.transaction_id = SecureRandom.hex(16) }
13 |
14 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
15 | end
16 |
17 | end
18 |
--------------------------------------------------------------------------------
/spec/orders/xe3_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::XE3 do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 | let(:document) { File.read( File.join( File.dirname(__FILE__), '..', 'fixtures', 'xml', 'swiss_direct_debit.xml') ) }
5 | subject { described_class.new(client, document) }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | describe '#to_transfer_xml' do
12 | before { subject.transaction_id = SecureRandom.hex(16) }
13 |
14 | specify { expect(subject.to_transfer_xml).to be_a_valid_ebics_doc }
15 | end
16 |
17 | end
18 |
--------------------------------------------------------------------------------
/spec/orders/z01_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::Z01 do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | end
12 |
--------------------------------------------------------------------------------
/spec/orders/z52_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::Z52 do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | end
12 |
--------------------------------------------------------------------------------
/spec/orders/z53_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::Z53 do
2 |
3 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
4 |
5 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
6 |
7 | describe '#to_xml' do
8 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
9 | end
10 |
11 | end
12 |
--------------------------------------------------------------------------------
/spec/orders/z54_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::Z54 do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), '..', 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 |
4 | subject { described_class.new(client, from: "2014-09-01", to: "2014-09-30") }
5 |
6 | describe '#to_xml' do
7 | specify { expect(subject.to_xml).to be_a_valid_ebics_doc }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/response_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::Response do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 | subject { described_class.new( client, ebics_response ) }
4 |
5 | describe '#digest_valid?' do
6 | let(:ebics_response) { File.read('spec/fixtures/xml/upload_init_response.xml') }
7 |
8 | it 'checks if //ds:DigestValue matches the calculated digest' do
9 | expect(subject.digest_valid?).to be(true)
10 | end
11 | end
12 |
13 | describe '#technical_code' do
14 | let(:ebics_response) { File.read('spec/fixtures/xml/ini_response_h004_ns.xml') }
15 |
16 | it 'is extracted from the response' do
17 | expect(subject.technical_code).to eq("000000")
18 | end
19 | end
20 |
21 | describe '#business_code' do
22 | let(:ebics_response) { File.read('spec/fixtures/xml/ebics_business_nok.xml') }
23 |
24 | it 'is extracted from the response' do
25 | expect(subject.business_code).to eq("091116")
26 | end
27 | end
28 |
29 | describe '#signature_valid?' do
30 | let(:ebics_response) { File.read('spec/fixtures/xml/upload_init_response.xml') }
31 |
32 | it 'checks if the signature value can be verified with the bank key' do
33 | expect(subject.signature_valid?).to be(true)
34 | end
35 | end
36 |
37 | describe '#public_digest_valid?' do
38 | let(:ebics_response) { File.read('spec/fixtures/xml/hpb_response_ebics_ns.xml') }
39 |
40 | it "checks if //xmlns:EncryptionPubKeyDigest matches the user encryption key" do
41 | expect(subject.public_digest_valid?).to be(true)
42 | end
43 | end
44 |
45 | describe 'order_data' do
46 | let(:ebics_response) { File.read('spec/fixtures/xml/hpb_response_ebics_ns.xml') }
47 | let(:order_data) { File.read('spec/fixtures/xml/hpb_response_order.xml') }
48 |
49 | it "retrieves the decrypted order data" do
50 | expect(subject.order_data).to eq(order_data)
51 | end
52 | end
53 |
54 | describe '#report_text' do
55 | let(:ebics_response) { File.read('spec/fixtures/xml/sta_response.xml') }
56 | it 'pulls the report_text from the response' do
57 | expect(subject.report_text).to eq('[EBICS_OK] OK')
58 | end
59 | end
60 |
61 | describe '#transaction_id' do
62 | let(:ebics_response) { File.read('spec/fixtures/xml/sta_response.xml') }
63 | it 'pulls the transaction_id from the response' do
64 | expect(subject.transaction_id).to eq('ECD6F062AAEDFA77250526A68CBEC549')
65 | end
66 | end
67 |
68 | describe '#order_id' do
69 | let(:ebics_response) { File.read('spec/fixtures/xml/cd1_init_response.xml') }
70 | it 'pulls the order_id from the response' do
71 | expect(subject.order_id).to eq('N00L')
72 | end
73 | end
74 |
75 | describe '#last_segment?' do
76 | describe 'when its the last segement' do
77 | let(:ebics_response) { File.read('spec/fixtures/xml/sta_response.xml') }
78 |
79 | it 'will be true' do
80 | expect(subject.last_segment?).to be(true)
81 | end
82 | end
83 |
84 | describe 'when there are more segments' do
85 | let(:ebics_response) { File.read('spec/fixtures/xml/sta_response_continued.xml') }
86 | it 'will be false' do
87 | expect(subject.last_segment?).to be(false)
88 | end
89 | end
90 | end
91 |
92 | describe '#segmented?' do
93 | describe 'when the response is segemnted' do
94 | let(:ebics_response) { File.read('spec/fixtures/xml/sta_response.xml') }
95 |
96 | it 'will be true' do
97 | expect(subject.segmented?).to be(true)
98 | end
99 | end
100 |
101 | describe 'when the response is not segemnted' do
102 | let(:ebics_response) { File.read('spec/fixtures/xml/hpb_response_ebics_ns.xml') }
103 |
104 | it 'will be false' do
105 | expect(subject.segmented?).to be(false)
106 | end
107 | end
108 | end
109 |
110 | end
111 |
--------------------------------------------------------------------------------
/spec/signer_spec.rb:
--------------------------------------------------------------------------------
1 | RSpec.describe Epics::Signer do
2 | let(:client) { Epics::Client.new( File.open(File.join( File.dirname(__FILE__), 'fixtures', 'SIZBN001.key')), 'secret' , 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') }
3 | let(:hpb) { Epics::HPB.new(client) }
4 |
5 | before do
6 | allow(hpb).to receive(:nonce) { "014a82626a51ee1cab547bbaf18a13a0" }
7 | allow(hpb).to receive(:timestamp) { "2014-09-09T09:33:12Z" }
8 | subject.digest!
9 | subject.sign!
10 | end
11 |
12 | subject { described_class.new(client, hpb.to_xml) }
13 |
14 | describe '#digest!' do
15 | it 'creates a digest of the *[authorized=true] nodes' do
16 | expect(subject.digest_node.content).to eq("iXchWJ3xMy508YBhzx0Fn9cYNyyAiS+X8CB8zb7tyfM=")
17 | end
18 |
19 | it 'bar' do
20 | expect(Epics::Response.new(client, subject.doc.to_xml(save_with: 32)).digest_valid?).to be(true)
21 | end
22 | end
23 |
24 | describe '#sign!' do
25 | it 'signs the complete ds:SignedInfo node' do
26 | expect(subject.doc.xpath("//ds:SignatureValue").first.content).to eq("o6G7zeU6IhEkQ51Mp5/aIhPcYiZAG1rERxFad+rVdbRCYJGUn6/BNath1cdTgoHQ+ZWn9+Y6IgFsKUYFp8QHrhYBJNhd38fi5wj2Eqv+J4nsfmSD9x6YFa8Q13cJ9/CakHp/C59bgFSJj77BzRFUPnW1Y1NuHj8n1OJ3iFTyF1vF6H6oRKHoE4cbK4jhD3f6udRvGglhW5J+TUFBM+2aE8njpzBZFjyQlct+5XUx3o+1GvaMUk5riH5sCQ95PAKuGTXFu0OLZvECDMA3kOia/l3VF09QUGsjxYF0jUn5WG6TnLy8+Odrh9tUgV9bS/swSeQ41Cah4Ehb0qTYFZoJ+w==")
27 | end
28 |
29 | it 'can be verified with the same key' do
30 | expect(client.x.key.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(subject.doc.xpath("//ds:SignatureValue").first.content), subject.signature_node.canonicalize)).to be(true)
31 | end
32 | end
33 |
34 | end
35 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2 | $LOAD_PATH.unshift(File.dirname(__FILE__))
3 |
4 | require 'rspec'
5 | require 'epics'
6 | require 'webmock/rspec'
7 | require 'rspec/matchers' # req by equivalent-xml custom matcher `be_equivalent_to`
8 | require 'equivalent-xml'
9 |
10 | Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
11 |
12 | RSpec.configure do |config|
13 | # rspec-expectations config goes here. You can use an alternate
14 | # assertion/expectation library such as wrong or the stdlib/minitest
15 | # assertions if you prefer.
16 | config.expect_with :rspec do |expectations|
17 | # This option will default to `true` in RSpec 4. It makes the `description`
18 | # and `failure_message` of custom matchers include text for helper methods
19 | # defined using `chain`, e.g.:
20 | # be_bigger_than(2).and_smaller_than(4).description
21 | # # => "be bigger than 2 and smaller than 4"
22 | # ...rather than:
23 | # # => "be bigger than 2"
24 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true
25 | end
26 |
27 | # rspec-mocks config goes here. You can use an alternate test double
28 | # library (such as bogus or mocha) by changing the `mock_with` option here.
29 | config.mock_with :rspec do |mocks|
30 | # Prevents you from mocking or stubbing a method that does not exist on
31 | # a real object. This is generally recommended, and will default to
32 | # `true` in RSpec 4.
33 | mocks.verify_partial_doubles = true
34 | end
35 |
36 | config.order = :random
37 |
38 | Kernel.srand config.seed
39 |
40 | if config.files_to_run.one?
41 | config.default_formatter = 'doc'
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/spec/support/ebics_matcher.rb:
--------------------------------------------------------------------------------
1 | RSpec::Matchers.define :be_a_valid_ebics_doc do
2 |
3 | ##
4 | # use #open instead of #read to have the includes working
5 | # http://stackoverflow.com/questions/11996326/nokogirixmlschema-syntaxerror-on-schema-load/22971456#22971456
6 | def xsd
7 | @xsd ||= Nokogiri::XML::Schema(File.open( File.join( File.dirname(__FILE__), '..', 'xsd', 'ebics_H004.xsd') ))
8 | end
9 |
10 | match do |actual|
11 | xsd.valid?(Nokogiri::XML(actual))
12 | end
13 |
14 | failure_message do |actual|
15 | "expected that #{actual} would be a valid EBICS doc:\n\n #{xsd.validate(Nokogiri::XML(actual))}"
16 | end
17 |
18 | description do
19 | "be a valid EBICS document"
20 | end
21 |
22 | end
--------------------------------------------------------------------------------
/spec/support/x_509_crt_generator.rb:
--------------------------------------------------------------------------------
1 | def generate_x_509_crt(key, distinguished_name)
2 | name = OpenSSL::X509::Name.parse(distinguished_name)
3 |
4 | cert = OpenSSL::X509::Certificate.new
5 | cert.version = 2
6 | cert.serial = 1
7 | cert.subject = name
8 | cert.issuer = name
9 | cert.public_key = key.public_key
10 | cert.not_before = Time.now
11 | cert.not_after = cert.not_before + 365 * 24 * 60 * 60
12 |
13 | ef = OpenSSL::X509::ExtensionFactory.new
14 | ef.subject_certificate = cert
15 | ef.issuer_certificate = cert
16 | cert.add_extension(ef.create_extension("basicConstraints", "CA:FALSE", true))
17 | cert.add_extension(ef.create_extension("keyUsage", "digitalSignature,keyEncipherment,nonRepudiation", true))
18 |
19 | cert.sign(key, OpenSSL::Digest::SHA256.new)
20 |
21 | cert.to_pem
22 | end
--------------------------------------------------------------------------------
/spec/xsd/ebics_H004.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ebics_H004.xsd inkludiert alle Schemadateien des EBICS-Protokolls, um die Eindeutigkeit von Element- und Typnamen im EBCIS Namespace zu erzwingen.
5 | ebics_H004.xsd includes all schema files for the EBICS protocol in order to enforce unique element and type names in the EBICS namespace.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/spec/xsd/ebics_hev.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ebics_hev.xsd ist das EBICS-Protokollschema entweder für Anfragen oder Rückmeldungen der Bank zu unterstützten EBICS-Versionen.
5 | ebics_hev.xsd is the appropriate EBICS protocol schema either for requests or responses according the EBICS versions supported by a bank.
6 |
7 |
8 |
9 | Datentyp für die Host-ID.
10 | Dataype for Host-ID.
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Datentyp für allgemeine Auftragsarten (Grundtyp).
19 | Datatype for general order types (basic type).
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Datentyp für Antwortcodes.
29 | Datatype for the return code
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | Datentyp für den Erklärungstext zum Antwortcode.
39 | Datatype for report text with respect to the return code
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | Datentyp für eine Versionsnummer
48 | Datatype for a release number
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Datentyp für Versionsnummer des EBICS-schemas
58 | Datatype for release-number of the EBICS scheme
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | Datentyp für technische Fehler.
68 | Datatype for technical error
69 |
70 |
71 |
72 |
73 | Rückmeldung des Ausführungsstatus mit einer eindeutigen Fehlernummer.
74 | Confirmation of the carried out status with a unique error code.
75 |
76 |
77 |
78 |
79 | Klartext der Rückmeldung des Ausführungsstatus.
80 | Clear text of the response (carried out status).
81 |
82 |
83 |
84 |
85 |
86 |
87 | Datentyp für die Request-Daten
88 | Data type for Request data
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | Datentyp für die Response-Daten
98 | Data type for Request data
99 |
100 |
101 |
102 |
103 |
104 | Von der Bank unterstützte EBICS-Versionen, z.B. 2.4
105 | EBICS-releases supported by the bank, e.g. 2.4
106 |
107 |
108 |
109 |
110 |
111 |
112 | der EBICS-Version eindeutig zugeordnete Schema-Version, z.B. H003
113 | EBICS-scheme-version, e.g. H003, well-defined for EBICS-release-Version
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 | Requestdaten
126 | request data
127 |
128 |
129 |
130 |
131 | Responsedaten
132 | response data
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/spec/xsd/ebics_keymgmt_response_H004.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ebics_keymgmt_response_H004.xsd ist das EBICS-Protokollschema für Schlüsselmanagement-Antwortnachrichten (HIA, HPB, HSA, INI).
6 |
7 |
8 |
9 | XML-Signature.
10 |
11 |
12 |
13 |
14 |
15 |
16 | Electronic Banking Internet Communication Standard des Zentralen Kreditausschusses (ZKA): Multibankfähige Schnittstelle zur internetbasierten Kommunikation.
17 |
18 |
19 |
20 |
21 |
22 | enthält die technischen Transaktionsdaten.
23 |
24 |
25 |
26 |
27 |
28 | enhält alle festen Headereinträge.
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | enthält alle variablen Headereinträge.
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | enthält die Auftragsdaten und den fachlichen ReturnCode.
46 |
47 |
48 |
49 |
50 |
51 | Transfer von Auftragsdaten; nur bei Download anzugeben (HPB).
52 |
53 |
54 |
55 |
56 |
57 | Informationen zur Verschlüsselung der Auftragsdaten
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | enthält Auftragsdaten.
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | Antwortcode für den vorangegangenen Transfer.
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | Zeitstempel der letzten Aktualisierung der Bankparameter; nur in der Initialisierungsphase anzugeben.
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | Datentyp für den variablen EBICS-Header.
117 |
118 |
119 |
120 |
121 | Auftragsnummer von Sendeaufträgen gemäß DFÜ-Abkommen (used for all key management order types except download order type HPB).
122 |
123 |
124 |
125 |
126 | Rückmeldung des Ausführungsstatus mit einer eindeutigen Fehlernummer.
127 |
128 |
129 |
130 |
131 | Klartext der Rückmeldung des Ausführungsstatus.
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------