heyzap-authlogic-oauth 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ == 1.0.8 release 2009-8-2
2
+
3
+ * Fixing unauthorized errors when you before_filter :require_no_user on the UserController#create action.
4
+
5
+ == 1.0.7 release 2009-7-20
6
+
7
+ * Fixing a OAuth unauthorized error when updating a user object with new oauth token/secret via the 'Register with OAuth' helper.
8
+
9
+ == 1.0.6 released 2009-6-29
10
+
11
+ * Any attributes set on the User model before saving, will now be maintained after the user
12
+ returns from authenticating with the oauth server.
13
+
14
+ == 1.0.4 released 2009-6-27
15
+
16
+ * Bug fix
17
+
18
+ == 1.0.2 released 2009-6-27
19
+
20
+ * Using oauth's callback_url parameter to control where the oauth server returns the user to the application.
21
+ The callback_url parameter was temporarily disabled on major oauth sites due to security concerns, but has been resolved.
22
+
23
+ * Removed the need to add specific oauth routes and an oauth_controller (YAY!). This makes using the plugin much easier.
24
+
25
+ == 1.0.1 released 2009-6-4
26
+
27
+ * Adding helpers for the login/register buttons to be used in conjunction with authlogic_oauth
28
+
29
+ == 1.0.0 released 2009-5-31
30
+
31
+ * Initial release.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 John Allison (johnallison.me)
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,20 @@
1
+ CHANGELOG.rdoc
2
+ MIT-LICENSE
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ init.rb
7
+ lib/authlogic_oauth.rb
8
+ lib/authlogic_oauth/acts_as_authentic.rb
9
+ lib/authlogic_oauth/helper.rb
10
+ lib/authlogic_oauth/oauth_process.rb
11
+ lib/authlogic_oauth/session.rb
12
+ lib/authlogic_oauth/version.rb
13
+ lib/oauth_callback_filter.rb
14
+ rails/init.rb
15
+ test/acts_as_authentic_test.rb
16
+ test/fixtures/users.yml
17
+ test/lib/user.rb
18
+ test/lib/user_session.rb
19
+ test/session_test.rb
20
+ test/test_helper.rb
@@ -0,0 +1,100 @@
1
+ = Authlogic OAuth
2
+
3
+ Authlogic OAuth is an extension of the Authlogic library to add OAuth support. One use case for authentication with OAuth is allowing users to log in with their Twitter credentials.
4
+
5
+ == Helpful links
6
+
7
+ * <b>Authlogic:</b> http://github.com/binarylogic/authlogic
8
+ * <b>OAuth Example Project:</b> http://github.com/jrallison/authlogic_example/tree/with-oauth
9
+ * <b>Live example with Twitter:</b> http://authlogic-oauth.heroku.com
10
+
11
+ == Install and use
12
+
13
+ === 1. Install Authlogic and setup your application
14
+
15
+ * <b>Authlogic:</b> http://github.com/binarylogic/authlogic
16
+ * <b>Authlogic Example:</b> http://github.com/binarylogic/authlogic_example
17
+
18
+ === 2. Install OAuth and Authlogic_Oauth
19
+
20
+ $ sudo gem install oauth
21
+ $ sudo gem install authlogic-oauth
22
+
23
+ Now add the gem dependencies in your config:
24
+
25
+ config.gem "oauth"
26
+ config.gem "authlogic-oauth", :lib => "authlogic_oauth"
27
+
28
+ Or for older version of rails, install it as a plugin:
29
+
30
+ $ script/plugin install git://github.com/jrallison/authlogic_oauth.git
31
+
32
+ === 3. Make some simple changes to your database:
33
+
34
+ class AddUsersOauthFields < ActiveRecord::Migration
35
+ def self.up
36
+ add_column :users, :oauth_token, :string
37
+ add_column :users, :oauth_secret, :string
38
+ add_index :users, :oauth_token
39
+
40
+ change_column :users, :login, :string, :default => nil, :null => true
41
+ change_column :users, :crypted_password, :string, :default => nil, :null => true
42
+ change_column :users, :password_salt, :string, :default => nil, :null => true
43
+ end
44
+
45
+ def self.down
46
+ remove_column :users, :oauth_token
47
+ remove_column :users, :oauth_secret
48
+
49
+ [:login, :crypted_password, :password_salt].each do |field|
50
+ User.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? }
51
+ change_column :users, field, :string, :default => "", :null => false
52
+ end
53
+ end
54
+ end
55
+
56
+ === 4. Make sure you save your objects properly
57
+
58
+ You only need to save your objects this way if you want the user to authenticate with their OAuth provider.
59
+
60
+ That being said, you probably want to do this in your controllers. You should do this for BOTH your User objects and UserSession objects (assuming you are authenticating users). It should look something like this:
61
+
62
+ @user_session.save do |result|
63
+ if result
64
+ flash[:notice] = "Login successful!"
65
+ redirect_back_or_default account_url
66
+ else
67
+ render :action => :new
68
+ end
69
+ end
70
+
71
+ You should save your @user objects this way as well, because you also want the user to authenticate with OAuth.
72
+
73
+ Notice we are saving with a block. Why? Because we need to redirect the user to their OAuth provider so that they can authenticate. When we do this, we don't want to execute that block of code, because if we do, we will get a DoubleRender error. This lets us skip that entire block and send the user along their way without any problems.
74
+
75
+ === 5. Define the oauth_consumer class method on your UserSession model
76
+
77
+ The oauth_consumer should return an OAuth::Consumer which is configured for your OAuth provider. Here's an example for Twitter:
78
+
79
+ class UserSession < Authlogic::Session::Base
80
+
81
+ def self.oauth_consumer
82
+ OAuth::Consumer.new("TOKEN", "SECRET",
83
+ { :site=>"http://twitter.com",
84
+ :authorize_url => "http://twitter.com/oauth/authenticate" })
85
+ end
86
+
87
+ end
88
+
89
+ === 6. Add login and register buttons to your views
90
+
91
+ <%= oauth_register_button :value => "Register with Twitter" %>
92
+ <%= oauth_login_button :value => "Login with Twitter" %>
93
+
94
+ That's it! The rest is taken care of for you.
95
+
96
+ = Here are some next steps for the plugin.
97
+
98
+ 1. Safe OAuth error handling.
99
+ 2. Remove oauth request from the Rails request cycle.
100
+
@@ -0,0 +1,20 @@
1
+ ENV['RDOCOPT'] = "-S -f html -T hanna"
2
+
3
+ require "rubygems"
4
+ require "hoe"
5
+ require File.dirname(__FILE__) << "/lib/authlogic_oauth/version"
6
+
7
+ Hoe.new("heyzap-authlogic-oauth", AuthlogicOauth::Version::STRING) do |p|
8
+ p.name = "heyzap-authlogic-oauth"
9
+ p.author = "John Allison"
10
+ p.email = 'jrallison@gmail.com'
11
+ p.summary = "An authlogic extension for authenticating via OAuth. (I.E. Twitter login)"
12
+ p.description = "An authlogic extension for authenticating via OAuth. This can be helpful for adding support for login/registration with Twitter credentials."
13
+ p.url = "http://github.com/jrallison/authlogic_oauth"
14
+ p.history_file = "CHANGELOG.rdoc"
15
+ p.readme_file = "README.rdoc"
16
+ p.extra_rdoc_files = ["CHANGELOG.rdoc", "README.rdoc"]
17
+ p.remote_rdoc_dir = ''
18
+ p.test_globs = ["test/*/test_*.rb", "test/*_test.rb", "test/*/*_test.rb"]
19
+ p.extra_deps = %w(activesupport)
20
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ File.dirname(__FILE__) + "/rails/init.rb"
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + "/authlogic_oauth/version"
2
+ require File.dirname(__FILE__) + "/authlogic_oauth/oauth_process"
3
+ require File.dirname(__FILE__) + "/authlogic_oauth/acts_as_authentic"
4
+ require File.dirname(__FILE__) + "/authlogic_oauth/session"
5
+ require File.dirname(__FILE__) + "/authlogic_oauth/helper"
6
+
7
+ ActiveRecord::Base.send(:include, AuthlogicOauth::ActsAsAuthentic)
8
+ Authlogic::Session::Base.send(:include, AuthlogicOauth::Session)
9
+ ActionController::Base.helper AuthlogicOauth::Helper
@@ -0,0 +1,134 @@
1
+ module AuthlogicOauth
2
+ module ActsAsAuthentic
3
+ def self.included(klass)
4
+ klass.class_eval do
5
+ extend Config
6
+ add_acts_as_authentic_module(Methods, :prepend)
7
+ end
8
+ end
9
+
10
+ module Config
11
+ # The name of the oauth token field in the database.
12
+ #
13
+ # * <tt>Default:</tt> :oauth_token
14
+ # * <tt>Accepts:</tt> Symbol
15
+ def oauth_token_field(value = nil)
16
+ rw_config(:oauth_token_field, value, :oauth_token)
17
+ end
18
+ alias_method :oauth_token_field=, :oauth_token_field
19
+
20
+ # The name of the oauth token secret field in the database.
21
+ #
22
+ # * <tt>Default:</tt> :oauth_secret
23
+ # * <tt>Accepts:</tt> Symbol
24
+ def oauth_secret_field(value = nil)
25
+ rw_config(:oauth_secret_field, value, :oauth_secret)
26
+ end
27
+ alias_method :oauth_secret_field=, :oauth_secret_field
28
+ end
29
+
30
+ module Methods
31
+ include OauthProcess
32
+
33
+ # Set up some simple validations
34
+ def self.included(klass)
35
+ klass.class_eval do
36
+ alias_method "#{oauth_token_field.to_s}=".to_sym, :oauth_token=
37
+ alias_method "#{oauth_secret_field.to_s}=".to_sym, :oauth_secret=
38
+ end
39
+
40
+ return if !klass.column_names.include?(klass.oauth_token_field.to_s)
41
+
42
+ klass.class_eval do
43
+ validate :validate_by_oauth, :if => :authenticating_with_oauth?
44
+
45
+ validates_uniqueness_of klass.oauth_token_field, :scope => validations_scope, :if => :using_oauth?
46
+ validates_presence_of klass.oauth_secret_field, :scope => validations_scope, :if => :using_oauth?
47
+
48
+ validates_length_of_password_field_options validates_length_of_password_field_options.merge(:if => :validate_password_with_oauth?)
49
+ validates_confirmation_of_password_field_options validates_confirmation_of_password_field_options.merge(:if => :validate_password_with_oauth?)
50
+ validates_length_of_password_confirmation_field_options validates_length_of_password_confirmation_field_options.merge(:if => :validate_password_with_oauth?)
51
+ validates_length_of_login_field_options validates_length_of_login_field_options.merge(:if => :validate_password_with_oauth?)
52
+ validates_format_of_login_field_options validates_format_of_login_field_options.merge(:if => :validate_password_with_oauth?)
53
+ end
54
+
55
+ # email needs to be optional for oauth
56
+ klass.validate_email_field = false
57
+ end
58
+
59
+ def save(perform_validation = true, &block)
60
+ if perform_validation && block_given? && redirecting_to_oauth_server?
61
+ # Save attributes so they aren't lost during the authentication with the oauth server
62
+ session_class.controller.session[:authlogic_oauth_attributes] = attributes.reject!{|k, v| v.blank?}
63
+ redirect_to_oauth
64
+ return false
65
+ end
66
+
67
+ result = super
68
+ yield(result) if block_given?
69
+ result
70
+ end
71
+
72
+ # accessors for oauth fields
73
+ def oauth_token
74
+ read_attribute(oauth_token_field)
75
+ end
76
+
77
+ def oauth_token=(value)
78
+ write_attribute(oauth_token_field, value.blank? ? nil : value)
79
+ end
80
+
81
+ def oauth_secret
82
+ read_attribute(oauth_secret_field)
83
+ end
84
+
85
+ def oauth_secret=(value)
86
+ write_attribute(oauth_secret_field, value.blank? ? nil : value)
87
+ end
88
+
89
+ private
90
+
91
+ def authenticating_with_oauth?
92
+ # Controller isn't available in all contexts (e.g. irb)
93
+ return false unless session_class.controller
94
+
95
+ # Initial request when user presses one of the button helpers
96
+ (session_class.controller.params && !session_class.controller.params[:register_with_oauth].blank?) ||
97
+ # When the oauth provider responds and we made the initial request
98
+ (oauth_response && session_class.controller.session && session_class.controller.session[:oauth_request_class] == self.class.name)
99
+ end
100
+
101
+ def authenticate_with_oauth
102
+ # Restore any attributes which were saved before redirecting to the oauth server
103
+ self.attributes = session_class.controller.session.delete(:authlogic_oauth_attributes)
104
+ access_token = generate_access_token
105
+
106
+ self.oauth_token = access_token.token
107
+ self.oauth_secret = access_token.secret
108
+ end
109
+
110
+ def access_token
111
+ OAuth::AccessToken.new(oauth,
112
+ read_attribute(oauth_token_field),
113
+ read_attribute(oauth_secret_field))
114
+ end
115
+
116
+ def using_oauth?
117
+ respond_to?(oauth_token_field) && !oauth_token.blank?
118
+ end
119
+
120
+ def validate_password_with_oauth?
121
+ !using_oauth? && require_password?
122
+ end
123
+
124
+ def oauth_token_field
125
+ self.class.oauth_token_field
126
+ end
127
+
128
+ def oauth_secret_field
129
+ self.class.oauth_secret_field
130
+ end
131
+
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,16 @@
1
+ module AuthlogicOauth
2
+ module Helper
3
+ def oauth_register_button(options = {})
4
+ oauth_button('register_with_oauth', options)
5
+ end
6
+
7
+ def oauth_login_button(options = {})
8
+ oauth_button('login_with_oauth', options)
9
+ end
10
+
11
+ private
12
+ def oauth_button(name, options = {})
13
+ "<input type='submit' value='#{options[:value]}' name='#{name}' id='user_submit' class='#{options[:class]}'/>"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,66 @@
1
+ module AuthlogicOauth
2
+ module OauthProcess
3
+
4
+ def generate_access_token
5
+ @access_token ||= request_token.get_access_token(:oauth_verifier => oauth_controller.params[:oauth_verifier])
6
+ end
7
+
8
+ private
9
+
10
+ def validate_by_oauth
11
+ validate_email_field = false
12
+
13
+ if oauth_response.blank?
14
+ redirect_to_oauth
15
+ else
16
+ authenticate_with_oauth
17
+ end
18
+ end
19
+
20
+ def redirecting_to_oauth_server?
21
+ authenticating_with_oauth? && oauth_response.blank?
22
+ end
23
+
24
+ def redirect_to_oauth
25
+ request = oauth.get_request_token :oauth_callback => build_callback_url
26
+ oauth_controller.session[:oauth_request_token] = request.token
27
+ oauth_controller.session[:oauth_request_token_secret] = request.secret
28
+
29
+ # Store the class which is redirecting, so we can ensure other classes
30
+ # don't get confused and attempt to use the response
31
+ oauth_controller.session[:oauth_request_class] = self.class.name
32
+
33
+ # Tell our rack callback filter what method the current request is using
34
+ oauth_controller.session[:oauth_callback_method] = oauth_controller.request.method
35
+
36
+ oauth_controller.redirect_to request.authorize_url
37
+ end
38
+
39
+ def build_callback_url
40
+ oauth_controller.url_for :controller => oauth_controller.controller_name, :action => oauth_controller.action_name
41
+ end
42
+
43
+ def request_token
44
+ OAuth::RequestToken.new(oauth,
45
+ oauth_controller.session[:oauth_request_token],
46
+ oauth_controller.session[:oauth_request_token_secret])
47
+ end
48
+
49
+ def oauth_response
50
+ oauth_controller.params && oauth_controller.params[:oauth_token]
51
+ end
52
+
53
+ def oauth_controller
54
+ is_auth_session? ? controller : session_class.controller
55
+ end
56
+
57
+ def oauth
58
+ is_auth_session? ? self.class.oauth_consumer : session_class.oauth_consumer
59
+ end
60
+
61
+ def is_auth_session?
62
+ self.is_a?(Authlogic::Session::Base)
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,76 @@
1
+ module AuthlogicOauth
2
+ # This module is responsible for adding oauth
3
+ # to the Authlogic::Session::Base class.
4
+ module Session
5
+ def self.included(klass)
6
+ klass.class_eval do
7
+ extend Config
8
+ include Methods
9
+ end
10
+ end
11
+
12
+ module Config
13
+ # * <tt>Default:</tt> :find_by_oauth_token
14
+ # * <tt>Accepts:</tt> Symbol
15
+ def find_by_oauth_method(value = nil)
16
+ rw_config(:find_by_oauth_method, value, :find_by_oauth_token)
17
+ end
18
+ alias_method :find_by_oauth_method=, :find_by_oauth_method
19
+ end
20
+
21
+ module Methods
22
+ include OauthProcess
23
+
24
+ def self.included(klass)
25
+ klass.class_eval do
26
+ validate :validate_by_oauth, :if => :authenticating_with_oauth?
27
+ end
28
+ end
29
+
30
+ # Hooks into credentials so that you can pass a user who has already has an oauth access token.
31
+ def credentials=(value)
32
+ super
33
+ values = value.is_a?(Array) ? value : [value]
34
+ hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
35
+ self.record = hash[:priority_record] if !hash.nil? && hash.key?(:priority_record)
36
+ end
37
+
38
+ def record=(record)
39
+ @record = record
40
+ end
41
+
42
+ # Clears out the block if we are authenticating with oauth,
43
+ # so that we can redirect without a DoubleRender error.
44
+ def save(&block)
45
+ block = nil if redirecting_to_oauth_server?
46
+ super(&block)
47
+ end
48
+
49
+ private
50
+
51
+ def authenticating_with_oauth?
52
+ # Initial request when user presses one of the button helpers
53
+ (controller.params && !controller.params[:login_with_oauth].blank?) ||
54
+ # When the oauth provider responds and we made the initial request
55
+ (oauth_response && controller.session && controller.session[:oauth_request_class] == self.class.name)
56
+ end
57
+
58
+ def authenticate_with_oauth
59
+ if @record
60
+ self.attempted_record = record
61
+ else
62
+ self.attempted_record = search_for_record(find_by_oauth_method, generate_access_token.token)
63
+ #errors.add_to_base("Unable to authenticate with Twitter.")
64
+ end
65
+
66
+ if !attempted_record
67
+ errors.add_to_base("Could not find user in our database, have you registered with your oauth account?")
68
+ end
69
+ end
70
+
71
+ def find_by_oauth_method
72
+ self.class.find_by_oauth_method
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,51 @@
1
+ module AuthlogicOauth
2
+ # A class for describing the current version of a library. The version
3
+ # consists of three parts: the +major+ number, the +minor+ number, and the
4
+ # +tiny+ (or +patch+) number.
5
+ class Version
6
+ include Comparable
7
+
8
+ # A convenience method for instantiating a new Version instance with the
9
+ # given +major+, +minor+, and +tiny+ components.
10
+ def self.[](major, minor, tiny)
11
+ new(major, minor, tiny)
12
+ end
13
+
14
+ attr_reader :major, :minor, :tiny
15
+
16
+ # Create a new Version object with the given components.
17
+ def initialize(major, minor, tiny)
18
+ @major, @minor, @tiny = major, minor, tiny
19
+ end
20
+
21
+ # Compare this version to the given +version+ object.
22
+ def <=>(version)
23
+ to_i <=> version.to_i
24
+ end
25
+
26
+ # Converts this version object to a string, where each of the three
27
+ # version components are joined by the '.' character. E.g., 2.0.0.
28
+ def to_s
29
+ @to_s ||= [@major, @minor, @tiny].join(".")
30
+ end
31
+
32
+ # Converts this version to a canonical integer that may be compared
33
+ # against other version objects.
34
+ def to_i
35
+ @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
36
+ end
37
+
38
+ def to_a
39
+ [@major, @minor, @tiny]
40
+ end
41
+
42
+ MAJOR = 1
43
+ MINOR = 0
44
+ TINY = 8
45
+
46
+ # The current version as a Version instance
47
+ CURRENT = new(MAJOR, MINOR, TINY)
48
+ # The current version as a String
49
+ STRING = CURRENT.to_s
50
+ end
51
+ end
@@ -0,0 +1,12 @@
1
+ class OauthCallbackFilter
2
+ def initialize(app)
3
+ @app = app
4
+ end
5
+
6
+ def call(env)
7
+ unless env["rack.session"][:oauth_callback_method].blank?
8
+ env["REQUEST_METHOD"] = env["rack.session"].delete(:oauth_callback_method).to_s.upcase
9
+ end
10
+ @app.call(env)
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ require "authlogic_oauth"
2
+ require "oauth_callback_filter"
3
+
4
+ # Throw callback rack app into the middleware stack
5
+ ActionController::Dispatcher.middleware = ActionController::MiddlewareStack.new do |m|
6
+ ActionController::Dispatcher.middleware.each do |klass|
7
+ m.use klass
8
+ end
9
+ m.use OauthCallbackFilter
10
+ end
@@ -0,0 +1,100 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class ActsAsAuthenticTest < ActiveSupport::TestCase
4
+ def test_included
5
+ assert User.send(:acts_as_authentic_modules).include?(AuthlogicOauth::ActsAsAuthentic::Methods)
6
+ assert_equal :validate_password_with_oauth?, User.validates_length_of_password_field_options[:if]
7
+ assert_equal :validate_password_with_oauth?, User.validates_confirmation_of_password_field_options[:if]
8
+ assert_equal :validate_password_with_oauth?, User.validates_length_of_password_confirmation_field_options[:if]
9
+ assert_equal :validate_password_with_oauth?, User.validates_length_of_login_field_options[:if]
10
+ assert_equal :validate_password_with_oauth?, User.validates_format_of_login_field_options[:if]
11
+ end
12
+
13
+ def test_required_fields_on_create
14
+ user = User.new
15
+ assert !user.save
16
+ assert user.errors.on(:login)
17
+ assert user.errors.on(:password)
18
+ assert user.errors.on(:password_confirmation)
19
+ end
20
+
21
+ def test_fields_not_required_on_create_if_using_oauth
22
+ user = User.new
23
+ user.oauth_token = "SLDKJSD"
24
+ assert !user.save {} # because we are redirecting, the user was NOT saved
25
+ #assert redirecting_to_oauth?
26
+ end
27
+
28
+ def test_login_not_required_on_update_if_using_oauth
29
+ john = users(:john)
30
+ assert_nil john.login
31
+ assert john.save
32
+ end
33
+
34
+ def test_password_not_required_on_update_if_using_oauth
35
+ john = users(:john)
36
+ assert_nil john.crypted_password
37
+ assert john.save
38
+ end
39
+
40
+ def test_email_not_required_on_update_if_using_oauth
41
+ john = users(:john)
42
+ assert_nil john.email
43
+ assert john.save
44
+ end
45
+
46
+ def test_fields_required_on_update_if_not_using_oauth
47
+ john = users(:john)
48
+ john.oauth_token = nil
49
+ assert_nil john.login
50
+ assert_nil john.crypted_password
51
+ assert_nil john.email
52
+ assert !john.save
53
+
54
+ assert john.errors.on(:login)
55
+ assert john.errors.on(:password)
56
+ assert john.errors.on(:password_confirmation)
57
+ end
58
+
59
+ def test_validates_uniqueness_of_oauth_token
60
+ u = User.new(:oauth_token => "johns_token")
61
+ assert !u.valid?
62
+ assert u.errors.on(:oauth_token)
63
+ end
64
+
65
+ def test_blank_oauth_token_gets_set_to_nil
66
+ u = User.new(:oauth_token => "")
67
+ assert_nil u.oauth_token
68
+ end
69
+
70
+ def test_blank_oauth_secret_gets_set_to_nil
71
+ u = User.new(:oauth_secret => "")
72
+ assert_nil u.oauth_secret
73
+ end
74
+
75
+ def test_updating_without_oauth
76
+ john = users(:john)
77
+ john.oauth_token = nil
78
+ john.login = "john"
79
+ john.email = "john@example.com"
80
+ john.password = "test"
81
+ john.password_confirmation = "test"
82
+ assert john.save
83
+ #assert !redirecting_to_yahoo?
84
+ end
85
+
86
+ def test_updating_without_validation
87
+ john = users(:john)
88
+ john.oauth_token = "SDSDGSDGSD"
89
+ assert john.save(false)
90
+ #assert !redirecting_to_yahoo?
91
+ end
92
+
93
+ def test_updating_without_a_block
94
+ john = users(:john)
95
+ john.oauth_token = "SDSDGSDGSD"
96
+ assert john.save
97
+ john.reload
98
+ assert_equal "SDSDGSDGSD", john.oauth_token
99
+ end
100
+ end
@@ -0,0 +1,6 @@
1
+ john:
2
+ persistence_token: 6cde0674657a8a313ce952df979de2830309aa4c11ca65805dd00bfdc65dbcc2f5e36718660a1d2e68c1a08c276d996763985d2f06fd3d076eb7bc4d97b1e317
3
+ single_access_token: <%= Authlogic::Random.friendly_token %>
4
+ perishable_token: <%= Authlogic::Random.friendly_token %>
5
+ oauth_token: johns_token
6
+ oauth_secret: johns_token_secret
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ acts_as_authentic
3
+ end
@@ -0,0 +1,7 @@
1
+ class UserSession < Authlogic::Session::Base
2
+
3
+ def self.oauth_consumer
4
+ OAuth::Consumer.new("CONSUMER_TOKEN", "CONSUMER_SECRET", { :site=>"http://example.com" })
5
+ end
6
+
7
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class SessionTest < ActiveSupport::TestCase
4
+ def test_authenticate_by_record
5
+ session = UserSession.new
6
+ assert session.respond_to?(:record)
7
+ session.record = users(:john)
8
+ assert_equal users(:john), session.record
9
+ end
10
+
11
+ def test_validate_by_nil_oauth_token
12
+ session = UserSession.new
13
+ assert !session.save
14
+ assert !redirecting_to_oauth?
15
+ end
16
+
17
+ def test_validate_by_oauth
18
+ controller.stubs(:params).returns({ :login_with_oauth => true })
19
+ session = UserSession.new
20
+ assert !session.save
21
+ assert redirecting_to_oauth?
22
+ end
23
+ end
@@ -0,0 +1,74 @@
1
+ require "test/unit"
2
+ require "rubygems"
3
+ require "ruby-debug"
4
+ require "active_record"
5
+
6
+ ActiveRecord::Schema.verbose = false
7
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
8
+ ActiveRecord::Base.configurations = true
9
+ ActiveRecord::Schema.define(:version => 1) do
10
+ create_table :users do |t|
11
+ t.datetime :created_at
12
+ t.datetime :updated_at
13
+ t.integer :lock_version, :default => 0
14
+ t.string :login
15
+ t.string :crypted_password
16
+ t.string :password_salt
17
+ t.string :persistence_token
18
+ t.string :single_access_token
19
+ t.string :perishable_token
20
+ t.string :oauth_token
21
+ t.string :oauth_secret
22
+ t.string :email
23
+ t.integer :login_count, :default => 0, :null => false
24
+ t.integer :failed_login_count, :default => 0, :null => false
25
+ t.datetime :last_request_at
26
+ t.datetime :current_login_at
27
+ t.datetime :last_login_at
28
+ t.string :current_login_ip
29
+ t.string :last_login_ip
30
+ end
31
+ end
32
+
33
+ require "active_record/fixtures"
34
+ require "action_controller"
35
+ require "oauth"
36
+ Rails = true # to trick authlogic into loading the rails adapter
37
+ require File.dirname(__FILE__) + "/../../authlogic/lib/authlogic"
38
+ require File.dirname(__FILE__) + "/../../authlogic/lib/authlogic/test_case"
39
+ require File.dirname(__FILE__) + '/../lib/authlogic_oauth' unless defined?(AuthlogicOauth)
40
+ require File.dirname(__FILE__) + '/lib/user'
41
+ require File.dirname(__FILE__) + '/lib/user_session'
42
+
43
+ class ActionController::Base
44
+ def redirecting_to
45
+ @redirect_to
46
+ end
47
+
48
+ def redirect_to(*args)
49
+ @redirect_to = args
50
+ end
51
+ end
52
+
53
+ class ActiveSupport::TestCase
54
+ include ActiveRecord::TestFixtures
55
+ self.fixture_path = File.dirname(__FILE__) + "/fixtures"
56
+ self.use_transactional_fixtures = false
57
+ self.use_instantiated_fixtures = false
58
+ self.pre_loaded_fixtures = false
59
+ fixtures :all
60
+ setup :activate_authlogic
61
+
62
+
63
+ def activate_authlogic
64
+ Authlogic::Session::Base.controller = controller
65
+ end
66
+
67
+ def controller
68
+ @controller ||= Authlogic::ControllerAdapters::RailsAdapter.new(ActionController::Base.new)
69
+ end
70
+
71
+ def redirecting_to_oauth?
72
+ controller.redirecting_to.to_s =~ /^http:\/\/example.com/
73
+ end
74
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: heyzap-authlogic-oauth
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.8
5
+ platform: ruby
6
+ authors:
7
+ - John Allison
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-03 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.3.3
34
+ version:
35
+ description: An authlogic extension for authenticating via OAuth. This can be helpful for adding support for login/registration with Twitter credentials.
36
+ email: jrallison@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - Manifest.txt
43
+ - CHANGELOG.rdoc
44
+ - README.rdoc
45
+ files:
46
+ - CHANGELOG.rdoc
47
+ - MIT-LICENSE
48
+ - Manifest.txt
49
+ - README.rdoc
50
+ - Rakefile
51
+ - init.rb
52
+ - lib/authlogic_oauth.rb
53
+ - lib/authlogic_oauth/acts_as_authentic.rb
54
+ - lib/authlogic_oauth/helper.rb
55
+ - lib/authlogic_oauth/oauth_process.rb
56
+ - lib/authlogic_oauth/session.rb
57
+ - lib/authlogic_oauth/version.rb
58
+ - lib/oauth_callback_filter.rb
59
+ - rails/init.rb
60
+ - test/acts_as_authentic_test.rb
61
+ - test/fixtures/users.yml
62
+ - test/lib/user.rb
63
+ - test/lib/user_session.rb
64
+ - test/session_test.rb
65
+ - test/test_helper.rb
66
+ has_rdoc: true
67
+ homepage: http://github.com/jrallison/authlogic_oauth
68
+ licenses: []
69
+
70
+ post_install_message:
71
+ rdoc_options:
72
+ - --main
73
+ - README.rdoc
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: "0"
87
+ version:
88
+ requirements: []
89
+
90
+ rubyforge_project: heyzap-authlogic-oauth
91
+ rubygems_version: 1.3.5
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: An authlogic extension for authenticating via OAuth. (I.E. Twitter login)
95
+ test_files:
96
+ - test/acts_as_authentic_test.rb
97
+ - test/session_test.rb