sepafm 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -0
  3. data/.travis.yml +1 -1
  4. data/lib/sepa/application_request.rb +30 -31
  5. data/lib/sepa/attribute_checks.rb +44 -15
  6. data/lib/sepa/banks/danske/danske_response.rb +21 -0
  7. data/lib/sepa/banks/danske/soap_danske.rb +7 -18
  8. data/lib/sepa/banks/nordea/nordea_response.rb +13 -0
  9. data/lib/sepa/banks/nordea/soap_nordea.rb +3 -63
  10. data/lib/sepa/banks/op/op_response.rb +76 -0
  11. data/lib/sepa/banks/op/soap_op.rb +14 -0
  12. data/lib/sepa/certificates/op_root_certificate.cer +30 -0
  13. data/lib/sepa/client.rb +20 -26
  14. data/lib/sepa/response.rb +28 -7
  15. data/lib/sepa/soap_builder.rb +65 -8
  16. data/lib/sepa/utilities.rb +8 -21
  17. data/lib/sepa/version.rb +1 -1
  18. data/lib/sepa/wsdl/wsdl_op_cert_production.xml +156 -0
  19. data/lib/sepa/wsdl/wsdl_op_cert_test.xml +157 -0
  20. data/lib/sepa/wsdl/wsdl_op_production.xml +234 -0
  21. data/lib/sepa/wsdl/wsdl_op_test.xml +234 -0
  22. data/lib/sepa/xml_schemas/op/ApplicationRequest_20080918.xsd +135 -0
  23. data/lib/sepa/xml_schemas/op/ApplicationResponse_20080918.xsd +311 -0
  24. data/lib/sepa/xml_schemas/op/CertApplicationRequest_200812.xsd +105 -0
  25. data/lib/sepa/xml_schemas/op/CertApplicationResponse_200812.xsd +88 -0
  26. data/lib/sepa/xml_templates/application_request/{create_certificate.xml → danske/create_certificate.xml} +8 -8
  27. data/lib/sepa/xml_templates/application_request/{danske_get_bank_certificate.xml → danske/get_bank_certificate.xml} +3 -3
  28. data/lib/sepa/xml_templates/application_request/download_file.xml +10 -11
  29. data/lib/sepa/xml_templates/application_request/download_file_list.xml +9 -10
  30. data/lib/sepa/xml_templates/application_request/nordea/get_certificate.xml +11 -0
  31. data/lib/sepa/xml_templates/application_request/op/get_certificate.xml +12 -0
  32. data/lib/sepa/xml_templates/application_request/op/get_service_certificates.xml +10 -0
  33. data/lib/sepa/xml_templates/soap/{create_certificate.xml → danske/create_certificate.xml} +6 -6
  34. data/lib/sepa/xml_templates/soap/{danske_get_bank_certificate.xml → danske/get_bank_certificate.xml} +5 -5
  35. data/lib/sepa/xml_templates/soap/nordea/get_certificate.xml +15 -0
  36. data/lib/sepa/xml_templates/soap/op/get_certificate.xml +14 -0
  37. data/lib/sepa/xml_templates/soap/op/get_service_certificates.xml +14 -0
  38. data/lib/sepafm.rb +36 -0
  39. data/readme.md +9 -6
  40. data/sepafm.gemspec +8 -8
  41. data/test/custom_assertions.rb +20 -0
  42. data/test/sepa/banks/op/op_application_request_test.rb +63 -0
  43. data/test/sepa/banks/op/op_cert_application_request_test.rb +77 -0
  44. data/test/sepa/banks/op/op_cert_request_soap_builder_test.rb +62 -0
  45. data/test/sepa/banks/op/op_generic_soap_builder_test.rb +52 -0
  46. data/test/sepa/banks/op/op_response_test.rb +13 -0
  47. data/test/sepa/client_test.rb +35 -1
  48. data/test/sepa/fixtures.rb +82 -0
  49. data/test/sepa/sepa_test.rb +1 -1
  50. data/test/test_helper.rb +1 -0
  51. data/test_client/data/certs_example.rb +9 -0
  52. data/test_client/data/params_example.rb +110 -0
  53. data/test_client/test_client.rb +61 -0
  54. metadata +42 -12
  55. data/lib/sepa/xml_templates/application_request/get_certificate.xml +0 -11
  56. 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: 3aefe6a38ae84af5717876529a623911ba878fe7
