Add handling for params

This commit is contained in:
Mike Mangino 2010-07-22 15:55:52 -04:00
parent 52491b2446
commit e812b926d6
5 changed files with 86 additions and 15 deletions

View File

@ -1,6 +1,6 @@
spec = Gem::Specification.new do |s| spec = Gem::Specification.new do |s|
s.name = 'facebooker2' s.name = 'facebooker2'
s.version = '0.0.4' s.version = '0.0.5'
s.summary = "Facebook Connect integration library for ruby and rails" s.summary = "Facebook Connect integration library for ruby and rails"
s.description = "Facebook Connect integration library for ruby and rails" s.description = "Facebook Connect integration library for ruby and rails"
s.files = Dir['lib/**/*.rb'] s.files = Dir['lib/**/*.rb']
@ -9,5 +9,6 @@ spec = Gem::Specification.new do |s|
s.author = "Mike Mangino" s.author = "Mike Mangino"
s.email = "mmangino@elevatedrails.com" s.email = "mmangino@elevatedrails.com"
s.homepage = "http://developers.facebook.com/docs/api" s.homepage = "http://developers.facebook.com/docs/api"
s.add_dependency('mogli', ">=0.0.4") s.add_dependency('mogli', ">=0.0.12")
s.add_dependency('ruby-hmac')
end end

View File

@ -1,6 +1,5 @@
# Facebooker2 # Facebooker2
require "mogli" require "mogli"
module Facebooker2 module Facebooker2
class NotConfigured < Exception; end class NotConfigured < Exception; end
class << self class << self

View File

@ -1,4 +1,6 @@
require "digest/md5" require "digest/md5"
require "hmac-sha2"
require "ruby-debug"
module Facebooker2 module Facebooker2
module Rails module Rails
module Controller module Controller
@ -10,26 +12,34 @@ module Facebooker2
end end
def current_facebook_user def current_facebook_user
fetch_client_and_user_from_cookie fetch_client_and_user
@_current_facebook_user @_current_facebook_user
end end
def current_facebook_client def current_facebook_client
fetch_client_and_user_from_cookie fetch_client_and_user
@_current_facebook_client @_current_facebook_client
end end
def fetch_client_and_user_from_cookie def fetch_client_and_user
return if @_fb_user_fetched return if @_fb_user_fetched
fetch_client_and_user_from_cookie
fetch_client_and_user_from_signed_request unless @_current_facebook_client
@_fb_user_fetched = true
end
def fetch_client_and_user_from_cookie
app_id = Facebooker2.app_id app_id = Facebooker2.app_id
if (hash_data = fb_cookie_hash_for_app_id(app_id)) and if (hash_data = fb_cookie_hash_for_app_id(app_id)) and
fb_cookie_signature_correct?(fb_cookie_hash_for_app_id(app_id),Facebooker2.secret) fb_cookie_signature_correct?(fb_cookie_hash_for_app_id(app_id),Facebooker2.secret)
client = Mogli::Client.new(hash_data["access_token"],hash_data["expires"].to_i) fb_create_user_and_client(hash_data["access_token"],hash_data["expires"],hash_data["uid"])
user = Mogli::User.new(:id=>hash_data["uid"])
user.client = @_current_facebook_client
fb_sign_in_user_and_client(user,client)
end end
@_fb_user_fetched = true end
def fb_create_user_and_client(token,expires,userid)
client = Mogli::Client.new(token,expires.to_i)
user = Mogli::User.new(:id=>userid)
fb_sign_in_user_and_client(user,client)
end end
def fb_sign_in_user_and_client(user,client) def fb_sign_in_user_and_client(user,client)
@ -67,6 +77,36 @@ module Facebooker2
test_string += secret test_string += secret
Digest::MD5.hexdigest(test_string) == hash["sig"] Digest::MD5.hexdigest(test_string) == hash["sig"]
end end
def fb_signed_request_json(encoded)
chars_to_add = 4-(encoded.size % 4)
encoded += ("=" * chars_to_add)
Base64.decode64(encoded)
end
def facebook_params
@facebook_param ||= fb_load_facebook_params
end
def fb_load_facebook_params
return {} if params[:signed_request].blank?
sig,encoded_json = params[:signed_request].split(".")
return {} unless fb_signed_request_sig_valid?(sig,encoded_json)
ActiveSupport::JSON.decode(fb_signed_request_json(encoded_json)).with_indifferent_access
end
def fb_signed_request_sig_valid?(sig,encoded)
base64 = Base64.encode64(HMAC::SHA256.digest(Facebooker2.secret,encoded))
#now make the url changes that facebook makes
url_escaped_base64 = base64.gsub(/=*\n?$/,"").tr("+/","-_")
sig == url_escaped_base64
end
def fetch_client_and_user_from_signed_request
if facebook_params[:oauth_token]
fb_create_user_and_client(facebook_params[:oauth_token],facebook_params[:expires],facebook_params[:user_id])
end
end
end end
end end
end end

View File

