authlogic-connect 0.0.3.9 → 0.0.4.03

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.
Files changed (35) hide show
  1. data/README.markdown +9 -5
  2. data/Rakefile +7 -3
  3. data/lib/authlogic-connect.rb +2 -2
  4. data/lib/authlogic_connect/{token.rb → access_token.rb} +1 -1
  5. data/lib/authlogic_connect/authlogic_connect.rb +0 -0
  6. data/lib/authlogic_connect/common/session.rb +13 -10
  7. data/lib/authlogic_connect/common/state.rb +21 -5
  8. data/lib/authlogic_connect/common/user.rb +27 -65
  9. data/lib/authlogic_connect/common/variables.rb +75 -11
  10. data/lib/authlogic_connect/oauth/helper.rb +0 -0
  11. data/lib/authlogic_connect/oauth/process.rb +19 -12
  12. data/lib/authlogic_connect/oauth/session.rb +15 -11
  13. data/lib/authlogic_connect/oauth/state.rb +19 -13
  14. data/lib/authlogic_connect/oauth/tokens/aol_token.rb +2 -0
  15. data/lib/authlogic_connect/oauth/tokens/google_token.rb +11 -11
  16. data/lib/authlogic_connect/oauth/tokens/meetup_token.rb +12 -0
  17. data/lib/authlogic_connect/oauth/tokens/netflix_token.rb +10 -0
  18. data/lib/authlogic_connect/oauth/tokens/oauth_token.rb +6 -2
  19. data/lib/authlogic_connect/oauth/tokens/ohloh_token.rb +9 -0
  20. data/lib/authlogic_connect/oauth/user.rb +9 -14
  21. data/lib/authlogic_connect/oauth/variables.rb +9 -0
  22. data/lib/authlogic_connect/openid/process.rb +49 -5
  23. data/lib/authlogic_connect/openid/session.rb +13 -34
  24. data/lib/authlogic_connect/openid/state.rb +45 -44
  25. data/lib/authlogic_connect/openid/tokens/openid_token.rb +1 -1
  26. data/lib/authlogic_connect/openid/user.rb +5 -29
  27. data/lib/authlogic_connect/openid/variables.rb +2 -2
  28. data/lib/open_id_authentication.rb +0 -1
  29. data/test/controllers/test_users_controller.rb +0 -0
  30. data/test/libs/database.rb +0 -0
  31. data/test/libs/user.rb +6 -2
  32. data/test/libs/user_session.rb +0 -0
  33. data/test/test_helper.rb +1 -1
  34. data/test/test_user.rb +5 -66
  35. metadata +10 -6
@@ -7,7 +7,7 @@ module AuthlogicConnect::Oauth
7
7
  include InstanceMethods
8
8
  end
9
9
  end
10
-
10
+
11
11
  module InstanceMethods
12
12
  include Process
13
13
 
@@ -30,12 +30,6 @@ module AuthlogicConnect::Oauth
30
30
  end
31
31
 
32
32
  private
33
- # Clears out the block if we are authenticating with oauth,
34
- # so that we can redirect without a DoubleRender error.
35
- def save_with_oauth(&block)
36
- block = nil if redirecting_to_oauth_server?
37
- return block.nil?
38
- end
39
33
 
40
34
  def complete_oauth_transaction
41
35
  if @record
@@ -46,13 +40,23 @@ module AuthlogicConnect::Oauth
46
40
  # attempted_record is part of AuthLogic
47
41
  hash = oauth_token_and_secret
48
42
  token = token_class.find_by_key_or_token(hash[:key], hash[:token], :include => [:user]) # some weird error if I leave out the include)
49
- self.attempted_record = token.user
43
+ if token
44
+ self.attempted_record = token.user
45
+ elsif auto_register?
46
+ self.attempted_record = klass.new
47
+ self.attempted_record.access_tokens << token_class.new(hash)
48
+ self.attempted_record.save
49
+ else
50
+ auth_session[:_key] = hash[:key]
51
+ auth_session[:_token] = hash[:token]
52
+ auth_session[:_secret] = hash[:secret]
53
+ end
50
54
  end
51
-
55
+
52
56
  if !attempted_record
53
- errors.add_to_base("Could not find user in our database, have you registered with your oauth account?")
57
+ errors.add(:user, "Could not find user in our database, have you registered with your oauth account?")
54
58
  end
55
59
  end
56
60
  end
57
61
  end
58
- end
62
+ end
@@ -5,7 +5,7 @@ module AuthlogicConnect::Oauth::State
5
5
  # checks that we just passed parameters to it,
