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.
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