ATTENTION: This document is only intended for developers.
Tomboy (or any other OAuth consumer like Tomdroid) uses OAuth for authentication when doing cloud/server synchronisation. The necessary OAuth Urls are retrieved via the root ApiRef call, and then used for the the OAuth 1.0a authentication/authorization steps.
Throughout this document we reference to the semi-official OAuth 1.0a flow chart:
Note that the terminology used in the flow chart is represented by an earlier draft of the OAuth specification (see next paragraph) - nevertheless, the flow is still the same.
The OAauth 1.0a specification is defined in RFC5849. For a better understanding, the terminology given in the RFC5849 Section 1.1 is mapped to the Tomboy/Rainy usecase here:
client (or consumer): The Tomboy note taking application (or equivalent clients like tomdroid)
server (or service provider): The cloud synchronisatzion server like Snowy, Rainy, Ubuntu One
user: The user (human) that operates Tomboy
protected resource: A note on the server
Sample HTTP Headers send by Tomboy when it connects to /oauth/request_token:
(wrapping and linebreaks added)
Authorization: OAuth realm="Snowy", oauth_callback="http%3A%2F%2Flocalhost%3A8000%2Ftomboy-web-sync%2F", oauth_consumer_key="anyone", oauth_nonce="2800852", oauth_signature="61EhqDJKkVzoZG%2bmwv0trkqaXp0%3d", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1351664093", oauth_version="1.0"
oauth_callback parameter indicates the Url that should be called once the authentication (NOT to be confused with authorization!) is complete. In the above example, Tomboy create a HTTP listener on localhost port 8000 on which it will await the authorization.
The Server (i.e. Rainy) checks that:
consumer_keyis known and valid
consumer_keysend by Tomboy or other clients MUST be
anyone- this is a hardcoded value
anyonein all Tomboy clients
Also this checks are not necessary since the key/secret are publicly known, the OAuth implementation requires this.
After the checks complete, the server responds with a pair of generated values that together form the unauthorized request token:
HTTP/1.1 200 OK oauth_token=e8eb5f51-4136-4df4-ac60-adedf79b7ce2 &oauth_token_secret=d5f971ea-acb4-4b7a-b7d4-561979f455cf &oauth_callback_confirmed=true
The consumer (Tomboy) now uses the authorize url it has requested via the root ApiRef call, which is most likely
/oauth/authorize and appends the request token obtained in step B:
GET /oauth/authorize?oauth_token=e8eb5f51-4136-4df4-ac60-adedf79b7ce2 &oauth_callback=http%3a%2f%2flocalhost%3a8000%2ftomboy-web-sync%2f HTTP/1.1
The above request is a live example is generated by Tomboy. Note that specifing an
oauth_callback is in violation of the OAUTH 1.0a RFC: The callback MUST be provided in step A. Although additional parameters are allowed in Step C, those additioanl parameters MUST NOT start with the
oauth_ prefix according to RFC5849. In the server implementation (Rainy), we can just ignore this parameter, and use the callback Url from Step A.
TODO: make sure Tomboy actually sends the callback in Step A (like Tomdroid does).
Tomdroid does not specify a callback url in this step (which is in compliance with the OAuth RFC), which means we MUST save the callback url from step A for this request token, or use a hardcoded callback which is most likely
tomdroid://sync. This special Url scheme
tomdroid seems to be android specific an is handled by tomdroids internal OAuth consumer library. We just make sure that we redirect to the callback url later on.
The server response MUST be an authorize page and can be any website that performs authentication, for example