4
- data.tar.gz: 6e7f6f900978fd42a02153d04ed834e964206ca7
3
+ metadata.gz: 6baff59782f24a508d2560a71b776fcb5374d598
4
+ data.tar.gz: 85b220374605d706461e301fc477574481635e31
5
5
  SHA512:
6
- metadata.gz: 2fb3932511a5c24d1be39e4afa01f332a668c9732255f1446b5fea72fad6756408b6d435dbddfde78bc500c2d18ee865c0b93a6a904f616681c3cf54765683c2
7
- data.tar.gz: 17b9b9ce641d796520d5c023b077daaadd181c2dc64b4678fc51d10b7c03f2619da95cb3fd26cc9fa32a0a7a8026a4cd48968b5e1e05a7d456f2d2f24a71be49
6
+ metadata.gz: 38454e6cac847fa6e23de5785b3e2db8c134a486ac8d124b8ca0b5e8f12c24b6a3bc4181541de0dad43135430d7a15c51cf16b0e76821d8ad3d0fbfde75489f0
7
+ data.tar.gz: de324888c9ea1b78f817b688ffbffacc11bcc4f1496cc3a9e48f22d2955e8db07aa02b0b356ca4ed7844b9e875e95e51bba71ed992faaa35ba8907f6c37aa5b1
data/.gitignore CHANGED
@@ -17,3 +17,9 @@ Gemfile.lock
17
17
  .ruby-version
18
18
 
19
19
  /.env
20
+
21
+ # Test client
22
+ /test_client/data/certs.rb
23
+ /test_client/data/params.rb
24
+ /test_client/data/payload.xml
25
+ /test_client/log/
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
+ sudo: false
2
3
  rvm:
3
- - 2.0.0
4
4
  - 2.1.7
5
5
  - 2.2.3
6
6
  notifications:
@@ -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
- case @command
84
- when :create_certificate
85
- set_create_certificate_nodes
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
- set_node("FileType", @file_type)
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
- set_node("FileType", @file_type)
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("Service", '')
141
- set_node("Content", format_cert_request(@signing_csr))
142
- set_node("HMAC", hmac(@pin, csr_to_binary(@signing_csr)))
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
- # @todo Move to {Utilities} and move document to parameters
188
- def add_node_to_root(node)
189
- @application_request.root.add_child(node)
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 @command == :get_certificate
232
- return if @command == :get_bank_certificate
233
- return if @command == :create_certificate
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
- [:get_certificate, :get_user_info, :download_file_list, :download_file, :upload_file]
14
+ STANDARD_COMMANDS +
15
+ %i(get_certificate)
15
16
  when :danske