6
6
  # and that the parameters say 'authentication_method' == 'oauth'
7
7
  def oauth_request?
8
- !auth_params.nil? && oauth_provider?
8
+ auth_params? && oauth_provider?
9
9
  end
10
10
 
11
11
  # 2. from call
@@ -13,19 +13,23 @@ module AuthlogicConnect::Oauth::State
13
13
  def oauth_response?
14
14
  !oauth_response.nil? && !auth_session.nil? && auth_session[:auth_request_class] == self.class.name && auth_session[:auth_method] == "oauth"
15
15
  end
16
- alias_method :oauth_complete?, :oauth_response?
16
+
17
+ def oauth_complete?
18
+ oauth_response? || stored_oauth_token_and_secret?
19
+ end
17
20
 
18
21
  # 3. either to or from call
19
22
  def using_oauth?
20
- oauth_request? || oauth_response?
23
+ oauth_request? || oauth_response? || stored_oauth_token_and_secret?
21
24
  end
22
25
 
23
26
  def new_oauth_request?
24
- oauth_response.blank?
27
+ return false if stored_oauth_token_and_secret?
28
+ return oauth_response.blank?
25
29
  end
26
30
 
27
31
  def oauth_provider?
28
- !oauth_provider.nil? && !oauth_provider.empty?
32
+ !oauth_provider.blank?
29
33
  end
30
34
 
31
35
  # main method we call on validation
@@ -37,18 +41,20 @@ module AuthlogicConnect::Oauth::State
37
41
  authenticating_with_oauth? && !oauth_complete?
38
42
  end
39
43
 
40
- # both checks if it can redirect, and does the redirect.
41
- # is there a more concise way to do this?
42
- def redirecting_to_oauth_server?
43
- if allow_oauth_redirect?
44
- redirect_to_oauth
45
- return true
46
- end
47
- return false
44
+ def start_oauth?
45
+ authenticating_with_oauth? && !oauth_complete?
46
+ end
47
+
48
+ def complete_oauth?
49
+ using_oauth? && !new_oauth_request?
48
50
  end
49
51
 
50
52
  def validate_password_with_oauth?
51
53
  !using_oauth? && require_password?
52
54
  end
53
55
 
56
+ def stored_oauth_token_and_secret?
57
+ !is_auth_session? && auth_params && auth_params.has_key?(:_key) && auth_params.has_key?(:_token) && auth_params.has_key?(:_secret)
58
+ end
59
+
54
60
  end
@@ -0,0 +1,2 @@
1
+ # http://dev.aol.com/openauth_gettingstarted
2
+ # https://my.screenname.aol.com/_cqr/login/login.psp?sitedomain=dev.aol.com&authLev=1&lang=en&locale=us&siteState=OrigUrl%3Dhttp%253A%252F%252Fdev.aol.com%252Fkeys
@@ -27,15 +27,15 @@
27
27
  # YouTube http://gdata.youtube.com
28
28
  class GoogleToken < OauthToken
29
29
 
30
- settings "https://www.google.com",
31
- :request_token_path => "/accounts/OAuthGetRequestToken",
32
- :authorize_path => "/accounts/OAuthAuthorizeToken",
33
- :access_token_path => "/accounts/OAuthGetAccessToken",
34
- :scope => "https://www.google.com/m8/feeds/"
35
-
36
- key do |access_token|
37
- body = JSON.parse(access_token.get("https://www.google.com/m8/feeds/contacts/default/full?alt=json&max-results=0").body)
38
- email = body["feed"]["author"].first["email"]["$t"] # $t is some weird google json thing
39
- end
40
-
30
+ settings "https://www.google.com",
31
+ :request_token_path => "/accounts/OAuthGetRequestToken",
32
+ :authorize_path => "/accounts/OAuthAuthorizeToken",
33
+ :access_token_path => "/accounts/OAuthGetAccessToken",
34
+ :scope => "https://www.googleapis.com/auth/userinfo#email"
35
+
36
+ key do |access_token|
37
+ body = JSON.parse(access_token.get("https://www.googleapis.com/userinfo/email?alt=json").body)
38
+ email = body["data"]["email"]
39
+ end
40
+
41
41
  end
