FormData being converted to JSON - scala

I'm trying to post to a service using Spray
var authenticationPipeline: HttpRequest => Future[Authentication] = sendReceive ~> unmarshal[Authentication]
I have a pipeline setup, that is expecting to return a type of Authentication (a case class) and unmarshal this. Pretty straight forward.
When constructing requests, I attempt to use to following pattern.
val fD = FormData(Seq(
"grant_type" -> "authorization_code",
"code" -> authorisation_code,
"redirect_uri" -> "http://www.example.com",
"client_id" -> apiClientId,
"client_secret" -> apiClientSecretKey
))
I'm then sending this like so.
authenticationPipeline(Post(oauthUrl, fD))
The issue is that the service I'm posting to is returning an unsupported media type error, and upon further inspection it looks like the http enitity's media/content type is json and the content is a json string.
I've got around this issue by using URLEncode and posting this raw string by manually constructing a HTTP request, the issue is now I'm running into issue with encoding and it's just not very clean code. I guess I'm just unsure why this is happening almost implicitly.
The following links influenced how I set this up but don't mention similar issues, https://groups.google.com/forum/#!topic/spray-user/JjA2LCLfib8 & Posting application/x-www-form-urlencoded using spray
Any pointers on what I could be doing wrong would be appreciated. Please let me know if I've omitted any essential information.
Thanks in advance!

By testing my code in isolation I was able to determine that one of my imports was bringing in an implicit JSON marshaller. By being more specific with my imports I was able to surmount this problem. Hope this helps someone in the future!

Related

Is there a way to set headers for GET requests in KDB?

