sepafm 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE +8 -0
- data/README.md +236 -0
- data/Rakefile +10 -0
- data/lib/danske_get_bank_certificate_test.rb +15 -0
- data/lib/sepa/application_request.rb +182 -0
- data/lib/sepa/application_response.rb +123 -0
- data/lib/sepa/client.rb +79 -0
- data/lib/sepa/danske_testing/keys/danske_encryption.crt +24 -0
- data/lib/sepa/filedescriptor.rb +7 -0
- data/lib/sepa/filetypeservice.rb +6 -0
- data/lib/sepa/nordea_testing/keys/CSR.csr +0 -0
- data/lib/sepa/nordea_testing/keys/nordea.crt +27 -0
- data/lib/sepa/nordea_testing/keys/nordea.key +19 -0
- data/lib/sepa/nordea_testing/response/content_053.xml +998 -0
- data/lib/sepa/nordea_testing/response/content_054.xml +1 -0
- data/lib/sepa/nordea_testing/response/download_file_response.xml +14 -0
- data/lib/sepa/nordea_testing/response/download_filelist_response.xml +14 -0
- data/lib/sepa/nordea_testing/response/get_user_info_response.xml +14 -0
- data/lib/sepa/nordea_testing/response/upload_file_response.xml +14 -0
- data/lib/sepa/response.rb +177 -0
- data/lib/sepa/sender_verifier.rb +15 -0
- data/lib/sepa/signature.rb +7 -0
- data/lib/sepa/soap_builder.rb +395 -0
- data/lib/sepa/soap_danske.rb +47 -0
- data/lib/sepa/soap_nordea.rb +68 -0
- data/lib/sepa/userfiletype.rb +16 -0
- data/lib/sepa/version.rb +3 -0
- data/lib/sepa/wsdl/wsdl_danske.xml +234 -0
- data/lib/sepa/wsdl/wsdl_danske_cert.xml +280 -0
- data/lib/sepa/wsdl/wsdl_nordea.xml +234 -0
- data/lib/sepa/wsdl/wsdl_nordea_cert.xml +187 -0
- data/lib/sepa/xml_parser.rb +291 -0
- data/lib/sepa/xml_schemas/application_request.xsd +135 -0
- data/lib/sepa/xml_schemas/application_response.xsd +311 -0
- data/lib/sepa/xml_schemas/cert_application_request.xsd +107 -0
- data/lib/sepa/xml_schemas/danske_pki.xsd +334 -0
- data/lib/sepa/xml_schemas/oasis-200401-wss-wssecurity-secext-1.0.xsd +195 -0
- data/lib/sepa/xml_schemas/oasis-200401-wss-wssecurity-utility-1.0.xsd +108 -0
- data/lib/sepa/xml_schemas/soap.xsd +126 -0
- data/lib/sepa/xml_schemas/wsdl.xml +310 -0
- data/lib/sepa/xml_schemas/xml.xsd +287 -0
- data/lib/sepa/xml_schemas/xmldsig-core-schema.xsd +318 -0
- data/lib/sepa/xml_templates/application_request/create_certificate.xml +10 -0
- data/lib/sepa/xml_templates/application_request/danske_get_bank_certificate.xml +10 -0
- data/lib/sepa/xml_templates/application_request/download_file.xml +32 -0
- data/lib/sepa/xml_templates/application_request/download_file_list.xml +29 -0
- data/lib/sepa/xml_templates/application_request/get_certificate.xml +10 -0
- data/lib/sepa/xml_templates/application_request/get_user_info.xml +26 -0
- data/lib/sepa/xml_templates/application_request/upload_file.xml +29 -0
- data/lib/sepa/xml_templates/soap/create_certificate.xml +15 -0
- data/lib/sepa/xml_templates/soap/danske_get_bank_certificate.xml +14 -0
- data/lib/sepa/xml_templates/soap/download_file.xml +16 -0
- data/lib/sepa/xml_templates/soap/download_file_list.xml +16 -0
- data/lib/sepa/xml_templates/soap/get_certificate.xml +13 -0
- data/lib/sepa/xml_templates/soap/get_user_info.xml +16 -0
- data/lib/sepa/xml_templates/soap/header.xml +37 -0
- data/lib/sepa/xml_templates/soap/upload_file.xml +16 -0
- data/lib/sepa.rb +21 -0
- data/lib/sepa_client_testing_mika.rb +32 -0
- data/lib/sepa_client_testing_tiere.rb +80 -0
- data/sepa.gemspec +29 -0
- data/test/sepa/application_request_test.rb +423 -0
- data/test/sepa/application_response_test.rb +238 -0
- data/test/sepa/cert_application_request_test.rb +99 -0
- data/test/sepa/client_test.rb +425 -0
- data/test/sepa/danske_test_keys/danskeroot.pem +25 -0
- data/test/sepa/danske_test_keys/encryption_pkcs.csr +0 -0
- data/test/sepa/danske_test_keys/signing_key.pem +27 -0
- data/test/sepa/danske_test_keys/signing_pkcs.csr +0 -0
- data/test/sepa/nordea_cert_request_soap_builder_test.rb +112 -0
- data/test/sepa/nordea_generic_soap_builder_test.rb +427 -0
- data/test/sepa/nordea_test_keys/nordea.crt +27 -0
- data/test/sepa/nordea_test_keys/nordea.key +19 -0
- data/test/sepa/nordea_test_keys/root_cert.cer +0 -0
- data/test/sepa/nordea_test_keys/testcert.csr +0 -0
- data/test/sepa/response_test.rb +269 -0
- data/test/sepa/sepa_test.rb +20 -0
- data/test/sepa/test_files/invalid.wsdl +1 -0
- data/test/sepa/test_files/test_responses/df.xml +20 -0
- data/test/sepa/test_files/test_responses/dfl.xml +20 -0
- data/test/sepa/test_files/test_responses/gui.xml +20 -0
- data/test/sepa/test_files/test_responses/uf.xml +20 -0
- data/test/sepa/user_file_type_test.rb +21 -0
- data/test/sepa/xml_parser_test.rb +73 -0
- data/test/test_helper.rb +9 -0
- metadata +256 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
require File.expand_path('../../test_helper.rb', __FILE__)
|
|
2
|
+
|
|
3
|
+
class NordeaGenericSoapBuilderTest < MiniTest::Test
|
|
4
|
+
def setup
|
|
5
|
+
@schemas_path = File.expand_path('../../../lib/sepa/xml_schemas',__FILE__)
|
|
6
|
+
|
|
7
|
+
@xml_templates_path = File.expand_path(
|
|
8
|
+
'../../../lib/sepa/xml_templates/soap',
|
|
9
|
+
__FILE__
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
keys_path = File.expand_path('../nordea_test_keys', __FILE__)
|
|
13
|
+
|
|
14
|
+
private_key = OpenSSL::PKey::RSA.new File.read "#{keys_path}/nordea.key"
|
|
15
|
+
cert = OpenSSL::X509::Certificate.new File.read "#{keys_path}/nordea.crt"
|
|
16
|
+
certplain = "-----BEGIN CERTIFICATE-----
|
|
17
|
+
MIIDwTCCAqmgAwIBAgIEAX1JuTANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJT
|
|
18
|
+
RTEeMBwGA1UEChMVTm9yZGVhIEJhbmsgQUIgKHB1YmwpMR8wHQYDVQQDExZOb3Jk
|
|
19
|
+
ZWEgQ29ycG9yYXRlIENBIDAxMRQwEgYDVQQFEws1MTY0MDYtMDEyMDAeFw0xMzA1
|
|
20
|
+
MDIxMjI2MzRaFw0xNTA1MDIxMjI2MzRaMEQxCzAJBgNVBAYTAkZJMSAwHgYDVQQD
|
|
21
|
+
DBdOb3JkZWEgRGVtbyBDZXJ0aWZpY2F0ZTETMBEGA1UEBRMKNTc4MDg2MDIzODCB
|
|
22
|
+
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwtFEfAtbJuGzQwwRumZkvYh2BjGY
|
|
23
|
+
VsAMUeiKtOne3bZSeisfCq+TXqL1gI9LofyeAQ9I/sDm6tL80yrD5iaSUqVm6A73
|
|
24
|
+
9MsmpW/iyZcVf7ms8xAN51ESUgN6akwZCU9pH62ngJDj2gUsktY0fpsoVsARdrvO
|
|
25
|
+
Fk0fTSUXKWd6LbcCAwEAAaOCAR0wggEZMAkGA1UdEwQCMAAwEQYDVR0OBAoECEBw
|
|
26
|
+
2cj7+XMAMBMGA1UdIAQMMAowCAYGKoVwRwEDMBMGA1UdIwQMMAqACEALddbbzwun
|
|
27
|
+
MDcGCCsGAQUFBwEBBCswKTAnBggrBgEFBQcwAYYbaHR0cDovL29jc3Aubm9yZGVh
|
|
28
|
+
LnNlL0NDQTAxMA4GA1UdDwEB/wQEAwIFoDCBhQYDVR0fBH4wfDB6oHigdoZ0bGRh
|
|
29
|
+
cCUzQS8vbGRhcC5uYi5zZS9jbiUzRE5vcmRlYStDb3Jwb3JhdGUrQ0ErMDElMkNv
|
|
30
|
+
JTNETm9yZGVhK0JhbmsrQUIrJTI4cHVibCUyOSUyQ2MlM0RTRSUzRmNlcnRpZmlj
|
|
31
|
+
YXRlcmV2b2NhdGlvbmxpc3QwDQYJKoZIhvcNAQEFBQADggEBACLUPB1Gmq6286/s
|
|
32
|
+
ROADo7N+w3eViGJ2fuOTLMy4R0UHOznKZNsuk4zAbS2KycbZsE5py4L8o+IYoaS8
|
|
33
|
+
8YHtEeckr2oqHnPpz/0Eg7wItj8Ad+AFWJqzbn6Hu/LQhlnl5JEzXzl3eZj9oiiJ
|
|
34
|
+
1q/2CGXvFomY7S4tgpWRmYULtCK6jode0NhgNnAgOI9uy76pSS16aDoiQWUJqQgV
|
|
35
|
+
ydowAnqS9h9aQ6gedwbOdtkWmwKMDVXU6aRz9Gvk+JeYJhtpuP3OPNGbbC5L7NVd
|
|
36
|
+
no+B6AtwxmG3ozd+mPcMeVuz6kKLAmQyIiBSrRNa5OrTkq/CUzxO9WUgTnm/Sri7
|
|
37
|
+
zReR6mU=
|
|
38
|
+
-----END CERTIFICATE-----"
|
|
39
|
+
pkeyplain = "-----BEGIN PRIVATE KEY-----
|
|
40
|
+
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMLRRHwLWybhs0MM
|
|
41
|
+
EbpmZL2IdgYxmFbADFHoirTp3t22UnorHwqvk16i9YCPS6H8ngEPSP7A5urS/NMq
|
|
42
|
+
w+YmklKlZugO9/TLJqVv4smXFX+5rPMQDedRElIDempMGQlPaR+tp4CQ49oFLJLW
|
|
43
|
+
NH6bKFbAEXa7zhZNH00lFylnei23AgMBAAECgYEAqt912/7x4jaQTrxlSELLFVp9
|
|
44
|
+
eo1BesVTiPwXvPpsGbbyvGjZ/ztkXNs9zZbh1aCGzZMkiR2U7F5GlsiprlIif4cF
|
|
45
|
+
6Xz7rCjaAs7iDRt9PjhjVuqNGR2I+VIIlbQ9XWFJ3lJFW3v7TIZ8JbLnn0XOFz+Z
|
|
46
|
+
BBSSGTK1zTNh4TBQtjECQQDe5M3uu9m4RwSw9R6GaDw/IFQZgr0oWSv0WIjRwvwW
|
|
47
|
+
nFnSX2lbkNAjulP0daGsmn7vxIpqZxPxwcrU4wFqTF5dAkEA38DnbCm3YfogzwLH
|
|
48
|
+
Nre2hBmGqjWarhtxqtRarrkgnmOd8W0Z1Hb1dSHrliUSVSrINbK5ZdEV15Rpu7VD
|
|
49
|
+
OePzIwJAPMslS+8alANyyR0iJUC65fDYX1jkZOPldDDNqIDJJxWf/hwd7WaTDpuc
|
|
50
|
+
mHmZDi3ZX2Y45oqUywSzYNtFoIuR1QJAZYUZuyqmSK77SdGB36K1DfSi9AFEQDC1
|
|
51
|
+
fwPAbTwTv6mFFPAiYxLiRZXxVPtW+QtjMXH4ymh2V4y/+GnCqbZyLwJBAJQSDAME
|
|
52
|
+
Sn4Uz7Zjk3UrBIbMYEv0u2mcCypwsb0nGE5/gzDPjGE9cxWW+rXARIs+sNQVClnh
|
|
53
|
+
45nhdfYxOjgYff0=
|
|
54
|
+
-----END PRIVATE KEY-----"
|
|
55
|
+
@params = {
|
|
56
|
+
bank: :nordea,
|
|
57
|
+
private_key_plain: pkeyplain,
|
|
58
|
+
cert_plain: certplain,
|
|
59
|
+
command: :get_user_info,
|
|
60
|
+
customer_id: '11111111',
|
|
61
|
+
environment: 'PRODUCTION',
|
|
62
|
+
status: 'NEW',
|
|
63
|
+
target_id: '11111111A1',
|
|
64
|
+
language: 'FI',
|
|
65
|
+
file_type: 'TITO',
|
|
66
|
+
content: Base64.encode64("Kurppa"),
|
|
67
|
+
file_reference: "11111111A12006030329501800000014"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@soap_request = Sepa::SoapBuilder.new(@params)
|
|
71
|
+
|
|
72
|
+
@doc = Nokogiri::XML(@soap_request.to_xml)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def test_get_user_info_template_is_unmodified
|
|
76
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
|
77
|
+
template = File.read("#{@xml_templates_path}/get_user_info.xml")
|
|
78
|
+
digest = Base64.encode64(sha1.digest(template)).strip
|
|
79
|
+
|
|
80
|
+
assert_equal digest, "A1UYZTOycIBHAY/70Q5G3lNjQBo="
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_download_file_list_template_is_unmodified
|
|
84
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
|
85
|
+
template = File.read("#{@xml_templates_path}/download_file_list.xml")
|
|
86
|
+
digest = Base64.encode64(sha1.digest(template)).strip
|
|
87
|
+
|
|
88
|
+
assert_equal digest, "+3UaQMgseUUn5OKUp/PTHl/BNFE="
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_download_file_template_is_unmodified
|
|
92
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
|
93
|
+
template = File.read("#{@xml_templates_path}/download_file.xml")
|
|
94
|
+
digest = Base64.encode64(sha1.digest(template)).strip
|
|
95
|
+
|
|
96
|
+
assert_equal digest, "HSWQCmwOsMdPJP3erjksi/Sz7hE="
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def test_should_not_initialize_with_unproper_params
|
|
100
|
+
@params = "kissa"
|
|
101
|
+
assert_raises(ArgumentError) do
|
|
102
|
+
Sepa::SoapBuilder.new(@params)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
def test_upload_file_template_is_unmodified
|
|
106
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
|
107
|
+
template = File.read("#{@xml_templates_path}/upload_file.xml")
|
|
108
|
+
digest = Base64.encode64(sha1.digest(template)).strip
|
|
109
|
+
|
|
110
|
+
assert_equal digest, "hdbglkugI1pzkeetqKIh2WBDkFM="
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def test_header_template_is_unmodified
|
|
114
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
|
115
|
+
template = File.read("#{@xml_templates_path}/header.xml")
|
|
116
|
+
digest = Base64.encode64(sha1.digest(template)).strip
|
|
117
|
+
|
|
118
|
+
assert_equal digest, "W6TTO6gmlVDssKeZJYsxiJebs6Q="
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_should_initialize_with_proper_params
|
|
122
|
+
assert Sepa::SoapBuilder.new(@params)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_should_get_error_if_private_key_plain_missing
|
|
126
|
+
@params.delete(:private_key_plain)
|
|
127
|
+
|
|
128
|
+
assert_raises(ArgumentError) do
|
|
129
|
+
Sepa::SoapBuilder.new(@params)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def test_should_get_error_if_cert_plain_missing
|
|
134
|
+
@params.delete(:cert_plain)
|
|
135
|
+
|
|
136
|
+
assert_raises(ArgumentError) do
|
|
137
|
+
Sepa::SoapBuilder.new(@params)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def test_should_get_error_if_command_missing
|
|
142
|
+
@params.delete(:command)
|
|
143
|
+
|
|
144
|
+
assert_raises(ArgumentError) do
|
|
145
|
+
Sepa::SoapBuilder.new(@params)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def test_should_get_error_if_customer_id_missing
|
|
150
|
+
@params.delete(:customer_id)
|
|
151
|
+
|
|
152
|
+
assert_raises(ArgumentError) do
|
|
153
|
+
Sepa::SoapBuilder.new(@params)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_should_get_error_if_target_id_missing
|
|
158
|
+
@params.delete(:target_id)
|
|
159
|
+
|
|
160
|
+
assert_raises(ArgumentError) do
|
|
161
|
+
Sepa::SoapBuilder.new(@params)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def test_should_get_error_if_language_missing
|
|
166
|
+
@params.delete(:language)
|
|
167
|
+
|
|
168
|
+
assert_raises(ArgumentError) do
|
|
169
|
+
Sepa::SoapBuilder.new(@params)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def test_should_load_correct_template_with_download_file_list
|
|
174
|
+
@params[:command] = :download_file_list
|
|
175
|
+
doc = Nokogiri::XML(Sepa::SoapBuilder.new(@params).to_xml)
|
|
176
|
+
|
|
177
|
+
assert doc.xpath(
|
|
178
|
+
'//cor:downloadFileListin', 'cor' => 'http://bxd.fi/CorporateFileService'
|
|
179
|
+
).first
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def test_should_load_correct_template_with_get_user_info
|
|
183
|
+
@params[:command] = :get_user_info
|
|
184
|
+
doc = Nokogiri::XML(Sepa::SoapBuilder.new(@params).to_xml)
|
|
185
|
+
|
|
186
|
+
assert doc.xpath(
|
|
187
|
+
'//cor:getUserInfoin', 'cor' => 'http://bxd.fi/CorporateFileService'
|
|
188
|
+
).first
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def test_should_load_correct_template_with_download_file
|
|
192
|
+
@params[:command] = :download_file
|
|
193
|
+
doc = Nokogiri::XML(Sepa::SoapBuilder.new(@params).to_xml)
|
|
194
|
+
|
|
195
|
+
assert doc.xpath(
|
|
196
|
+
'//cor:downloadFilein', 'cor' => 'http://bxd.fi/CorporateFileService'
|
|
197
|
+
).first
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def test_should_load_correct_template_with_upload_file
|
|
201
|
+
@params[:command] = :upload_file
|
|
202
|
+
doc = Nokogiri::XML(Sepa::SoapBuilder.new(@params).to_xml)
|
|
203
|
+
|
|
204
|
+
assert doc.xpath(
|
|
205
|
+
'//cor:uploadFilein', 'cor' => 'http://bxd.fi/CorporateFileService'
|
|
206
|
+
).first
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def test_should_raise_error_if_unrecognised_command
|
|
210
|
+
@params[:command] = :wrong_command
|
|
211
|
+
|
|
212
|
+
assert_raises(ArgumentError) do
|
|
213
|
+
soap = Sepa::SoapBuilder.new(@params)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def test_sender_id_is_properly_set
|
|
218
|
+
assert_equal @params[:customer_id],
|
|
219
|
+
@doc.xpath("//bxd:SenderId", 'bxd' => 'http://model.bxd.fi').first.content
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Just testing that the content of the node is an actual hex number and that
|
|
223
|
+
# the length is 30 characters because 35 is the max that can be set
|
|
224
|
+
# according to the schema and Securerandom can generate only some int times 2
|
|
225
|
+
def test_request_id_is_properly_set
|
|
226
|
+
request_id_node = @doc.xpath(
|
|
227
|
+
"//bxd:RequestId", 'bxd' => 'http://model.bxd.fi'
|
|
228
|
+
).first
|
|
229
|
+
|
|
230
|
+
assert request_id_node.content =~ /^[0-9A-F]+$/i
|
|
231
|
+
assert_equal request_id_node.content.length, 34
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def test_timestamp_is_set_correctly
|
|
235
|
+
timestamp_node = @doc.xpath(
|
|
236
|
+
"//bxd:Timestamp", 'bxd' => 'http://model.bxd.fi'
|
|
237
|
+
).first
|
|
238
|
+
|
|
239
|
+
timestamp = Time.strptime(timestamp_node.content, '%Y-%m-%dT%H:%M:%S%z')
|
|
240
|
+
|
|
241
|
+
assert timestamp <= Time.now && timestamp > (Time.now - 60)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def test_language_is_set_correctly
|
|
245
|
+
language_node = @doc.xpath(
|
|
246
|
+
"//bxd:Language", 'bxd' => 'http://model.bxd.fi'
|
|
247
|
+
).first
|
|
248
|
+
|
|
249
|
+
assert_equal language_node.content, @params[:language]
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def test_user_agent_is_set_correctly
|
|
253
|
+
user_agent_node = @doc.xpath(
|
|
254
|
+
"//bxd:UserAgent", 'bxd' => 'http://model.bxd.fi'
|
|
255
|
+
).first
|
|
256
|
+
|
|
257
|
+
assert_equal user_agent_node.content,
|
|
258
|
+
"Sepa Transfer Library version " + Sepa::VERSION
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# I'm quite sure that receiver id and target is are the same
|
|
262
|
+
def test_receiver_is_is_set_correctly
|
|
263
|
+
receiver_id_node = @doc.xpath(
|
|
264
|
+
"//bxd:ReceiverId", 'bxd' => 'http://model.bxd.fi'
|
|
265
|
+
).first
|
|
266
|
+
|
|
267
|
+
assert_equal receiver_id_node.content, @params[:target_id]
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# Just test that the content of application request is a base64 encoded xml
|
|
271
|
+
# document and that it's customer is matches the one provided in the params
|
|
272
|
+
def test_application_request_should_be_inserted_properly
|
|
273
|
+
ar_node = @doc.xpath(
|
|
274
|
+
"//bxd:ApplicationRequest", 'bxd' => 'http://model.bxd.fi'
|
|
275
|
+
).first
|
|
276
|
+
|
|
277
|
+
ar_doc = Nokogiri::XML(Base64.decode64(ar_node.content))
|
|
278
|
+
|
|
279
|
+
assert ar_doc.respond_to?(:canonicalize)
|
|
280
|
+
assert_equal ar_doc.at_css("CustomerId").content, @params[:customer_id]
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def test_cert_is_added_correctly
|
|
284
|
+
added_cert = @doc.xpath(
|
|
285
|
+
"//wsse:BinarySecurityToken", 'wsse' => 'http://docs.oasis-open.org/wss' \
|
|
286
|
+
'/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
|
|
287
|
+
).first.content
|
|
288
|
+
|
|
289
|
+
actual_cert = @params.fetch(:cert).to_s
|
|
290
|
+
actual_cert = actual_cert.split('-----BEGIN CERTIFICATE-----')[1]
|
|
291
|
+
actual_cert = actual_cert.split('-----END CERTIFICATE-----')[0]
|
|
292
|
+
actual_cert = actual_cert.gsub(/\s+/, "")
|
|
293
|
+
|
|
294
|
+
assert_equal added_cert, actual_cert
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def test_body_digest_is_calculated_correctly
|
|
298
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
|
299
|
+
|
|
300
|
+
# Digest which is calculated from the body and added to the header
|
|
301
|
+
added_digest = @doc.xpath(
|
|
302
|
+
"//dsig:Reference[@URI='#sdf6sa7d86f87s6df786sd87f6s8fsda']/dsig:Digest" \
|
|
303
|
+
"Value", 'dsig' => 'http://www.w3.org/2000/09/xmldsig#'
|
|
304
|
+
).first.content
|
|
305
|
+
|
|
306
|
+
body_node = @doc.xpath(
|
|
307
|
+
"//env:Body", 'env' => 'http://schemas.xmlsoap.org/soap/envelope/'
|
|
308
|
+
).first
|
|
309
|
+
|
|
310
|
+
body_node = body_node.canonicalize(
|
|
311
|
+
mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,inclusive_namespaces=nil,
|
|
312
|
+
with_comments=false
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
actual_digest = Base64.encode64(sha1.digest(body_node)).strip
|
|
316
|
+
|
|
317
|
+
assert_equal actual_digest, added_digest
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def test_header_created_timestamp_is_added_correctly
|
|
321
|
+
timestamp_node = @doc.xpath(
|
|
322
|
+
"//wsu:Created", 'wsu' => 'http://docs.oasis-open.org/wss/2004/01/oasis' \
|
|
323
|
+
'-200401-wss-wssecurity-utility-1.0.xsd'
|
|
324
|
+
).first
|
|
325
|
+
|
|
326
|
+
timestamp = Time.strptime(timestamp_node.content, '%Y-%m-%dT%H:%M:%S%z')
|
|
327
|
+
|
|
328
|
+
assert timestamp <= Time.now && timestamp > (Time.now - 60)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def test_header_expires_timestamp_is_added_correctly
|
|
332
|
+
timestamp_node = @doc.xpath(
|
|
333
|
+
"//wsu:Expires", 'wsu' => 'http://docs.oasis-open.org/wss/2004/01/oasis' \
|
|
334
|
+
'-200401-wss-wssecurity-utility-1.0.xsd'
|
|
335
|
+
).first
|
|
336
|
+
|
|
337
|
+
timestamp = Time.strptime(timestamp_node.content, '%Y-%m-%dT%H:%M:%S%z')
|
|
338
|
+
|
|
339
|
+
assert timestamp <= (Time.now + 3600) &&
|
|
340
|
+
timestamp > ((Time.now + 3600) - 60)
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
def test_header_timestamps_digest_is_calculated_correctly
|
|
344
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
|
345
|
+
|
|
346
|
+
added_digest = @doc.xpath(
|
|
347
|
+
"//dsig:Reference[@URI='#dsfg8sdg87dsf678g6dsg6ds7fg']/dsig:DigestValue",
|
|
348
|
+
'dsig' => 'http://www.w3.org/2000/09/xmldsig#'
|
|
349
|
+
).first.content
|
|
350
|
+
|
|
351
|
+
timestamp_node = @doc.xpath(
|
|
352
|
+
"//wsu:Timestamp", 'wsu' => 'http://docs.oasis-open.org/wss/2004/01/oas' \
|
|
353
|
+
'is-200401-wss-wssecurity-utility-1.0.xsd'
|
|
354
|
+
).first
|
|
355
|
+
|
|
356
|
+
timestamp_node = timestamp_node.canonicalize(
|
|
357
|
+
mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,inclusive_namespaces=nil,
|
|
358
|
+
with_comments=false
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
actual_digest = Base64.encode64(sha1.digest(timestamp_node)).strip
|
|
362
|
+
|
|
363
|
+
assert_equal actual_digest, added_digest
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
def test_signature_is_calculated_correctly
|
|
367
|
+
sha1 = OpenSSL::Digest::SHA1.new
|
|
368
|
+
private_key = @params.fetch(:private_key)
|
|
369
|
+
|
|
370
|
+
added_signature = @doc.xpath(
|
|
371
|
+
"//dsig:SignatureValue", 'dsig' => 'http://www.w3.org/2000/09/xmldsig#'
|
|
372
|
+
).first.content
|
|
373
|
+
|
|
374
|
+
signed_info_node = @doc.xpath(
|
|
375
|
+
"//dsig:SignedInfo", 'dsig' => 'http://www.w3.org/2000/09/xmldsig#'
|
|
376
|
+
).first
|
|
377
|
+
|
|
378
|
+
signed_info_node = signed_info_node.canonicalize(
|
|
379
|
+
mode=Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0,inclusive_namespaces=nil,
|
|
380
|
+
with_comments=false
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
actual_signature = Base64.encode64(
|
|
384
|
+
private_key.sign(sha1, signed_info_node)
|
|
385
|
+
).gsub(/\s+/, "")
|
|
386
|
+
|
|
387
|
+
assert_equal actual_signature, added_signature
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
def test_should_validate_against_schema
|
|
391
|
+
Dir.chdir(@schemas_path) do
|
|
392
|
+
xsd = Nokogiri::XML::Schema(IO.read('soap.xsd'))
|
|
393
|
+
assert xsd.valid?(@doc)
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def test_schema_validation_should_fail_with_wrong_must_understand_value
|
|
398
|
+
security_node = @doc.xpath(
|
|
399
|
+
'//wsse:Security', 'wsse' => 'http://docs.oasis-open.org/wss/2004/01/oa' \
|
|
400
|
+
'sis-200401-wss-wssecurity-secext-1.0.xsd'
|
|
401
|
+
).first
|
|
402
|
+
|
|
403
|
+
security_node['env:mustUnderstand'] = '3'
|
|
404
|
+
|
|
405
|
+
Dir.chdir(@schemas_path) do
|
|
406
|
+
xsd = Nokogiri::XML::Schema(IO.read('soap.xsd'))
|
|
407
|
+
refute xsd.valid?(@doc)
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
def test_should_validate_against_ws_security_schema
|
|
412
|
+
ws_node = @doc.xpath(
|
|
413
|
+
'//wsse:Security', 'wsse' => 'http://docs.oasis-open.org/wss/2004/01/oa' \
|
|
414
|
+
'sis-200401-wss-wssecurity-secext-1.0.xsd'
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
ws_node = ws_node.to_xml
|
|
418
|
+
|
|
419
|
+
ws_node = Nokogiri::XML(ws_node)
|
|
420
|
+
|
|
421
|
+
Dir.chdir(@schemas_path) do
|
|
422
|
+
xsd = Nokogiri::XML::Schema IO.read 'oasis-200401-wss-wssecurity-secext' \
|
|
423
|
+
'-1.0.xsd'
|
|
424
|
+
assert xsd.valid?(ws_node)
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Bag Attributes
|
|
2
|
+
localKeyID: 4B 45 59 35 31 38 32 35 62 36 35 30 30 30 30 31 32 35 32 00
|
|
3
|
+
subject=/C=FI/CN=Nordea Demo Certificate/serialNumber=5780860238
|
|
4
|
+
issuer=/C=SE/O=Nordea Bank AB (publ)/CN=Nordea Corporate CA 01/serialNumber=516406-0120
|
|
5
|
+
-----BEGIN CERTIFICATE-----
|
|
6
|
+
MIIDwTCCAqmgAwIBAgIEAX1JuTANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJT
|
|
7
|
+
RTEeMBwGA1UEChMVTm9yZGVhIEJhbmsgQUIgKHB1YmwpMR8wHQYDVQQDExZOb3Jk
|
|
8
|
+
ZWEgQ29ycG9yYXRlIENBIDAxMRQwEgYDVQQFEws1MTY0MDYtMDEyMDAeFw0xMzA1
|
|
9
|
+
MDIxMjI2MzRaFw0xNTA1MDIxMjI2MzRaMEQxCzAJBgNVBAYTAkZJMSAwHgYDVQQD
|
|
10
|
+
DBdOb3JkZWEgRGVtbyBDZXJ0aWZpY2F0ZTETMBEGA1UEBRMKNTc4MDg2MDIzODCB
|
|
11
|
+
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwtFEfAtbJuGzQwwRumZkvYh2BjGY
|
|
12
|
+
VsAMUeiKtOne3bZSeisfCq+TXqL1gI9LofyeAQ9I/sDm6tL80yrD5iaSUqVm6A73
|
|
13
|
+
9MsmpW/iyZcVf7ms8xAN51ESUgN6akwZCU9pH62ngJDj2gUsktY0fpsoVsARdrvO
|
|
14
|
+
Fk0fTSUXKWd6LbcCAwEAAaOCAR0wggEZMAkGA1UdEwQCMAAwEQYDVR0OBAoECEBw
|
|
15
|
+
2cj7+XMAMBMGA1UdIAQMMAowCAYGKoVwRwEDMBMGA1UdIwQMMAqACEALddbbzwun
|
|
16
|
+
MDcGCCsGAQUFBwEBBCswKTAnBggrBgEFBQcwAYYbaHR0cDovL29jc3Aubm9yZGVh
|
|
17
|
+
LnNlL0NDQTAxMA4GA1UdDwEB/wQEAwIFoDCBhQYDVR0fBH4wfDB6oHigdoZ0bGRh
|
|
18
|
+
cCUzQS8vbGRhcC5uYi5zZS9jbiUzRE5vcmRlYStDb3Jwb3JhdGUrQ0ErMDElMkNv
|
|
19
|
+
JTNETm9yZGVhK0JhbmsrQUIrJTI4cHVibCUyOSUyQ2MlM0RTRSUzRmNlcnRpZmlj
|
|
20
|
+
YXRlcmV2b2NhdGlvbmxpc3QwDQYJKoZIhvcNAQEFBQADggEBACLUPB1Gmq6286/s
|
|
21
|
+
ROADo7N+w3eViGJ2fuOTLMy4R0UHOznKZNsuk4zAbS2KycbZsE5py4L8o+IYoaS8
|
|
22
|
+
8YHtEeckr2oqHnPpz/0Eg7wItj8Ad+AFWJqzbn6Hu/LQhlnl5JEzXzl3eZj9oiiJ
|
|
23
|
+
1q/2CGXvFomY7S4tgpWRmYULtCK6jode0NhgNnAgOI9uy76pSS16aDoiQWUJqQgV
|
|
24
|
+
ydowAnqS9h9aQ6gedwbOdtkWmwKMDVXU6aRz9Gvk+JeYJhtpuP3OPNGbbC5L7NVd
|
|
25
|
+
no+B6AtwxmG3ozd+mPcMeVuz6kKLAmQyIiBSrRNa5OrTkq/CUzxO9WUgTnm/Sri7
|
|
26
|
+
zReR6mU=
|
|
27
|
+
-----END CERTIFICATE-----
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Bag Attributes
|
|
2
|
+
localKeyID: 4B 45 59 35 31 38 32 35 62 36 35 30 30 30 30 31 32 35 32 00
|
|
3
|
+
Key Attributes: <No Attributes>
|
|
4
|
+
-----BEGIN PRIVATE KEY-----
|
|
5
|
+
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMLRRHwLWybhs0MM
|
|
6
|
+
EbpmZL2IdgYxmFbADFHoirTp3t22UnorHwqvk16i9YCPS6H8ngEPSP7A5urS/NMq
|
|
7
|
+
w+YmklKlZugO9/TLJqVv4smXFX+5rPMQDedRElIDempMGQlPaR+tp4CQ49oFLJLW
|
|
8
|
+
NH6bKFbAEXa7zhZNH00lFylnei23AgMBAAECgYEAqt912/7x4jaQTrxlSELLFVp9
|
|
9
|
+
eo1BesVTiPwXvPpsGbbyvGjZ/ztkXNs9zZbh1aCGzZMkiR2U7F5GlsiprlIif4cF
|
|
10
|
+
6Xz7rCjaAs7iDRt9PjhjVuqNGR2I+VIIlbQ9XWFJ3lJFW3v7TIZ8JbLnn0XOFz+Z
|
|
11
|
+
BBSSGTK1zTNh4TBQtjECQQDe5M3uu9m4RwSw9R6GaDw/IFQZgr0oWSv0WIjRwvwW
|
|
12
|
+
nFnSX2lbkNAjulP0daGsmn7vxIpqZxPxwcrU4wFqTF5dAkEA38DnbCm3YfogzwLH
|
|
13
|
+
Nre2hBmGqjWarhtxqtRarrkgnmOd8W0Z1Hb1dSHrliUSVSrINbK5ZdEV15Rpu7VD
|
|
14
|
+
OePzIwJAPMslS+8alANyyR0iJUC65fDYX1jkZOPldDDNqIDJJxWf/hwd7WaTDpuc
|
|
15
|
+
mHmZDi3ZX2Y45oqUywSzYNtFoIuR1QJAZYUZuyqmSK77SdGB36K1DfSi9AFEQDC1
|
|
16
|
+
fwPAbTwTv6mFFPAiYxLiRZXxVPtW+QtjMXH4ymh2V4y/+GnCqbZyLwJBAJQSDAME
|
|
17
|
+
Sn4Uz7Zjk3UrBIbMYEv0u2mcCypwsb0nGE5/gzDPjGE9cxWW+rXARIs+sNQVClnh
|
|
18
|
+
45nhdfYxOjgYff0=
|
|
19
|
+
-----END PRIVATE KEY-----
|
|
Binary file
|
|
Binary file
|