Class: Sepa::SoapBuilder
- Inherits:
-
Object
- Object
- Sepa::SoapBuilder
- Includes:
- Utilities
- Defined in:
- lib/sepa/soap_builder.rb
Overview
Builds a soap message with given parameters. This class is extended with proper bank module depending on bank.
Instance Attribute Summary collapse
-
#application_request ⇒ ApplicationRequest
readonly
Application request built with the same parameters as the soap.
Instance Method Summary collapse
-
#add_body_to_header ⇒ Nokogiri::XML
private
Adds soap body to header template.
-
#build_certificate_request ⇒ Nokogiri::XML
private
Sets contents for certificate request.
-
#build_common_request ⇒ Nokogiri::XML
private
Builds generic request which is a request made with commands: * Get User Info * Download File * Download File List * Upload File.
-
#calculate_digest(doc, node) ⇒ String
private
Calculates digest hash for the given node in the given document.
-
#calculate_signature(doc, node) ⇒ String
private
Calculates signature for the given node in the given document.
-
#common_set_body_contents ⇒ Object
private
Sets nodes for generic requests, application request is base64 encoded here.
-
#find_correct_bank_extension ⇒ Object
private
Extends the class with proper module depending on bank.
-
#find_correct_build ⇒ Nokogiri::XML
private
Determines which soap request to build based on command.
-
#initialize(params) ⇒ SoapBuilder
constructor
Initializes the SoapBuilder with the params hash and then extends the SoapBuilder with the correct bank module.
-
#load_header_template ⇒ Nokogiri::XML
private
Loads soap header template to be later populated.
-
#process_header ⇒ Object
private
Add needed information to soap header.
-
#request_id ⇒ String
private
Generates a random request id.
- #set_application_request ⇒ Object private
-
#set_body_contents ⇒ Nokogiri::XML
private
Sets soap body contents.
-
#set_node(doc, node, value, namespace: nil) ⇒ Object
private
Sets value to a node's content in the given document.
-
#set_token_id ⇒ Object
private
Generates a random token id and sets it to correct node.
-
#to_xml ⇒ String
Returns the soap as raw xml.
Methods included from Utilities
#canonicalize_exclusively, #canonicalized_node, #cert_request_valid?, #check_validity_against_schema, #csr_to_binary, #decode, #encode, #extract_cert, #format_cert, #format_cert_request, #hmac, #iso_time, #load_body_template, #process_cert_value, #rsa_key, #set_node_id, #validate_signature, #verify_certificate_against_root_certificate, #x509_certificate, #xml_doc
Constructor Details
#initialize(params) ⇒ SoapBuilder
Initializes the Sepa::SoapBuilder with the params hash and then extends the Sepa::SoapBuilder with the correct bank module. The Sepa::SoapBuilder class is usually created by the client which handles parameter validation.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/sepa/soap_builder.rb', line 17 def initialize(params) @bank = params[:bank] @own_signing_certificate = params[:own_signing_certificate] @command = params[:command] @content = params[:content] @customer_id = params[:customer_id] @bank_encryption_certificate = params[:bank_encryption_certificate] @environment = params[:environment] @file_reference = params[:file_reference] @file_type = params[:file_type] @language = params[:language] @signing_private_key = params[:signing_private_key] @status = params[:status] @target_id = params[:target_id] @application_request = ApplicationRequest.new params @header_template = load_header_template @template = load_body_template SOAP_TEMPLATE_PATH find_correct_bank_extension end |
Instance Attribute Details
#application_request ⇒ ApplicationRequest (readonly)
Application request built with the same parameters as the soap
10 11 12 |
# File 'lib/sepa/soap_builder.rb', line 10 def application_request @application_request end |
Instance Method Details
#add_body_to_header ⇒ Nokogiri::XML (private)
Adds soap body to header template
149 150 151 152 153 |
# File 'lib/sepa/soap_builder.rb', line 149 def add_body_to_header body = @template.at_css('env|Body') @header_template.root.add_child(body) @header_template end |
#build_certificate_request ⇒ Nokogiri::XML (private)
Sets contents for certificate request
78 79 80 |
# File 'lib/sepa/soap_builder.rb', line 78 def build_certificate_request set_body_contents end |
#build_common_request ⇒ Nokogiri::XML (private)
Builds generic request which is a request made with commands:
- Get User Info
- Download File
- Download File List
- Upload File
68 69 70 71 72 73 |
# File 'lib/sepa/soap_builder.rb', line 68 def build_common_request common_set_body_contents set_receiver_id process_header add_body_to_header end |
#calculate_digest(doc, node) ⇒ String (private)
remove this method and use Utilities#calculate_digest
Calculates digest hash for the given node in the given document. The node is canonicalized exclusively before digest calculation.
101 102 103 104 105 106 107 |
# File 'lib/sepa/soap_builder.rb', line 101 def calculate_digest(doc, node) sha1 = OpenSSL::Digest::SHA1.new node = doc.at_css(node) canon_node = canonicalize_exclusively(node) encode(sha1.digest(canon_node)).gsub(/\s+/, "") end |
#calculate_signature(doc, node) ⇒ String (private)
refactor to use canonicalization from utilities
Calculates signature for the given node in the given document. Uses the signing private key given to SoapBuilder for the signing. The node is canonicalized exclusively before signature calculation.
117 118 119 120 121 122 123 124 |
# File 'lib/sepa/soap_builder.rb', line 117 def calculate_signature(doc, node) sha1 = OpenSSL::Digest::SHA1.new node = doc.at_css(node) canon_signed_info_node = canonicalize_exclusively(node) signature = @signing_private_key.sign(sha1, canon_signed_info_node) encode(signature).gsub(/\s+/, "") end |
#common_set_body_contents ⇒ Object (private)
Sets nodes for generic requests, application request is base64 encoded here.
208 209 210 211 212 213 214 215 |
# File 'lib/sepa/soap_builder.rb', line 208 def common_set_body_contents set_application_request set_node @template, 'bxd|SenderId', @customer_id set_node @template, 'bxd|RequestId', request_id set_node @template, 'bxd|Timestamp', iso_time set_node @template, 'bxd|Language', @language set_node @template, 'bxd|UserAgent', "Sepa Transfer Library version #{VERSION}" end |
#find_correct_bank_extension ⇒ Object (private)
Extends the class with proper module depending on bank
49 50 51 |
# File 'lib/sepa/soap_builder.rb', line 49 def find_correct_bank_extension extend("Sepa::#{@bank.capitalize}SoapRequest".constantize) end |
#find_correct_build ⇒ Nokogiri::XML (private)
Determines which soap request to build based on command. Certificate requests are built differently than generic requests.
57 58 59 |
# File 'lib/sepa/soap_builder.rb', line 57 def find_correct_build STANDARD_COMMANDS.include?(@command) ? build_common_request : build_certificate_request end |
#load_header_template ⇒ Nokogiri::XML (private)
Loads soap header template to be later populated
129 130 131 132 |
# File 'lib/sepa/soap_builder.rb', line 129 def load_header_template path = File.open("#{SOAP_TEMPLATE_PATH}/header.xml") Nokogiri::XML(path) end |
#process_header ⇒ Object (private)
split into smaller methods
Add needed information to soap header. Mainly security related stuff. The process is as follows:
- The reference id of the security token is set using #set_token_id method
- Created and expires timestamps are set. Expires is set to be 5 minutes after creation.
- Timestamp reference id is set with Utilities#set_node_id method
- The digest of timestamp node is calculated and set to correct node
- The reference id of body is set with Utilities#set_node_id
- The digest of body is calculated and set to correct node
- The signature of SignedInfo node is calculated and added to correct node
- Own signing certificate is formatted (Begin and end certificate removed and linebreaks removed) and embedded in the soap
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/sepa/soap_builder.rb', line 167 def process_header set_token_id set_node(@header_template, 'wsu|Created', iso_time) set_node(@header_template, 'wsu|Expires', (Time.now.utc + 300).iso8601) = set_node_id(@header_template, OASIS_UTILITY, 'Timestamp', 0) = calculate_digest(@header_template, 'wsu|Timestamp') dsig = "dsig|Reference[URI='##{}'] dsig|DigestValue" set_node(@header_template, dsig, ) body_id = set_node_id(@template, ENVELOPE, 'Body', 1) body_digest = calculate_digest(@template, 'env|Body') dsig = "dsig|Reference[URI='##{body_id}'] dsig|DigestValue" set_node(@header_template, dsig, body_digest) signature = calculate_signature(@header_template, 'dsig|SignedInfo') set_node(@header_template, 'dsig|SignatureValue', signature) formatted_cert = format_cert(@own_signing_certificate) set_node(@header_template, 'wsse|BinarySecurityToken', formatted_cert) end |
#request_id ⇒ String (private)
Generates a random request id
203 204 205 |
# File 'lib/sepa/soap_builder.rb', line 203 def request_id SecureRandom.hex(17) end |
#set_application_request ⇒ Object (private)
217 218 219 |
# File 'lib/sepa/soap_builder.rb', line 217 def set_application_request set_node @template, 'bxd|ApplicationRequest', @application_request.to_base64 end |
#set_body_contents ⇒ Nokogiri::XML (private)
Sets soap body contents. Application request is base64 encoded here.
85 86 87 88 89 90 91 92 |
# File 'lib/sepa/soap_builder.rb', line 85 def set_body_contents set_node @template, "ApplicationRequest", @application_request.to_base64, namespace: cert_ns set_node @template, "SenderId", @customer_id, namespace: cert_ns set_node @template, "RequestId", request_id, namespace: cert_ns set_node @template, "Timestamp", iso_time, namespace: cert_ns @template end |
#set_node(doc, node, value, namespace: nil) ⇒ Object (private)
Sets value to a node's content in the given document
138 139 140 141 142 143 144 |
# File 'lib/sepa/soap_builder.rb', line 138 def set_node(doc, node, value, namespace: nil) if namespace doc.at("xmlns|#{node}", xmlns: namespace).content = value else doc.at(node).content = value end end |
#set_token_id ⇒ Object (private)
Generates a random token id and sets it to correct node
193 194 195 196 197 198 |
# File 'lib/sepa/soap_builder.rb', line 193 def set_token_id security_token_id = "token-#{SecureRandom.uuid}" @header_template.at('wsse|BinarySecurityToken')['wsu:Id'] = security_token_id @header_template.at('wsse|Reference')['URI'] = "##{security_token_id}" end |
#to_xml ⇒ String
Returns the soap as raw xml
42 43 44 |
# File 'lib/sepa/soap_builder.rb', line 42 def to_xml find_correct_build.to_xml end |