Thursday, May 5, 2011

Google Latitude : Ruby on Rails Example using Oauth

A good Example of Google Latitude on Ruby on Rails that was
what I was searching for the past few days .I thought it
would be good to include this one in my blog as it already
contained a lot of stuff on Google Latitude .

This are the simple steps you need to follow to
have your Google Latitude Oauth on Ruby on Rails
running .

Register Domain with Google

a)Go to: https://www.google.com/accounts/ManageDomains
Add a domain name & register it .

After registering your domain , the next step is to create
an pair of RSA keys , this one is needed for encryption
of the data to be send during the OAuth Handshake .

In linux and OS X you can use openssl
openssl req -x509 -nodes -days 365 -newkey rsa:1024
-sha1 -subj ‘/C=US/ST=CA/L=San
Francisco/CN=example.com’ -keyout rsakey.pem -out
rsacert.pem

Upload the rsacert.pem, and keep the rsakey.pem in a
safe place. For the Target URL path prefix, Just add
the domain name.

Get the Oauth Consumer Key and Secret .

2) OAuth GEM

Include in your environment.rb
config.gem "oauth"
You need to install it to use in your system .
Recommended version 0.4.1 .






3) Generate OAuth Access Token Model

$ ruby script/generate model OAuthAccessToken
Note: I've done this because I don't want to store
my access token directly in my User model. This
gives me the option of having tokens for multiple
scopes for a user through a polymorphic association.

Migration:

create_table :oauth_access_tokens do |t|
t.string :oauth_token, :oauth_secret, :scope
t.string :subject_type, :limit > 30 #for polymorphic association
t.integer :subject_id
t.timestampsend

4)User Model

has_one :latitude_access_token,
:model_name => 'OAuthAccessToken',
:as => :subject, :conditions => ['scope = ?','latitude']

5)Setup OAUTH Consumer for Latitude


Create class lib/o_auth_consumers.rb

class OAuthConsumers  
  Latitude = OAuth::Consumer.new( CONSUMER_KEY, 
      CONSUMER_SECRET, {
      :site => "https://www.google.com",
      :request_token_path => "/accounts/OAuthGetRequestToken",
      :access_token_path => "/accounts/OAuthGetAccessToken",
      :authorize_path=> "/latitude/apps/OAuthAuthorizeToken",
      :signature_method => "RSA-SHA1",
      :private_key_file => "#{RAILS_ROOT}/config/rsakey.pem" 
       #path to my rsakey that I saved earlier
  }) 

end
Remember to change the CONSUMER_KEY and
CONSUMER_SECRET which you got from step1.


6)Generate Controller for APP
ruby script/generate controller latitude

require 'oauth'
require 'oauth/signature/rsa/sha1'
class LatitudeController < ApplicationController

def index
    #check the user has a latitude oauth access token
    if current_user.latitude_access_token
      token = 
     OAuth::Token.new(current_user.latitude_access_token.oauth_token,     current_user.latitude_access_token.oauth_secret)
      @request = JSON.parse(OAuthConsumers::Google.request('get', "https://www.googleapis.com/latitude/v1/currentLocation", token).body)
      @lat = @request['data']['latitude']
      @lng = @request['data']['longitude']
      @time = Time.at((@request['data']['timestampMs'].to_i)
       /1000).strftime('%b %d, %Y - %T')
    else
      redirect_to :action => 'authorise'
    end
    
  end

 def authorise
 if !params[:oauth_token]

request_token = OAuthConsumers::Latitude.get_request_token(
{ :oauth_callback => "http://localhost:3000/latitude/authorise" },
{ :scope => "https://www.googleapis.com/auth/latitude" }
                        )

session[:oauth_secret] = request_token.secret
      redirect_to request_token.authorize_url + 
      "&domain=example.com&granularity=best&location=all"
      else
      request_token = OAuth::RequestToken.new(
                         OAuthConsumers::Latitude,
                         params[:oauth_token],
                         session[:oauth_secret]
                       )
 begin
        access_token = 
        request_token.get_access_token(
         :oauth_verifier => params[:oauth_verifier] )
        rescue
        redirect_to :action => 'index'
      end

if access_token
        #now save the access token for this user 
        OauthAccessToken.create :subject => current_user,
                                :scope => 'latitude',
                                :oauth_token => access_token.token,
                                :oauth_secret => access_token.secret
      end

   redirect_to latitude_path
    end
  end
  
end
7) Get the Latitude To Work

That's pretty much it. Go to http://localhost:3000/latitude,
you will be directed to Google to authorise your account,
then once that all goes through, you will be sent back to
your app, an Access Token will be created which will be
stored for your user. I'm not exactly sure how long this
lasts at the moment, but I'm testing that right now and
will update if I find anything important. Sorry guys just
can't show you a live demo right now . But if anyone of
you make one please do leave a comment over here ,so that
I can tell my readers "Hey checkout this live Demo".


Thanks to Ben Petro for creating the code on Ruby On Rails
platform .