Added basic controller and helper code
This commit is contained in:
parent
e5997a8697
commit
e60e187a05
@ -1 +1,13 @@
|
|||||||
# Facebooker2
|
# Facebooker2
|
||||||
|
module Facebooker2
|
||||||
|
|
||||||
|
class << self
|
||||||
|
attr_accessor :api_key, :secret, :app_id
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
require "mogli"
|
||||||
|
|
||||||
|
require "facebooker2/rails/controller"
|
||||||
|
require "facebooker2/rails/helpers/facebook_connect"
|
4
lib/facebooker2/rails.rb
Normal file
4
lib/facebooker2/rails.rb
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
module Facebooker2
|
||||||
|
module Rails
|
||||||
|
end
|
||||||
|
end
|
59
lib/facebooker2/rails/controller.rb
Normal file
59
lib/facebooker2/rails/controller.rb
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
require "digest/md5"
|
||||||
|
require "ruby-debug"
|
||||||
|
module Facebooker2
|
||||||
|
module Rails
|
||||||
|
module Controller
|
||||||
|
|
||||||
|
def current_facebook_user
|
||||||
|
fetch_client_and_user_from_cookie
|
||||||
|
@_current_facebook_user
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_facebook_client
|
||||||
|
fetch_client_and_user_from_cookie
|
||||||
|
@_current_facebook_client
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_client_and_user_from_cookie
|
||||||
|
return if @_fb_user_fetched
|
||||||
|
app_id = Facebooker2.app_id
|
||||||
|
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)
|
||||||
|
@_current_facebook_client = Mogli::Client.new(hash_data["access_token"],hash_data["expires"].to_i)
|
||||||
|
@_current_facebook_user = Mogli::User.new(:id=>hash_data["uid"])
|
||||||
|
@_current_facebook_user.client = @_current_facebook_client
|
||||||
|
end
|
||||||
|
@_fb_user_fetched = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def fb_cookie_hash_for_app_id(app_id)
|
||||||
|
return nil unless fb_cookie_for_app_id?(app_id)
|
||||||
|
hash={}
|
||||||
|
data = fb_cookie_for_app_id(app_id)
|
||||||
|
data.split("&").each do |str|
|
||||||
|
parts = str.split("=")
|
||||||
|
hash[parts.first] = parts.last
|
||||||
|
end
|
||||||
|
hash
|
||||||
|
end
|
||||||
|
|
||||||
|
def fb_cookie_for_app_id?(app_id)
|
||||||
|
!fb_cookie_for_app_id(app_id).nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def fb_cookie_for_app_id(app_id)
|
||||||
|
cookies["fbs_#{app_id}"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def fb_cookie_signature_correct?(hash,secret)
|
||||||
|
sorted_keys = hash.keys.reject {|k| k=="sig"}.sort
|
||||||
|
test_string = ""
|
||||||
|
sorted_keys.each do |key|
|
||||||
|
test_string += "#{key}=#{hash[key]}"
|
||||||
|
end
|
||||||
|
test_string += secret
|
||||||
|
Digest::MD5.hexdigest(test_string) == hash["sig"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
45
lib/facebooker2/rails/helpers/facebook_connect.rb
Normal file
45
lib/facebooker2/rails/helpers/facebook_connect.rb
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
module Facebooker2
|
||||||
|
module Rails
|
||||||
|
module Helpers
|
||||||
|
module FacebookConnect
|
||||||
|
#
|
||||||
|
# Render an <fb:login-button> element, similar to
|
||||||
|
# fb_login_button. Adds a js redirect to the onlogin event via rjs.
|
||||||
|
#
|
||||||
|
# ==== Examples
|
||||||
|
#
|
||||||
|
# fb_login_and_redirect '/other_page'
|
||||||
|
# => <fb:login-button onlogin="window.location.href = "/other_page";"></fb:login-button>
|
||||||
|
#
|
||||||
|
# Like #fb_login_button, this also supports the :text option
|
||||||
|
#
|
||||||
|
# fb_login_and_redirect '/other_page', :text => "Login with Facebook", :v => '2'
|
||||||
|
# => <fb:login-button onlogin="window.location.href = "/other_page";" v="2">Login with Facebook</fb:login-button>
|
||||||
|
#
|
||||||
|
def fb_login_and_redirect(url, options = {})
|
||||||
|
js = update_page do |page|
|
||||||
|
page.redirect_to url
|
||||||
|
end
|
||||||
|
|
||||||
|
text = options.delete(:text)
|
||||||
|
|
||||||
|
content_tag("fb:login-button",text,options.merge(:onlogin=>js))
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Logs the user out of facebook and redirects to the given URL
|
||||||
|
# args are passed to the call to link_to_function
|
||||||
|
def fb_logout_link(text,url,*args)
|
||||||
|
function= "FB.logout(function() {window.location.href = '#{url}';})"
|
||||||
|
link_to_function text, function, *args
|
||||||
|
end
|
||||||
|
|
||||||
|
def fb_server_fbml(style=nil,&proc)
|
||||||
|
style_string=" style=\"#{style}\"" if style
|
||||||
|
content = capture(&proc)
|
||||||
|
concat("<fb:serverFbml#{style_string}><script type='text/fbml'>#{content}</script></fb:serverFbml>")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
spec/facebooker2_spec.rb
Normal file
20
spec/facebooker2_spec.rb
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
require "spec_helper"
|
||||||
|
describe Facebooker2 do
|
||||||
|
|
||||||
|
describe "Configuration" do
|
||||||
|
it "allows setting of the api_key" do
|
||||||
|
Facebooker2.api_key = "123456"
|
||||||
|
Facebooker2.api_key.should == "123456"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows setting of the secret" do
|
||||||
|
Facebooker2.secret = "mysecret"
|
||||||
|
Facebooker2.secret.should == "mysecret"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has an app_id" do
|
||||||
|
Facebooker2.app_id = "12345"
|
||||||
|
Facebooker2.app_id.should == "12345"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
49
spec/helpers/facebook_connect_spec.rb
Normal file
49
spec/helpers/facebook_connect_spec.rb
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
require "spec_helper"
|
||||||
|
require "ruby-debug"
|
||||||
|
describe Facebooker2::Rails::Helpers::FacebookConnect, :type=>:helper do
|
||||||
|
include Facebooker2::Rails::Helpers::FacebookConnect
|
||||||
|
describe "fb_login_and_redirect" do
|
||||||
|
it "renders a login button" do
|
||||||
|
fb_login_and_redirect("/").should ==
|
||||||
|
"<fb:login-button onlogin=\"window.location.href = "/";\"></fb:login-button>"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows you to specify the text of the button" do
|
||||||
|
fb_login_and_redirect("/",:text=>"my test").should ==
|
||||||
|
"<fb:login-button onlogin=\"window.location.href = "/";\">my test</fb:login-button>"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Logging out" do
|
||||||
|
it "has an fb_logout_link" do
|
||||||
|
fb_logout_link("logout","/").should ==
|
||||||
|
"<a href=\"#\" onclick=\"FB.logout(function() {window.location.href = '/';}); return false;\">logout</a>"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "server FBML" do
|
||||||
|
it "renders the yielded content inside of an fbml block" do
|
||||||
|
fb_server_fbml do
|
||||||
|
|
||||||
|
end
|
||||||
|
output_buffer.should == "<fb:serverFbml><script type='text/fbml'></script></fb:serverFbml>"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "includes the content inside the block" do
|
||||||
|
fb_server_fbml do
|
||||||
|
"inner text"
|
||||||
|
end
|
||||||
|
output_buffer.should == "<fb:serverFbml><script type='text/fbml'>inner text</script></fb:serverFbml>"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows specifying style attributes" do
|
||||||
|
fb_server_fbml "width: 750px;" do
|
||||||
|
|
||||||
|
end
|
||||||
|
output_buffer.should == "<fb:serverFbml style=\"width: 750px;\"><script type='text/fbml'></script></fb:serverFbml>"
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
88
spec/rails/controller_spec.rb
Normal file
88
spec/rails/controller_spec.rb
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
require "spec_helper"
|
||||||
|
|
||||||
|
class FakeController
|
||||||
|
include Facebooker2::Rails::Controller
|
||||||
|
end
|
||||||
|
|
||||||
|
describe Facebooker2::Rails::Controller do
|
||||||
|
before(:each) do
|
||||||
|
Facebooker2.app_id = "12345"
|
||||||
|
Facebooker2.secret = "42ca6de519d53f6e0420247a4d108d90"
|
||||||
|
end
|
||||||
|
describe "Cookie handling" do
|
||||||
|
let :controller do
|
||||||
|
controller = FakeController.new
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
it "knows if a cookie exists for this app" do
|
||||||
|
controller.fb_cookie_for_app_id?(12345).should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "knows when there isn't a cookie" do
|
||||||
|
controller.fb_cookie_for_app_id?(432432).should be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "gets the hash from the cookie" do
|
||||||
|
controller.stub!(:cookies).and_return("fbs_12345"=>"param1=val1¶m2=val2")
|
||||||
|
controller.fb_cookie_hash_for_app_id(12345).should == {"param1"=>"val1", "param2"=>"val2"}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a user from the cookie" do
|
||||||
|
controller.current_facebook_user.should_not be_nil
|
||||||
|
controller.current_facebook_user.should be_an_instance_of(Mogli::User)
|
||||||
|
controller.current_facebook_user.id.should == "12451752"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't create a user if there is no app cookie" do
|
||||||
|
Facebooker2.app_id="other_app"
|
||||||
|
controller.current_facebook_user.should be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a client from the cookie" do
|
||||||
|
controller.current_facebook_client.should_not be_nil
|
||||||
|
controller.current_facebook_client.should be_an_instance_of(Mogli::Client)
|
||||||
|
controller.current_facebook_client.access_token.should == "114355055262088|57f0206b01ad48bf84ac86f1-12451752|63WyZjRQbzowpN8ibdIfrsg80OA."
|
||||||
|
end
|
||||||
|
|
||||||
|
it "verifies that the signature is correct" do
|
||||||
|
controller.fb_cookie_signature_correct?({
|
||||||
|
"access_token" => "114355055262088|57f0206b01ad48bf84ac86f1-12451752|63WyZjRQbzowpN8ibdIfrsg80OA.",
|
||||||
|
"expires" => "0",
|
||||||
|
"secret" => "1e3375dcc4527e7ead0f82c095421690",
|
||||||
|
"session_key" => "57f0206b01ad48bf84ac86f1-12451752",
|
||||||
|
"uid" => "12451752",
|
||||||
|
"sig" => "4337fcdee4cc68bb70ec495c0eebf89c"},
|
||||||
|
"42ca6de519d53f6e0420247a4d108d90"
|
||||||
|
).should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false if the signature is not correct" do
|
||||||
|
controller.fb_cookie_signature_correct?({
|
||||||
|
"access_token" => "114355055262088|57f0206b01ad48bf84ac86f1-12451752|63WyZjRQbzowpN8ibdIfrsg80OA.",
|
||||||
|
"expires" => "0",
|
||||||
|
"secret" => "1e3375dcc4527e7ead0f82c095421690",
|
||||||
|
"session_key" => "57f0206b01ad48bf84ac86f1-12451752",
|
||||||
|
"uid" => "5436785463785",
|
||||||
|
"sig" => "4337fcdee4cc68bb70ec495c0eebf89c"},
|
||||||
|
"42ca6de519d53f6e0420247a4d108d90"
|
||||||
|
).should be_false
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Methods" do
|
||||||
|
it "has a current_facebook_user" do
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has a current_facebook_client" do
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
0
spec/spec.opts
Normal file
0
spec/spec.opts
Normal file
26
spec/spec_helper.rb
Normal file
26
spec/spec_helper.rb
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
require "rubygems"
|
||||||
|
require "active_support"
|
||||||
|
require "action_pack"
|
||||||
|
require "action_view"
|
||||||
|
require "action_controller"
|
||||||
|
require 'action_controller/test_process'
|
||||||
|
require 'action_controller/integration'
|
||||||
|
require 'active_support/test_case'
|
||||||
|
require 'spec/test/unit'
|
||||||
|
|
||||||
|
|
||||||
|
require "facebooker2"
|
||||||
|
gem "rspec-rails"
|
||||||
|
|
||||||
|
#required because view tests need a controller
|
||||||
|
class ApplicationController < ActionController::Base
|
||||||
|
end
|
||||||
|
|
||||||
|
#load just the files needed for helper tests so that we don't need a full rails stack
|
||||||
|
require "spec/rails/example/functional_example_group"
|
||||||
|
require "spec/rails/example/helper_example_group"
|
||||||
|
require 'spec/rails/interop/testcase'
|
||||||
|
|
||||||
|
Spec::Example::ExampleGroupFactory.default(ActiveSupport::TestCase)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user