devise_facebook_open_graph 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ gem 'rails', '>= 3.0.0.beta3'
2
+ gem 'devise', '>= 1.1.rc1'
3
+ gem 'koala'
4
+ gem 'json' # Koala needs this, but it has no gem spec which dictates this on it's own as it seems
5
+
6
+
7
+ group :development do
8
+ gem 'bundler'
9
+ gem 'rake'
10
+ gem 'jeweler'
11
+ gem 'rspec'
12
+ end
@@ -0,0 +1,112 @@
1
+ ---
2
+ dependencies:
3
+ rails:
4
+ group:
5
+ - :default
6
+ version: ">= 3.0.0.beta3"
7
+ rake:
8
+ group:
9
+ - :development
10
+ version: ">= 0"
11
+ rspec:
12
+ group:
13
+ - :development
14
+ version: ">= 0"
15
+ json:
16
+ group:
17
+ - :default
18
+ version: ">= 0"
19
+ devise:
20
+ group:
21
+ - :default
22
+ version: ">= 1.1.rc1"
23
+ bundler:
24
+ group:
25
+ - :development
26
+ version: ">= 0"
27
+ jeweler:
28
+ group:
29
+ - :development
30
+ version: ">= 0"
31
+ koala:
32
+ group:
33
+ - :default
34
+ version: ">= 0"
35
+ specs:
36
+ - rake:
37
+ version: 0.8.7
38
+ - abstract:
39
+ version: 1.0.0
40
+ - builder:
41
+ version: 2.1.2
42
+ - i18n:
43
+ version: 0.3.7
44
+ - memcache-client:
45
+ version: 1.8.3
46
+ - tzinfo:
47
+ version: 0.3.22
48
+ - activesupport:
49
+ version: 3.0.0.beta3
50
+ - activemodel:
51
+ version: 3.0.0.beta3
52
+ - erubis:
53
+ version: 2.6.5
54
+ - rack:
55
+ version: 1.1.0
56
+ - rack-mount:
57
+ version: 0.6.4
58
+ - rack-test:
59
+ version: 0.5.4
60
+ - actionpack:
61
+ version: 3.0.0.beta3
62
+ - mime-types:
63
+ version: "1.16"
64
+ - polyglot:
65
+ version: 0.3.1
66
+ - treetop:
67
+ version: 1.4.8
68
+ - mail:
69
+ version: 2.2.3
70
+ - text-hyphen:
71
+ version: 1.0.0
72
+ - text-format:
73
+ version: 1.0.0
74
+ - actionmailer:
75
+ version: 3.0.0.beta3
76
+ - arel:
77
+ version: 0.3.3
78
+ - activerecord:
79
+ version: 3.0.0.beta3
80
+ - activeresource:
81
+ version: 3.0.0.beta3
82
+ - bundler:
83
+ version: 0.9.26
84
+ - warden:
85
+ version: 0.10.7
86
+ - devise:
87
+ version: 1.1.rc1
88
+ - json_pure:
89
+ version: 1.4.3
90
+ - gemcutter:
91
+ version: 0.5.0
92
+ - git:
93
+ version: 1.2.5
94
+ - rubyforge:
95
+ version: 2.0.4
96
+ - jeweler:
97
+ version: 1.4.0
98
+ - json:
99
+ version: 1.4.3
100
+ - koala:
101
+ version: 0.7.2
102
+ - thor:
103
+ version: 0.13.6
104
+ - railties:
105
+ version: 3.0.0.beta3
106
+ - rails:
107
+ version: 3.0.0.beta3
108
+ - rspec:
109
+ version: 1.3.0
110
+ hash: 69ed2d8540d60c12b9b97af95a0db518ddfd013f
111
+ sources: []
112
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Thorbjørn Hermansen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,183 @@
1
+ = devise_facebook_open_graph
2
+
3
+ The goal of this gem is to give Devise the ability to authorize users based if they are connected to Facebook or not.
4
+ It relays on connection to Facebook set up via the Facebook JavaScript SDK. Maybe devise facebook js sdk connectable
5
+ should be a better name for this gem ;-)
6
+
7
+ == Warning
8
+
9
+ I guess I should start with a small warning: Right now, this gem is kinda a fast-written prototype for me. Don't expect anything to
10
+ work ;-) ..Even though committed code do work for me in my Rails 3 beta 3 application :-) I have managed to authenticate users which
11
+ sign in via Facebook's JavaScript SDK and I guess this code might be useful to others too. Sadly, I haven't written any specs while
12
+ writing this code. This is not 100% complete code either. For instance, creating users based on facebook connection is not finished,
13
+ although I guess it will be soon.
14
+
15
+
16
+
17
+ = How to get started
18
+
19
+ == Set up gem dependency in your Gemfile
20
+
21
+ gem 'devise_facebook_open_graph'
22
+
23
+ == Get facebook credentials, add ids and keys to a configuration file
24
+
25
+ If you haven't done so already, create a facebook application so you'll acquire an application id, secret and an API key.
26
+ You can register applications here: http://www.facebook.com/developers/.
27
+
28
+ DeviseFacebookOpenGraph provides a class for easy access to configuration values. These are by default read from
29
+ Rails.root/config/facebook.yml which should look something like this:
30
+
31
+ production: &production
32
+ application_id: ""
33
+ api_key: ""
34
+ application_secret: ""
35
+
36
+ development:
37
+ <<: *production
38
+
39
+ == Configure your model to use facebook_open_graph_authenticatable
40
+ class User < ActiveRecord::Base
41
+ devise :database_authenticatable, :facebook_open_graph_authenticatable # etc..
42
+
43
+ == Add facebook user id column to your users table
44
+
45
+ class CreateUsers < ActiveRecord::Migration
46
+ def self.up
47
+ create_table :users do |t|
48
+ # ...other definitions here..
49
+
50
+ t.facebook_open_graph_authenticatable
51
+ end
52
+
53
+ add_index :users, User.facebook_uid_field, :unique => true
54
+ end
55
+
56
+
57
+ def self.down
58
+ drop_table :users
59
+ end
60
+ end
61
+
62
+
63
+ == Add Facebook SDK initializer HTML and JavaScript
64
+
65
+ The next thing we'll be doing are adding Facebook's JavaScript SDK and initialize it. This should be added
66
+ at the bottom of the page, before </body>. Add it with the helper <tt>facebook_init_javascript_sdk</tt>. I guess
67
+ more options to this one will come later.
68
+
69
+ == Add Facebook login button to your page
70
+
71
+ This can be done in different ways. One way is to use the fbml tag <tt>fb:login-button</tt>. See
72
+ http://developers.facebook.com/docs/authentication/, single sign-on section for more information.
73
+
74
+ == Last step...
75
+
76
+ Once a user has clicked your login button a cookie will be set with name fbs_<your_application_id>. When this is
77
+ set and Warden tries the authentication strategy which this gem provides it will parse the cookie content, find
78
+ the user's facebook uid and look that up in your users' table. If found, the user is authenticated.
79
+
80
+ == How to sign out users?
81
+
82
+ Facebook connected users are signed out when they sign out of Facebook. You can log a user out by calling <tt>FB.logout()</tt>
83
+ from your JavaScript. Here are some lines of JavaScript (jQuery) which I use to sign in/out users. Hope it helps you out if you are stuck:
84
+
85
+ $("a#sign_out").click(function(e) {
86
+ var sign_out_link = $(this);
87
+
88
+ FB.getLoginStatus(function(response) {
89
+ if (response.session) { // User is connected to Facebook
90
+ e.preventDefault();
91
+
92
+ FB.logout(function() { // Signs the user out and redirect to the application's sign out url
93
+ window.location.href = sign_out_link.attr("href");
94
+ });
95
+ }
96
+ });
97
+ });
98
+
99
+ FB.Event.subscribe('auth.login', function(response) {
100
+ window.location.href = "/profile"; // Redirect to some url when the user gets connected to facebook
101
+ });
102
+
103
+ For more information take a look at http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus
104
+ Oh! ..and you might want to start here: http://developers.facebook.com/docs/reference/javascript/
105
+
106
+
107
+ == Callbacks
108
+
109
+ There are defined some callback methods for devise models which are set up to be facebook_open_graph_authenticatable.
110
+ When these methods are called the model should have access to the facebook session through self.
111
+ Just make a call to facebook_session on your model. With this session you have access to uid, open graph api on behalf of the user
112
+ etc. Take a look at DeviseFacebookOpenGraph::Facebook::Session and the Koala gem which we use for communicating with the open graph.
113
+
114
+ === before/after/around create_by_facebook
115
+
116
+ This one is called when a new user is created based on facebook connection, but the facebook uid is now found in the database.
117
+ Note that this is only relevant if devise's configuration value facebook_auto_create_account is set to true. Oh, one more thing,
118
+ the user is as a default saved without running validations meaning that you should implement a before_create_by_facebook function and extract
119
+ what you can like email etc from the facebook_session. You can override this though via configuration key 'run_validations_when_creating_facebook_user'.
120
+
121
+ ==== Simple example on how to extract user's data from Facebook
122
+ class User < ActiveRecord::Base
123
+ before_create_by_facebook :extract_user_data_from_facebook_session
124
+
125
+ def extract_user_data_from_facebook_session
126
+ # The following code returns hash with information about current user being created
127
+ # For more information, see Koala gem documentation http://wiki.github.com/arsduo/koala/graph-api
128
+ user_data_from_facebook = facebook_session.graph.get_object(:me)
129
+ # Assign attributes with fetched data..
130
+ end
131
+ end
132
+
133
+ === before/after/around connecting_to_facebook
134
+
135
+ These are called when Devise authenticates the user via facebook connect. In effect the user will be connected to facebook
136
+ at this point; signing out of facebook means signing out of your application too and visa-versa. As you might expect from a
137
+ before filter; you can halt the connection to facebook in the before filter by making it return false.
138
+
139
+ == Configuration
140
+
141
+ There are some configuration options which you can add in config/initializers/devise.rb
142
+
143
+ # Overrides the default column name for where to store the user's facebook user id
144
+ #config.facebook_uid_field = "facebook_uid"
145
+
146
+ # Auto creates accounts for new users. Default is true
147
+ #config.facebook_auto_create_account = true
148
+
149
+ # Runs validation when auto creating users on facebook connect. Default is false
150
+ #config.run_validations_when_creating_facebook_user = false
151
+
152
+ # Skip confirmation loop on facebook connection users. Default is true
153
+ #config,skip_confimation_for_facebook_users = true
154
+
155
+
156
+ == Access facebook session through controllers and views
157
+
158
+ When a user is signed in via facebook connect you have access to the user's facebook session by calling <tt>facebook_session</tt>
159
+ inside a controller or view. With this session you have access to the user's open graph by calling <tt>facebook_session.graph</tt>.
160
+ See the simple example on how to extract user's data from Facebook above.
161
+
162
+
163
+
164
+ = TODO
165
+ * Add other controller helpers for easy access to users facebook session (more specifically access to user's session & open graph).
166
+ * Add support for non-JavaScript authentication (see http://developers.facebook.com/docs/authentication/ "Authenticating Users in a Web Application").
167
+ * I'm sure there are more things to do..
168
+ * ..For instance; I guess some testing should be nice :-]
169
+
170
+
171
+ == Note on Patches/Pull Requests
172
+
173
+ * Fork the project.
174
+ * Make your feature addition or bug fix.
175
+ * Add tests for it. This is important so I don't break it in a
176
+ future version unintentionally.
177
+ * Commit, do not mess with rakefile, version, or history.
178
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
179
+ * Send me a pull request. Bonus points for topic branches.
180
+
181
+ == Copyright
182
+
183
+ Copyright (c) 2010 Thorbjørn Hermansen. See LICENSE for details.
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'bundler'
4
+
5
+ Bundler.setup
6
+
7
+ begin
8
+ require 'jeweler'
9
+ Jeweler::Tasks.new do |gem|
10
+ gem.name = "devise_facebook_open_graph"
11
+ gem.summary = %Q{Extends Devise with an authentication strategy against Facebook}
12
+ gem.description = %Q{Extends Devise with an authentication strategy against Facebook's Open Graph and it's JavaScrip SDK}
13
+ gem.email = "thhermansen@gmail.com"
14
+ gem.homepage = "http://github.com/thhermansen/devise_facebook_open_graph"
15
+ gem.authors = ["Thorbjørn Hermansen"]
16
+ gem.add_bundler_dependencies
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ end
20
+
21
+
22
+ require 'rake/rdoctask'
23
+ Rake::RDocTask.new do |rdoc|
24
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
25
+
26
+ rdoc.rdoc_dir = 'rdoc'
27
+ rdoc.title = "devise_facebook_open_graph #{version}"
28
+ rdoc.rdoc_files.include('README*')
29
+ rdoc.rdoc_files.include('lib/**/*.rb')
30
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
@@ -0,0 +1,85 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{devise_facebook_open_graph}
8
+ s.version = "0.0.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Thorbj\303\270rn Hermansen"]
12
+ s.date = %q{2010-06-15}
13
+ s.description = %q{Extends Devise with an authentication strategy against Facebook's Open Graph and it's JavaScrip SDK}
14
+ s.email = %q{thhermansen@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "devise_facebook_open_graph.gemspec",
29
+ "init.rb",
30
+ "lib/devise_facebook_open_graph.rb",
31
+ "lib/devise_facebook_open_graph/facebook/config.rb",
32
+ "lib/devise_facebook_open_graph/facebook/session.rb",
33
+ "lib/devise_facebook_open_graph/model.rb",
34
+ "lib/devise_facebook_open_graph/rails.rb",
35
+ "lib/devise_facebook_open_graph/rails/controller_helpers.rb",
36
+ "lib/devise_facebook_open_graph/rails/view_helpers.rb",
37
+ "lib/devise_facebook_open_graph/schema.rb",
38
+ "lib/devise_facebook_open_graph/strategy.rb",
39
+ "spec/spec.opts",
40
+ "spec/spec_helper.rb"
41
+ ]
42
+ s.homepage = %q{http://github.com/thhermansen/devise_facebook_open_graph}
43
+ s.rdoc_options = ["--charset=UTF-8"]
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = %q{1.3.7}
46
+ s.summary = %q{Extends Devise with an authentication strategy against Facebook}
47
+ s.test_files = [
48
+ "spec/spec_helper.rb"
49
+ ]
50
+
51
+ if s.respond_to? :specification_version then
52
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
53
+ s.specification_version = 3
54
+
55
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
56
+ s.add_runtime_dependency(%q<rails>, [">= 3.0.0.beta3"])
57
+ s.add_development_dependency(%q<rake>, [">= 0"])
58
+ s.add_development_dependency(%q<rspec>, [">= 0"])
59
+ s.add_runtime_dependency(%q<devise>, [">= 1.1.rc1"])
60
+ s.add_runtime_dependency(%q<json>, [">= 0"])
61
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
62
+ s.add_development_dependency(%q<bundler>, [">= 0"])
63
+ s.add_runtime_dependency(%q<koala>, [">= 0"])
64
+ else
65
+ s.add_dependency(%q<rails>, [">= 3.0.0.beta3"])
66
+ s.add_dependency(%q<rake>, [">= 0"])
67
+ s.add_dependency(%q<rspec>, [">= 0"])
68
+ s.add_dependency(%q<devise>, [">= 1.1.rc1"])
69
+ s.add_dependency(%q<json>, [">= 0"])
70
+ s.add_dependency(%q<jeweler>, [">= 0"])
71
+ s.add_dependency(%q<bundler>, [">= 0"])
72
+ s.add_dependency(%q<koala>, [">= 0"])
73
+ end
74
+ else
75
+ s.add_dependency(%q<rails>, [">= 3.0.0.beta3"])
76
+ s.add_dependency(%q<rake>, [">= 0"])
77
+ s.add_dependency(%q<rspec>, [">= 0"])
78
+ s.add_dependency(%q<devise>, [">= 1.1.rc1"])
79
+ s.add_dependency(%q<json>, [">= 0"])
80
+ s.add_dependency(%q<jeweler>, [">= 0"])
81
+ s.add_dependency(%q<bundler>, [">= 0"])
82
+ s.add_dependency(%q<koala>, [">= 0"])
83
+ end
84
+ end
85
+
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require "devise_facebook_open_graph"
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+ require 'devise'
3
+
4
+
5
+ require 'devise_facebook_open_graph/rails'
6
+
7
+ module DeviseFacebookOpenGraph
8
+ module Facebook
9
+ extend ActiveSupport::Autoload
10
+
11
+ autoload :Config
12
+ autoload :Session
13
+ end
14
+
15
+ module Rails
16
+ extend ActiveSupport::Autoload
17
+
18
+ autoload :ViewHelpers
19
+ autoload :ControllerHelpers
20
+ end
21
+ end
22
+
23
+
24
+
25
+ require 'devise_facebook_open_graph/strategy'
26
+ require 'devise_facebook_open_graph/schema'
27
+
28
+ module Devise
29
+ #
30
+ # Specifies database column name to store the facebook user id.
31
+ #
32
+ mattr_accessor :facebook_uid_field
33
+ @@facebook_uid_field = :facebook_uid
34
+
35
+ #
36
+ # Instructs this gem to auto create an account for facebook
37
+ # users which have not visited before
38
+ #
39
+ mattr_accessor :facebook_auto_create_account
40
+ @@facebook_auto_create_account = true
41
+
42
+ #
43
+ # Runs validation when auto creating users on facebook connect
44
+ #
45
+ mattr_accessor :run_validations_when_creating_facebook_user
46
+ @@run_validations_when_creating_facebook_user = false
47
+
48
+ #
49
+ # Skip confirmation loop on facebook connection users
50
+ #
51
+ mattr_accessor :skip_confimation_for_facebook_users
52
+ @@skip_confimation_for_facebook_users = true
53
+ end
54
+
55
+ Devise.add_module(:facebook_open_graph_authenticatable,
56
+ :strategy => true,
57
+ :controller => :sessions,
58
+ :model => 'devise_facebook_open_graph/model'
59
+ )
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+ require "yaml"
3
+
4
+ #
5
+ # Provides basic Facebook functionality. You can ask it for
6
+ # the current configuration strings like Facebook.api_key,
7
+ # Facebook.application_id and Facebook.application_secret.
8
+ #
9
+ module DeviseFacebookOpenGraph
10
+ module Facebook
11
+ module Config
12
+ class << self
13
+
14
+ #
15
+ # Overrides the default configuration file path which is
16
+ # read from when requesting application_id, api_key,
17
+ # application_secret etc.
18
+ #
19
+ #
20
+ #
21
+ attr_accessor :path
22
+
23
+ %w(application_id api_key application_secret).each do |config_key|
24
+ define_method config_key do
25
+ instance_variable_get('@'+config_key) or
26
+ instance_variable_set('@'+config_key, config[config_key].value)
27
+ end
28
+ end
29
+
30
+ def sdk_java_script_source
31
+ "http://connect.facebook.net/#{I18n.locale}/all.js"
32
+ end
33
+
34
+ def facebook_session_name
35
+ "fbs_#{application_id}"
36
+ end
37
+
38
+ private
39
+ def config_file_path
40
+ path || ::Rails.root.join('config', 'facebook.yml')
41
+ end
42
+
43
+ def config
44
+ @config ||= YAML.parse_file(config_file_path)[::Rails.env]
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ require 'koala'
4
+
5
+ module DeviseFacebookOpenGraph
6
+ module Facebook
7
+ class Session
8
+ #
9
+ # Keys found in cookie content. We are supplying reader
10
+ # methods for these values which are read from cookie content
11
+ #
12
+ FACEBOOK_SESSION_KEYS = %w(session_key expires uid sig secret access_token)
13
+
14
+ #
15
+ # Creates a new Facebook session based cookies hash from a request
16
+ #
17
+ def initialize(cookies)
18
+ @cookies = cookies
19
+ end
20
+
21
+ #
22
+ # Returns facebook's cookie content
23
+ #
24
+ def cookie_content
25
+ @cookie_content ||= parse_cookie
26
+ end
27
+
28
+ #
29
+ # Gives access to query as user with an oauth access token fetched from the cookie content
30
+ #
31
+ def graph
32
+ Koala::Facebook::GraphAPI.new(access_token)
33
+ end
34
+
35
+
36
+ #
37
+ # Define reader methods for facebook session keys
38
+ #
39
+ FACEBOOK_SESSION_KEYS.each do |key|
40
+ define_method key do
41
+ cookie_content[key] if cookie_content
42
+ end
43
+ end
44
+
45
+ #
46
+ # Is this a valid session? True if we were able to parse facebook's cookie content
47
+ #
48
+ def valid?
49
+ !!cookie_content
50
+ end
51
+
52
+ private
53
+ def parse_cookie # :nodoc:
54
+ oauth = Koala::Facebook::OAuth.new(Config.application_id, Config.application_secret)
55
+ parsed = oauth.get_user_from_cookie(@cookies)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ require 'devise'
3
+
4
+ module Devise
5
+ module Models
6
+ module FacebookOpenGraphAuthenticatable
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ attr_accessor :facebook_session
11
+ define_model_callbacks :create_by_facebook
12
+ define_model_callbacks :connecting_to_facebook
13
+ end
14
+
15
+ module ClassMethods
16
+ Devise::Models.config(self,
17
+ :facebook_uid_field, :facebook_auto_create_account, :run_validations_when_creating_facebook_user,
18
+ :skip_confimation_for_facebook_users
19
+ )
20
+
21
+ def facebook_auto_create_account?
22
+ !!facebook_auto_create_account
23
+ end
24
+
25
+ def authenticate_facebook_user(facebook_uid)
26
+ send("find_by_" + facebook_uid_field.to_s, facebook_uid)
27
+ end
28
+ end
29
+
30
+ def set_facebook_credentials_from_session!
31
+ raise "Can't set facebook credentials from session without the session!" if facebook_session.blank?
32
+ send(self.class.facebook_uid_field.to_s+'=', facebook_session.uid)
33
+ make_facebook_model_valid!
34
+ end
35
+
36
+ def authenticated_via_facebook?
37
+ read_attribute(self.class.facebook_uid_field).present?
38
+ end
39
+
40
+ private
41
+ #
42
+ # In case of model having included other modules like
43
+ # database_authenticate and so on we need to "by pass" some validations etc.
44
+ #
45
+ def make_facebook_model_valid!
46
+ # These database fields are required if authenticable is used
47
+ write_attribute(:password_salt, '') if self.respond_to?(:password_salt)
48
+ write_attribute(:encrypted_password, '') if self.respond_to?(:encrypted_password)
49
+
50
+ skip_confirmation! if self.class.skip_confimation_for_facebook_users && respond_to?(:skip_confirmation!)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,2 @@
1
+ ActiveSupport.on_load(:action_view) { include DeviseFacebookOpenGraph::Rails::ViewHelpers }
2
+ ActiveSupport.on_load(:action_controller) { include DeviseFacebookOpenGraph::Rails::ControllerHelpers }
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ module DeviseFacebookOpenGraph
4
+ module Rails
5
+ module ControllerHelpers
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ helper_method :facebook_session
10
+ end
11
+
12
+ def facebook_session
13
+ @facebook_session ||= DeviseFacebookOpenGraph::Facebook::Session.new(cookies)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ module DeviseFacebookOpenGraph
4
+ module Rails
5
+ module ViewHelpers
6
+ #
7
+ # Inserts facebook HTML and javascript tag for initializing
8
+ # JavaScript SDK. See http://developers.facebook.com/docs/authentication/: Single Sign-on.
9
+ #
10
+ # Some options to this helper-method might be added in the future :-)
11
+ #
12
+ def facebook_init_javascript_sdk
13
+ buffer = content_tag :div, '', :id => 'fb-root'
14
+ buffer << javascript_include_tag(DeviseFacebookOpenGraph::Facebook::Config.sdk_java_script_source)
15
+
16
+ buffer << javascript_tag(<<-JAVASCRIPT)
17
+ FB.init({
18
+ appId: '#{DeviseFacebookOpenGraph::Facebook::Config.application_id}',
19
+ status: true,
20
+ cookie: true,
21
+ xfbml: true
22
+ });
23
+ JAVASCRIPT
24
+
25
+ buffer.html_safe
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module DeviseFacebookOpenGraph
4
+ module Schema
5
+ def facebook_open_graph_authenticatable
6
+ apply_schema ::Devise.facebook_uid_field, :integer, :limit => 8
7
+ end
8
+ end
9
+ end
10
+
11
+ Devise::Schema.module_eval do
12
+ include DeviseFacebookOpenGraph::Schema
13
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+
3
+ require 'devise/strategies/base'
4
+
5
+ module Devise
6
+ module FacebookOpenGraphAuthenticatable
7
+ module Strategies
8
+ class FacebookOpenGraphAuthenticatable < ::Devise::Strategies::Base
9
+ #
10
+ # This strategy is valid if Facebook has set it's session data object in
11
+ # current application's domain cookies.
12
+ #
13
+ def valid?
14
+ mapping.to.respond_to?(:authenticate_facebook_user) && cookies.has_key?(::DeviseFacebookOpenGraph::Facebook::Config.facebook_session_name)
15
+ end
16
+
17
+ #
18
+ # Authenticates the user as if this requests seems
19
+ # valid as FacebookOpenGraphAuthenticatable
20
+ #
21
+ # Tries to auto create the user if configured to do so.
22
+ #
23
+ def authenticate!
24
+ session = DeviseFacebookOpenGraph::Facebook::Session.new(cookies)
25
+
26
+ if session.valid?
27
+ klass = mapping.to
28
+ user = klass.authenticate_facebook_user session.uid
29
+
30
+ if user.blank? && klass.facebook_auto_create_account?
31
+ user = klass.new
32
+ user.facebook_session = session
33
+ user.set_facebook_credentials_from_session!
34
+ user.run_callbacks :create_by_facebook do
35
+ begin
36
+ user.save(:validate => klass.run_validations_when_creating_facebook_user)
37
+ rescue ActiveRecord::RecordNotUnique
38
+ fail!(:not_unique_user_on_creation) and return
39
+ end
40
+ end
41
+
42
+ if klass.run_validations_when_creating_facebook_user && !user.persisted?
43
+ fail!(:invalid_facebook_user_on_creation) and return
44
+ end
45
+ end
46
+
47
+ if user.present? && user.persisted?
48
+ user.facebook_session = session
49
+ user.run_callbacks :connecting_to_facebook do
50
+ success!(user) and return
51
+ end
52
+ else
53
+ fail!(:facebook_user_not_found_locally) and return
54
+ end
55
+ else
56
+ fail!(:invalid_facebook_session) and return
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ ::Warden::Strategies.add(:facebook_open_graph_authenticatable, Devise::FacebookOpenGraphAuthenticatable::Strategies::FacebookOpenGraphAuthenticatable)
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'devise_facebook_open_graph'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,204 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devise_facebook_open_graph
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - "Thorbj\xC3\xB8rn Hermansen"
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-06-15 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rails
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: -1848230021
30
+ segments:
31
+ - 3
32
+ - 0
33
+ - 0
34
+ - beta3
35
+ version: 3.0.0.beta3
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: rake
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: :development
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: rspec
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ type: :development
65
+ version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: devise
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 977940498
75
+ segments:
76
+ - 1
77
+ - 1
78
+ - rc1
79
+ version: 1.1.rc1
80
+ type: :runtime
81
+ version_requirements: *id004
82
+ - !ruby/object:Gem::Dependency
83
+ name: json
84
+ prerelease: false
85
+ requirement: &id005 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ type: :runtime
95
+ version_requirements: *id005
96
+ - !ruby/object:Gem::Dependency
97
+ name: jeweler
98
+ prerelease: false
99
+ requirement: &id006 !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ hash: 3
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ type: :development
109
+ version_requirements: *id006
110
+ - !ruby/object:Gem::Dependency
111
+ name: bundler
112
+ prerelease: false
113
+ requirement: &id007 !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ hash: 3
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ type: :development
123
+ version_requirements: *id007
124
+ - !ruby/object:Gem::Dependency
125
+ name: koala
126
+ prerelease: false
127
+ requirement: &id008 !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ hash: 3
133
+ segments:
134
+ - 0
135
+ version: "0"
136
+ type: :runtime
137
+ version_requirements: *id008
138
+ description: Extends Devise with an authentication strategy against Facebook's Open Graph and it's JavaScrip SDK
139
+ email: thhermansen@gmail.com
140
+ executables: []
141
+
142
+ extensions: []
143
+
144
+ extra_rdoc_files:
145
+ - LICENSE
146
+ - README.rdoc
147
+ files:
148
+ - .document
149
+ - .gitignore
150
+ - Gemfile
151
+ - Gemfile.lock
152
+ - LICENSE
153
+ - README.rdoc
154
+ - Rakefile
155
+ - VERSION
156
+ - devise_facebook_open_graph.gemspec
157
+ - init.rb
158
+ - lib/devise_facebook_open_graph.rb
159
+ - lib/devise_facebook_open_graph/facebook/config.rb
160
+ - lib/devise_facebook_open_graph/facebook/session.rb
161
+ - lib/devise_facebook_open_graph/model.rb
162
+ - lib/devise_facebook_open_graph/rails.rb
163
+ - lib/devise_facebook_open_graph/rails/controller_helpers.rb
164
+ - lib/devise_facebook_open_graph/rails/view_helpers.rb
165
+ - lib/devise_facebook_open_graph/schema.rb
166
+ - lib/devise_facebook_open_graph/strategy.rb
167
+ - spec/spec.opts
168
+ - spec/spec_helper.rb
169
+ has_rdoc: true
170
+ homepage: http://github.com/thhermansen/devise_facebook_open_graph
171
+ licenses: []
172
+
173
+ post_install_message:
174
+ rdoc_options:
175
+ - --charset=UTF-8
176
+ require_paths:
177
+ - lib
178
+ required_ruby_version: !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ hash: 3
184
+ segments:
185
+ - 0
186
+ version: "0"
187
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
+ none: false
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ hash: 3
193
+ segments:
194
+ - 0
195
+ version: "0"
196
+ requirements: []
197
+
198
+ rubyforge_project:
199
+ rubygems_version: 1.3.7
200
+ signing_key:
201
+ specification_version: 3
202
+ summary: Extends Devise with an authentication strategy against Facebook
203
+ test_files:
204
+ - spec/spec_helper.rb