I'm trying to make get requested with .Q.hg (HTTP get), but I need to edit the request headers to provide API keys. How can I do this?
You can try this function I wrote a few years back for a POC (similar reason - I needed to supply multiple headers). It's based on .Q.hmb which underpins .Q.hp/hg. Please note - it was never extensively tested & there are likely better alternatives out there, but it will perhaps work as a quick solution.
k)req:{[url;method;hd;bd]d:s,s:"\r\n";url:$[10=#url;url;1_$url];p:{$[#y;y;x]}/getenv`$_:\("HTTP";"NO"),\:"_PROXY";u:.Q.hap#url;t:~(~#*p)||/(*":"\:u 2)like/:{(("."=*x)#"*"),x}'","\:p 1;a:$[t;p:.Q.hap#*p;u]1;(4+*r ss d)_r:(`$":",,/($[t;p;u]0 2))($method)," ",$[t;url;u 3]," HTTP/1.1",s,(s/:("Connection: close";"Host: ",u 2),((0<#a)#,$[t;"Proxy-";""],"Authorization: Basic ",.Q.btoa a),($[#hd;(!hd),'": ",/:. hd;()])),($[#bd;(s,"Content-length: ",$#bd),d,bd;d])}
It takes 4 arguments:
Resource URL
HTTP method
Dictionary of headers
Message body as JSON object
Sending a request to a test server..
q).j.k req["https://httpbin.org/get";`GET;("Content-Type";"someOtherHeader")!(.h.ty`json;"blah");""] // no body so pass empty string
args | (`symbol$())!()
headers| `Content-Type`Host`Someotherheader`X-Amzn-Trace-Id!("application/jso..
url | "https://httpbin.org/get"

Can't authenticate properly with Chef API

I have been attempting to put together a Scala library for making calls to Chef APIs but I keep getting this problem with authenticating the API calls.
I have triple checked and the private key is correct and all other headers. The code I am using is here:
https://github.com/LiamHaworth/shef/blob/master/src/main/scala/au/id/haworth/shef/ChefUtils.scala
and I am calling it like so
import au.id.haworth.shef.{RequestMethod, ChefUtils}
import au.id.haworth.shef.ChefServer
val key = io.Source.fromFile("user.pem").getLines.mkString("\n")
val chefServer = ChefServer("chef.example.com", 443, "https", "myorg", "myuser", key)
ChefUtils.sendRequestToServer(chefServer, RequestMethod.GET, "", "")
But I keep on getting this response from the server
"{"error":["Invalid signature for user or client 'myuser'"]}"
I am sure that the problem is simple and is staring me in the face but I can't see it so any help will be greatly appreciated
I have successfully got the API to authenticate. After using knife in debug mode to check what headers it was producing and adding a extra line into my mixlib to print the canonical headers I got it working.
With the canonical headers printed by mixlib I ran them through my signing code and found that I wasn't getting the same result with the signature so I dug a bit deeper to find I was signing my headers in the terribly wrong way.
I was digesting them not signing them! After swapping out RSADigestSigner for Signature in my code and changing the algorithm (SHA1withRSA to RSA) I finally got the headers to be signed the same as the mixlib ones!.
TL;DR I derped and used the wrong classes to do what I wanted to do. The changes I made can be seen in this commit:
https://github.com/LiamHaworth/shef/commit/2db2aa5b89cae272eecd0901be91533b61d2a6c3

Get form parameters from a post request using spray/scala

I'm really new with all this Scala/Spray. With some testing I was able to get parameters from a Get request using the parameters function. However I'm trying to fetch some parameters sent from a POST request on the body of the request. It seems like parameters function is unable to fetch those values.
As an example, I'm trying to get this values "name=john&lastname=smith" from the post request body. What is the best option to get these values?
Thank you
You could use [Form-Field-Filters] to extract parameters from POSTs
[Form-Field-Filters] https://github.com/spray/spray/wiki/Form-Field-Filters
Indeed, the parameters directive only handles things actually in the query-string and not parameters in the body of the request. To get things out of the body, you'll need to use the content directive and then unmarshal the content.
This spray-user thread may be helpful, as it includes some unmarshalling code doing precisely what you're looking for.
As of recent Spray versions, you need to use the Unmarshaller for FormData.

JAX-RS/Jersey client: unmarshall URI encoded name/value pairs

I wondered if anyone knows how best to unmarshall a response from a JAX-RS/Jersey client that is returning a response from paypal. The response is URI encoded in name/value pairs. I ask because I've already written some code that unmarshalls a google geocode response, given a class hierarchy it automagically transforms the JSON response into objects, but alas I've not been able to do similar with this simpler problem.
TIMESTAMP=2011%2d06%2d03T13%3a22%3a17Z&CORRELATIONID=f708c43c1d078&ACK=Success&VERSION=56%
Thanks for any help.
You're going to need to do something like this: Parsing query strings on Android.

Problem with OAuth, POST with parameters

I'm using Jon Crosby's open source Objective-C OAuth library http://code.google.com/p/oauthconsumer/ for some basic http authentication that does not deal with tokens, only consumer key and consumer secret. My code works great for GET, GET with parameters in the URL, and POST. When I issue a POST request that has parameters in the URL, though, the request fails authorization. I'm trying to figure out why.
The server is using Apache Commons OAuth, so I'd like to compare my base string with that library. Here's a contrived example and the base string and signature produced by my library. Can anyone see what the problem is?
consumer key: abcdef
consumer secret: ghijkl
POST request: http://emptyrandomhost.com/a/uriwith/params?interesting=foo&prolific=bar
my base string: POST&http%3A%2F%2Femptyrandomhost.com%2Fa%2Furiwith%2Fparams&interesting%3Dfoo%26oauth_consumer_key%3Dabcdef%26oauth_nonce%3D1%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D2%26oauth_version%3D1.0%26prolific%3Dbar
This data produces the following OAuth header authorization:
Authorization: OAuth oauth_consumer_key="abcdef",
oauth_version="1.0",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="2",
oauth_nonce="1",
oauth_signature="Z0PVIz5Lo4eB7aZFT8FE3%2FFlbz0%3D"
And apparently my signature is wrong. The problem has to either be in the construction of the base string, in the way that the HMAC-SHA1 function is implemented (using Apple's CCHmac from CommonHMAC.h, so hopefully this isn't it), or with my Base64Transcoder, which is open source c. 2003 by Jonathan Wight/Toxic Software. I primarily suspect the base string, since the requests work for GET and POST and only fail with POST with URL parameters as above.
Can someone with lots of OAuth experience spot the problem above? Something else that would be very useful is the base string that is produced by Apache Commons OAuth in their authentication. Thanks.
As per RFC 5849 section 3.4.1.2, the OAuth base string URI does not include the query string or fragment. If either the client or the server does not remove the query parameters from the base string URI and add them to the normalized OAuth parameter list, the signatures won't match. Unfortunately, it's hard to tell which side is making this mistake. But it's easy to determine this is the problem: If it always works without query parameters but always fails with query parameters, you can be pretty sure that one side or the other is generating the wrong base string. (Be sure that it always happens though... intermittent errors would be something else. Similarly, if it never works with or without a query string, that would also be something else.) The other possibility is that normalization was done incorrectly — the parameter list must be sorted and percent encoded sequences must be upper-cased. If it's not normalized correctly on both sides, that will also cause a base string mismatch, and thus a signature mismatch.
you can build and check visually your request at this URL:
http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iv-signing-requests/
Open the boxes denoted by [+] signs and fill in your values, that way you may be able to see if the problem is at your code, or at the provider side.