@@ -0,0 +1,12 @@
1
+ # http://www.meetup.com/meetup_api/docs/#oauth
2
+ # protected resources: http://api.meetup.com
3
+ class MeetupToken < OauthToken
4
+
5
+ key :user_id
6
+
7
+ settings "http://www.meetup.com/"
8
+ :request_token_path => "/oauth/request",
9
+ :authorize_path => "/authorize",
10
+ :access_token_path => "/oauth/access"
11
+
12
+ end
@@ -0,0 +1,10 @@
1
+ class NetflixToken < OauthToken
2
+
3
+ key :user_id
4
+
5
+ settings "http://api.netflix.com",
6
+ :request_token_path => "/oauth/request_token",
7
+ :access_token_path => "/oauth/access_token",
8
+ :authorize_path => "/oauth/login"
9
+
10
+ end
@@ -1,4 +1,4 @@
1
- class OauthToken < Token
1
+ class OauthToken < AccessToken
2
2
 
3
3
  def client
4
4
  unless @client
@@ -63,7 +63,9 @@ class OauthToken < Token
63
63
  def find_by_key_or_token(key, token, options = {})
64
64
  result = self.find_by_key(key, options) unless key.nil?
65
65
  unless result
66
- result = self.find_by_token(token, options) unless token.nil?
66
+ if !token.blank? && self.respond_to?(:find_by_token)
67
+ result = self.find_by_token(token, options)
68
+ end
67
69
  end
68
70
  result
69
71
  end
@@ -78,6 +80,7 @@ class OauthToken < Token
78
80
  redirect_uri = options[:redirect_uri]
79
81
  token = options[:token]
80
82
  secret = options[:secret]
83
+
81
84
  if oauth_version == 1.0
82
85
  access = request_token(token, secret).get_access_token(:oauth_verifier => oauth_verifier)
83
86
  result = {:token => access.token, :secret => access.secret, :key => nil}
@@ -95,6 +98,7 @@ class OauthToken < Token
95
98
  access = consumer.web_server.get_access_token(secret, :redirect_uri => redirect_uri)
96
99
  result = {:token => access.token, :secret => secret, :key => nil}
97
100
  end
101
+
98
102
  result
99
103
  end
100
104
 
@@ -0,0 +1,9 @@
1
+ # https://www.ohloh.net/
2
+ # http://www.ohloh.net/api/oauth
3
+ class OhlohToken < OauthToken
4
+
5
+ key :user_id
6
+
7
+ settings "http://www.ohloh.net"
8
+
9
+ end
@@ -24,12 +24,10 @@ module AuthlogicConnect::Oauth::User
24
24
  validates_length_of_password_confirmation_field_options validates_length_of_password_confirmation_field_options.merge(:if => :validate_password_with_oauth?)
25
25
  validates_length_of_login_field_options validates_length_of_login_field_options.merge(:if => :validate_password_with_oauth?)
26
26
  validates_format_of_login_field_options validates_format_of_login_field_options.merge(:if => :validate_password_with_oauth?)
27
+
27
28
  end
28
-
29
- # email needs to be optional for oauth
30
- base.validate_email_field = false
31
29
  end
32
-
30
+
33
31
  # user adds a few extra things to this method from Process
34
32
  # modules work like inheritance
35
33
  def save_oauth_session
@@ -37,6 +35,10 @@ module AuthlogicConnect::Oauth::User
37
35
  auth_session[:auth_attributes] = attributes.reject!{|k, v| v.blank?} unless is_auth_session?
38
36
  end
39
37
 
38
+ def redirect_to_oauth
39
+ return has_token?(oauth_provider) ? false : super
40
+ end
41
+
40
42
  def restore_attributes
41
43
  # Restore any attributes which were saved before redirecting to the auth server
42
44
  self.attributes = auth_session[:auth_attributes]
@@ -47,20 +49,13 @@ module AuthlogicConnect::Oauth::User
47
49
  # to the database.
48
50
  # it is called by the validation chain.
49
51
  def complete_oauth_transaction
50
- unless create_oauth_token
51
- self.errors.add(:tokens, "you have already created an account using your #{token_class.service_name} account, so it")
52
- end
53
- end
54
-
55
- def create_oauth_token
56
52
  token = token_class.new(oauth_token_and_secret)
57
53
 
58
- if has_token?(oauth_provider) || Token.find_by_key(token.key) || Token.find_by_token(token.token)
59
- return false
54
+ if has_token?(oauth_provider) || token_class.find_by_key_or_token(token.key, token.token)
55
+ self.errors.add(:tokens, "you have already created an account using your #{token_class.service_name} account, so it")
60
56
  else
61
- self.tokens << token
57
+ self.access_tokens << token
62
58
  self.active_token = token
63
- return true
64
59
  end
65
60
  end
66
61
 
@@ -41,9 +41,18 @@ module AuthlogicConnect::Oauth::Variables
41
41
  token_class.consumer
42
42
  end
43
43
 