16
- [:get_bank_certificate, :download_file_list, :download_file,
17
- :upload_file, :create_certificate]
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 [:get_certificate, :get_bank_certificate, :create_certificate].include? command
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
- return unless [:upload_file, :download_file_list, :download_file].include? command
66
-
67
- unless file_type && file_type.respond_to?(:size) && file_type.size < 35
68
- errors.add(:file_type, FILE_TYPE_ERROR_MESSAGE)
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 [:get_user_info,
75
- :get_certificate,
76
- :create_certificate,
77
- :get_bank_certificate].include? command
78
-
79
- # Danske Bank does not use target_id
80
- return if bank == :danske
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
- set_generic_request_contents
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
- # Determines which soap request to build based on command. Certificate requests are built
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
- # Generates a random request id for Nordea request
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,14 @@
1
+ module Sepa
2
+ # Contains OP specific soap building functionality
3
+ module OpSoapRequest
4
+ private
5
+
6
+ def set_receiver_id
7
+ set_node @template, 'bxd|ReceiverId', 'OKOYFIHH'
8
+ end
9
+
10
+ def cert_ns
11
+ OP_PKI
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFMzCCAxugAwIBAgICHhkwDQYJKoZIhvcNAQELBQAwKjELMAkGA1UEBhMCRkkx
3
+ GzAZBgNVBAMTEk9QLVBvaGpvbGEgUm9vdCBDQTAeFw0xMjA2MDcwODQyNDJaFw00
4
+ MTA2MDcwODQyNDJaMCoxCzAJBgNVBAYTAkZJMRswGQYDVQQDExJPUC1Qb2hqb2xh
5
+ IFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCdFCgwifVV
6
+ /XdLNmuIAUox7H3RZOyWotq3HUyGWCX/T337wfrbAQWXSa8C4z2Adr0O3P0qMEFR
7
+ BKt2p4zupD4bkzR1p8tn/K2Y+TVf/ZAjpk3S1/7KZT8DqRCnlb2IuUCeO0OaC0gk
8
+ XIqkeeoogHhYYdQwI0qai2qk8N3jgTlOXqAHceg+yO0h58VIcCaASfR9zIclmYLK
9
+ g2pFPoC22+2QlCgSg4M1ceoiie48Nzk+BYA1Qm1TGjox9BGakiSq+pF+6GC+QBjM
10
+ lnd8rz8lAPqZ7eoukLanOZxo97bG1nIsEyrDTBT+hdkJj4VG+m0Q8oLtBfzadekM
11
+ dWwjHgRWYcQHrlI5WxTgAT5iDdGMrg05cM8poxy09HoFBKHS1fgaFVddr7MFqZcu
12
+ z/kyaQevjnsfPXkI3eDqhxnLbRjHrnqBWX7ELyLgcEjX4syTteKp8aAeYdvN8U8A
13
+ MJ/q56Guob5g/RlDfBXO9aoSyR3bPh6m8sGNgfB38NDKpO6NZK04vLvK3hF0NhWd
14
+ Lqr+ccs1slaWPR2mK0+19o7EjObWGPBxCs17jkd2OV7iXQwt1gaNcIhDDjpH4MdR
15
+ 4FZla64vfuMh1lsVtqi0goCuS6p4aH7VIhjTNVPlQulLgFj2e41z3DmpCo/gfZ65
16
+ QDYYVzFZmCQFfaeoyfZ6SK/jVjUEthSC8wIDAQABo2MwYTAfBgNVHSMEGDAWgBTJ
17
+ N/SYhJwjwZbTpFuapA8rFyyQvDAdBgNVHQ4EFgQUyTf0mIScI8GW06RbmqQPKxcs
18
+ kLwwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
19
+ BQADggIBAFD28Nl4kdeC54BI7IKtCIflTbFmMRykTEvJsPN6t566FxjKSim4KzJ+
20
+ aPXz5DNx7bLXBaFePpOYUhnX6ritZv53Y9MqWjon9L48T2LGbtU8wd7+CWvkjx6r
21
+ 37RGOLUAblfj8Av2lt0wwAusy1AtJtYJf3cvxRRLnUgmoEXh19u0LbhB0NXsPUEv
22
+ js1UuFTq00/KJq/609R73IjzaStWgBXvEDRVJvAhwqlH+xw/5wo+aCcIpdES9kFU
23
+ sVFp9iEMIDBjzQiOm39nIpjUr5irrtiO469yfarwP4JgBXGUP+DoWeB+fYQgK0RG
24
+ /6WN1AZlO+lcChR7k83QeIAnPg698DQNiVMdpXKQKAM+7ri24mtWJOJXAoaA4bhP
25
+ oUL17kys7/m//n9cjlsc4iH+bLSnzUpronznGgMu6XfFFgAhZsYKLVNGCFwuc2Gc
26
+ 7y/Luj5aXh3C1PEvN/SDNhe0j2q2z0FSpT/NMja/KXydTF4B3j0/eVmAbUP3WXWC
27
+ 11LoUQDo9A9hqejoUu+fc7KXob/iDztnpweabNvrMCvYPsiGfiuUPgI5+nxDCH9B
28
+ uxHHUhFLF5/QMPKsvyZekaxMDxlWLs7RJeK4f4pGTbOTTnwwcQ791IcgNR2bYOku
29
+ 7nxefQXOs2Z3xFETBfoNkVGiIVf5AyXigVKFyBXIfCOK9RHJMVEq
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 = [:nordea, :danske]
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.to_s
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
- case bank
297
- when :nordea
298
- if command == :get_certificate
299
- file = "wsdl_nordea_cert.xml"
300
- else
301
- file = "wsdl_nordea.xml"
302
- end
303
- when :danske
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
- "#{WSDL_PATH}/#{file}"
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
- response: response,
323
- error: error,
324
- command: command
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
- case bank
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
- @soap = hash[:response]
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, NOT_OK_RESPONSE_CODE_ERROR_MESSAGE)
301
+ errors.add(:base, { response_code: response_code, response_text: response_text })
281
302
  end
282
303
  end
283
304