gitorious_openid_auth 1.1.0

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.
@@ -0,0 +1,37 @@
1
+ * Dump heavy lifting off to rack-openid gem. OpenIdAuthentication is just a simple controller concern.
2
+
3
+ * Fake HTTP method from OpenID server since they only support a GET. Eliminates the need to set an extra route to match the server's reply. [Josh Peek]
4
+
5
+ * OpenID 2.0 recommends that forms should use the field name "openid_identifier" rather than "openid_url" [Josh Peek]
6
+
7
+ * Return open_id_response.display_identifier to the application instead of .endpoints.claimed_id. [nbibler]
8
+
9
+ * Add Timeout protection [Rick]
10
+
11
+ * An invalid identity url passed through authenticate_with_open_id will no longer raise an InvalidOpenId exception. Instead it will return Result[:missing] to the completion block.
12
+
13
+ * Allow a return_to option to be used instead of the requested url [Josh Peek]
14
+
15
+ * Updated plugin to use Ruby OpenID 2.x.x [Josh Peek]
16
+
17
+ * Tied plugin to ruby-openid 1.1.4 gem until we can make it compatible with 2.x [DHH]
18
+
19
+ * Use URI instead of regexps to normalize the URL and gain free, better matching #8136 [dkubb]
20
+
21
+ * Allow -'s in #normalize_url [Rick]
22
+
23
+ * remove instance of mattr_accessor, it was breaking tests since they don't load ActiveSupport. Fix Timeout test [Rick]
24
+
25
+ * Throw a InvalidOpenId exception instead of just a RuntimeError when the URL can't be normalized [DHH]
26
+
27
+ * Just use the path for the return URL, so extra query parameters don't interfere [DHH]
28
+
29
+ * Added a new default database-backed store after experiencing trouble with the filestore on NFS. The file store is still available as an option [DHH]
30
+
31
+ * Added normalize_url and applied it to all operations going through the plugin [DHH]
32
+
33
+ * Removed open_id? as the idea of using the same input box for both OpenID and username has died -- use using_open_id? instead (which checks for the presence of params[:openid_url] by default) [DHH]
34
+
35
+ * Added OpenIdAuthentication::Result to make it easier to deal with default situations where you don't care to do something particular for each error state [DHH]
36
+
37
+ * Stop relying on root_url being defined, we can just grab the current url instead [DHH]
@@ -0,0 +1,8 @@
1
+ Contributing to open_id_authentication:
2
+
3
+ 1. Fork the [official repository](http://github.com/Velir/open_id_authentication/tree/master).
4
+ 2. Make your changes in a topic branch.
5
+ 3. Send a pull request.
6
+
7
+ Notes:
8
+ * Please don't update the Gem version.
@@ -0,0 +1,242 @@
1
+ OpenIdAuthentication
2
+ ====================
3
+
4
+ Provides a thin wrapper around the excellent ruby-openid gem from JanRan. Be sure to install that first:
5
+
6
+ gem install ruby-openid
7
+
8
+ To understand what OpenID is about and how it works, it helps to read the documentation for lib/openid/consumer.rb
9
+ from that gem.
10
+
11
+ The specification used is http://openid.net/specs/openid-authentication-2_0.html.
12
+
13
+
14
+ Prerequisites
15
+ -------------
16
+
17
+ OpenID authentication uses the session, so be sure that you haven't turned that off.
18
+
19
+ Alternatively, you can use the file-based store, which just relies on on tmp/openids being present in RAILS_ROOT. But be aware that this store only works if you have a single application server. And it's not safe to use across NFS. It's recommended that you use the database store if at all possible. To use the file-based store, you'll also have to add this line to your config/environment.rb:
20
+
21
+ OpenIdAuthentication.store = :file
22
+
23
+ This particular plugin also relies on the fact that the authentication action allows for both POST and GET operations.
24
+ If you're using RESTful authentication, you'll need to explicitly allow for this in your routes.rb.
25
+
26
+ The plugin also expects to find a root_url method that points to the home page of your site. You can accomplish this by using a root route in config/routes.rb:
27
+
28
+ root :to => "articles#index"
29
+
30
+ This plugin relies on Rails Edge revision 6317 or newer.
31
+
32
+
33
+ Example
34
+ -------
35
+
36
+ This example is just to meant to demonstrate how you could use OpenID authentication. You might well want to add
37
+ salted hash logins instead of plain text passwords and other requirements on top of this. Treat it as a starting point,
38
+ not a destination.
39
+
40
+ Note that the User model referenced in the simple example below has an 'identity_url' attribute. You will want to add the same or similar field to whatever
41
+ model you are using for authentication.
42
+
43
+ Also of note is the following code block used in the example below:
44
+
45
+ authenticate_with_open_id do |result, identity_url|
46
+ ...
47
+ end
48
+
49
+ In the above code block, 'identity_url' will need to match user.identity_url exactly. 'identity_url' will be a string in the form of 'http://example.com' -
50
+ If you are storing just 'example.com' with your user, the lookup will fail.
51
+
52
+ There is a handy method in this plugin called 'normalize_url' that will help with validating OpenID URLs.
53
+
54
+ OpenIdAuthentication.normalize_url(user.identity_url)
55
+
56
+ The above will return a standardized version of the OpenID URL - the above called with 'example.com' will return 'http://example.com/'
57
+ It will also raise an InvalidOpenId exception if the URL is determined to not be valid.
58
+ Use the above code in your User model and validate OpenID URLs before saving them.
59
+
60
+ config/routes.rb
61
+
62
+ #config/routes.rb
63
+ root :to => "articles#index"
64
+ resource :session
65
+
66
+ app/views/sessions/new.erb
67
+
68
+ #app/views/sessions/new.erb
69
+ <% form_tag(session_url) do %>
70
+ <p>
71
+ <label for="name">Username:</label>
72
+ <%= text_field_tag "name" %>
73
+ </p>
74
+
75
+ <p>
76
+ <label for="password">Password:</label>
77
+ <%= password_field_tag %>
78
+ </p>
79
+
80
+ <p>
81
+ <!-- ...or use: -->
82
+ </p>
83
+
84
+ <p>
85
+ <label for="openid_identifier">OpenID:</label>
86
+ <%= text_field_tag "openid_identifier" %>
87
+ </p>
88
+
89
+ <p>
90
+ <%= submit_tag 'Sign in', :disable_with => "Signing in&hellip;" %>
91
+ </p>
92
+ <% end %>
93
+
94
+
95
+ app/controllers/sessions_controller.rb
96
+
97
+ #app/controllers/sessions_controller.rb
98
+ class SessionsController < ApplicationController
99
+ def create
100
+ if using_open_id?
101
+ open_id_authentication
102
+ else
103
+ password_authentication(params[:name], params[:password])
104
+ end
105
+ end
106
+
107
+
108
+ protected
109
+ def password_authentication(name, password)
110
+ if @current_user = @account.users.authenticate(params[:name], params[:password])
111
+ successful_login
112
+ else
113
+ failed_login "Sorry, that username/password doesn't work"
114
+ end
115
+ end
116
+
117
+ def open_id_authentication
118
+ authenticate_with_open_id do |result, identity_url|
119
+ if result.successful?
120
+ if @current_user = @account.users.find_by_identity_url(identity_url)
121
+ successful_login
122
+ else
123
+ failed_login "Sorry, no user by that identity URL exists (#{identity_url})"
124
+ end
125
+ else
126
+ failed_login result.message
127
+ end
128
+ end
129
+ end
130
+
131
+
132
+ private
133
+ def successful_login
134
+ session[:user_id] = @current_user.id
135
+ redirect_to(root_url)
136
+ end
137
+
138
+ def failed_login(message)
139
+ flash[:error] = message
140
+ redirect_to(new_session_url)
141
+ end
142
+ end
143
+
144
+
145
+
146
+ If you're fine with the result messages above and don't need individual logic on a per-failure basis,
147
+ you can collapse the case into a mere boolean:
148
+
149
+ def open_id_authentication
150
+ authenticate_with_open_id do |result, identity_url|
151
+ if result.successful? && @current_user = @account.users.find_by_identity_url(identity_url)
152
+ successful_login
153
+ else
154
+ failed_login(result.message || "Sorry, no user by that identity URL exists (#{identity_url})")
155
+ end
156
+ end
157
+ end
158
+
159
+
160
+ Simple Registration OpenID Extension
161
+ ------------------------------------
162
+
163
+ Some OpenID Providers support this lightweight profile exchange protocol. See more: http://www.openidenabled.com/openid/simple-registration-extension
164
+
165
+ You can support it in your app by changing #open_id_authentication
166
+
167
+ def open_id_authentication(identity_url)
168
+ # Pass optional :required and :optional keys to specify what sreg fields you want.
169
+ # Be sure to yield registration, a third argument in the
170
+ # #authenticate_with_open_id block.
171
+ authenticate_with_open_id(identity_url,
172
+ :required => [ :nickname, :email ],
173
+ :optional => :fullname) do |result, identity_url, registration|
174
+ case result.status
175
+ when :missing
176
+ failed_login "Sorry, the OpenID server couldn't be found"
177
+ when :invalid
178
+ failed_login "Sorry, but this does not appear to be a valid OpenID"
179
+ when :canceled
180
+ failed_login "OpenID verification was canceled"
181
+ when :failed
182
+ failed_login "Sorry, the OpenID verification failed"
183
+ when :successful
184
+ if @current_user = @account.users.find_by_identity_url(identity_url)
185
+ assign_registration_attributes!(registration)
186
+
187
+ if current_user.save
188
+ successful_login
189
+ else
190
+ failed_login "Your OpenID profile registration failed: " +
191
+ @current_user.errors.full_messages.to_sentence
192
+ end
193
+ else
194
+ failed_login "Sorry, no user by that identity URL exists"
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ # registration is a hash containing the valid sreg keys given above
201
+ # use this to map them to fields of your user model
202
+ def assign_registration_attributes!(registration)
203
+ model_to_registration_mapping.each do |model_attribute, registration_attribute|
204
+ unless registration[registration_attribute].blank?
205
+ @current_user.send("#{model_attribute}=", registration[registration_attribute])
206
+ end
207
+ end
208
+ end
209
+
210
+ def model_to_registration_mapping
211
+ { :login => 'nickname', :email => 'email', :display_name => 'fullname' }
212
+ end
213
+
214
+ Attribute Exchange OpenID Extension
215
+ -----------------------------------
216
+
217
+ Some OpenID providers also support the OpenID AX (attribute exchange) protocol for exchanging identity information between endpoints. See more: http://openid.net/specs/openid-attribute-exchange-1_0.html
218
+
219
+ Accessing AX data is very similar to the Simple Registration process, described above -- just add the URI identifier for the AX field to your :optional or :required parameters. For example:
220
+
221
+ authenticate_with_open_id(identity_url,
222
+ :required => [ :email, 'http://schema.openid.net/birthDate' ]) do
223
+ |result, identity_url, registration, ax|
224
+
225
+ This would provide the sreg data for :email via registration, and the AX data for http://schema.openid.net/birthDate via ax.
226
+
227
+ Contributing
228
+ ------------
229
+
230
+ Please see the [contribution guidelines](http://github.com/Velir/open_id_authentication/blob/master/CONTRIBUTION_GUIDELINES.md).
231
+
232
+ Credits
233
+ -------
234
+
235
+ open_id_authentication was written by David Heinemeier Hansson with a number of other [contributors](https://github.com/Velir/open_id_authentication/contributors).
236
+
237
+ open_id_authentication maintenance is funded by [Velir](http://velir.com).
238
+
239
+
240
+ License
241
+ -------
242
+ Copyright (c) 2007-2011 David Heinemeier Hansson, released under the MIT license
@@ -0,0 +1,145 @@
1
+ require 'uri'
2
+ require 'openid'
3
+ require 'rack/openid'
4
+
5
+ module OpenIdAuthentication
6
+ def self.new(app)
7
+ store = OpenIdAuthentication.store
8
+ if store.nil?
9
+ Rails.logger.warn "OpenIdAuthentication.store is nil. Using in-memory store."
10
+ end
11
+
12
+ ::Rack::OpenID.new(app, OpenIdAuthentication.store)
13
+ end
14
+
15
+ def self.store
16
+ @@store
17
+ end
18
+
19
+ def self.store=(*store_option)
20
+ store, *parameters = *([ store_option ].flatten)
21
+
22
+ @@store = case store
23
+ when :memory
24
+ require 'openid/store/memory'
25
+ OpenID::Store::Memory.new
26
+ when :file
27
+ require 'openid/store/filesystem'
28
+ OpenID::Store::Filesystem.new(Rails.root.join('tmp/openids'))
29
+ when :memcache
30
+ require 'memcache'
31
+ require 'openid/store/memcache'
32
+ OpenID::Store::Memcache.new(MemCache.new(parameters))
33
+ else
34
+ store
35
+ end
36
+ end
37
+
38
+ self.store = nil
39
+
40
+ class Result
41
+ ERROR_MESSAGES = {
42
+ :missing => "Sorry, the OpenID server couldn't be found",
43
+ :invalid => "Sorry, but this does not appear to be a valid OpenID",
44
+ :canceled => "OpenID verification was canceled",
45
+ :failed => "OpenID verification failed",
46
+ :setup_needed => "OpenID verification needs setup"
47
+ }
48
+
49
+ def self.[](code)
50
+ new(code)
51
+ end
52
+
53
+ def initialize(code)
54
+ @code = code
55
+ end
56
+
57
+ def status
58
+ @code
59
+ end
60
+
61
+ ERROR_MESSAGES.keys.each { |state| define_method("#{state}?") { @code == state } }
62
+
63
+ def successful?
64
+ @code == :successful
65
+ end
66
+
67
+ def unsuccessful?
68
+ ERROR_MESSAGES.keys.include?(@code)
69
+ end
70
+
71
+ def message
72
+ ERROR_MESSAGES[@code]
73
+ end
74
+ end
75
+
76
+ module ControllerMethods
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
+
90
+ if request.env[Rack::OpenID::RESPONSE]
91
+ complete_open_id_authentication(&block)
92
+ else
93
+ begin_open_id_authentication(identifier, options, &block)
94
+ end
95
+ end
96
+
97
+ private
98
+ def open_id_identifier
99
+ params[:openid_identifier] || params[:openid_url]
100
+ end
101
+
102
+ def begin_open_id_authentication(identifier, options = {})
103
+ options[:identifier] = identifier
104
+ value = Rack::OpenID.build_header(options)
105
+ response.headers[Rack::OpenID::AUTHENTICATE_HEADER] = value
106
+ head :unauthorized
107
+ end
108
+
109
+ def complete_open_id_authentication
110
+ response = request.env[Rack::OpenID::RESPONSE]
111
+ identifier = response.display_identifier
112
+
113
+ case response.status
114
+ when OpenID::Consumer::SUCCESS
115
+ yield Result[:successful], identifier,
116
+ OpenID::SReg::Response.from_success_response(response),
117
+ OpenID::AX::FetchResponse.from_success_response(response)
118
+ when :missing
119
+ yield Result[:missing], identifier, nil
120
+ when :invalid
121
+ yield Result[:invalid], identifier, nil
122
+ when OpenID::Consumer::CANCEL
123
+ yield Result[:canceled], identifier, nil
124
+ when OpenID::Consumer::FAILURE
125
+ yield Result[:failed], identifier, nil
126
+ when OpenID::Consumer::SETUP_NEEDED
127
+ yield Result[:setup_needed], response.setup_url, nil
128
+ end
129
+ end
130
+ end
131
+
132
+ if Rails.version >= '3'
133
+ class Railtie < ::Rails::Railtie
134
+ config.app_middleware.use OpenIdAuthentication
135
+
136
+ config.after_initialize do
137
+ OpenID::Util.logger = Rails.logger
138
+ end
139
+
140
+ ActiveSupport.on_load :action_controller do
141
+ ActionController::Base.send :include, ::OpenIdAuthentication::ControllerMethods
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,4 @@
1
+ module OpenIdAuthentication
2
+ VERSION = "1.1.0"
3
+ end
4
+
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gitorious_openid_auth
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Christian Johansen
9
+ - Patrick Robertson
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-10-30 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rack-openid
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '1.3'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '1.3'
31
+ description: ! "open_id_authentication provides a thin wrapper around the excellent
32
+ rack-openid\n gem."
33
+ email:
34
+ - christian@gitorious.com
35
+ - patrick.robertson@velir.com
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - CHANGELOG
41
+ - README.md
42
+ - CONTRIBUTION_GUIDELINES.md
43
+ - lib/open_id_authentication.rb
44
+ - lib/open_id_authentication/version.rb
45
+ homepage: https://gitorious.org/gitorious/openid_auth
46
+ licenses: []
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 1.8.23
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: open_id_authentication provides a thin wrapper around the excellent rack-openid
69
+ gem.
70
+ test_files: []