How do I use add_document_method in soap4r - ruby

I am looking for a complete example of how to use Soap4r to send a request to document/literal style web service request? The very same question on SOAP::RPC::Driver formatting problems. How can I change it? on Stackoverflow is there, but I couldn't find the way to call the method. Below is how my current request is generated.
<env:Body>
<n1:GetUserContact xmlns:n1="xmlns:http://foo.bar.baz.com/faz" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<userID xsi:type="xsd:string">
0123456
</userID>
</n1:GetUserContact>
</env:Body>
but I want my request to be in the following format, which is document/literal
<env:Body>
<n1:GetUserContact xmlns:n1="xmlns:http://foo.bar.baz.com/faz" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<n1:userID xsi:type="xsd:string">
0123456
</n1:userID>
</n1:GetUserContact>
</env:Body>
Or
<env:Body>
<GetUserContact xmlns="http://foo.bar.baz.com/faz" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<userID xsi:type="xsd:string">
0123456
</userID>
</GetUserContact>
</env:Body>
I also looked at this but I couldn't set the elementformdefault in my application because my Soap4r does not support this element name. I am not good at Ruby so excuse me if I am making any mistake. I am using ruby 1.8.6 on Ubuntu 8.04 and I installed soap4r-1.5.8 but even without that gem, my application runs(default soap4r library may be at work)
I don't know how to get ruby soap4r-1.5.8 lib to work instead of default soap4r library. You might wonder what my question is, and desperately all I want is to get this working anyway by any means.

Related

Extract account ID from Oracle SOA response in SoapUI

We have an Oracle SOA gateway setup that we can pass SOAP requests to. Right now, I'm trying to use SoapUI to create test cases. In this particular one, I'm trying to create a customer account. I've got the skeleton setup, but I'm having issues setting the correct XPath up to extract the account ID from the SOAP response.
The response I get back from the SOA gateway is:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<OutputParameters xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/apps/hz/soaprovider/plsql/hz_cust_account_v2pub/create_cust_account__1/">
<X_CUST_ACCOUNT_ID>1459660</X_CUST_ACCOUNT_ID>
<X_ACCOUNT_NUMBER>58946</X_ACCOUNT_NUMBER>
<X_PARTY_ID>3101110</X_PARTY_ID>
<X_PARTY_NUMBER>215767</X_PARTY_NUMBER>
<X_PROFILE_ID>3322847</X_PROFILE_ID>
<X_RETURN_STATUS>S</X_RETURN_STATUS>
<X_MSG_COUNT>0</X_MSG_COUNT>
<X_MSG_DATA xsi:nil="true"/>
</OutputParameters>
</env:Body>
</env:Envelope>
From this, I'm trying to extract the returned X_CUST_ACCOUNT_ID, and put it into a property. The XPath that I'm using is
//OutputParameters/X_CUST_ACCOUNT_ID
However, doing so, all I get is an error stating
"Missing match for Source XPath [//OutputParameters/X_CUST_ACCOUNT_ID]"
I've spent hours trying various XPath expressions, and all I get are either missing match or syntax errors.
You were missing the fact that OutputParameters also has a default namespace defined by
xmlns="http://xmlns.oracle.com/apps/hz/soaprovider/plsql/hz_cust_account_v2pub/create_cust_account__1/"
To also ignore this namespace, you can use the following expression:
//*[local-name()='OutputParameters']/*[local-name()='X_CUST_ACCOUNT_ID']

What methods exist to auto-generate ruby client stubs from WSDL files?

I'm using Ruby and the Savon gem to interact with SOAP/WS and would like to auto-generate the client request methods from the WSDL in Ruby.
Before I do this, I'd like to know if there's any other Ruby/SOAP library that does this?
Edit: Please note, I already know this isn't available in Savon out the box, in fact my intention is to add in the feature, I'm in the process checking if this exists somewhere else written in Ruby.
Since it's only few days since you asked this question, and I've run into same problem I've decided to create small script to do that.
Download - save as objects.rb for example and run with _bunde exec objects.rb path_to.wsdl_
https://gist.github.com/4622792
Let me know if it works ^^
Take a look at Savon's spec, it has pretty rich testing environment
I think ads_common by Google is relevant to you.
google-api-ads-ruby/ads_common at master ยท googleads/google-api-ads-ruby
rake generate can create the client libraries automatically from WSDL.
It is specialized for Google Ads, but this notion would be helpful to create a versatile client library automatically from WSDL in Ruby.

