devise_oauth2_authenticatable 0.0.1

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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
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
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 bhbryant
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.
data/README.rdoc ADDED
@@ -0,0 +1,82 @@
1
+ = devise_oauth2_authenticatable
2
+
3
+ This is the basic framework for an OAuth2 gem for Devise.
4
+
5
+ It currently works with FacebookGraph, to get started begin by registering a new application at
6
+
7
+ http://developers.facebook.com/setup/
8
+
9
+
10
+
11
+ A generator is provided for creating your oauth yml file
12
+
13
+ script/generate devise_oauth2_authenticatable
14
+
15
+ Ex:
16
+
17
+ script/generate devise_oauth2_authenticatable --id API_ID --key SECRET --server https://graph.facebook.com --scope 'email,offline_access,publish_stream'
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+ for more details
26
+
27
+ http://developers.facebook.com/docs/authentication/
28
+
29
+
30
+
31
+ It's based on the devise facebook gem provided by grimen
32
+
33
+ http://github.com/grimen/devise_facebook_connectable
34
+
35
+
36
+
37
+
38
+ And uses the example provided in OAuth2 library provided by mbleigh
39
+
40
+ http://github.com/intridea/oauth2
41
+
42
+
43
+
44
+
45
+
46
+
47
+ DB Migration :
48
+
49
+ add_column :users, :oauth2_uid, :integer, :limit => 8 # BIGINT unsigned / 64-bit int
50
+ add_column :users, :oauth2_token, :string, :limit => 149 # [128][1][20] chars
51
+ add_index :users, :oauth2_uid, :unique => true
52
+
53
+
54
+
55
+ Note:
56
+
57
+ A little souce of confusion when working with Facebook Graph
58
+
59
+ The api key and secret key are no the same a Facebook Connect/the old API.
60
+
61
+ The client id should be your application id and the client_key, should be your API key (not secret key)
62
+
63
+
64
+
65
+
66
+
67
+
68
+ Description goes here.
69
+
70
+ == Note on Patches/Pull Requests
71
+
72
+ * Fork the project.
73
+ * Make your feature addition or bug fix.
74
+ * Add tests for it. This is important so I don't break it in a
75
+ future version unintentionally.
76
+ * Commit, do not mess with rakefile, version, or history.
77
+ (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)
78
+ * Send me a pull request. Bonus points for topic branches.
79
+
80
+ == Copyright
81
+
82
+ Copyright (c) 2010 bhbryant. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require File.join(File.dirname(__FILE__), 'lib', 'devise_oauth2_authenticatable', 'version')
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "devise_oauth2_authenticatable"
9
+ gem.version = ::Devise::Oauth2Authenticatable::VERSION
10
+ gem.summary = %{Devise << OAuth2}
11
+ gem.description = %{Implements OAuth2 for devises, specifically integrating with facebook Graph}
12
+ gem.email = "benjamin@bryantmarkowsky.com"
13
+ gem.homepage = "http://github.com/bhbryant/devise_oauth2_authenticatable"
14
+ gem.authors = ["bhbryant"]
15
+ gem.add_development_dependency "rspec", ">= 1.2.9"
16
+
17
+ gem.add_dependency'devise', '>= 1.0.0'
18
+ gem.add_dependency "oauth2"
19
+ gem.add_dependency "json"
20
+
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
26
+ end
27
+
28
+ require 'spec/rake/spectask'
29
+ Spec::Rake::SpecTask.new(:spec) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ task :default => :spec
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "devise_oauth2_authenticatable #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
@@ -0,0 +1,73 @@
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_oauth2_authenticatable}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["bhbryant"]
12
+ s.date = %q{2010-05-18}
13
+ s.description = %q{Implements OAuth2 for devises, specifically integrating with facebook Graph}
14
+ s.email = %q{benjamin@bryantmarkowsky.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "devise_oauth2_authenticatable.gemspec",
26
+ "generators/devise_oauth2_authenticatable/devise_oauth2_authenticatable_generator.rb",
27
+ "generators/devise_oauth2_authenticatable/templates/oauth2_config.yml",
28
+ "lib/devise_oauth2_authenticatable.rb",
29
+ "lib/devise_oauth2_authenticatable/locales/en.yml",
30
+ "lib/devise_oauth2_authenticatable/model.rb",
31
+ "lib/devise_oauth2_authenticatable/routes.rb",
32
+ "lib/devise_oauth2_authenticatable/schema.rb",
33
+ "lib/devise_oauth2_authenticatable/strategy.rb",
34
+ "lib/devise_oauth2_authenticatable/version.rb",
35
+ "lib/devise_oauth2_authenticatable/view_helpers.rb",
36
+ "rails/init.rb",
37
+ "spec/devise_oauth2_authenticatable_spec.rb",
38
+ "spec/spec.opts",
39
+ "spec/spec_helper.rb"
40
+ ]
41
+ s.homepage = %q{http://github.com/bhbryant/devise_oauth2_authenticatable}
42
+ s.rdoc_options = ["--charset=UTF-8"]
43
+ s.require_paths = ["lib"]
44
+ s.rubygems_version = %q{1.3.6}
45
+ s.summary = %q{Devise << OAuth2}
46
+ s.test_files = [
47
+ "spec/devise_oauth2_authenticatable_spec.rb",
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::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
56
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
57
+ s.add_runtime_dependency(%q<devise>, [">= 1.0.0"])
58
+ s.add_runtime_dependency(%q<oauth2>, [">= 0"])
59
+ s.add_runtime_dependency(%q<json>, [">= 0"])
60
+ else
61
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
62
+ s.add_dependency(%q<devise>, [">= 1.0.0"])
63
+ s.add_dependency(%q<oauth2>, [">= 0"])
64
+ s.add_dependency(%q<json>, [">= 0"])
65
+ end
66
+ else
67
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
68
+ s.add_dependency(%q<devise>, [">= 1.0.0"])
69
+ s.add_dependency(%q<oauth2>, [">= 0"])
70
+ s.add_dependency(%q<json>, [">= 0"])
71
+ end
72
+ end
73
+
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ class DeviseOauth2AuthenticatableGenerator < Rails::Generator::Base #:nodoc:
4
+
5
+ default_options :client_id => "YOUR_APP_API_ID",
6
+ :client_key => "YOUR_APP_SECRET_KEY",
7
+ :auth_server => "https://graph.facebook.com",
8
+ :requested_scope => "email,offline_access,publish_stream"
9
+
10
+ def manifest
11
+ record do |m|
12
+ # m.dependency 'xd_receiver', [], options.merge(:collision => :skip)
13
+ m.template 'oauth2_config.yml', File.join(*%w[config oauth2_config.yml])
14
+ # m.template 'devise.facebook_connectable.js', File.join(*%w[public javascripts devise.facebook_connectable.js])
15
+ end
16
+ end
17
+
18
+ protected
19
+
20
+ def add_options!(opt)
21
+ opt.separator ''
22
+ opt.separator 'Options:'
23
+
24
+ opt.on('--id CLIENT_ID', "Application API ID.") do |v|
25
+ options[:client_id] = v if v.present?
26
+ end
27
+
28
+ opt.on('--key SECRET_KEY', "Application Secret key.") do |v|
29
+ options[:client_key] = v if v.present?
30
+ end
31
+ opt.on('--server AUTH_SERVER', "Authentication Server.") do |v|
32
+ options[:auth_server] = v if v.present?
33
+ end
34
+ opt.on('--resources REQUESTED_RESOURCES', "Requested Resources.") do |v|
35
+ options[:requested_scope] = v if v.present?
36
+ end
37
+ end
38
+
39
+
40
+ def banner
41
+ "Usage: #{$0} devise_oauth2_authenticatable [--id API_ID] [--key SECRET_KEY] [--server AUTH_SERVER] [--scope REQUESTED RESOURCES]"
42
+ end
43
+
44
+ end
@@ -0,0 +1,23 @@
1
+ defaults: &defaults
2
+ # Required.
3
+ client_id: <%= options[:client_id] %>
4
+ client_secret: <%= options[:client_key] %>
5
+ authorization_server: <%= options[:auth_server] %>
6
+ requested_scope: <%= options[:requested_scope] %>
7
+
8
+
9
+
10
+ development:
11
+ <<: *defaults
12
+
13
+ test: &test
14
+ <<: *defaults
15
+
16
+ production: &production
17
+ <<: *defaults
18
+
19
+ # staging:
20
+ # <<: *production
21
+ #
22
+ # cucumber:
23
+ # <<: *test
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+ require 'devise'
3
+ require 'oauth2'
4
+
5
+
6
+ require 'devise_oauth2_authenticatable/model'
7
+ require 'devise_oauth2_authenticatable/strategy'
8
+ require 'devise_oauth2_authenticatable/schema'
9
+ require 'devise_oauth2_authenticatable/routes'
10
+ #require 'devise_oauth2_authenticatable/controller_filters'
11
+ require 'devise_oauth2_authenticatable/view_helpers'
12
+
13
+
14
+ module Devise
15
+ # Specifies the name of the database column name used for storing
16
+ # the oauth UID. Useful if this info should be saved in a
17
+ # generic column if different authentication solutions are used.
18
+ mattr_accessor :oauth2_uid_field
19
+ @@oauth2_uid_field = :oauth2_uid
20
+
21
+ # Specifies the name of the database column name used for storing
22
+ # the user Facebook session key. Useful if this info should be saved in a
23
+ # generic column if different authentication solutions are used.
24
+ mattr_accessor :oauth2_token_field
25
+ @@oauth2_token_field = :oauth2_token
26
+
27
+ # Specifies if account should be created if no account exists for
28
+ # a specified Facebook UID or not.
29
+ mattr_accessor :oauth2_auto_create_account
30
+ @@oauth2_auto_create_account = true
31
+
32
+ def self.oauth2_client
33
+ @@oauth2_client ||= OAuth2::Client.new(OAUTH2_CONFIG['client_id'], OAUTH2_CONFIG['client_secret'], :site => OAUTH2_CONFIG['authorization_server'])
34
+ end
35
+
36
+
37
+ def self.session_sign_in_url(request, mapping)
38
+ url = URI.parse(request.url)
39
+ url.path = "#{mapping.parsed_path}/#{mapping.path_names[:sign_in]}"
40
+ url.query = nil
41
+ url.to_s
42
+ end
43
+
44
+ def self.requested_scope
45
+ @@requested_scope ||= OAUTH2_CONFIG['requested_scope']
46
+ end
47
+
48
+ end
49
+
50
+ # Load core I18n locales: en
51
+ #
52
+ I18n.load_path.unshift File.join(File.dirname(__FILE__), *%w[devise_oauth2_authenticatable locales en.yml])
53
+
54
+ # Add +:facebook_connectable+ strategies to defaults.
55
+ #
56
+ Devise.add_module(:oauth2_authenticatable,
57
+ :strategy => true,
58
+ :controller => :sessions,
59
+ :model => 'devise_oauth2_authenticatable/model')
@@ -0,0 +1,9 @@
1
+ en:
2
+ devise:
3
+ sessions:
4
+ oauth2_invalid: "Could not login. Invalid account."
5
+ oauth2_timeout: "OAuth2 session expired., please sign in again to continue."
6
+ oauth2_authenticity_token: "Something went wrong. For security reasons, please sign in again." # Revise this message =)
7
+ oauth2_actions:
8
+ sign_in: "Sign in" # NOTE: Not used for the default Facebook Connect button.
9
+ sign_out: "Sign out"
@@ -0,0 +1,197 @@
1
+ # encoding: utf-8
2
+ require 'devise/models'
3
+
4
+
5
+ module Devise #:nodoc:
6
+ # module OAuth2Authenticatable #:nodoc:
7
+ module Models #:nodoc:
8
+
9
+ # OAuth2 Connectable Module, responsible for validating authenticity of a
10
+ # user and storing credentials while signing in using their OAuth2 account.
11
+ #
12
+ # == Configuration:
13
+ #
14
+ # You can overwrite configuration values by setting in globally in Devise (+Devise.setup+),
15
+ # using devise method, or overwriting the respective instance method.
16
+ #
17
+ # +oauth2_uid_field+ - Defines the name of the OAuth2 user UID database attribute/column.
18
+ #
19
+ # +oauth2_token_field+ - Defines the name of the OAuth2 session key database attribute/column.
20
+ #
21
+ # +oauth2_auto_create_account+ - Speifies if account should automatically be created upon connect
22
+ # if not already exists.
23
+ #
24
+ # == Examples:
25
+ #
26
+ # User.oauth2_connect(:uid => '123456789') # returns authenticated user or nil
27
+ # User.find(1).oauth2_connected? # returns true/false
28
+ #
29
+ module Oauth2Authenticatable
30
+
31
+ def self.included(base) #:nodoc:
32
+ base.class_eval do
33
+ extend ClassMethods
34
+ end
35
+ end
36
+
37
+ # Store OAuth2 Connect account/session credentials.
38
+ #
39
+ def store_oauth2_credentials!(attributes = {})
40
+ self.send(:"#{self.class.oauth2_uid_field}=", attributes[:uid])
41
+ self.send(:"#{self.class.oauth2_token_field}=", attributes[:token])
42
+
43
+ # Confirm without e-mail - if confirmable module is loaded.
44
+ self.skip_confirmation! if self.respond_to?(:skip_confirmation!)
45
+
46
+ # Only populate +email+ field if it's available (e.g. if +authenticable+ module is used).
47
+ self.email = attributes[:email] || '' if self.respond_to?(:email)
48
+
49
+ # Lazy hack: These database fields are required if +authenticable+/+confirmable+
50
+ # module(s) is used. Could be avoided with :null => true for authenticatable
51
+ # migration, but keeping this to avoid unnecessary problems.
52
+ self.password_salt = '' if self.respond_to?(:password_salt)
53
+ self.encrypted_password = '' if self.respond_to?(:encrypted_password)
54
+ end
55
+
56
+ # Checks if OAuth2 Connected.
57
+ #
58
+ def oauth2_connected?
59
+ self.send(:"#{self.class.oauth2_uid_field}").present?
60
+ end
61
+ alias :is_oauth2_connected? :oauth2_connected?
62
+
63
+ # Hook that gets called *before* connect (only at creation). Useful for
64
+ # specifiying additional user info (etc.) from OAuth2.
65
+ #
66
+ # Default: Do nothing.
67
+ #
68
+ # == Examples:
69
+ #
70
+ # # Overridden in OAuth2 Connect:able model, e.g. "User".
71
+ # #
72
+ # def before_oauth2_auto_create(oauth2_user_attributes)
73
+
74
+ # self.profile.first_name = oauth2_user_attributes.first_name
75
+
76
+ #
77
+ # end
78
+ #
79
+ # == For more info:
80
+ #
81
+ # * http://oauth2er.pjkh.com/user/populate
82
+ #
83
+ def on_before_oauth2_auto_create(oauth2_user_attributes)
84
+
85
+ if self.respond_to?(:before_oauth2_auto_create)
86
+ self.send(:before_oauth2_auto_create, oauth2_user_attributes) rescue nil
87
+ end
88
+ end
89
+
90
+ # Hook that gets called *after* a connection (each time). Useful for
91
+ # fetching additional user info (etc.) from OAuth2.
92
+ #
93
+ # Default: Do nothing.
94
+ #
95
+ # == Example:
96
+ #
97
+ # # Overridden in OAuth2 Connect:able model, e.g. "User".
98
+ # #
99
+ # def after_oauth2_connect(oauth2_user_attributes)
100
+ # # See "on_before_oauth2_connect" example.
101
+ # end
102
+ #
103
+ def on_after_oauth2_connect(oauth2_user_attributes)
104
+
105
+ if self.respond_to?(:after_oauth2_auto_create)
106
+ self.send(:after_oauth2_auto_create, oauth2_user_attributes) rescue nil
107
+ end
108
+ end
109
+
110
+ # Optional: Store session key.
111
+ #
112
+ def store_session(using_token)
113
+ if self.token != using_token
114
+ self.update_attribute(self.send(:"#{self.class.oauth2_token_field}"), using_token)
115
+ end
116
+ end
117
+
118
+ protected
119
+
120
+ # Passwords are always required if it's a new rechord and no oauth_id exists, or if the password
121
+ # or confirmation are being set somewhere.
122
+ def password_required?
123
+
124
+ ( new_record? && oauth2_uid.nil? ) || !password.nil? || !password_confirmation.nil?
125
+ end
126
+
127
+ module ClassMethods
128
+
129
+ # Configuration params accessible within +Devise.setup+ procedure (in initalizer).
130
+ #
131
+ # == Example:
132
+ #
133
+ # Devise.setup do |config|
134
+ # config.oauth2_uid_field = :oauth2_uid
135
+ # config.oauth2_token_field = :oauth2_token
136
+ # config.oauth2_auto_create_account = true
137
+ # end
138
+ #
139
+ ::Devise::Models.config(self,
140
+ :oauth2_uid_field,
141
+ :oauth2_token_field,
142
+ :oauth2_auto_create_account
143
+ )
144
+
145
+ # Alias don't work for some reason, so...a more Ruby-ish alias
146
+ # for +oauth2_auto_create_account+.
147
+ #
148
+ def oauth2_auto_create_account?
149
+ self.oauth2_auto_create_account
150
+ end
151
+
152
+ # Authenticate a user based on OAuth2 UID.
153
+ #
154
+ def authenticate_with_oauth2(oauth2_id, oauth2_token)
155
+
156
+ # find user and update access token
157
+ returning(self.find_for_oauth2(oauth2_id)) do |user|
158
+ user.update_attributes(:oauth2_token => oauth2_token) unless user.nil?
159
+ end
160
+
161
+ end
162
+
163
+ protected
164
+
165
+
166
+
167
+ # Find first record based on conditions given (OAuth2 UID).
168
+ # Overwrite to add customized conditions, create a join, or maybe use a
169
+ # namedscope to filter records while authenticating.
170
+ #
171
+ # == Example:
172
+ #
173
+ # def self.find_for_oauth2(uid, conditions = {})
174
+ # conditions[:active] = true
175
+ # self.find_by_oauth2_uid(uid, :conditions => conditions)
176
+ # end
177
+ #
178
+ def find_for_oauth2(uid, conditions = {})
179
+
180
+ self.find_by_oauth2_uid(uid, :conditions => conditions)
181
+ end
182
+
183
+
184
+
185
+ # Contains the logic used in authentication. Overwritten by other devise modules.
186
+ # In the OAuth2 Connect case; nothing fancy required.
187
+ #
188
+ def valid_for_oauth2(resource, attributes)
189
+ true
190
+ end
191
+
192
+ end
193
+
194
+ end
195
+ end
196
+ # end
197
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ ActionController::Routing::RouteSet::Mapper.class_eval do
4
+
5
+ protected
6
+
7
+ # Setup routes for +OAuth2SessionsController+.
8
+ #
9
+ alias :oauth2_authenticatable :database_authenticatable
10
+
11
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ require 'devise/schema'
3
+
4
+ module Devise #:nodoc:
5
+ module Oauth2Authenticatable #:nodoc:
6
+
7
+ module Schema
8
+
9
+ # Database migration schema for Facebook Connect.
10
+ #
11
+ def oauth2_authenticatable
12
+ apply_schema ::Devise.oauth2_uid_field, Integer, :limit => 8 # BIGINT unsigned / 64-bit int
13
+ apply_schema ::Devise.oauth2_token_field, String, :limit => 149 # [128][1][20] chars
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+
20
+ Devise::Schema.module_eval do
21
+ include ::Devise::Oauth2Authenticatable::Schema
22
+ end
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+ require 'devise/strategies/base'
3
+
4
+
5
+ module Devise #:nodoc:
6
+ module Oauth2Authenticatable #:nodoc:
7
+ module Strategies #:nodoc:
8
+
9
+ # Default strategy for signing in a user using Facebook Connect (a Facebook account).
10
+ # Redirects to sign_in page if it's not authenticated
11
+ #
12
+ class Oauth2Authenticatable < ::Devise::Strategies::Base
13
+
14
+
15
+
16
+ # Without a oauth session authentication cannot proceed.
17
+ #
18
+ def valid?
19
+
20
+ valid_controller? && valid_params? && mapping.to.respond_to?('authenticate_with_oauth2')
21
+
22
+ end
23
+
24
+ # Authenticate user with OAuth2
25
+ #
26
+ def authenticate!
27
+ klass = mapping.to
28
+ begin
29
+
30
+
31
+ # Verify User Auth code and get access token from auth server: will error on failue
32
+ access_token = Devise::oauth2_client.web_server.get_access_token(
33
+ params[:code], :redirect_uri => Devise::session_sign_in_url(request,mapping)
34
+ )
35
+
36
+ # retrieve user attributes
37
+
38
+ # Get user details from OAuth2 Service
39
+ # NOTE: Facebook Graph Specific
40
+ # TODO: break this out into separate model or class to handle
41
+ # different oauth2 providers
42
+ oauth2_user_attributes = JSON.parse(access_token.get('/me'))
43
+
44
+ user = klass.authenticate_with_oauth2(oauth2_user_attributes['id'], access_token.token)
45
+
46
+
47
+
48
+ if user.present?
49
+ user.on_after_oauth2_connect(oauth2_user_attributes)
50
+ success!(user)
51
+ else
52
+ if klass.oauth2_auto_create_account?
53
+
54
+
55
+
56
+ user = returning(klass.new) do |u|
57
+ u.store_oauth2_credentials!(
58
+ :token => access_token.token,
59
+ :uid => oauth2_user_attributes['id']
60
+ )
61
+ u.on_before_oauth2_auto_create(oauth2_user_attributes)
62
+ end
63
+
64
+ begin
65
+
66
+
67
+ user.save(true)
68
+ user.on_after_oauth2_connect(oauth2_user_attributes)
69
+
70
+
71
+ success!(user)
72
+ rescue
73
+ fail!(:oauth2_invalid)
74
+ end
75
+ else
76
+ fail!(:oauth2_invalid)
77
+ end
78
+ end
79
+
80
+ rescue => e
81
+ fail!(e.message)
82
+ end
83
+ end
84
+
85
+
86
+
87
+
88
+ protected
89
+ def valid_controller?
90
+ params[:controller] == 'sessions'
91
+ end
92
+
93
+ def valid_params?
94
+ params[:code].present?
95
+ end
96
+
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ Warden::Strategies.add(:oauth2_authenticatable, Devise::Oauth2Authenticatable::Strategies::Oauth2Authenticatable)
@@ -0,0 +1,5 @@
1
+ module Devise
2
+ module Oauth2Authenticatable
3
+ VERSION = "0.0.1".freeze
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ require 'devise/mapping'
3
+
4
+ module Devise #:nodoc:
5
+ module Oauth2Authenticatable #:nodoc:
6
+
7
+ # OAuth2 view helpers to easily add the link to the OAuth2 connection popup and also the necessary JS code.
8
+ #
9
+ module Helpers
10
+
11
+ # Creates the link to
12
+ def link_to_oauth2(link_text, options={})
13
+
14
+
15
+ session_sign_in_url = Devise::session_sign_in_url(request,::Devise.mappings[:user])
16
+
17
+ link_to link_text, Devise::oauth2_client.web_server.authorize_url(
18
+ :redirect_uri => session_sign_in_url,
19
+ :scope => Devise::requested_scope
20
+ ), options
21
+ end
22
+
23
+
24
+
25
+ end
26
+ end
27
+ end
28
+
29
+ ::ActionView::Base.send :include, Devise::Oauth2Authenticatable::Helpers
data/rails/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ Devise::OAUTH2_CONFIG = YAML.load_file(Rails.root.join('config', 'oauth2_config.yml'))[Rails.env]
3
+
4
+ require 'devise_oauth2_authenticatable'
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "DeviseOauth2Authenticatable" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
data/spec/spec.opts ADDED
@@ -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_oauth2_authenticatable'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devise_oauth2_authenticatable
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - bhbryant
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-18 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 9
31
+ version: 1.2.9
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: devise
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 1
43
+ - 0
44
+ - 0
45
+ version: 1.0.0
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: oauth2
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ type: :runtime
59
+ version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ name: json
62
+ prerelease: false
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ type: :runtime
71
+ version_requirements: *id004
72
+ description: Implements OAuth2 for devises, specifically integrating with facebook Graph
73
+ email: benjamin@bryantmarkowsky.com
74
+ executables: []
75
+
76
+ extensions: []
77
+
78
+ extra_rdoc_files:
79
+ - LICENSE
80
+ - README.rdoc
81
+ files:
82
+ - .document
83
+ - .gitignore
84
+ - LICENSE
85
+ - README.rdoc
86
+ - Rakefile
87
+ - devise_oauth2_authenticatable.gemspec
88
+ - generators/devise_oauth2_authenticatable/devise_oauth2_authenticatable_generator.rb
89
+ - generators/devise_oauth2_authenticatable/templates/oauth2_config.yml
90
+ - lib/devise_oauth2_authenticatable.rb
91
+ - lib/devise_oauth2_authenticatable/locales/en.yml
92
+ - lib/devise_oauth2_authenticatable/model.rb
93
+ - lib/devise_oauth2_authenticatable/routes.rb
94
+ - lib/devise_oauth2_authenticatable/schema.rb
95
+ - lib/devise_oauth2_authenticatable/strategy.rb
96
+ - lib/devise_oauth2_authenticatable/version.rb
97
+ - lib/devise_oauth2_authenticatable/view_helpers.rb
98
+ - rails/init.rb
99
+ - spec/devise_oauth2_authenticatable_spec.rb
100
+ - spec/spec.opts
101
+ - spec/spec_helper.rb
102
+ has_rdoc: true
103
+ homepage: http://github.com/bhbryant/devise_oauth2_authenticatable
104
+ licenses: []
105
+
106
+ post_install_message:
107
+ rdoc_options:
108
+ - --charset=UTF-8
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ segments:
123
+ - 0
124
+ version: "0"
125
+ requirements: []
126
+
127
+ rubyforge_project:
128
+ rubygems_version: 1.3.6
129
+ signing_key:
130
+ specification_version: 3
131
+ summary: Devise << OAuth2
132
+ test_files:
133
+ - spec/devise_oauth2_authenticatable_spec.rb
134
+ - spec/spec_helper.rb