authlogic-oid 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|