|
HowPownceAPIworks
This is a rough draft of how the Pownce API works
The Pownce API works like this:First, all requests should at least specify the Content-Type to be "application/x-www-urlencoded" First, you must perform a GET command to /api/login/ using standard, basic, HTTP auth. You provide your pownce username and password, base64'd as is specified and you get an XML response with several bits of information. The most important is the 'token' attribute of the root element of the response. The rest of the information are specifics about your account such as your full name, the URL of your profile icon, what kind of account you have, your max file upload amount, and a few more. The response looks like this: <?xml version="1.0" encoding="utf-8"?>
<login xmlns="http://pownce.com/Atom" xmlns:atom="http://www.w3.org/2005/Atom"
token="xxxxxxxxxxxxxxxxxxxxxxx">
<user pro="1" maxuploadsizemb="100">
<atom:author>
<atom:name>Clint E.</atom:name>
<atom:uri>http://pownce.com/clint/</atom:uri>
<username>clint</username>
<image>http://pownce.com/profile_photos/c/l/i/clint/275_medium.png</image>
</atom:author>
</user>
</login>All further requests to the API will require that you construct what is known as a "WSSE Username Token" and must be passed along with the rest of the POST data with the parameter key of 'auth'. A WSSE Username Token is formatted as follows UsernameToken Username="clint", PasswordDigest="2Q5EIuxjY4tpbLoLXWObXFtd+jw=", Nonce="DSALlkfdd34lkfsd=", Created="2007-07-16T19:54:21Z" This token consists of 4 items, the username, a password digest, a "Nonce" or random string, and a timestamp in W3DTF format 1 2. The Username is your Pownce username, your Nonce is randomly generated by you, and the timestamp is the time when your Nonce was created. Technically, this doesn't have to be speficially when you created the Nonce, but it should be consistent throughout this process. As per Mark Pilgrim's explaination 1, the Password Digest is specified as follows:
In my python library this looks like this: def get_digest(password=None,nonce=None,timestamp=None):
m = hashlib.sha1()
if timestamp == None:
timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
if password == None:
password = PASSWORD
if nonce == None:
n = hashlib.sha1()
n.update(SECRET+str(time.time()))
nonce = n.hexdigest()
m.update(nonce+timestamp+password)
password_sha = m.digest()
digest = base64.encodestring(password_sha)
return digest.strip(), timestamp, nonce.strip()I create the nonce by concatinating a static string which the user supplies with a UNIX timestamp when the nonce was created. Again, this need not be random, but should be consistent throughout. Once you've generated a working PasswordDigest, you can simply plop into the above format all the peices of the puzzle (nonce, timestamp, username, and PasswordDigest) as POST parameters. Depending on the type of note you'd like to upload you will have to add additional parameters. Sending Notes:Every note you send must have a destination (called 'note_to'), which must be one of the following:
The numbers xx and yyy are probably provided in a call to /api/notes/for/<your_username>/ There are four types of notes, all of which include a body. This is specified as "note-body". The type of note you're sending is specified by a 'note-type' parameter which I indicate in parenthesis next to each of the following items. 1. Message (note-message) A message is the simplest type of note. You must simply send along the note-type, note-body, and send_to parameters along with your WSSE Username token. 2. Link (note-link) A link note is the next simplest. In addition to all the items you send with a message, you also send along a 'url' parameter containing the url of the link. 3. Event (note-event) An event is the most complex note. In addition to all the parameters you send with the message note, you must send along the following:
A file is also complex but in a different way than the event note. In addition to the items you specify with the message note, you must send a 'Filename' parameter. In addition, you must alter the headers of your request to contain: Content-Type: multipart/form-data; boundary=------------ae0GI3ei4gL6ae0Ij5Ij5ei4KM7ei4 Content-Length: yyyyy for example. The random characters there are meaningless, and I'm not sure if there is a required length. yyyyy is the length, in characters, of the MIME encoded data you send to the server. I'm not going to delve in to the specifices of mime-encoding your request, but this is what the data of your request would look like for a small text file: ------------ae0GI3ei4gL6ae0Ij5Ij5ei4KM7ei4 Content-Disposition: form-data; name="Filename" testfile.txt ------------ae0GI3ei4gL6ae0Ij5Ij5ei4KM7ei4 Content-Disposition: form-data; name="auth" UsernameToken Username="clint", PasswordDigest="ztx+laokpMlpZaWtnOa57k8MzIQ=", Nonce="KjsaeiuDFKJEwkr4332rL=", Created="2007-07-16T21:35:50Z" ------------ae0GI3ei4gL6ae0Ij5Ij5ei4KM7ei4 Content-Disposition: form-data; name="note_type" note-file ------------ae0GI3ei4gL6ae0Ij5Ij5ei4KM7ei4 Content-Disposition: form-data; name="note_body" my file ------------ae0GI3ei4gL6ae0Ij5Ij5ei4KM7ei4 Content-Disposition: form-data; name="note_to" all ------------ae0GI3ei4gL6ae0Ij5Ij5ei4KM7ei4 Content-Disposition: form-data; name="media_file"; filename="testfile.txt" Content-Type: application/octet-stream Blah! These are file contents! ------------ae0GI3ei4gL6ae0Ij5Ij5ei4KM7ei4 Content-Disposition: form-data; name="Upload" Submit Query ------------ae0GI3ei4gL6ae0Ij5Ij5ei4KM7ei4-- |
Sign in to add a comment
Just to clarify the construction of the WSSE Username token:
The password that is used is not the user password. You have to use the token that was returned by the GET command to /api/login/.
nevermind, had to do additional processing after using URLEncoder, working now