bryanl-facebooker2 0.0.5.x1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ # Facebooker2
2
+ require "mogli"
3
+ module Facebooker2
4
+ class NotConfigured < Exception; end
5
+ class << self
6
+ attr_accessor :api_key, :secret, :app_id
7
+ end
8
+
9
+ def self.secret
10
+ @secret || raise_unconfigured_exception
11
+ end
12
+
13
+ def self.app_id
14
+ @app_id || raise_unconfigured_exception
15
+ end
16
+
17
+ def self.raise_unconfigured_exception
18
+ raise NotConfigured.new("No configuration provided for Facebooker2. Either set the app_id and secret or call Facebooker2.load_facebooker_yaml in an initializer")
19
+ end
20
+
21
+ def self.configuration=(hash)
22
+ self.api_key = hash[:api_key]
23
+ self.secret = hash[:secret]
24
+ self.app_id = hash[:app_id]
25
+ end
26
+
27
+ def self.load_facebooker_yaml
28
+ config = YAML.load(ERB.new(File.read(File.join(::Rails.root,"config","facebooker.yml"))).result)[::Rails.env]
29
+ raise NotConfigured.new("Unable to load configuration for #{::Rails.env} from facebooker.yml. Is it set up?") if config.nil?
30
+ self.configuration = config.with_indifferent_access
31
+ end
32
+
33
+ def self.cast_to_facebook_id(object)
34
+ if object.kind_of?(Mogli::Profile)
35
+ object.id
36
+ elsif object.respond_to?(:facebook_id)
37
+ object.facebook_id
38
+ else
39
+ object
40
+ end
41
+ end
42
+ end
43
+
44
+
45
+ require "facebooker2/rails/controller"
46
+ require "facebooker2/rails/helpers/facebook_connect"
47
+ require "facebooker2/rails/helpers/javascript"
48
+ require "facebooker2/rails/helpers/request_forms"
49
+ require "facebooker2/rails/helpers/user"
50
+ require "facebooker2/rails/helpers"
@@ -0,0 +1,4 @@
1
+ module Facebooker2
2
+ module Rails
3
+ end
4
+ end
@@ -0,0 +1,113 @@
1
+ require "digest/md5"
2
+ require "hmac-sha2"
3
+ require "ruby-debug"
4
+ module Facebooker2
5
+ module Rails
6
+ module Controller
7
+
8
+ def self.included(controller)
9
+ controller.helper Facebooker2::Rails::Helpers
10
+ controller.helper_method :current_facebook_user
11
+ controller.helper_method :current_facebook_client
12
+ controller.helper_method :facebook_params
13
+ end
14
+
15
+ def current_facebook_user
16
+ fetch_client_and_user
17
+ @_current_facebook_user
18
+ end
19
+
20
+ def current_facebook_client
21
+ fetch_client_and_user
22
+ @_current_facebook_client
23
+ end
24
+
25
+ def fetch_client_and_user
26
+ return if @_fb_user_fetched
27
+ fetch_client_and_user_from_cookie
28
+ fetch_client_and_user_from_signed_request unless @_current_facebook_client
29
+ @_fb_user_fetched = true
30
+ end
31
+
32
+ def fetch_client_and_user_from_cookie
33
+ app_id = Facebooker2.app_id
34
+ if (hash_data = fb_cookie_hash_for_app_id(app_id)) and
35
+ fb_cookie_signature_correct?(fb_cookie_hash_for_app_id(app_id),Facebooker2.secret)
36
+ fb_create_user_and_client(hash_data["access_token"],hash_data["expires"],hash_data["uid"])
37
+ end
38
+ end
39
+
40
+ def fb_create_user_and_client(token,expires,userid)
41
+ client = Mogli::Client.new(token,expires.to_i)
42
+ user = Mogli::User.new(:id=>userid)
43
+ fb_sign_in_user_and_client(user,client)
44
+ end
45
+
46
+ def fb_sign_in_user_and_client(user,client)
47
+ user.client = client
48
+ @_current_facebook_user = user
49
+ @_current_facebook_client = client
50
+ @_fb_user_fetched = true
51
+ end
52
+
53
+ def fb_cookie_hash_for_app_id(app_id)
54
+ return nil unless fb_cookie_for_app_id?(app_id)
55
+ hash={}
56
+ data = fb_cookie_for_app_id(app_id).gsub(/"/,"")
57
+ data.split("&").each do |str|
58
+ parts = str.split("=")
59
+ hash[parts.first] = parts.last
60
+ end
61
+ hash
62
+ end
63
+
64
+ def fb_cookie_for_app_id?(app_id)
65
+ !fb_cookie_for_app_id(app_id).nil?
66
+ end
67
+
68
+ def fb_cookie_for_app_id(app_id)
69
+ cookies["fbs_#{app_id}"]
70
+ end
71
+
72
+ def fb_cookie_signature_correct?(hash,secret)
73
+ sorted_keys = hash.keys.reject {|k| k=="sig"}.sort
74
+ test_string = ""
75
+ sorted_keys.each do |key|
76
+ test_string += "#{key}=#{hash[key]}"
77
+ end
78
+ test_string += secret
79
+ Digest::MD5.hexdigest(test_string) == hash["sig"]
80
+ end
81
+
82
+ def fb_signed_request_json(encoded)
83
+ chars_to_add = 4-(encoded.size % 4)
84
+ encoded += ("=" * chars_to_add)
85
+ Base64.decode64(encoded)
86
+ end
87
+
88
+ def facebook_params
89
+ @facebook_param ||= fb_load_facebook_params
90
+ end
91
+
92
+ def fb_load_facebook_params
93
+ return {} if params[:signed_request].blank?
94
+ sig,encoded_json = params[:signed_request].split(".")
95
+ return {} unless fb_signed_request_sig_valid?(sig,encoded_json)
96
+ ActiveSupport::JSON.decode(fb_signed_request_json(encoded_json)).with_indifferent_access
97
+ end
98
+
99
+ def fb_signed_request_sig_valid?(sig,encoded)
100
+ base64 = Base64.encode64(HMAC::SHA256.digest(Facebooker2.secret,encoded))
101
+ #now make the url changes that facebook makes
102
+ url_escaped_base64 = base64.gsub(/=*\n?$/,"").tr("+/","-_")
103
+ sig == url_escaped_base64
104
+ end
105
+
106
+ def fetch_client_and_user_from_signed_request
107
+ if facebook_params[:oauth_token]
108
+ fb_create_user_and_client(facebook_params[:oauth_token],facebook_params[:expires],facebook_params[:user_id])
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,33 @@
1
+ module Facebooker2
2
+ module Rails
3
+ module Helpers
4
+ include FacebookConnect
5
+ include Javascript
6
+ include RequestForms
7
+ include User
8
+
9
+ def fb_stringify_vals(hash)
10
+ result={}
11
+ hash.each do |key,value|
12
+ result[key]=value.to_s
13
+ end
14
+ result
15
+ end
16
+ def fb_transform_keys(options,transformation_hash)
17
+ new_hash = {}
18
+ options.each do |key,value|
19
+ new_key = transformation_hash[key]||key
20
+ new_hash[new_key]=value
21
+ end
22
+ new_hash
23
+ end
24
+ FB_ALWAYS_VALID_OPTION_KEYS = [:class, :style]
25
+
26
+ def fb_assert_valid_keys(options,*valid_keys)
27
+ unknown_keys = options.keys - [valid_keys + FB_ALWAYS_VALID_OPTION_KEYS].flatten
28
+ raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,51 @@
1
+ module Facebooker2
2
+ module Rails
3
+ module Helpers
4
+ module FacebookConnect
5
+ #
6
+ # Render an <fb:login-button> element, similar to
7
+ # fb_login_button. Adds a js redirect to the onlogin event via rjs.
8
+ #
9
+ # ==== Examples
10
+ #
11
+ # fb_login_and_redirect '/other_page'
12
+ # => <fb:login-button onlogin="window.location.href = &quot;/other_page&quot;;"></fb:login-button>
13
+ #
14
+ # Like #fb_login_button, this also supports the :text option
15
+ #
16
+ # fb_login_and_redirect '/other_page', :text => "Login with Facebook", :v => '2'
17
+ # => <fb:login-button onlogin="window.location.href = &quot;/other_page&quot;;" v="2">Login with Facebook</fb:login-button>
18
+ #
19
+ def fb_login_and_redirect(url, options = {})
20
+ js = update_page do |page|
21
+ page.redirect_to url
22
+ end
23
+
24
+ text = options.delete(:text)
25
+
26
+ content_tag("fb:login-button",text,options.merge(:onlogin=>js))
27
+ end
28
+
29
+ def fb_login(options = {},&proc)
30
+ js = capture(&proc)
31
+ text = options.delete(:text)
32
+ concat(content_tag("fb:login-button",text,options.merge(:onlogin=>js)))
33
+ end
34
+
35
+ #
36
+ # Logs the user out of facebook and redirects to the given URL
37
+ # args are passed to the call to link_to_function
38
+ def fb_logout_link(text,url,*args)
39
+ function= "FB.logout(function() {window.location.href = '#{url}';})"
40
+ link_to_function text, function, *args
41
+ end
42
+
43
+ def fb_server_fbml(style=nil,&proc)
44
+ style_string=" style=\"#{style}\"" if style
45
+ content = capture(&proc)
46
+ concat("<fb:serverFbml#{style_string}><script type='text/fbml'>#{content}</script></fb:serverFbml>")
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,39 @@
1
+ module Facebooker2
2
+ module Rails
3
+ module Helpers
4
+ module Javascript
5
+ def fb_connect_async_js(app_id=Facebooker2.app_id,options={},&proc)
6
+ opts = Hash.new(true).merge!(options)
7
+ cookie = opts[:cookie]
8
+ status = opts[:status]
9
+ xfbml = opts[:xfbml]
10
+ extra_js = capture(&proc) if block_given?
11
+ js = <<-JAVASCRIPT
12
+ <script>
13
+ window.fbAsyncInit = function() {
14
+ FB.init({
15
+ appId : '#{app_id}',
16
+ status : #{status}, // check login status
17
+ cookie : #{cookie}, // enable cookies to allow the server to access the session
18
+ xfbml : #{xfbml} // parse XFBML
19
+ });
20
+ #{extra_js}
21
+ };
22
+
23
+ (function() {
24
+ var s = document.createElement('div');
25
+ s.setAttribute('id','fb-root');
26
+ document.documentElement.getElementsByTagName("HEAD")[0].appendChild(s);
27
+ var e = document.createElement('script');
28
+ e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
29
+ e.async = true;
30
+ s.appendChild(e);
31
+ }());
32
+ </script>
33
+ JAVASCRIPT
34
+ block_given? ? concat(js) : js
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ module Facebooker2
2
+ module Rails
3
+ module Helpers
4
+ module RequestForms
5
+ def fb_req_choice(label,url)
6
+ tag "fb:req-choice",:label=>label,:url=>url
7
+ end
8
+
9
+ def fb_multi_friend_selector(message,options={},&block)
10
+ options = fb_stringify_vals({:showborder=>false,:actiontext=>message,:max=>20}.merge(options.dup))
11
+ tag("fb:multi-friend-selector",options)
12
+ end
13
+
14
+ def fb_request_form(type,url,message,options={},&block)
15
+ content = capture(&block)
16
+ concat(content_tag("fb:request-form", content.to_s + fb_forgery_protection_token_tag,
17
+ {:action=>url,:method=>"post",:invite=>true,:type=>type,:content=>message}.merge(options)))
18
+ end
19
+
20
+
21
+ def fb_forgery_protection_token_tag
22
+ unless protect_against_forgery?
23
+ ''
24
+ else
25
+ tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
26
+ end
27
+ end
28
+
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,49 @@
1
+ module Facebooker2
2
+ module Rails
3
+ module Helpers
4
+ module User
5
+ # Render an fb:name tag for the given user
6
+ # This renders the name of the user specified. You can use this tag as both subject and object of
7
+ # a sentence. <em> See </em> http://wiki.developers.facebook.com/index.php/Fb:name for full description.
8
+ # Use this tag on FBML pages instead of retrieving the user's info and rendering the name explicitly.
9
+ #
10
+ def fb_name(user, options={})
11
+ options = fb_transform_keys(options,FB_NAME_OPTION_KEYS_TO_TRANSFORM)
12
+ fb_assert_valid_keys(options, FB_NAME_VALID_OPTION_KEYS)
13
+ options.merge!(:uid => Facebooker2.cast_to_facebook_id(user))
14
+ content_tag("fb:name",nil, fb_stringify_vals(options))
15
+ end
16
+
17
+ FB_NAME_OPTION_KEYS_TO_TRANSFORM = {:first_name_only => :firstnameonly,
18
+ :last_name_only => :lastnameonly,
19
+ :show_network => :shownetwork,
20
+ :use_you => :useyou,
21
+ :if_cant_see => :ifcantsee,
22
+ :subject_id => :subjectid}
23
+ FB_NAME_VALID_OPTION_KEYS = [:firstnameonly, :linked, :lastnameonly, :possessive, :reflexive,
24
+ :shownetwork, :useyou, :ifcantsee, :capitalize, :subjectid]
25
+
26
+
27
+ def fb_profile_pic(user, options={})
28
+ options = options.dup
29
+ validate_fb_profile_pic_size(options)
30
+ options = fb_transform_keys(options,FB_PROFILE_PIC_OPTION_KEYS_TO_TRANSFORM)
31
+ fb_assert_valid_keys(options,FB_PROFILE_PIC_VALID_OPTION_KEYS)
32
+ options.merge!(:uid => Facebooker2.cast_to_facebook_id(user))
33
+ content_tag("fb:profile-pic", nil,fb_stringify_vals(options))
34
+ end
35
+
36
+ FB_PROFILE_PIC_OPTION_KEYS_TO_TRANSFORM = {:facebook_logo => 'facebook-logo'}
37
+ FB_PROFILE_PIC_VALID_OPTION_KEYS = [:size, :linked, 'facebook-logo', :width, :height]
38
+ VALID_FB_PROFILE_PIC_SIZES = [:thumb, :small, :normal, :square]
39
+ def validate_fb_profile_pic_size(options)
40
+ if options.has_key?(:size) && !VALID_FB_PROFILE_PIC_SIZES.include?(options[:size].to_sym)
41
+ raise(ArgumentError, "Unknown value for size: #{options[:size]}")
42
+ end
43
+ end
44
+
45
+
46
+ end
47
+ end
48
+ end
49
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bryanl-facebooker2
3
+ version: !ruby/object:Gem::Version
4
+ hash: 8118012
5
+ prerelease: true
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 5
10
+ - x1
11
+ version: 0.0.5.x1
12
+ platform: ruby
13
+ authors:
14
+ - Mike Mangino
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-08-17 00:00:00 -04:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: mogli
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 7
31
+ segments:
32
+ - 0
33
+ - 0
34
+ - 12
35
+ version: 0.0.12
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: ruby-hmac
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ hash: 3
47
+ segments:
48
+ - 0
49
+ version: "0"
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ description: Facebook Connect integration library for ruby and rails
53
+ email: mmangino@elevatedrails.com
54
+ executables: []
55
+
56
+ extensions: []
57
+
58
+ extra_rdoc_files: []
59
+
60
+ files:
61
+ - lib/facebooker2/rails/controller.rb
62
+ - lib/facebooker2/rails/helpers/facebook_connect.rb
63
+ - lib/facebooker2/rails/helpers/javascript.rb
64
+ - lib/facebooker2/rails/helpers/request_forms.rb
65
+ - lib/facebooker2/rails/helpers/user.rb
66
+ - lib/facebooker2/rails/helpers.rb
67
+ - lib/facebooker2/rails.rb
68
+ - lib/facebooker2.rb
69
+ has_rdoc: true
70
+ homepage: http://developers.facebook.com/docs/api
71
+ licenses: []
72
+
73
+ post_install_message:
74
+ rdoc_options: []
75
+
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ hash: 3
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">"
91
+ - !ruby/object:Gem::Version
92
+ hash: 25
93
+ segments:
94
+ - 1
95
+ - 3
96
+ - 1
97
+ version: 1.3.1
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.3.7
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Facebook Connect integration library for ruby and rails
105
+ test_files: []
106
+