sepafm 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +6 -0
- data/.travis.yml +1 -1
- data/lib/sepa/application_request.rb +30 -31
- data/lib/sepa/attribute_checks.rb +44 -15
- data/lib/sepa/banks/danske/danske_response.rb +21 -0
- data/lib/sepa/banks/danske/soap_danske.rb +7 -18
- data/lib/sepa/banks/nordea/nordea_response.rb +13 -0
- data/lib/sepa/banks/nordea/soap_nordea.rb +3 -63
- data/lib/sepa/banks/op/op_response.rb +76 -0
- data/lib/sepa/banks/op/soap_op.rb +14 -0
- data/lib/sepa/certificates/op_root_certificate.cer +30 -0
- data/lib/sepa/client.rb +20 -26
- data/lib/sepa/response.rb +28 -7
- data/lib/sepa/soap_builder.rb +65 -8
- data/lib/sepa/utilities.rb +8 -21
- data/lib/sepa/version.rb +1 -1
- data/lib/sepa/wsdl/wsdl_op_cert_production.xml +156 -0
- data/lib/sepa/wsdl/wsdl_op_cert_test.xml +157 -0
- data/lib/sepa/wsdl/wsdl_op_production.xml +234 -0
- data/lib/sepa/wsdl/wsdl_op_test.xml +234 -0
- data/lib/sepa/xml_schemas/op/ApplicationRequest_20080918.xsd +135 -0
- data/lib/sepa/xml_schemas/op/ApplicationResponse_20080918.xsd +311 -0
- data/lib/sepa/xml_schemas/op/CertApplicationRequest_200812.xsd +105 -0
- data/lib/sepa/xml_schemas/op/CertApplicationResponse_200812.xsd +88 -0
- data/lib/sepa/xml_templates/application_request/{create_certificate.xml → danske/create_certificate.xml} +8 -8
- data/lib/sepa/xml_templates/application_request/{danske_get_bank_certificate.xml → danske/get_bank_certificate.xml} +3 -3
- data/lib/sepa/xml_templates/application_request/download_file.xml +10 -11
- data/lib/sepa/xml_templates/application_request/download_file_list.xml +9 -10
- data/lib/sepa/xml_templates/application_request/nordea/get_certificate.xml +11 -0
- data/lib/sepa/xml_templates/application_request/op/get_certificate.xml +12 -0
- data/lib/sepa/xml_templates/application_request/op/get_service_certificates.xml +10 -0
- data/lib/sepa/xml_templates/soap/{create_certificate.xml → danske/create_certificate.xml} +6 -6
- data/lib/sepa/xml_templates/soap/{danske_get_bank_certificate.xml → danske/get_bank_certificate.xml} +5 -5
- data/lib/sepa/xml_templates/soap/nordea/get_certificate.xml +15 -0
- data/lib/sepa/xml_templates/soap/op/get_certificate.xml +14 -0
- data/lib/sepa/xml_templates/soap/op/get_service_certificates.xml +14 -0
- data/lib/sepafm.rb +36 -0
- data/readme.md +9 -6
- data/sepafm.gemspec +8 -8
- data/test/custom_assertions.rb +20 -0
- data/test/sepa/banks/op/op_application_request_test.rb +63 -0
- data/test/sepa/banks/op/op_cert_application_request_test.rb +77 -0
- data/test/sepa/banks/op/op_cert_request_soap_builder_test.rb +62 -0
- data/test/sepa/banks/op/op_generic_soap_builder_test.rb +52 -0
- data/test/sepa/banks/op/op_response_test.rb +13 -0
- data/test/sepa/client_test.rb +35 -1
- data/test/sepa/fixtures.rb +82 -0
- data/test/sepa/sepa_test.rb +1 -1
- data/test/test_helper.rb +1 -0
- data/test_client/data/certs_example.rb +9 -0
- data/test_client/data/params_example.rb +110 -0
- data/test_client/test_client.rb +61 -0
- metadata +42 -12
- data/lib/sepa/xml_templates/application_request/get_certificate.xml +0 -11
- data/lib/sepa/xml_templates/soap/get_certificate.xml +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6baff59782f24a508d2560a71b776fcb5374d598
|
4
|
+
data.tar.gz: 85b220374605d706461e301fc477574481635e31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38454e6cac847fa6e23de5785b3e2db8c134a486ac8d124b8ca0b5e8f12c24b6a3bc4181541de0dad43135430d7a15c51cf16b0e76821d8ad3d0fbfde75489f0
|
7
|
+
data.tar.gz: de324888c9ea1b78f817b688ffbffacc11bcc4f1496cc3a9e48f22d2955e8db07aa02b0b356ca4ed7844b9e875e95e51bba71ed992faaa35ba8907f6c37aa5b1
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -80,27 +80,16 @@ module Sepa
|
|
80
80
|
|
81
81
|
# Determines which content setting method to call depending on {#command}
|
82
82
|
def set_nodes_contents
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
when :get_certificate
|
87
|
-
set_get_certificate_nodes
|
88
|
-
when :download_file_list
|
89
|
-
set_download_file_list_nodes
|
90
|
-
when :download_file
|
91
|
-
set_download_file_nodes
|
92
|
-
when :upload_file
|
93
|
-
set_upload_file_nodes
|
94
|
-
when :get_bank_certificate
|
95
|
-
set_get_bank_certificate_nodes
|
96
|
-
end
|
83
|
+
method = "set_#{@command}_nodes"
|
84
|
+
|
85
|
+
send(method) if self.class.private_method_defined? method
|
97
86
|
end
|
98
87
|
|
99
88
|
# Sets nodes' values for download file request
|
100
89
|
def set_download_file_nodes
|
101
90
|
add_target_id_after 'FileReferences'
|
102
91
|
set_node("Status", @status)
|
103
|
-
|
92
|
+
add_node_to_root 'FileType', content: @file_type if @file_type.present?
|
104
93
|
set_node("FileReference", @file_reference)
|
105
94
|
end
|
106
95
|
|
@@ -129,17 +118,20 @@ module Sepa
|
|
129
118
|
def set_download_file_list_nodes
|
130
119
|
add_target_id_after 'Environment'
|
131
120
|
set_node("Status", @status)
|
132
|
-
|
121
|
+
add_node_to_root 'FileType', content: @file_type if @file_type.present?
|
133
122
|
end
|
134
123
|
|
135
|
-
# Sets nodes' contents for Nordea's get certificate request
|
136
|
-
#
|
137
|
-
# @todo Raise error if {#bank} is other than Nordea like in {#set_get_bank_certificate_nodes}
|
138
|
-
# @todo Check further into what service actually is
|
124
|
+
# Sets nodes' contents for Nordea's and OP's get certificate request
|
139
125
|
def set_get_certificate_nodes
|
140
|
-
set_node
|
141
|
-
set_node
|
142
|
-
set_node
|
126
|
+
set_node "Service", "MATU" if @bank == :op
|
127
|
+
set_node "TransferKey", @pin if @bank == :op
|
128
|
+
set_node "HMAC", hmac(@pin, csr_to_binary(@signing_csr)) if @bank == :nordea
|
129
|
+
set_node "Content", format_cert_request(@signing_csr)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Sets nodes' contents for OP's get service certificates request
|
133
|
+
def set_service_certificates_nodes
|
134
|
+
set_node("Service", "MATU")
|
143
135
|
end
|
144
136
|
|
145
137
|
# Sets nodes' contents for Danske Bank's create certificate request. Environment is set to
|
@@ -182,11 +174,15 @@ module Sepa
|
|
182
174
|
@application_request.at_css("xmlns|#{node}", 'xmlns' => xmlns).remove
|
183
175
|
end
|
184
176
|
|
185
|
-
# Adds node to the root of the application request
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
177
|
+
# Adds node to the root of the application request and content to it if specified
|
178
|
+
def add_node_to_root(node, content: nil)
|
179
|
+
unless node.is_a? Nokogiri::XML::Node
|
180
|
+
node = Nokogiri::XML::Node.new node, @application_request
|
181
|
+
end
|
182
|
+
|
183
|
+
@application_request.root.add_child node
|
184
|
+
|
185
|
+
set_node(node.name, content) if content
|
190
186
|
end
|
191
187
|
|
192
188
|
# Calculates the digest of {#application_request}
|
@@ -228,9 +224,12 @@ module Sepa
|
|
228
224
|
# {#own_signing_certificate} to the signature node.
|
229
225
|
def process_signature
|
230
226
|
# No signature for Certificate Requests
|
231
|
-
return if
|
232
|
-
|
233
|
-
|
227
|
+
return if %i(
|
228
|
+
create_certificate
|
229
|
+
get_bank_certificate
|
230
|
+
get_certificate
|
231
|
+
get_service_certificates
|
232
|
+
).include? @command
|
234
233
|
|
235
234
|
signature_node = remove_node('Signature', 'http://www.w3.org/2000/09/xmldsig#')
|
236
235
|
digest = calculate_digest
|
@@ -11,10 +11,22 @@ module Sepa
|
|
11
11
|
def allowed_commands
|
12
12
|
case bank
|
13
13
|
when :nordea
|
14
|
-
|
14
|
+
STANDARD_COMMANDS +
|
15
|
+
%i(get_certificate)
|
15
16
|
when :danske
|
16
|
-
|
17
|
-
|
17
|
+
STANDARD_COMMANDS -
|
18
|
+
%i(get_user_info) +
|
19
|
+
%i(
|
20
|
+
create_certificate
|
21
|
+
get_bank_certificate
|
22
|
+
)
|
23
|
+
when :op
|
24
|
+
STANDARD_COMMANDS -
|
25
|
+
%i(get_user_info) +
|
26
|
+
%i(
|
27
|
+
get_certificate
|
28
|
+
get_service_certificates
|
29
|
+
)
|
18
30
|
else
|
19
31
|
[]
|
20
32
|
end
|
@@ -27,7 +39,12 @@ module Sepa
|
|
27
39
|
|
28
40
|
# Checks that signing keys and certificates can be initialized properly.
|
29
41
|
def check_keys
|
30
|
-
return if
|
42
|
+
return if %i(
|
43
|
+
create_certificate
|
44
|
+
get_bank_certificate
|
45
|
+
get_certificate
|
46
|
+
get_service_certificates
|
47
|
+
).include? command
|
31
48
|
|
32
49
|
begin
|
33
50
|
rsa_key signing_private_key
|
@@ -62,22 +79,34 @@ module Sepa
|
|
62
79
|
|
63
80
|
# Checks that {Client#file_type} is proper
|
64
81
|
def check_file_type
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
82
|
+
if file_type.present?
|
83
|
+
valid = file_type.size < 35
|
84
|
+
else
|
85
|
+
return if bank == :op && %i(download_file
|
86
|
+
download_file_list).include?(command)
|
87
|
+
|
88
|
+
valid = !(%i(
|
89
|
+
download_file
|
90
|
+
download_file_list
|
91
|
+
upload_file
|
92
|
+
).include? command)
|
69
93
|
end
|
94
|
+
|
95
|
+
errors.add(:file_type, FILE_TYPE_ERROR_MESSAGE) unless valid
|
70
96
|
end
|
71
97
|
|
72
98
|
# Checks that {Client#target_id} is valid.
|
73
99
|
def check_target_id
|
74
|
-
return if
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
100
|
+
return if %i(
|
101
|
+
create_certificate
|
102
|
+
get_bank_certificate
|
103
|
+
get_certificate
|
104
|
+
get_user_info
|
105
|
+
).include?(command) ||
|
106
|
+
%i(
|
107
|
+
danske
|
108
|
+
op
|
109
|
+
).include?(bank)
|
81
110
|
|
82
111
|
check_presence_and_length(:target_id, 80, TARGET_ID_ERROR_MESSAGE)
|
83
112
|
end
|
@@ -106,6 +106,27 @@ module Sepa
|
|
106
106
|
return super unless [:get_bank_certificate, :create_certificate].include? @command
|
107
107
|
|
108
108
|
node = doc.at('xmlns|ReturnCode', xmlns: DANSKE_PKI)
|
109
|
+
node = doc.at('xmlns|ReturnCode', xmlns: DANSKE_PKIF) unless node
|
110
|
+
|
111
|
+
node.content if node
|
112
|
+
end
|
113
|
+
|
114
|
+
# Extract response text from the response. Overrides super method when {#command} is
|
115
|
+
# `:get_bank_certificate` or `:create_certificate` because response text node is named
|
116
|
+
# differently in those responses.
|
117
|
+
#
|
118
|
+
# @return [String] if response text is found
|
119
|
+
# @return [nil] if response text cannot be found
|
120
|
+
# @see Response#response_text
|
121
|
+
def response_text
|
122
|
+
return super unless %i(
|
123
|
+
create_certificate
|
124
|
+
get_bank_certificate
|
125
|
+
).include? @command
|
126
|
+
|
127
|
+
node = doc.at('xmlns|ReturnText', xmlns: DANSKE_PKI)
|
128
|
+
node = doc.at('xmlns|ReturnText', xmlns: DANSKE_PKIF) unless node
|
129
|
+
|
109
130
|
node.content if node
|
110
131
|
end
|
111
132
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Sepa
|
2
|
-
|
2
|
+
|
3
3
|
# Contains Danske Bank specific soap building functionality
|
4
4
|
module DanskeSoapRequest
|
5
5
|
|
@@ -85,21 +85,6 @@ module Sepa
|
|
85
85
|
ar
|
86
86
|
end
|
87
87
|
|
88
|
-
# Sets contents for generic request's nodes. Generic requests are:
|
89
|
-
# * Upload file
|
90
|
-
# * Download file
|
91
|
-
# * Download file list
|
92
|
-
#
|
93
|
-
# @todo make ReceiverId dynamic
|
94
|
-
def set_generic_request_contents
|
95
|
-
set_node(@template, 'bxd|SenderId', @customer_id)
|
96
|
-
set_node(@template, 'bxd|RequestId', request_id)
|
97
|
-
set_node(@template, 'bxd|Timestamp', iso_time)
|
98
|
-
set_node(@template, 'bxd|Language', @language)
|
99
|
-
set_node(@template, 'bxd|UserAgent', "Sepa Transfer Library version " + VERSION)
|
100
|
-
set_node(@template, 'bxd|ReceiverId', "DABAFIHH")
|
101
|
-
end
|
102
|
-
|
103
88
|
# Sets contents for create certificate requests.
|
104
89
|
#
|
105
90
|
# @todo rename
|
@@ -132,7 +117,8 @@ module Sepa
|
|
132
117
|
#
|
133
118
|
# @return [Nokogiri::XML] the complete soap
|
134
119
|
def build_danske_generic_request
|
135
|
-
|
120
|
+
common_set_body_contents
|
121
|
+
set_receiver_id
|
136
122
|
encrypted_request = encrypt_application_request
|
137
123
|
add_encrypted_generic_request_to_soap(encrypted_request)
|
138
124
|
|
@@ -204,10 +190,13 @@ module Sepa
|
|
204
190
|
# Generates a random 10-character request id for Danske Bank's requests.
|
205
191
|
#
|
206
192
|
# @return [String] 10-character hexnumeric request id
|
207
|
-
# @todo move to utilities
|
208
193
|
def request_id
|
209
194
|
SecureRandom.hex(5)
|
210
195
|
end
|
211
196
|
|
197
|
+
def set_receiver_id
|
198
|
+
set_node(@template, 'bxd|ReceiverId', 'DABAFIHH')
|
199
|
+
end
|
200
|
+
|
212
201
|
end
|
213
202
|
end
|
@@ -33,6 +33,19 @@ module Sepa
|
|
33
33
|
node.content if node
|
34
34
|
end
|
35
35
|
|
36
|
+
# Returns the response text in the response. Overrides {Response#response_text} if {#command} is
|
37
|
+
# `:get_certificate`, because the namespace is different with that command.
|
38
|
+
#
|
39
|
+
# @return [String] response text if it is found
|
40
|
+
# @return [nil] if response text cannot be found
|
41
|
+
# @see Response#response_text
|
42
|
+
def response_text
|
43
|
+
return super unless command == :get_certificate
|
44
|
+
|
45
|
+
node = doc.at('xmlns|ResponseText', xmlns: NORDEA_PKI)
|
46
|
+
node.content if node
|
47
|
+
end
|
48
|
+
|
36
49
|
# Checks whether the certificate embedded in the response soap has been signed with Nordea's
|
37
50
|
# root certificate.
|
38
51
|
#
|
@@ -1,74 +1,14 @@
|
|
1
1
|
module Sepa
|
2
|
-
|
3
2
|
# Contains Nordea specific soap building functionality
|
4
3
|
module NordeaSoapRequest
|
5
|
-
|
6
4
|
private
|
7
5
|
|
8
|
-
|
9
|
-
# differently than generic requests.
|
10
|
-
#
|
11
|
-
# @return [Nokogiri::XML] the soap as a nokogiri document
|
12
|
-
def find_correct_build
|
13
|
-
case @command
|
14
|
-
when :get_certificate
|
15
|
-
build_certificate_request
|
16
|
-
when :get_user_info, :download_file_list, :download_file, :upload_file
|
17
|
-
build_common_request
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# Sets contents for certificate request
|
22
|
-
#
|
23
|
-
# @return [Nokogiri::XML] the template with contents added to it
|
24
|
-
def build_certificate_request
|
25
|
-
set_body_contents
|
26
|
-
end
|
27
|
-
|
28
|
-
# Sets soap body contents. Application request is base64 encoded here.
|
29
|
-
#
|
30
|
-
# @return [Nokogiri::XML] the soap with contents added to it
|
31
|
-
# @todo rename, because apparently only sets certificate contents
|
32
|
-
def set_body_contents
|
33
|
-
set_node(@template, 'cer|ApplicationRequest', @application_request.to_base64)
|
34
|
-
set_node(@template, 'cer|SenderId', @customer_id)
|
35
|
-
set_node(@template, 'cer|RequestId', request_id)
|
36
|
-
set_node(@template, 'cer|Timestamp', iso_time)
|
37
|
-
|
38
|
-
@template
|
39
|
-
end
|
40
|
-
|
41
|
-
# Builds generic request which is a request made with commands:
|
42
|
-
# * Get User Info
|
43
|
-
# * Download File
|
44
|
-
# * Download File List
|
45
|
-
# * Upload File
|
46
|
-
#
|
47
|
-
# @return [Nokogiri::XML] the generic request soap
|
48
|
-
def build_common_request
|
49
|
-
common_set_body_contents
|
50
|
-
process_header
|
51
|
-
add_body_to_header
|
52
|
-
end
|
53
|
-
|
54
|
-
# Sets nodes for generic requests, application request is base64 encoded here.
|
55
|
-
def common_set_body_contents
|
56
|
-
set_node(@template, 'bxd|ApplicationRequest', @application_request.to_base64)
|
57
|
-
set_node(@template, 'bxd|SenderId', @customer_id)
|
58
|
-
set_node(@template, 'bxd|RequestId', request_id)
|
59
|
-
set_node(@template, 'bxd|Timestamp', iso_time)
|
60
|
-
set_node(@template, 'bxd|Language', @language)
|
61
|
-
set_node(@template, 'bxd|UserAgent', "Sepa Transfer Library version #{VERSION}")
|
6
|
+
def set_receiver_id
|
62
7
|
set_node(@template, 'bxd|ReceiverId', @target_id)
|
63
8
|
end
|
64
9
|
|
65
|
-
|
66
|
-
|
67
|
-
# @return [String] hexnumeric request id
|
68
|
-
# @todo move to utilities
|
69
|
-
def request_id
|
70
|
-
SecureRandom.hex(17)
|
10
|
+
def cert_ns
|
11
|
+
NORDEA_PKI
|
71
12
|
end
|
72
|
-
|
73
13
|
end
|
74
14
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Sepa
|
2
|
+
# Handles OP specific response logic. Mainly certificate specific stuff.
|
3
|
+
class OpResponse < Response
|
4
|
+
include Utilities
|
5
|
+
|
6
|
+
# Extracts own signing certificate from the response.
|
7
|
+
#
|
8
|
+
# @return [String] own signing certificate as string it it is found
|
9
|
+
# @return [nil] if the certificate cannot be found
|
10
|
+
def own_signing_certificate
|
11
|
+
application_response = extract_application_response(OP_PKI)
|
12
|
+
at = 'xmlns|Certificate > xmlns|Certificate'
|
13
|
+
node = Nokogiri::XML(application_response).at(at, xmlns: OP_XML_DATA)
|
14
|
+
|
15
|
+
return unless node
|
16
|
+
|
17
|
+
cert_value = process_cert_value node.content
|
18
|
+
cert = x509_certificate cert_value
|
19
|
+
cert.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the response code in the response. Overrides {Response#response_code} if {#command} is
|
23
|
+
# `:get_certificate`, because the namespace is different with that command.
|
24
|
+
#
|
25
|
+
# @return [String] response code if it is found
|
26
|
+
# @return [nil] if response code cannot be found
|
27
|
+
# @see Response#response_code
|
28
|
+
def response_code
|
29
|
+
return super unless %i(
|
30
|
+
get_certificate
|
31
|
+
get_service_certificates
|
32
|
+
).include? command
|
33
|
+
|
34
|
+
node = doc.at('xmlns|ResponseCode', xmlns: OP_PKI)
|
35
|
+
node.content if node
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns the response text in the response. Overrides {Response#response_text} if {#command} is
|
39
|
+
# `:get_certificate`, because the namespace is different with that command.
|
40
|
+
#
|
41
|
+
# @return [String] response text if it is found
|
42
|
+
# @return [nil] if response text cannot be found
|
43
|
+
# @see Response#response_text
|
44
|
+
def response_text
|
45
|
+
return super unless %i(
|
46
|
+
get_certificate
|
47
|
+
get_service_certificates
|
48
|
+
).include? command
|
49
|
+
|
50
|
+
node = doc.at('xmlns|ResponseText', xmlns: OP_PKI)
|
51
|
+
node.content if node
|
52
|
+
end
|
53
|
+
|
54
|
+
# Checks whether the certificate embedded in the response soap has been signed with OP's
|
55
|
+
# root certificate. The check is skipped in test environment, because a different root
|
56
|
+
# certificate is used
|
57
|
+
#
|
58
|
+
# @return [true] if certificate is trusted
|
59
|
+
# @return [false] if certificate fails to verify
|
60
|
+
# @see DanskeResponse#certificate_is_trusted?
|
61
|
+
def certificate_is_trusted?
|
62
|
+
return true if environment == :test
|
63
|
+
verify_certificate_against_root_certificate(certificate, OP_ROOT_CERTIFICATE)
|
64
|
+
end
|
65
|
+
|
66
|
+
# OP's get service certificates response isn't signed
|
67
|
+
def validate_hashes
|
68
|
+
super unless command == :get_service_certificates
|
69
|
+
end
|
70
|
+
|
71
|
+
# OP's get service certificates response isn't signed
|
72
|
+
def verify_signature
|
73
|
+
super unless command == :get_service_certificates
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
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
|
30
|
+
-----END CERTIFICATE-----
|
data/lib/sepa/client.rb
CHANGED
@@ -165,7 +165,11 @@ module Sepa
|
|
165
165
|
attr_accessor :encryption_csr
|
166
166
|
|
167
167
|
# The list of banks that are currently supported by this gem
|
168
|
-
BANKS =
|
168
|
+
BANKS = %i(
|
169
|
+
danske
|
170
|
+
nordea
|
171
|
+
op
|
172
|
+
)
|
169
173
|
|
170
174
|
# Languages that are currently supported by the gem
|
171
175
|
LANGUAGES = ['FI', 'SE', 'EN']
|
@@ -256,7 +260,7 @@ module Sepa
|
|
256
260
|
response &&= response.to_xml
|
257
261
|
rescue Savon::Error => e
|
258
262
|
response = nil
|
259
|
-
error = e.
|
263
|
+
error = e.http.body
|
260
264
|
end
|
261
265
|
|
262
266
|
initialize_response(error, response)
|
@@ -293,22 +297,16 @@ module Sepa
|
|
293
297
|
# Returns path to WSDL file according to {#bank} and {#command}
|
294
298
|
# @return [String] Path to the WSDL file of the bank and command
|
295
299
|
def wsdl
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
if [:get_bank_certificate, :create_certificate].include? command
|
305
|
-
file = "wsdl_danske_cert.xml"
|
306
|
-
else
|
307
|
-
file = "wsdl_danske.xml"
|
308
|
-
end
|
309
|
-
end
|
300
|
+
file = if STANDARD_COMMANDS.include?(command)
|
301
|
+
"wsdl_#{bank}"
|
302
|
+
else
|
303
|
+
"wsdl_#{bank}_cert"
|
304
|
+
end
|
305
|
+
|
306
|
+
path = "#{WSDL_PATH}/#{file}"
|
307
|
+
path2 = "#{path}_#{environment}.xml"
|
310
308
|
|
311
|
-
"#{
|
309
|
+
File.exist?(path2) ? path2 : "#{path}.xml"
|
312
310
|
end
|
313
311
|
|
314
312
|
# Initializes {Response} as correct class for a bank. Also converts possible
|
@@ -319,20 +317,16 @@ module Sepa
|
|
319
317
|
# @return [Response] A {Response} with a correct class for a bank
|
320
318
|
def initialize_response(error, response)
|
321
319
|
options = {
|
322
|
-
|
323
|
-
|
324
|
-
|
320
|
+
command: command,
|
321
|
+
environment: environment,
|
322
|
+
error: error,
|
323
|
+
response: response
|
325
324
|
}
|
326
325
|
if encryption_private_key && !encryption_private_key.empty?
|
327
326
|
options[:encryption_private_key] = rsa_key(encryption_private_key)
|
328
327
|
end
|
329
328
|
|
330
|
-
|
331
|
-
when :nordea
|
332
|
-
NordeaResponse.new options
|
333
|
-
when :danske
|
334
|
-
DanskeResponse.new options
|
335
|
-
end
|
329
|
+
"Sepa::#{bank.capitalize}Response".constantize.new(options)
|
336
330
|
end
|
337
331
|
|
338
332
|
end
|
data/lib/sepa/response.rb
CHANGED
@@ -23,6 +23,11 @@ module Sepa
|
|
23
23
|
# @return [Symbol]
|
24
24
|
attr_reader :command
|
25
25
|
|
26
|
+
# The environment in which the request was sent
|
27
|
+
#
|
28
|
+
# @return [Symbol]
|
29
|
+
attr_reader :environment
|
30
|
+
|
26
31
|
validate :document_must_validate_against_schema
|
27
32
|
validate :client_errors
|
28
33
|
validate :validate_response_code
|
@@ -41,10 +46,11 @@ module Sepa
|
|
41
46
|
# encryption_private_key: OpenSSL::PKey::RSA
|
42
47
|
# }
|
43
48
|
def initialize(hash = {})
|
44
|
-
@
|
45
|
-
@command = hash[:command]
|
46
|
-
@error = hash[:error]
|
49
|
+
@command = hash[:command]
|
47
50
|
@encryption_private_key = hash[:encryption_private_key]
|
51
|
+
@environment = hash[:environment]
|
52
|
+
@error = hash[:error]
|
53
|
+
@soap = hash[:response]
|
48
54
|
end
|
49
55
|
|
50
56
|
# Returns the soap of the response as a Nokogiri document
|
@@ -54,6 +60,13 @@ module Sepa
|
|
54
60
|
@doc ||= xml_doc @soap
|
55
61
|
end
|
56
62
|
|
63
|
+
# Returns the error of the response as a Nokogiri document
|
64
|
+
#
|
65
|
+
# @return [Nokogiri::XML] The error as Nokogiri document
|
66
|
+
def error_doc
|
67
|
+
@error_doc ||= xml_doc @error
|
68
|
+
end
|
69
|
+
|
57
70
|
# Verifies that all digest values in the response match the actual ones. Takes an optional
|
58
71
|
# verbose parameter to show which digests didn't match. The digest embedded in the document are
|
59
72
|
# first retrieved with {#find_digest_values} method and if none are found, false is returned.
|
@@ -197,6 +210,17 @@ module Sepa
|
|
197
210
|
# @return [nil] if the response code cannot be found
|
198
211
|
def response_code
|
199
212
|
node = doc.at('xmlns|ResponseCode', xmlns: BXD)
|
213
|
+
node = error_doc.at('xmlns|ResponseCode', xmlns: BXD) unless node
|
214
|
+
node.content if node
|
215
|
+
end
|
216
|
+
|
217
|
+
# Returns the response text of the response
|
218
|
+
#
|
219
|
+
# @return [String] if the response text can be found
|
220
|
+
# @return [nil] if the response text cannot be found
|
221
|
+
def response_text
|
222
|
+
node = doc.at('xmlns|ResponseText', xmlns: BXD)
|
223
|
+
node = error_doc.at('xmlns|ResponseText', xmlns: BXD) unless node
|
200
224
|
node.content if node
|
201
225
|
end
|
202
226
|
|
@@ -272,12 +296,9 @@ module Sepa
|
|
272
296
|
end
|
273
297
|
|
274
298
|
# Validates response code in response. "00" and "24" are currently considered valid.
|
275
|
-
# Validation is not run if {#error} is present
|
276
299
|
def validate_response_code
|
277
|
-
return if @error
|
278
|
-
|
279
300
|
unless %w(00 24).include? response_code
|
280
|
-
errors.add(:base,
|
301
|
+
errors.add(:base, { response_code: response_code, response_text: response_text })
|
281
302
|
end
|
282
303
|
end
|
283
304
|
|