forked from mreinsch/authlogic_openid
/
session.rb
133 lines (114 loc) · 4.8 KB
/
session.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
module AuthlogicOpenid
# This module is responsible for adding all of the OpenID goodness to the Authlogic::Session::Base class.
module Session
# Add a simple openid_identifier attribute and some validations for the field.
def self.included(klass)
klass.class_eval do
extend Config
include Methods
end
end
module Config
# What method should we call to find a record by the openid_identifier?
# This is useful if you want to store multiple openid_identifiers for a single record.
# You could do something like:
#
# class User < ActiveRecord::Base
# def self.find_by_openid_identifier(identifier)
# user.first(:conditions => {:openid_identifiers => {:identifier => identifier}})
# end
# end
#
# Obviously the above depends on what you are calling your assocition, etc. But you get the point.
#
# * <tt>Default:</tt> :find_by_openid_identifier
# * <tt>Accepts:</tt> Symbol
def find_by_openid_identifier_method(value = nil)
rw_config(:find_by_openid_identifier_method, value, :find_by_openid_identifier)
end
alias_method :find_by_openid_identifier_method=, :find_by_openid_identifier_method
# Add this in your Session object to Auto Register a new user using openid via sreg
def auto_register(value=true)
auto_register_value(value)
end
def auto_register_value(value=nil)
rw_config(:auto_register,value,false)
end
alias_method :auto_register=,:auto_register
end
module Methods
def self.included(klass)
klass.class_eval do
attr_reader :openid_identifier
validate :validate_openid_error
validate :validate_by_openid, :if => :authenticating_with_openid?
end
end
# Hooks into credentials so that you can pass an :openid_identifier key.
def credentials=(value)
super
values = value.is_a?(Array) ? value : [value]
hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
self.openid_identifier = hash[:openid_identifier] if !hash.nil? && hash.key?(:openid_identifier)
end
def openid_identifier=(value)
@openid_identifier = value.blank? ? nil : OpenID.normalize_url(value)
@openid_error = nil
rescue OpenID::DiscoveryFailure => e
@openid_identifier = nil
@openid_error = e.message
end
# Cleaers out the block if we are authenticating with OpenID, so that we can redirect without a DoubleRender
# error.
def save(&block)
block = nil if !openid_identifier.blank?
super(&block)
end
private
def authenticating_with_openid?
attempted_record.nil? && errors.empty? && (!openid_identifier.blank? || (controller.params[:open_id_complete] && controller.params[:for_session]))
end
def find_by_openid_identifier_method
self.class.find_by_openid_identifier_method
end
def find_by_openid_identifier_method
self.class.find_by_openid_identifier_method
end
def auto_register?
self.class.auto_register_value
end
def validate_by_openid
self.remember_me = controller.params[:remember_me] == "true" if controller.params.key?(:remember_me)
options = {
:required => klass.openid_required_fields,
:optional => klass.openid_optional_fields,
:return_to => controller.url_for(:for_session => "1", :remember_me => remember_me?),
:method => :post}
controller.send(:authenticate_with_open_id, openid_identifier, options) do |result, openid_identifier, registration|
if result.unsuccessful?
errors.add_to_base(result.message)
return
end
self.attempted_record = klass.send(find_by_openid_identifier_method, openid_identifier)
if !attempted_record
if auto_register?
self.attempted_record = klass.new
attempted_record.openid_identifier = openid_identifier
attempted_record.send(:map_openid_registration, registration)
if ! attempted_record.save
errors.add(:openid_identifier, "error auto-registering new openid account")
end
return
else
errors.add(:openid_identifier, "did not match any users in our database, have you set up your account to use OpenID?")
return
end
end
end
end
def validate_openid_error
errors.add(:openid_identifier, @openid_error) if @openid_error
end
end
end
end