How to do xml signing in ruby

I need to sign xml using ruby, someone know any method or lib for that?
My xml skeleton is:
<?xml version="1.0" encoding="ISO-8859-1"?>
<Message>
<MessageId>
<ServiceId>service</ServiceId>
<Version>1.0</Version>
<MsgDesc>Service Description</MsgDesc>
<Code>4</Code>
<FromAddress>from</FromAddress>
<ToAddress>to</ToAddress>
<Date>2012-10-29</Date>
</MessageId>
<MessageBody/>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>??????</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>????????????</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>????????</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</message>
I tried this code for DigestValue and I have tested it, comparing it with my java example, but DigestValue is not matching with the response of my java example:
require 'base64'
require 'openssl'
to_sign_xml = File.read 'service.xml'
digest = OpenSSL::Digest::SHA1.digest(to_sign_xml)
digest = Base64.encode64(digest.to_s).gsub(/\n/, '')
raise digest.inspect
My file service.xml contain that:
<Message>
<MessageId>
<ServiceId>service</ServiceId>
<Version>1.0</Version>
<MsgDesc>Service Description</MsgDesc>
<Code>4</Code>
<FromAddress>from</FromAddress>
<ToAddress>to</ToAddress>
<Date>2012-10-29</Date>
</MessageId>
<MessageBody/>
<Message>
If you're still interested I made this gem a week ago. It's still in development but the basic stuff is implemented. This gem is tested against signatures created with the xmlsec library.
http://www.aleksey.com/xmlsec/
I'm actively working with this gem at the moment so bugs should be fixed relatively quick.
https://rubygems.org/gems/xmldsig
Unfortunately, XML signature creation and verification is very complicated. Details may be found in the spec. I started implementing it to propose as an addition to stdlib some time ago, but then stopped because another project became more important and Nokogiri started to offer the Canonicalization features that I needed and had unfortunately already implemented using libxml directly. You might want to have a look there to see what's needed, and then port the ideas to plain Nokogiri code.
Using those, it should be possible to completely implement XML-DSIG in Ruby. But be prepared, it's not an easy thing to do, lots and lots of small details that have great potential to drive you nuts...
You might be better off by switching to JRuby, and by integrating the default implementation of XML-DSIG that ships with the Java standard libraries.
Here is a usable gem for signing/digesting, however I still have some problem with canonicalization and probably that's why I don't get the proper digests: https://github.com/ebeigarts/signer

Savon: How to change header from being <env:Header> to <soap:Header> or something different

In Savon, is there a way to change
<env:Header>
to be
<soap:Header>
or anything different?
I've tried in the request block putting an additional header tag like this:
soap.header['soap:Header']
But that won't work.
I've browsed Savon Docs and haven't found anywhere to change that tag, only by manually building the XML.
EDITED for Savon 1.0.0
The value can be set in the configure block where you can also set logging and other parameters. Simply put
Savon.configure do |c|
c.env_namespace = :soap
end
into your code.
For newer versions of Savon:
Savon.client(env_namespace: :soapenv)

Ruby Oauth File upload/Multipart POST request

I've been looking at this for a couple of days now and haven't
found a solution. Is there a way to upload a file using OAuth-Ruby?
I am working with a REST system that protects their resource with oauth. I am building a test tool using ruby and oauth-ruby to make it easier to upload test data to the system. But I can't get around to upload files to the resources.
When I send a normal request, everything works but adding a file as a
parameter makes the signature invalid.
Example:
#access_token.post("http://.../imageresource", {:name=>"awesome cat"}, {'Content-Type' => 'multipart/form-data'})
works but gives me:
<error>
<message>images/POST: Request has no file data</message>
</error>
I am not sure how to add a file to the post.
Any thoughts on this?
Thanks,
I know this is old but I'm looking to do this too, this looks like it could do the trick.
Actually there's a question ruby-how-to-post-a-file-via-http-as-multipart-form-data that has an example.
This is either impossible to do with the oauth gem or exceedingly difficult. Either way, I don't know of any way to do it using that gem.
It can be done trivially with my signet gem as long as you have a handy way to construct a valid multipart request body. The construction of such a request body is out-of-scope of an OAuth gem, but should be pretty easy to do with most HTTP clients. The httpadapter gem can then translate the request into a form that signet can sign. Let me know if your preferred HTTP client isn't supported by httpadapter and I'll get that resolved immediately.
See the second example on the fetch_protected_resource method to get an idea for how this might be done.

Resources