@ -21,7 +21,7 @@ module Facebooker2
}; };
(function() { (function() {
ar s = document.createElement('div'); var s = document.createElement('div');
s.setAttribute('id','fb-root'); s.setAttribute('id','fb-root');
document.documentElement.getElementsByTagName("HEAD")[0].appendChild(s); document.documentElement.getElementsByTagName("HEAD")[0].appendChild(s);
var e = document.createElement('script'); var e = document.createElement('script');

View File

@ -12,6 +12,7 @@ describe Facebooker2::Rails::Controller do
let :controller do let :controller do
controller = FakeController.new controller = FakeController.new
controller.stub!(:params).and_return({})
controller.stub!(:cookies).and_return("fbs_12345"=>"\"access_token=114355055262088|57f0206b01ad48bf84ac86f1-12451752|63WyZjRQbzowpN8ibdIfrsg80OA.&expires=0&secret=1e3375dcc4527e7ead0f82c095421690&session_key=57f0206b01ad48bf84ac86f1-12451752&sig=4337fcdee4cc68bb70ec495c0eebf89c&uid=12451752\"") controller.stub!(:cookies).and_return("fbs_12345"=>"\"access_token=114355055262088|57f0206b01ad48bf84ac86f1-12451752|63WyZjRQbzowpN8ibdIfrsg80OA.&expires=0&secret=1e3375dcc4527e7ead0f82c095421690&session_key=57f0206b01ad48bf84ac86f1-12451752&sig=4337fcdee4cc68bb70ec495c0eebf89c&uid=12451752\"")
controller controller
end end
@ -57,6 +58,16 @@ describe Facebooker2::Rails::Controller do
controller.current_facebook_client.access_token.should == "114355055262088|57f0206b01ad48bf84ac86f1-12451752|63WyZjRQbzowpN8ibdIfrsg80OA." controller.current_facebook_client.access_token.should == "114355055262088|57f0206b01ad48bf84ac86f1-12451752|63WyZjRQbzowpN8ibdIfrsg80OA."
end end
it "creates a client from params" do
controller.stub!(:cookies).and_return({})
controller.stub!(:facebook_params).and_return(
:oauth_token => "103188716396725|2.N0kBq5D0cbwjTGm9J4xRgA__.3600.1279814400-585612657|Txwy8S7sWBIJnyAXebEgSx6ntgY.",
:expires=>"1279814400",
:user_id => "585612657")
controller.current_facebook_client.access_token.should == "103188716396725|2.N0kBq5D0cbwjTGm9J4xRgA__.3600.1279814400-585612657|Txwy8S7sWBIJnyAXebEgSx6ntgY."
controller.current_facebook_user.id.should == "585612657"
end
it "verifies that the signature is correct" do it "verifies that the signature is correct" do
controller.fb_cookie_signature_correct?({ controller.fb_cookie_signature_correct?({
"access_token" => "114355055262088|57f0206b01ad48bf84ac86f1-12451752|63WyZjRQbzowpN8ibdIfrsg80OA.", "access_token" => "114355055262088|57f0206b01ad48bf84ac86f1-12451752|63WyZjRQbzowpN8ibdIfrsg80OA.",
@ -85,6 +96,26 @@ describe Facebooker2::Rails::Controller do
end end
describe "Signed Request handling" do
it "should correctly parse JSON that is poorly encoded" do
controller.fb_signed_request_json("eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImV4cGlyZXMiOjEyNzk4MTQ0MDAsIm9hdXRoX3Rva2VuIjoiMTAzMTg4NzE2Mzk2NzI1fDIuTjBrQnE1RDBjYndqVEdtOUo0eFJnQV9fLjM2MDAuMTI3OTgxNDQwMC01ODU2MTI2NTd8VHh3eThTN3NXQklKbnlBWGViRWdTeDZudGdZLiIsInVzZXJfaWQiOiI1ODU2MTI2NTcifQ").
should == "{\"algorithm\":\"HMAC-SHA256\",\"expires\":1279814400,\"oauth_token\":\"103188716396725|2.N0kBq5D0cbwjTGm9J4xRgA__.3600.1279814400-585612657|Txwy8S7sWBIJnyAXebEgSx6ntgY.\",\"user_id\":\"585612657\"}"
end
it "provides facebook_params if the sig is valid" do
Facebooker2.secret = "mysecretkey"
controller.stub!(:params).and_return(:signed_request=>"N1JJFILX63MufS1zpHZwN109VK1ggzEsD0N4pH-yPtc.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImV4cGlyZXMiOjEyNzk4MjE2MDAsIm9hdXRoX3Rva2VuIjoiMTAzMTg4NzE2Mzk2NzI1fDIucnJRSktyRzFRYXpGYTFoa2Z6MWpMZ19fLjM2MDAuMTI3OTgyMTYwMC01MzI4Mjg4Njh8TWF4QVdxTWtVS3lKbEFwOVgwZldGWEF0M004LiIsInVzZXJfaWQiOiI1MzI4Mjg4NjgifQ")
controller.facebook_params[:user_id].should == "532828868"
end
it "doesn't provide facebook params if the sig is invalid" do
Facebooker2.secret = "mysecretkey"
controller.stub!(:params).and_return(:signed_request=>"invalid.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImV4cGlyZXMiOjEyNzk4MjE2MDAsIm9hdXRoX3Rva2VuIjoiMTAzMTg4NzE2Mzk2NzI1fDIucnJRSktyRzFRYXpGYTFoa2Z6MWpMZ19fLjM2MDAuMTI3OTgyMTYwMC01MzI4Mjg4Njh8TWF4QVdxTWtVS3lKbEFwOVgwZldGWEF0M004LiIsInVzZXJfaWQiOiI1MzI4Mjg4NjgifQ")
controller.facebook_params.should be_blank
end
end
describe "Methods" do describe "Methods" do
it "allows you to sign in a user" do it "allows you to sign in a user" do