lsdr-authlogic-connect 0.0.3.9
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/MIT-LICENSE +20 -0
- data/README.markdown +240 -0
- data/Rakefile +71 -0
- data/init.rb +1 -0
- data/lib/authlogic-connect.rb +27 -0
- data/lib/authlogic_connect/authlogic_connect.rb +46 -0
- data/lib/authlogic_connect/callback_filter.rb +19 -0
- data/lib/authlogic_connect/common.rb +10 -0
- data/lib/authlogic_connect/common/session.rb +27 -0
- data/lib/authlogic_connect/common/state.rb +16 -0
- data/lib/authlogic_connect/common/user.rb +115 -0
- data/lib/authlogic_connect/common/variables.rb +77 -0
- data/lib/authlogic_connect/engine.rb +14 -0
- data/lib/authlogic_connect/ext.rb +56 -0
- data/lib/authlogic_connect/oauth.rb +14 -0
- data/lib/authlogic_connect/oauth/helper.rb +20 -0
- data/lib/authlogic_connect/oauth/process.rb +68 -0
- data/lib/authlogic_connect/oauth/session.rb +58 -0
- data/lib/authlogic_connect/oauth/state.rb +54 -0
- data/lib/authlogic_connect/oauth/tokens/facebook_token.rb +11 -0
- data/lib/authlogic_connect/oauth/tokens/get_satisfaction_token.rb +9 -0
- data/lib/authlogic_connect/oauth/tokens/google_token.rb +41 -0
- data/lib/authlogic_connect/oauth/tokens/linked_in_token.rb +19 -0
- data/lib/authlogic_connect/oauth/tokens/myspace_token.rb +26 -0
- data/lib/authlogic_connect/oauth/tokens/oauth_token.rb +131 -0
- data/lib/authlogic_connect/oauth/tokens/opensocial_token.rb +0 -0
- data/lib/authlogic_connect/oauth/tokens/twitter_token.rb +8 -0
- data/lib/authlogic_connect/oauth/tokens/vimeo_token.rb +18 -0
- data/lib/authlogic_connect/oauth/tokens/yahoo_token.rb +19 -0
- data/lib/authlogic_connect/oauth/user.rb +68 -0
- data/lib/authlogic_connect/oauth/variables.rb +55 -0
- data/lib/authlogic_connect/openid.rb +11 -0
- data/lib/authlogic_connect/openid/process.rb +30 -0
- data/lib/authlogic_connect/openid/session.rb +78 -0
- data/lib/authlogic_connect/openid/state.rb +47 -0
- data/lib/authlogic_connect/openid/tokens/aol_token.rb +0 -0
- data/lib/authlogic_connect/openid/tokens/blogger_token.rb +0 -0
- data/lib/authlogic_connect/openid/tokens/flickr_token.rb +0 -0
- data/lib/authlogic_connect/openid/tokens/my_openid_token.rb +3 -0
- data/lib/authlogic_connect/openid/tokens/openid_token.rb +9 -0
- data/lib/authlogic_connect/openid/user.rb +62 -0
- data/lib/authlogic_connect/openid/variables.rb +19 -0
- data/lib/authlogic_connect/token.rb +53 -0
- data/lib/open_id_authentication.rb +128 -0
- data/rails/init.rb +19 -0
- data/test/controllers/test_users_controller.rb +21 -0
- data/test/libs/database.rb +48 -0
- data/test/libs/user.rb +3 -0
- data/test/libs/user_session.rb +2 -0
- data/test/old.rb +53 -0
- data/test/test_authlogic_connect.rb +13 -0
- data/test/test_helper.rb +153 -0
- data/test/test_user.rb +255 -0
- metadata +247 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
module AuthlogicConnect::Openid
|
2
|
+
end
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + "/openid/state"
|
5
|
+
require File.dirname(__FILE__) + "/openid/variables"
|
6
|
+
require File.dirname(__FILE__) + "/openid/process"
|
7
|
+
require File.dirname(__FILE__) + "/openid/user"
|
8
|
+
require File.dirname(__FILE__) + "/openid/session"
|
9
|
+
|
10
|
+
ActiveRecord::Base.send(:include, AuthlogicConnect::Openid::User)
|
11
|
+
Authlogic::Session::Base.send(:include, AuthlogicConnect::Openid::Session)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module AuthlogicConnect::Openid::Process
|
2
|
+
|
3
|
+
include AuthlogicConnect::Openid::Variables
|
4
|
+
|
5
|
+
# want to do this after the final save
|
6
|
+
def cleanup_openid_session
|
7
|
+
[:auth_attributes, :authentication_type, :auth_callback_method].each {|key| auth_session.delete(key)}
|
8
|
+
auth_session.each_key do |key|
|
9
|
+
auth_session.delete(key) if key.to_s =~ /^OpenID/
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate_by_openid
|
14
|
+
errors.add(:tokens, "had the following error: #{@openid_error}") if @openid_error
|
15
|
+
end
|
16
|
+
|
17
|
+
def save_openid_session
|
18
|
+
# Tell our rack callback filter what method the current request is using
|
19
|
+
auth_session[:auth_callback_method] = auth_controller.request.method
|
20
|
+
auth_session[:auth_attributes] = attributes_to_save
|
21
|
+
auth_session[:authentication_type] = auth_params[:authentication_type]
|
22
|
+
auth_session[:auth_method] = "openid"
|
23
|
+
end
|
24
|
+
|
25
|
+
def restore_attributes
|
26
|
+
# Restore any attributes which were saved before redirecting to the auth server
|
27
|
+
self.attributes = auth_session[:auth_attributes]
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module AuthlogicConnect::Openid
|
2
|
+
# This module is responsible for adding all of the OpenID goodness to the Authlogic::Session::Base class.
|
3
|
+
module Session
|
4
|
+
# Add a simple openid_identifier attribute and some validations for the field.
|
5
|
+
def self.included(klass)
|
6
|
+
klass.class_eval do
|
7
|
+
include InstanceMethods
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
include AuthlogicConnect::Openid::Process
|
13
|
+
|
14
|
+
def self.included(klass)
|
15
|
+
klass.class_eval do
|
16
|
+
validate :validate_openid_error
|
17
|
+
validate :validate_by_openid, :if => :authenticating_with_openid?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Hooks into credentials so that you can pass an :openid_identifier key.
|
22
|
+
def credentials=(value)
|
23
|
+
super
|
24
|
+
values = value.is_a?(Array) ? value : [value]
|
25
|
+
hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
|
26
|
+
self.openid_identifier = hash[:openid_identifier] if !hash.nil? && hash.key?(:openid_identifier)
|
27
|
+
end
|
28
|
+
|
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
|
+
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
|
+
|
41
|
+
def auto_register?
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
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])
|
48
|
+
self.attempted_record = token.user if token
|
49
|
+
if !attempted_record
|
50
|
+
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
|
59
|
+
else
|
60
|
+
errors.add(:openid_identifier, "did not match any users in our database, have you set up your account to use OpenID?")
|
61
|
+
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
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def validate_openid_error
|
74
|
+
errors.add(:openid_identifier, @openid_error) if @openid_error
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# all these methods must return true or false
|
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
|
+
|
47
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module AuthlogicConnect::Openid
|
2
|
+
module User
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
add_acts_as_authentic_module(AuthlogicConnect::Openid::Process, :prepend)
|
6
|
+
add_acts_as_authentic_module(InstanceMethods, :append)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module InstanceMethods
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.class_eval do
|
14
|
+
validate :validate_by_openid, :if => :authenticating_with_openid?
|
15
|
+
|
16
|
+
validates_length_of_password_field_options validates_length_of_password_field_options.merge(:if => :validate_password_with_openid?)
|
17
|
+
validates_confirmation_of_password_field_options validates_confirmation_of_password_field_options.merge(:if => :validate_password_with_openid?)
|
18
|
+
validates_length_of_password_confirmation_field_options validates_length_of_password_confirmation_field_options.merge(:if => :validate_password_with_openid?)
|
19
|
+
validates_length_of_login_field_options validates_length_of_login_field_options.merge(:if => :validate_password_with_openid?)
|
20
|
+
validates_format_of_login_field_options validates_format_of_login_field_options.merge(:if => :validate_password_with_openid?)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def authenticate_with_openid
|
25
|
+
@openid_error = nil
|
26
|
+
if !openid_response?
|
27
|
+
save_openid_session
|
28
|
+
else
|
29
|
+
restore_attributes
|
30
|
+
end
|
31
|
+
options = {}
|
32
|
+
options[:return_to] = auth_callback_url(:for_model => "1", :action => "create")
|
33
|
+
auth_controller.send(:authenticate_with_open_id, openid_identifier, options) do |result, openid_identifier|
|
34
|
+
create_openid_token(result, openid_identifier)
|
35
|
+
return true
|
36
|
+
end
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_openid_token(result, openid_identifier)
|
41
|
+
if result.unsuccessful?
|
42
|
+
@openid_error = result.message
|
43
|
+
elsif Token.find_by_key(openid_identifier.normalize_identifier)
|
44
|
+
else
|
45
|
+
token = OpenidToken.new(:key => openid_identifier)
|
46
|
+
self.tokens << token
|
47
|
+
self.active_token = token
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def attributes_to_save
|
52
|
+
attr_list = [:id, :password, crypted_password_field, password_salt_field, :persistence_token, :perishable_token, :single_access_token, :login_count,
|
53
|
+
:failed_login_count, :last_request_at, :current_login_at, :last_login_at, :current_login_ip, :last_login_ip, :created_at,
|
54
|
+
:updated_at, :lock_version]
|
55
|
+
attrs_to_save = attributes.clone.delete_if do |k, v|
|
56
|
+
attr_list.include?(k.to_sym)
|
57
|
+
end
|
58
|
+
attrs_to_save.merge!(:password => password, :password_confirmation => password_confirmation)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module AuthlogicConnect::Openid::Variables
|
2
|
+
include AuthlogicConnect::Openid::State
|
3
|
+
|
4
|
+
# openid_provider = "blogger", "myopenid", etc.
|
5
|
+
# openid_identifier = "viatropos.myopenid.com", etc.
|
6
|
+
# openid_key = "viatropos"
|
7
|
+
# def openid_attributes
|
8
|
+
# [:openid_provider, :openid_identifier, :openid_key]
|
9
|
+
# end
|
10
|
+
|
11
|
+
def openid_identifier
|
12
|
+
auth_params[:openid_identifier]
|
13
|
+
end
|
14
|
+
|
15
|
+
def openid_provider
|
16
|
+
from_session_or_params(:openid_provider)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class Token < ActiveRecord::Base
|
2
|
+
belongs_to :user
|
3
|
+
|
4
|
+
def client
|
5
|
+
self.class.client
|
6
|
+
end
|
7
|
+
|
8
|
+
def consumer
|
9
|
+
self.class.consumer
|
10
|
+
end
|
11
|
+
|
12
|
+
def service_name
|
13
|
+
self.class.service_name
|
14
|
+
end
|
15
|
+
|
16
|
+
def settings
|
17
|
+
self.class.settings
|
18
|
+
end
|
19
|
+
|
20
|
+
def get(path)
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def service_name
|
26
|
+
@service_name ||= self.to_s.underscore.scan(/^(.*?)(_token)?$/)[0][0].to_sym
|
27
|
+
end
|
28
|
+
|
29
|
+
def client
|
30
|
+
raise "implement client in subclass"
|
31
|
+
end
|
32
|
+
|
33
|
+
def consumer
|
34
|
+
raise "implement consumer in subclass"
|
35
|
+
end
|
36
|
+
|
37
|
+
def settings(site, hash = {})
|
38
|
+
@settings = hash.merge(:site => site)
|
39
|
+
end
|
40
|
+
|
41
|
+
def config
|
42
|
+
@settings ||= {}
|
43
|
+
@settings.dup
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def credentials
|
49
|
+
@credentials ||= AuthlogicConnect.credentials(service_name)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# copied from open_id_authentication plugin on github
|
2
|
+
require 'uri'
|
3
|
+
require 'openid'
|
4
|
+
require 'rack/openid'
|
5
|
+
|
6
|
+
module OpenIdAuthentication
|
7
|
+
def self.new(app)
|
8
|
+
store = OpenIdAuthentication.store
|
9
|
+
if store.nil?
|
10
|
+
Rails.logger.warn "OpenIdAuthentication.store is nil. Using in-memory store."
|
11
|
+
end
|
12
|
+
|
13
|
+
::Rack::OpenID.new(app, OpenIdAuthentication.store)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.store
|
17
|
+
@@store
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.store=(*store_option)
|
21
|
+
store, *parameters = *([ store_option ].flatten)
|
22
|
+
|
23
|
+
@@store = case store
|
24
|
+
when :memory
|
25
|
+
require 'openid/store/memory'
|
26
|
+
OpenID::Store::Memory.new
|
27
|
+
when :file
|
28
|
+
require 'openid/store/filesystem'
|
29
|
+
OpenID::Store::Filesystem.new(Rails.root.join('tmp/openids'))
|
30
|
+
when :memcache
|
31
|
+
require 'memcache'
|
32
|
+
require 'openid/store/memcache'
|
33
|
+
OpenID::Store::Memcache.new(MemCache.new(parameters))
|
34
|
+
else
|
35
|
+
store
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
self.store = nil
|
40
|
+
|
41
|
+
class Result
|
42
|
+
ERROR_MESSAGES = {
|
43
|
+
:missing => "Sorry, the OpenID server couldn't be found",
|
44
|
+
:invalid => "Sorry, but this does not appear to be a valid OpenID",
|
45
|
+
:canceled => "OpenID verification was canceled",
|
46
|
+
:failed => "OpenID verification failed",
|
47
|
+
:setup_needed => "OpenID verification needs setup"
|
48
|
+
}
|
49
|
+
|
50
|
+
def self.[](code)
|
51
|
+
new(code)
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialize(code)
|
55
|
+
@code = code
|
56
|
+
end
|
57
|
+
|
58
|
+
def status
|
59
|
+
@code
|
60
|
+
end
|
61
|
+
|
62
|
+
ERROR_MESSAGES.keys.each { |state| define_method("#{state}?") { @code == state } }
|
63
|
+
|
64
|
+
def successful?
|
65
|
+
@code == :successful
|
66
|
+
end
|
67
|
+
|
68
|
+
def unsuccessful?
|
69
|
+
ERROR_MESSAGES.keys.include?(@code)
|
70
|
+
end
|
71
|
+
|
72
|
+
def message
|
73
|
+
ERROR_MESSAGES[@code]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
protected
|
78
|
+
# The parameter name of "openid_identifier" is used rather than
|
79
|
+
# the Rails convention "open_id_identifier" because that's what
|
80
|
+
# the specification dictates in order to get browser auto-complete
|
81
|
+
# working across sites
|
82
|
+
def using_open_id?(identifier = nil) #:doc:
|
83
|
+
identifier ||= open_id_identifier
|
84
|
+
!identifier.blank? || request.env[Rack::OpenID::RESPONSE]
|
85
|
+
end
|
86
|
+
|
87
|
+
def authenticate_with_open_id(identifier = nil, options = {}, &block) #:doc:
|
88
|
+
identifier ||= open_id_identifier
|
89
|
+
if request.env[Rack::OpenID::RESPONSE]
|
90
|
+
complete_open_id_authentication(&block)
|
91
|
+
else
|
92
|
+
begin_open_id_authentication(identifier, options, &block)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
def open_id_identifier
|
98
|
+
params[:openid_identifier] || params[:openid_url]
|
99
|
+
end
|
100
|
+
|
101
|
+
def begin_open_id_authentication(identifier, options = {})
|
102
|
+
options[:identifier] = identifier
|
103
|
+
value = Rack::OpenID.build_header(options)
|
104
|
+
response.headers[Rack::OpenID::AUTHENTICATE_HEADER] = value
|
105
|
+
head :unauthorized
|
106
|
+
end
|
107
|
+
|
108
|
+
def complete_open_id_authentication
|
109
|
+
response = request.env[Rack::OpenID::RESPONSE]
|
110
|
+
identifier = response.display_identifier
|
111
|
+
|
112
|
+
case response.status
|
113
|
+
when OpenID::Consumer::SUCCESS
|
114
|
+
yield Result[:successful], identifier,
|
115
|
+
OpenID::SReg::Response.from_success_response(response)
|
116
|
+
when :missing
|
117
|
+
yield Result[:missing], identifier, nil
|
118
|
+
when :invalid
|
119
|
+
yield Result[:invalid], identifier, nil
|
120
|
+
when OpenID::Consumer::CANCEL
|
121
|
+
yield Result[:canceled], identifier, nil
|
122
|
+
when OpenID::Consumer::FAILURE
|
123
|
+
yield Result[:failed], identifier, nil
|
124
|
+
when OpenID::Consumer::SETUP_NEEDED
|
125
|
+
yield Result[:setup_needed], response.setup_url, nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|