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 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
- attrs_to_persist = attributes.delete_if do |k, v|
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
- self.attributes = session_class.controller.session[:openid_attributes]
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[:required_field] = [self.class.login_field, self.class.email_field].compact
74
- options[:optional_fields] = [:fullname]
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
- def map_openid_registration(registration)
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.first_name ||= registration[:fullname].split(" ").last if respond_to?(:last_name) && !registration[:last_name].blank?
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
- attr_reader :openid_identifier
8
- validate :validate_openid_error
9
- validate :validate_by_openid, :if => :authenticating_with_openid?
7
+ extend Config
8
+ include Methods
10
9
  end
11
10
  end
12
11
 
13
- # Hooks into credentials so that you can pass an :openid_identifier key.
14
- def credentials=(value)
15
- super
16
- values = value.is_a?(Array) ? value : [value]
17
- hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
18
- self.openid_identifier = hash[:openid_identifier] if !hash.nil? && hash.key?(:openid_identifier)
19
- end
20
-
21
- def openid_identifier=(value)
22
- @openid_identifier = value.blank? ? nil : OpenIdAuthentication.normalize_identifier(value)
23
- @openid_error = nil
24
- rescue OpenIdAuthentication::InvalidOpenId => e
25
- @openid_identifier = nil
26
- @openid_error = e.message
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(&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
- def validate_by_openid
42
- controller.send(:authenticate_with_open_id, openid_identifier, :return_to => controller.url_for(:for_session => "1")) do |result, openid_identifier|
43
- if result.unsuccessful?
44
- errors.add_to_base(result.message)
45
- return
46
- end
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
- def validate_openid_error
58
- errors.add(:openid_identifier, @openid_error) if @openid_error
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
@@ -41,7 +41,7 @@ module AuthlogicOpenid
41
41
 
42
42
  MAJOR = 1
43
43
  MINOR = 0
44
- TINY = 2
44
+ TINY = 3
45
45
 
46
46
  # The current version as a Version instance
47
47
  CURRENT = new(MAJOR, MINOR, TINY)
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.2
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-30 00:00:00 -04:00
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.11.0
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