44
+ def stored_oauth_token_and_secret
45
+ if auth_controller?
46
+ {:key => auth_params[:_key], :token => auth_params[:_token], :secret => auth_params[:_secret]}
47
+ else
48
+ {:key => nil, :token => nil, :secret => nil}
49
+ end
50
+ end
51
+
44
52
  # this is a thick method.
45
53
  # it gives you the final key and secret that we will store in the database
46
54
  def oauth_token_and_secret
55
+ return stored_oauth_token_and_secret if stored_oauth_token_and_secret?
47
56
  token_class.get_token_and_secret(
48
57
  :token => auth_session[:oauth_request_token],
49
58
  :secret => oauth_version == 1.0 ? auth_session[:oauth_request_token_secret] : oauth_token,
@@ -2,16 +2,56 @@ module AuthlogicConnect::Openid::Process
2
2
 
3
3
  include AuthlogicConnect::Openid::Variables
4
4
 
5
+ def start_openid
6
+ save_openid_session
7
+ call_openid
8
+ end
9
+
10
+ def complete_openid
11
+ restore_attributes
12
+ call_openid
13
+ end
14
+
15
+ def call_openid
16
+ options = {}
17
+ options[:return_to] = auth_callback_url
18
+ # this is called both on start and complete.
19
+ # reason being, in the open_id_authentication library (where "authenticate_with_open_id" is defined),
20
+ # it checks the rack session to find openid pareters, and knows whether we're at
21
+ # start or complete
22
+ auth_controller.send(:authenticate_with_open_id, openid_identifier, options) do |result, openid_identifier|
23
+ complete_openid_transaction(result, openid_identifier)
24
+ return true
25
+ end
26
+ return false
27
+ end
28
+
29
+ def complete_openid_transaction(result, openid_identifier)
30
+ if result.unsuccessful?
31
+ errors.add_to_base(result.message)
32
+ end
33
+
34
+ if AccessToken.find_by_key(openid_identifier.normalize_identifier)
35
+ else
36
+ token = OpenidToken.new(:key => openid_identifier)
37
+ self.access_tokens << token
38
+ self.active_token = token
39
+ end
40
+ end
41
+
5
42
  # want to do this after the final save
6
43
  def cleanup_openid_session
7
- [:auth_attributes, :authentication_type, :auth_callback_method].each {|key| auth_session.delete(key)}
44
+ [:auth_attributes, :authentication_type, :auth_callback_method].each {|key| remove_session_key(key)}
8
45
  auth_session.each_key do |key|
9
- auth_session.delete(key) if key.to_s =~ /^OpenID/
46
+ remove_session_key(key) if key.to_s =~ /^OpenID/
10
47
  end
11
48
  end
12
49
 
13
50
  def validate_by_openid
14
- errors.add(:tokens, "had the following error: #{@openid_error}") if @openid_error
51
+ if processing_authentication
52
+ authentication_protocol(:openid, :start) || authentication_protocol(:openid, :complete)
53
+ errors.add(:access_tokens, "had the following error: #{@openid_error}") if @openid_error
54
+ end
15
55
  end
16
56
 
17
57
  def save_openid_session
@@ -22,9 +62,13 @@ module AuthlogicConnect::Openid::Process
22
62
  auth_session[:auth_method] = "openid"
23
63
  end
24
64
 
65
+ def attributes_to_save
66
+ {}
67
+ end
68
+
25
69
  def restore_attributes
26
70
  # Restore any attributes which were saved before redirecting to the auth server
27
- self.attributes = auth_session[:auth_attributes]
71
+ self.attributes = auth_session[:auth_attributes] unless is_auth_session?
28
72
  end
29
73
 
30
- end
74
+ end
@@ -13,7 +13,6 @@ module AuthlogicConnect::Openid
13
13
 
14
14
  def self.included(klass)
15
15
  klass.class_eval do
16
- validate :validate_openid_error
17
16
  validate :validate_by_openid, :if => :authenticating_with_openid?
18
17
  end
19
18
  end
@@ -26,53 +25,33 @@ module AuthlogicConnect::Openid
26
25
  self.openid_identifier = hash[:openid_identifier] if !hash.nil? && hash.key?(:openid_identifier)
27
26
  end
28
27
 
29
- # Cleaers out the block if we are authenticating with OpenID, so that we can redirect without a DoubleRender
30
- # error.
31
- def save_with_openid(&block)
32
- block = nil if Token.find_by_key(openid_identifier.normalize_identifier)
33
- return block.nil?
34
- end
35
-
36
28
  private
37
- def authenticating_with_openid?
38
- attempted_record.nil? && errors.empty? && (!openid_identifier.blank? || (controller.params[:open_id_complete] && controller.params[:for_session]))
39
- end
40
29
 
41
30
  def auto_register?
42
31
  false
43
32
  end
44
33
 
45
- def validate_by_openid
46
- self.remember_me = auth_params[:remember_me] == "true" if auth_params.key?(:remember_me)
47
- token = Token.find_by_key(openid_identifier.normalize_identifier, :include => [:user])
34
+ def complete_openid_transaction(result, openid_identifier)
35
+ if result.unsuccessful?
36
+ errors.add_to_base(result.message)
37
+ end
38
+
39
+ token = AccessToken.find_by_key(openid_identifier.normalize_identifier, :include => [:user])
40
+
48
41
  self.attempted_record = token.user if token
42
+
49
43
  if !attempted_record
50
44
  if auto_register?
51
- self.attempted_record = klass.new :openid_identifier => openid_identifier
52
- attempted_record.save do |result|
53
- if result
54
- true
55
- else
56
- false
57
- end
58
- end
45
+ self.attempted_record = klass.new
46
+ self.attempted_record.access_tokens << OpenidToken.new(:key => openid_identifier.normalize_identifier)
47
+ self.attempted_record.save
59
48
  else
60
- errors.add(:openid_identifier, "did not match any users in our database, have you set up your account to use OpenID?")
49
+ auth_session[:openid_identifier] = openid_identifier
50
+ errors.add(:user, "Could not find user in our database, have you registered with your openid account?")
61
51
  end
62
- return
63
- end
64
- controller.send(:authenticate_with_open_id, openid_identifier, :return_to => controller.url_for(:for_session => "1", :remember_me => remember_me?)) do |result, openid_identifier|
65
- if result.unsuccessful?
66
- errors.add_to_base(result.message)
67
- return
68
- end
69
-
70
52
  end
71
53
  end
72
54
 
73
- def validate_openid_error
74
- errors.add(:openid_identifier, @openid_error) if @openid_error
75
- end
76
55
  end
77
56
  end
78
57
  end
@@ -1,47 +1,48 @@
1
1
  # all these methods must return true or false
2
2
  module AuthlogicConnect::Openid::State
3
- # 1. to call
4
- def openid_request?
5
- !openid_identifier.blank?
6
- end
7
-
8
- def openid_identifier?
9
- openid_request?
10
- end
11
-
12
- def openid_provider?
13
-
14
- end
15
-
16
- # 2. from call
17
- # better check needed
18
- def openid_response?
19
- !auth_session[:auth_attributes].nil? && auth_session[:auth_method] == "openid"
20
- end
21
- alias_method :openid_complete?, :openid_response?
22
-
23
- # 3. either to or from call
24
- # this should include more!
25
- # we know we are using open id if:
26
- # the params passed in have "openid_identifier"
27
- def using_openid?
28
- openid_request? || openid_response?
29
- end
30
-
31
- def authenticating_with_openid?
32
- session_class.activated? && using_openid?
33
- end
34
-
35
- def allow_openid_redirect?
36
- authenticating_with_openid?
37
- end
38
-
39
- def redirecting_to_openid_server?
40
- allow_openid_redirect? && !authenticate_with_openid
41
- end
42
-
43
- def validate_password_with_openid?
44
- !using_openid? && require_password?
45
- end
46
-
3
+
4
+ # 1. to call
5
+ def openid_request?
6
+ !openid_identifier.blank? && auth_session[:auth_attributes].nil?
7
+ end
8
+
9
+ def openid_identifier?
10
+ openid_request?
11
+ end
12
+
13
+ def openid_provider?
14
+
15
+ end
16
+
17
+ # 2. from call
18
+ # better check needed
19
+ def openid_response?
20
+ auth_controller? && !auth_session[:auth_attributes].nil? && auth_session[:auth_method] == "openid"
21
+ end
22
+ alias_method :openid_complete?, :openid_response?
23
+
24
+ # 3. either to or from call
25
+ # this should include more!
26
+ # we know we are using open id if:
27
+ # the params passed in have "openid_identifier"
28
+ def using_openid?
29
+ auth_controller? && (openid_request? || openid_response?)
30
+ end
31
+
32
+ def authenticating_with_openid?
33
+ auth_controller? && auth_class.activated? && using_openid?
34
+ end
35
+
36
+ def start_openid?
37
+ authenticating_with_openid? && !openid_response?
38
+ end
39
+
40
+ def complete_openid?
41
+ openid_complete?
42
+ end
43
+
44
+ def validate_password_with_openid?
45
+ !using_openid? && require_password?
46
+ end
47
+
47
48
  end