logankoester-authlogic-oauth 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -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.
data/MIT-LICENSE ADDED
@@ -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.
data/Manifest.txt ADDED
@@ -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
data/README.rdoc ADDED
@@ -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/authorize?force_login=true" })
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
+
data/Rakefile ADDED
@@ -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("logankoester-authlogic-oauth", AuthlogicOauth::Version::STRING) do |p|
8
+ p.name = "logankoester-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,136 @@
1
+ require 'authlogic'
2
+
3
+ module AuthlogicOauth
4
+ module ActsAsAuthentic
5
+ def self.included(klass)
6
+ klass.class_eval do
7
+ extend Config
8
+ add_acts_as_authentic_module(Methods, :prepend)
9
+ end
10
+ end
11
+
12
+ module Config
13
+ # The name of the oauth token field in the database.
14
+ #
15
+ # * <tt>Default:</tt> :oauth_token
16
+ # * <tt>Accepts:</tt> Symbol
17
+ def oauth_token_field(value = nil)
18
+ rw_config(:oauth_token_field, value, :oauth_token)
19
+ end
20
+ alias_method :oauth_token_field=, :oauth_token_field
21
+
22
+ # The name of the oauth token secret field in the database.
23
+ #
24
+ # * <tt>Default:</tt> :oauth_secret
25
+ # * <tt>Accepts:</tt> Symbol
26
+ def oauth_secret_field(value = nil)
27
+ rw_config(:oauth_secret_field, value, :oauth_secret)
28
+ end
29
+ alias_method :oauth_secret_field=, :oauth_secret_field
30
+ end
31
+
32
+ module Methods
33
+ include OauthProcess
34
+
35
+ # Set up some simple validations
36
+ def self.included(klass)
37
+ klass.class_eval do
38
+ alias_method "#{oauth_token_field.to_s}=".to_sym, :oauth_token=
39
+ alias_method "#{oauth_secret_field.to_s}=".to_sym, :oauth_secret=
40
+ end
41
+
42
+ return if !klass.column_names.include?(klass.oauth_token_field.to_s)
43
+
44
+ klass.class_eval do
45
+ validate :validate_by_oauth, :if => :authenticating_with_oauth?
46
+
47
+ validates_uniqueness_of klass.oauth_token_field, :scope => validations_scope, :if => :using_oauth?
48
+ validates_presence_of klass.oauth_secret_field, :scope => validations_scope, :if => :using_oauth?
49
+
50
+ validates_length_of_password_field_options validates_length_of_password_field_options.merge(:if => :validate_password_with_oauth?)
51
+ validates_confirmation_of_password_field_options validates_confirmation_of_password_field_options.merge(:if => :validate_password_with_oauth?)
52
+ validates_length_of_password_confirmation_field_options validates_length_of_password_confirmation_field_options.merge(:if => :validate_password_with_oauth?)
53
+ validates_length_of_login_field_options validates_length_of_login_field_options.merge(:if => :validate_password_with_oauth?)
54
+ validates_format_of_login_field_options validates_format_of_login_field_options.merge(:if => :validate_password_with_oauth?)
55
+ end
56
+
57
+ # email needs to be optional for oauth
58
+ klass.validate_email_field = false
59
+ end
60
+
61
+ def save(perform_validation = true, &block)
62
+ if perform_validation && block_given? && redirecting_to_oauth_server?
63
+ # Save attributes so they aren't lost during the authentication with the oauth server
64
+ session_class.controller.session[:authlogic_oauth_attributes] = attributes.reject!{|k, v| v.blank?}
65
+ redirect_to_oauth
66
+ return false
67
+ end
68
+
69
+ result = super
70
+ yield(result) if block_given?
71
+ result
72
+ end
73
+
74
+ # accessors for oauth fields
75
+ def oauth_token
76
+ read_attribute(oauth_token_field)
77
+ end
78
+
79
+ def oauth_token=(value)
80
+ write_attribute(oauth_token_field, value.blank? ? nil : value)
81
+ end
82
+
83
+ def oauth_secret
84
+ read_attribute(oauth_secret_field)
85
+ end
86
+
87
+ def oauth_secret=(value)
88
+ write_attribute(oauth_secret_field, value.blank? ? nil : value)
89
+ end
90
+
91
+ private
92
+
93
+ def authenticating_with_oauth?
94
+ # Controller isn't available in all contexts (e.g. irb)
95
+ return false unless session_class.controller
96
+
97
+ # Initial request when user presses one of the button helpers
98
+ (session_class.controller.params && !session_class.controller.params[:register_with_oauth].blank?) ||
99
+ # When the oauth provider responds and we made the initial request
100
+ (oauth_response && session_class.controller.session && session_class.controller.session[:oauth_request_class] == self.class.name)
101
+ end
102
+
103
+ def authenticate_with_oauth
104
+ # Restore any attributes which were saved before redirecting to the oauth server
105
+ self.attributes = session_class.controller.session.delete(:authlogic_oauth_attributes)
106
+ access_token = generate_access_token
107
+
108
+ self.oauth_token = access_token.token
109
+ self.oauth_secret = access_token.secret
110
+ end
111
+
112
+ def access_token
113
+ OAuth::AccessToken.new(oauth,
114
+ read_attribute(oauth_token_field),
115
+ read_attribute(oauth_secret_field))
116
+ end
117
+
118
+ def using_oauth?
119
+ respond_to?(oauth_token_field) && !oauth_token.blank?
120
+ end
121
+
122
+ def validate_password_with_oauth?
123
+ !using_oauth? && require_password?
124
+ end
125
+
126
+ def oauth_token_field
127
+ self.class.oauth_token_field
128
+ end
129
+
130
+ def oauth_secret_field
131
+ self.class.oauth_secret_field
132
+ end
133
+
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,28 @@
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
+ def oauth_register_image_button(image, options = {})
12
+ oauth_image_button('register_with_oauth', image, options)
13
+ end
14
+
15
+ def oauth_login_image_button(image, options = {})
16
+ oauth_image_button('login_with_oauth', image, options)
17
+ end
18
+
19
+ private
20
+ def oauth_button(name, options = {})
21
+ "<input type='submit' value='#{options[:value]}' name='#{name}' id='user_submit' class='#{options[:class]}'/>"
22
+ end
23
+
24
+ def oauth_image_button(name, image, options = {})
25
+ "<input type='image', src='#{image}' value='#{options[:value]}' name='#{name}' id='user_submit' class='#{options[:class]}'/>"
26
+ end
27
+ end
28
+ 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 && 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,77 @@
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
+ return false if authenticating_with_unauthorized_record?
53
+ # Initial request when user presses one of the button helpers
54
+ (controller.params && !controller.params[:login_with_oauth].blank?) ||
55
+ # When the oauth provider responds and we made the initial request
56
+ (oauth_response && controller.session && controller.session[:oauth_request_class] == self.class.name)
57
+ end
58
+
59
+ def authenticate_with_oauth
60
+ if @record
61
+ self.attempted_record = record
62
+ else
63
+ self.attempted_record = search_for_record(find_by_oauth_method, generate_access_token.token)
64
+ #errors.add_to_base("Unable to authenticate with Twitter.")
65
+ end
66
+
67
+ if !attempted_record
68
+ errors.add_to_base("Could not find user in our database, have you registered with your oauth account?")
69
+ end
70
+ end
71
+
72
+ def find_by_oauth_method
73
+ self.class.find_by_oauth_method
74
+ end
75
+ end
76
+ end
77
+ 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 = 9
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
data/rails/init.rb ADDED
@@ -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
data/test/lib/user.rb ADDED
@@ -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,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logankoester-authlogic-oauth
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 9
9
+ version: 1.0.9
10
+ platform: ruby
11
+ authors:
12
+ - John Allison
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-06 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: hoe
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 2
41
+ - 3
42
+ - 3
43
+ version: 2.3.3
44
+ type: :development
45
+ version_requirements: *id002
46
+ description: An authlogic extension for authenticating via OAuth. This can be helpful for adding support for login/registration with Twitter credentials.
47
+ email: jrallison@gmail.com
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - Manifest.txt
54
+ - CHANGELOG.rdoc
55
+ - README.rdoc
56
+ files:
57
+ - CHANGELOG.rdoc
58
+ - MIT-LICENSE
59
+ - Manifest.txt
60
+ - README.rdoc
61
+ - Rakefile
62
+ - init.rb
63
+ - lib/authlogic_oauth.rb
64
+ - lib/authlogic_oauth/acts_as_authentic.rb
65
+ - lib/authlogic_oauth/helper.rb
66
+ - lib/authlogic_oauth/oauth_process.rb
67
+ - lib/authlogic_oauth/session.rb
68
+ - lib/authlogic_oauth/version.rb
69
+ - lib/oauth_callback_filter.rb
70
+ - rails/init.rb
71
+ - test/acts_as_authentic_test.rb
72
+ - test/fixtures/users.yml
73
+ - test/lib/user.rb
74
+ - test/lib/user_session.rb
75
+ - test/session_test.rb
76
+ - test/test_helper.rb
77
+ has_rdoc: true
78
+ homepage: http://github.com/jrallison/authlogic_oauth
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options:
83
+ - --main
84
+ - README.rdoc
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ segments:
99
+ - 0
100
+ version: "0"
101
+ requirements: []
102
+
103
+ rubyforge_project: logankoester-authlogic-oauth
104
+ rubygems_version: 1.3.6
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: An authlogic extension for authenticating via OAuth. (I.E. Twitter login)
108
+ test_files:
109
+ - test/session_test.rb
110
+ - test/acts_as_authentic_test.rb