authlogic-oid 1.0.2 → 1.0.3
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/CHANGELOG.rdoc +8 -0
- data/README.rdoc +1 -1
- data/lib/authlogic_openid/acts_as_authentic.rb +65 -12
- data/lib/authlogic_openid/session.rb +78 -44
- data/lib/authlogic_openid/version.rb +1 -1
- metadata +3 -3
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 1.0.3 released 2009-4-3
|
2
|
+
|
3
|
+
* Added find_by_openid_identifier config option for AuthlogicOpenid::Session.
|
4
|
+
* Set the openid_identifier by the one passed back by the provider in AuthlogicOpenid::ActsAsAuthentic.
|
5
|
+
* Added required_fields and optional_fields config options for AuthlogicOpenid::ActsAsAuthentic.
|
6
|
+
* Added map_openid_registration, attributes_to_save, and map_saved_attributes methods to customize how attributes are set for AuthlogicOpenid::ActsAsAuthentic.
|
7
|
+
* Make authenticating_with_openid? method a little more stringent to avoid trying to double authenticate. Ex: finding a session in the save block during a successful save.
|
8
|
+
|
1
9
|
== 1.0.2 released 2009-3-30
|
2
10
|
|
3
11
|
* Remove config block in initializer.
|
data/README.rdoc
CHANGED
@@ -4,7 +4,7 @@ Authlogic OpenID is an extension of the Authlogic library to add OpenID support.
|
|
4
4
|
|
5
5
|
== Helpful links
|
6
6
|
|
7
|
-
* <b>Documentation:</b> http://authlogic.rubyforge.org
|
7
|
+
* <b>Documentation:</b> http://authlogic-oid.rubyforge.org
|
8
8
|
* <b>Authlogic:</b> http://github.com/binarylogic/authlogic
|
9
9
|
* <b>Live example:</b> http://authlogicexample.binarylogic.com
|
10
10
|
|
@@ -8,10 +8,35 @@ module AuthlogicOpenid
|
|
8
8
|
# OpenID is being used.
|
9
9
|
def self.included(klass)
|
10
10
|
klass.class_eval do
|
11
|
+
extend Config
|
11
12
|
add_acts_as_authentic_module(Methods, :prepend)
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
16
|
+
module Config
|
17
|
+
# Some OpenID providers support a lightweight profile exchange protocol, for those that do, you can require
|
18
|
+
# certain fields. This is convenient for new registrations, as it will basically fill out the fields in the
|
19
|
+
# form for them, so they don't have to re-type information already stored with their OpenID account.
|
20
|
+
#
|
21
|
+
# For more info and what fields you can use see: http://openid.net/specs/openid-simple-registration-extension-1_0.html
|
22
|
+
#
|
23
|
+
# * <tt>Default:</tt> []
|
24
|
+
# * <tt>Accepts:</tt> Array of symbols
|
25
|
+
def required_fields(value = nil)
|
26
|
+
config(:required_fields, value, [])
|
27
|
+
end
|
28
|
+
alias_method :required_fields=, :required_fields
|
29
|
+
|
30
|
+
# Same as required_fields, but optional instead.
|
31
|
+
#
|
32
|
+
# * <tt>Default:</tt> []
|
33
|
+
# * <tt>Accepts:</tt> Array of symbols
|
34
|
+
def optional_fields(value = nil)
|
35
|
+
config(:optional_fields, value, [])
|
36
|
+
end
|
37
|
+
alias_method :optional_fields=, :optional_fields
|
38
|
+
end
|
39
|
+
|
15
40
|
module Methods
|
16
41
|
# Set up some simple validations
|
17
42
|
def self.included(klass)
|
@@ -57,27 +82,22 @@ module AuthlogicOpenid
|
|
57
82
|
@openid_error = nil
|
58
83
|
|
59
84
|
if !openid_complete?
|
60
|
-
|
61
|
-
[:password, crypted_password_field, password_salt_field, :persistence_token, :perishable_token, :single_access_token, :login_count,
|
62
|
-
:failed_login_count, :last_request_at, :current_login_at, :last_login_at, :current_login_ip, :last_login_ip, :created_at,
|
63
|
-
:updated_at, :lock_version].include?(k.to_sym)
|
64
|
-
end
|
65
|
-
attrs_to_persist.merge!(:password => password, :password_confirmation => password_confirmation)
|
66
|
-
session_class.controller.session[:openid_attributes] = attrs_to_persist
|
85
|
+
session_class.controller.session[:openid_attributes] = attributes_to_save
|
67
86
|
else
|
68
|
-
|
87
|
+
map_saved_attributes(session_class.controller.session[:openid_attributes])
|
69
88
|
session_class.controller.session[:openid_attributes] = nil
|
70
89
|
end
|
71
90
|
|
72
91
|
options = {}
|
73
|
-
options[:
|
74
|
-
options[:
|
92
|
+
options[:required] = self.class.required_fields
|
93
|
+
options[:optional] = self.class.optional_fields
|
75
94
|
options[:return_to] = session_class.controller.url_for(:for_model => "1")
|
76
95
|
|
77
96
|
session_class.controller.send(:authenticate_with_open_id, openid_identifier, options) do |result, openid_identifier, registration|
|
78
97
|
if result.unsuccessful?
|
79
98
|
@openid_error = result.message
|
80
99
|
else
|
100
|
+
self.openid_identifier = openid_identifier
|
81
101
|
map_openid_registration(registration)
|
82
102
|
end
|
83
103
|
|
@@ -87,10 +107,43 @@ module AuthlogicOpenid
|
|
87
107
|
return false
|
88
108
|
end
|
89
109
|
|
90
|
-
|
110
|
+
# Override this method to map the OpenID registration fields with fields in your model. See the required_fields and
|
111
|
+
# optional_fields configuration options to enable this feature.
|
112
|
+
#
|
113
|
+
# Basically you will get a hash of values passed as a single argument. Then just map them as you see fit. Check out
|
114
|
+
# the source of this method for an example.
|
115
|
+
def map_openid_registration(registration) # :doc:
|
91
116
|
self.name ||= registration[:fullname] if respond_to?(:name) && !registration[:fullname].blank?
|
92
117
|
self.first_name ||= registration[:fullname].split(" ").first if respond_to?(:first_name) && !registration[:fullname].blank?
|
93
|
-
self.
|
118
|
+
self.last_name ||= registration[:fullname].split(" ").last if respond_to?(:last_name) && !registration[:last_name].blank?
|
119
|
+
end
|
120
|
+
|
121
|
+
# This method works in conjunction with map_saved_attributes.
|
122
|
+
#
|
123
|
+
# Let's say a user fills out a registration form, provides an OpenID and submits the form. They are then redirected to their
|
124
|
+
# OpenID provider. All is good and they are redirected back. All of those fields they spent time filling out are forgetten
|
125
|
+
# and they have to retype them all. To avoid this, AuthlogicOpenid saves all of these attributes in the session and then
|
126
|
+
# attempts to restore them. See the source for what attributes it saves. If you need to block more attributes, or save
|
127
|
+
# more just override this method and do whatever you want.
|
128
|
+
def attributes_to_save # :doc:
|
129
|
+
attrs_to_save = attributes.clone.delete_if do |k, v|
|
130
|
+
[:password, crypted_password_field, password_salt_field, :persistence_token, :perishable_token, :single_access_token, :login_count,
|
131
|
+
:failed_login_count, :last_request_at, :current_login_at, :last_login_at, :current_login_ip, :last_login_ip, :created_at,
|
132
|
+
:updated_at, :lock_version].include?(k.to_sym)
|
133
|
+
end
|
134
|
+
attrs_to_save.merge!(:password => password, :password_confirmation => password_confirmation)
|
135
|
+
end
|
136
|
+
|
137
|
+
# This method works in conjunction with attributes_to_save. See that method for a description of the why these methods exist.
|
138
|
+
#
|
139
|
+
# If the default behavior of this method is not sufficient for you because you have attr_protected or attr_accessible then
|
140
|
+
# override this method and set them individually. Maybe something like this would be good:
|
141
|
+
#
|
142
|
+
# attrs.each do |key, value|
|
143
|
+
# send("#{key}=", value)
|
144
|
+
# end
|
145
|
+
def map_saved_attributes(attrs) # :doc:
|
146
|
+
self.attributes = attrs
|
94
147
|
end
|
95
148
|
|
96
149
|
def validate_openid
|
@@ -4,58 +4,92 @@ module AuthlogicOpenid
|
|
4
4
|
# Add a simple openid_identifier attribute and some validations for the field.
|
5
5
|
def self.included(klass)
|
6
6
|
klass.class_eval do
|
7
|
-
|
8
|
-
|
9
|
-
validate :validate_by_openid, :if => :authenticating_with_openid?
|
7
|
+
extend Config
|
8
|
+
include Methods
|
10
9
|
end
|
11
10
|
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
# error.
|
31
|
-
def save(&block)
|
32
|
-
block = nil if !openid_identifier.blank?
|
33
|
-
super(&block)
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
def authenticating_with_openid?
|
38
|
-
!openid_identifier.blank? || (controller.params[:open_id_complete] && controller.params[:for_session])
|
12
|
+
module Config
|
13
|
+
# What method should we call to find a record by the openid_identifier?
|
14
|
+
# This is useful if you want to store multiple openid_identifiers for a single record.
|
15
|
+
# You could do something like:
|
16
|
+
#
|
17
|
+
# class User < ActiveRecord::Base
|
18
|
+
# def self.find_by_openid_identifier(identifier)
|
19
|
+
# user.first(:conditions => {:openid_identifiers => {:identifier => identifier}})
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# Obviously the above depends on what you are calling your assocition, etc. But you get the point.
|
24
|
+
#
|
25
|
+
# * <tt>Default:</tt> :find_by_openid_identifier
|
26
|
+
# * <tt>Accepts:</tt> Symbol
|
27
|
+
def find_by_openid_identifier_method(value = nil)
|
28
|
+
config(:find_by_openid_identifier_method, value, :find_by_openid_identifier)
|
39
29
|
end
|
30
|
+
alias_method :find_by_openid_identifier_method=, :find_by_openid_identifier_method
|
31
|
+
end
|
40
32
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
self.attempted_record = klass.find_by_openid_identifier(openid_identifier)
|
49
|
-
|
50
|
-
if !attempted_record
|
51
|
-
errors.add(:openid_identifier, "did not match any users in our database, have you set up your account to use OpenID?")
|
52
|
-
return
|
53
|
-
end
|
33
|
+
module Methods
|
34
|
+
def self.included(klass)
|
35
|
+
klass.class_eval do
|
36
|
+
attr_reader :openid_identifier
|
37
|
+
validate :validate_openid_error
|
38
|
+
validate :validate_by_openid, :if => :authenticating_with_openid?
|
54
39
|
end
|
55
40
|
end
|
56
41
|
|
57
|
-
|
58
|
-
|
42
|
+
# Hooks into credentials so that you can pass an :openid_identifier key.
|
43
|
+
def credentials=(value)
|
44
|
+
super
|
45
|
+
values = value.is_a?(Array) ? value : [value]
|
46
|
+
hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
|
47
|
+
self.openid_identifier = hash[:openid_identifier] if !hash.nil? && hash.key?(:openid_identifier)
|
48
|
+
end
|
49
|
+
|
50
|
+
def openid_identifier=(value)
|
51
|
+
@openid_identifier = value.blank? ? nil : OpenIdAuthentication.normalize_identifier(value)
|
52
|
+
@openid_error = nil
|
53
|
+
rescue OpenIdAuthentication::InvalidOpenId => e
|
54
|
+
@openid_identifier = nil
|
55
|
+
@openid_error = e.message
|
59
56
|
end
|
57
|
+
|
58
|
+
# Cleaers out the block if we are authenticating with OpenID, so that we can redirect without a DoubleRender
|
59
|
+
# error.
|
60
|
+
def save(&block)
|
61
|
+
block = nil if !openid_identifier.blank?
|
62
|
+
super(&block)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def authenticating_with_openid?
|
67
|
+
attempted_record.nil? && errors.empty? && (!openid_identifier.blank? || (controller.params[:open_id_complete] && controller.params[:for_session]))
|
68
|
+
end
|
69
|
+
|
70
|
+
def find_by_openid_identifier_method
|
71
|
+
self.class.find_by_openid_identifier_method
|
72
|
+
end
|
73
|
+
|
74
|
+
def validate_by_openid
|
75
|
+
controller.send(:authenticate_with_open_id, openid_identifier, :return_to => controller.url_for(:for_session => "1")) do |result, openid_identifier|
|
76
|
+
if result.unsuccessful?
|
77
|
+
errors.add_to_base(result.message)
|
78
|
+
return
|
79
|
+
end
|
80
|
+
|
81
|
+
self.attempted_record = klass.send(find_by_openid_identifier_method, openid_identifier)
|
82
|
+
|
83
|
+
if !attempted_record
|
84
|
+
errors.add(:openid_identifier, "did not match any users in our database, have you set up your account to use OpenID?")
|
85
|
+
return
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def validate_openid_error
|
91
|
+
errors.add(:openid_identifier, @openid_error) if @openid_error
|
92
|
+
end
|
93
|
+
end
|
60
94
|
end
|
61
95
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authlogic-oid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Johnson of Binary Logic
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-03
|
12
|
+
date: 2009-04-03 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.12.1
|
34
34
|
version:
|
35
35
|
description: Extension of the Authlogic library to add OpenID support.
|
36
36
|
email: bjohnson@binarylogic.com
|