gtg-facebooker2 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,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
@@ -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,4 @@
1
+ module Facebooker2
2
+ module Rails
3
+ end
4
+ end
@@ -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(File.read(File.join(::Rails.root,"config","facebooker.yml")))[::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"
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gtg-facebooker2
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 6
10
+ version: 0.0.6
11
+ platform: ruby
12
+ authors:
13
+ - Mike Mangino
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-23 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: mogli
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 0
32
+ - 0
33
+ - 12
34
+ version: 0.0.12
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: ruby-hmac
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ description: Facebook Connect integration library for ruby and rails
52
+ email: mmangino@elevatedrails.com,goss@gamesthatgive.net
53
+ executables: []
54
+
55
+ extensions: []
56
+
57
+ extra_rdoc_files: []
58
+
59
+ files:
60
+ - lib/facebooker2/rails/controller.rb
61
+ - lib/facebooker2/rails/helpers/facebook_connect.rb
62
+ - lib/facebooker2/rails/helpers/javascript.rb
63
+ - lib/facebooker2/rails/helpers/request_forms.rb
64
+ - lib/facebooker2/rails/helpers/user.rb
65
+ - lib/facebooker2/rails/helpers.rb
66
+ - lib/facebooker2/rails.rb
67
+ - lib/facebooker2.rb
68
+ has_rdoc: false
69
+ homepage: http://developers.facebook.com/docs/api
70
+ licenses: []
71
+
72
+ post_install_message:
73
+ rdoc_options: []
74
+
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 3
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ requirements: []
96
+
97
+ rubyforge_project:
98
+ rubygems_version: 1.3.7
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Facebook Connect integration library for ruby and rails
102
+ test_files: []
103
+