myobie-rails-auth 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +8 -8
- data/VERSION.yml +1 -1
- data/lib/rails-auth.rb +2 -2
- data/lib/rails-auth/authenticated_helper.rb +1 -1
- data/lib/rails-auth/authentication.rb +40 -13
- data/lib/rails-auth/session_mixin.rb +11 -4
- data/lib/rails-auth/strategies/openid.rb +150 -0
- data/lib/rails-auth/strategy.rb +6 -5
- metadata +2 -1
- data/test/rails-auth_test.rb +0 -7
- data/test/test_helper.rb +0 -9
data/README.markdown
CHANGED
@@ -87,14 +87,14 @@ There is a lot of digest and other crap that encrypts the passwords. We save an
|
|
87
87
|
|
88
88
|
There is also some remember/forget stuff in there.
|
89
89
|
|
90
|
-
[examples]: http://github.com/myobie/rails-auth/tree/
|
91
|
-
[init]: http://github.com/myobie/rails-auth/blob/
|
92
|
-
[a-simple]: http://github.com/myobie/rails-auth/blob/
|
93
|
-
[a-complex]: http://github.com/myobie/rails-auth/blob/
|
94
|
-
[s-simple]: http://github.com/myobie/rails-auth/blob/
|
95
|
-
[s-complex]: http://github.com/myobie/rails-auth/blob/
|
96
|
-
[m-simple]: http://github.com/myobie/rails-auth/blob/
|
97
|
-
[m-complex]: http://github.com/myobie/rails-auth/blob/
|
90
|
+
[examples]: http://github.com/myobie/rails-auth/tree/master/examples
|
91
|
+
[init]: http://github.com/myobie/rails-auth/blob/master/examples/initializers/authentication.rb
|
92
|
+
[a-simple]: http://github.com/myobie/rails-auth/blob/master/examples/controllers/application_controller_simple.rb
|
93
|
+
[a-complex]: http://github.com/myobie/rails-auth/blob/master/examples/controllers/application_controller_complex.rb
|
94
|
+
[s-simple]: http://github.com/myobie/rails-auth/blob/master/examples/controllers/sessions_controller_simple.rb
|
95
|
+
[s-complex]: http://github.com/myobie/rails-auth/blob/master/examples/controllers/sessions_controller_complex.rb
|
96
|
+
[m-simple]: http://github.com/myobie/rails-auth/blob/master/examples/models/user_simple.rb
|
97
|
+
[m-complex]: http://github.com/myobie/rails-auth/blob/master/examples/models/user_complex.rb
|
98
98
|
|
99
99
|
TODO
|
100
100
|
====
|
data/VERSION.yml
CHANGED
data/lib/rails-auth.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class String
|
2
2
|
def /(other)
|
3
|
-
|
3
|
+
File.join(self, other.to_s)
|
4
4
|
end
|
5
5
|
end
|
6
6
|
|
@@ -17,5 +17,5 @@ require 'rails-auth/strategy'
|
|
17
17
|
basic_path = "rails-auth/strategies"
|
18
18
|
|
19
19
|
# Rails::Authentication.register(:basic_auth, basic_path / "basic_auth.rb")
|
20
|
-
|
20
|
+
Rails::Authentication.register(:openid, basic_path / "openid.rb")
|
21
21
|
Rails::Authentication.register(:password_form, basic_path / "password_form.rb")
|
@@ -8,7 +8,7 @@ module Rails
|
|
8
8
|
|
9
9
|
protected
|
10
10
|
def ensure_authenticated(*strategies)
|
11
|
-
session.authenticate!(
|
11
|
+
session.authenticate!(self, *strategies) unless session.authenticated?
|
12
12
|
auth = session.authentication
|
13
13
|
if auth.halted?
|
14
14
|
response.headers.merge!(auth.headers)
|
@@ -10,7 +10,7 @@ module Rails
|
|
10
10
|
class NotImplemented < Exception; end
|
11
11
|
|
12
12
|
# This method returns the default user class to use throughout the
|
13
|
-
#
|
13
|
+
# rails-auth authentication framework. Rails::Authentication.user_class can
|
14
14
|
# be used by other plugins, and by default by strategies.
|
15
15
|
#
|
16
16
|
# By Default it is set to User class. If you need a different class
|
@@ -19,7 +19,16 @@ module Rails
|
|
19
19
|
# @return <User Class Object>
|
20
20
|
#
|
21
21
|
# @api overwritable
|
22
|
-
|
22
|
+
cattr_writer :user_class
|
23
|
+
|
24
|
+
def self.user_class
|
25
|
+
case @@user_class
|
26
|
+
when String
|
27
|
+
@@user_class && @@user_class.constantize
|
28
|
+
when Class
|
29
|
+
@@user_class
|
30
|
+
end
|
31
|
+
end
|
23
32
|
|
24
33
|
|
25
34
|
### copied from restful authentication
|
@@ -59,6 +68,17 @@ module Rails
|
|
59
68
|
session[:user] = store_user(user)
|
60
69
|
@user = session[:user] ? user : session[:user]
|
61
70
|
end
|
71
|
+
|
72
|
+
def selected_strategy
|
73
|
+
return nil if session[:selected_strategy].nil?
|
74
|
+
@selected_strategy ||= session[:selected_strategy].constantize
|
75
|
+
end
|
76
|
+
|
77
|
+
def selected_strategy=(strategy)
|
78
|
+
session[:selected_strategy] = nil && return if strategy.nil?
|
79
|
+
session[:selected_strategy] = strategy.name
|
80
|
+
@selected_strategy = strategy
|
81
|
+
end
|
62
82
|
|
63
83
|
# The workhorse of the framework. The authentiate! method is where
|
64
84
|
# the work is done. authenticate! will try each strategy in order
|
@@ -78,25 +98,26 @@ module Rails
|
|
78
98
|
rest = rest.flatten
|
79
99
|
|
80
100
|
strategies = if rest.empty?
|
81
|
-
if
|
82
|
-
|
101
|
+
if session[:authentication_strategies]
|
102
|
+
session[:authentication_strategies]
|
83
103
|
else
|
84
104
|
Rails::Authentication.default_strategy_order
|
85
105
|
end
|
86
106
|
else
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
107
|
+
session[:authentication_strategies] ||= []
|
108
|
+
session[:authentication_strategies] << rest
|
109
|
+
session[:authentication_strategies].flatten!.uniq!
|
110
|
+
session[:authentication_strategies]
|
91
111
|
end
|
92
112
|
|
93
113
|
msg = opts[:message] || error_message
|
94
114
|
user = nil
|
115
|
+
strategy = nil
|
95
116
|
# This one should find the first one that matches. It should not run any other
|
96
117
|
strategies.detect do |s|
|
97
|
-
|
98
|
-
unless
|
99
|
-
strategy =
|
118
|
+
_s = Rails::Authentication.lookup_strategy[s] # Get the strategy from string or class
|
119
|
+
unless _s.abstract?
|
120
|
+
strategy = _s.new(request, params)
|
100
121
|
user = strategy.run!
|
101
122
|
if strategy.halted?
|
102
123
|
self.headers, self.status, self.body = [strategy.headers, strategy.status, strategy.body]
|
@@ -106,9 +127,14 @@ module Rails
|
|
106
127
|
user
|
107
128
|
end
|
108
129
|
end
|
109
|
-
|
130
|
+
|
131
|
+
self.selected_strategy = strategy.class
|
132
|
+
|
133
|
+
user = run_after_authentication_callbacks(user, request, params) if user
|
134
|
+
|
110
135
|
# Finally, Raise an error if there is no user found, or set it in the session if there is.
|
111
136
|
raise Rails::Authentication::Unauthenticated, msg unless user
|
137
|
+
|
112
138
|
session[:authentication_strategies] = nil # clear the session of Failed Strategies if login is successful
|
113
139
|
self.user = user
|
114
140
|
end
|
@@ -116,6 +142,7 @@ module Rails
|
|
116
142
|
# "Logs Out" a user from the session. Also clears out all session data
|
117
143
|
def abandon!
|
118
144
|
@user = nil
|
145
|
+
@selected_strategy = nil
|
119
146
|
session.clear
|
120
147
|
end
|
121
148
|
|
@@ -164,7 +191,7 @@ module Rails
|
|
164
191
|
when Class
|
165
192
|
h[k] = k
|
166
193
|
when String, Symbol
|
167
|
-
h[k] = Rails::Authentication::Strategies
|
194
|
+
h[k] = ("%s::%s" % ["Rails::Authentication::Strategies", k]).constantize
|
168
195
|
end
|
169
196
|
end
|
170
197
|
end
|
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Rails::Authentication::SessionMixin
|
3
2
|
# Access to the authentication object directly. Particularly useful
|
4
3
|
# for accessing the errors.
|
5
4
|
#
|
@@ -39,5 +38,13 @@ class ActionController::Session::AbstractStore::SessionHash
|
|
39
38
|
def abandon!
|
40
39
|
authentication.abandon!
|
41
40
|
end
|
42
|
-
|
43
|
-
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
class ActionController::Session::AbstractStore::SessionHash
|
45
|
+
include Rails::Authentication::SessionMixin
|
46
|
+
end
|
47
|
+
|
48
|
+
class ActionController::TestSession < Hash
|
49
|
+
include Rails::Authentication::SessionMixin
|
50
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# The openid strategy attempts to login users based on the OpenID protocol
|
2
|
+
# http://openid.net/
|
3
|
+
#
|
4
|
+
# Overwrite the on_sucess!, on_failure!, on_setup_needed!, and on_cancel! to customize events.
|
5
|
+
#
|
6
|
+
# Overwite the required_reg_fields method to require different sreg fields. Default is email and nickname
|
7
|
+
#
|
8
|
+
# Overwrite the openid_store method to customize your session store
|
9
|
+
#
|
10
|
+
# == Requirments
|
11
|
+
#
|
12
|
+
# === Routes:
|
13
|
+
# :openid - an action that is accessilbe via http GET and protected via ensure_authenticated
|
14
|
+
# :signup - a url accessed via GET that takes a user to a signup form (overwritable)
|
15
|
+
#
|
16
|
+
# === Attributes
|
17
|
+
# :identity_url - A string for holding the identity_url associated with this user (overwritable)
|
18
|
+
#
|
19
|
+
# install the ruby-openid gem
|
20
|
+
require 'openid'
|
21
|
+
require 'openid/store/filesystem'
|
22
|
+
require 'openid/extensions/sreg'
|
23
|
+
|
24
|
+
class Rails::Authentication
|
25
|
+
module Strategies
|
26
|
+
module Basic
|
27
|
+
class OpenID < Rails::Authentication::Strategy
|
28
|
+
|
29
|
+
def run!
|
30
|
+
if request.params[:'openid.mode']
|
31
|
+
params_with_path = params.reject { |key, value| request.path_parameters[key] }
|
32
|
+
params_with_path.delete(:format)
|
33
|
+
|
34
|
+
response = consumer.complete(params_with_path, "#{request.protocol}#{request.host_with_port}" + request.path)
|
35
|
+
case response.status.to_s
|
36
|
+
when 'success'
|
37
|
+
sreg_response = ::OpenID::SReg::Response.from_success_response(response)
|
38
|
+
result = on_success!(response, sreg_response)
|
39
|
+
Rails.logger.info "\n\n#{result.inspect}\n\n"
|
40
|
+
result
|
41
|
+
when 'failure'
|
42
|
+
on_failure!(response)
|
43
|
+
when 'setup_needed'
|
44
|
+
on_setup_needed!(response)
|
45
|
+
when 'cancel'
|
46
|
+
on_cancel!(response)
|
47
|
+
end
|
48
|
+
elsif identity_url = params[:identity_url]
|
49
|
+
begin
|
50
|
+
openid_request = consumer.begin(identity_url)
|
51
|
+
openid_reg = ::OpenID::SReg::Request.new
|
52
|
+
openid_reg.request_fields(required_reg_fields)
|
53
|
+
openid_request.add_extension(openid_reg)
|
54
|
+
customize_openid_request!(openid_request)
|
55
|
+
redirect!(openid_request.redirect_url([request.protocol, request.host_with_port].join, openid_callback_url))
|
56
|
+
rescue ::OpenID::OpenIDError => e
|
57
|
+
request.session.authentication.errors.clear!
|
58
|
+
request.session.authentication.errors.add(:openid, 'The OpenID verification failed')
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end # run!
|
63
|
+
|
64
|
+
|
65
|
+
# Overwrite this to add extra options to the OpenID request before it is made.
|
66
|
+
#
|
67
|
+
# @example request.return_to_args["remember_me"] = 1 # remember_me=1 is added when returning from the OpenID provider.
|
68
|
+
#
|
69
|
+
# @api overwritable
|
70
|
+
def customize_openid_request!(openid_request)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Used to define the callback url for the openid provider. By default it
|
74
|
+
# is set to the named :openid route.
|
75
|
+
#
|
76
|
+
# @api overwritable
|
77
|
+
def openid_callback_url
|
78
|
+
"#{[request.protocol, request.host_with_port].join}/login"
|
79
|
+
end
|
80
|
+
|
81
|
+
# Overwrite the on_success! method with the required behavior for successful logins
|
82
|
+
#
|
83
|
+
# @api overwritable
|
84
|
+
def on_success!(response, sreg_response)
|
85
|
+
if user = find_user_by_identity_url(response.identity_url)
|
86
|
+
user
|
87
|
+
else
|
88
|
+
session[:openid] = {:identity_url => response.identity_url}
|
89
|
+
required_reg_fields.each do |f|
|
90
|
+
session[:openid][f.to_sym] = sreg_response.data[f] if sreg_response.data[f]
|
91
|
+
end if sreg_response
|
92
|
+
#redirect!(Rails::Router.url(:signup))
|
93
|
+
redirect!("#{[request.protocol, request.host_with_port].join}/signup")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Overwrite the on_failure! method with the required behavior for failed logins
|
98
|
+
#
|
99
|
+
# @api overwritable
|
100
|
+
def on_failure!(response)
|
101
|
+
session.authentication.errors.clear!
|
102
|
+
session.authentication.errors.add(:openid, 'OpenID verification failed, maybe the provider is down? Or the session timed out')
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# @api overwritable
|
108
|
+
def on_setup_needed!(response)
|
109
|
+
session.authentication.errors.clear!
|
110
|
+
session.authentication.errors.add(:openid, 'OpenID does not seem to be configured correctly')
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# @api overwritable
|
116
|
+
def on_cancel!(response)
|
117
|
+
session.authentication.errors.clear!
|
118
|
+
session.authentication.errors.add(:openid, 'OpenID rejected our request')
|
119
|
+
nil
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
# @api overwritable
|
124
|
+
def required_reg_fields
|
125
|
+
['nickname', 'email']
|
126
|
+
end
|
127
|
+
|
128
|
+
# Overwrite this to properly support your user model
|
129
|
+
#
|
130
|
+
# @api overwritable
|
131
|
+
def find_user_by_identity_url(url)
|
132
|
+
user_class.first(:conditions => {:identity_url => url})
|
133
|
+
end
|
134
|
+
|
135
|
+
# Overwrite this method to set your store
|
136
|
+
#
|
137
|
+
# @api overwritable
|
138
|
+
def openid_store
|
139
|
+
::OpenID::Store::Filesystem.new("#{Rails.root}/tmp/openid")
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
def consumer
|
144
|
+
@consumer ||= ::OpenID::Consumer.new(request.session, openid_store)
|
145
|
+
end
|
146
|
+
|
147
|
+
end # OpenID
|
148
|
+
end # Basic
|
149
|
+
end # Strategies
|
150
|
+
end # Rails::Authentication
|
data/lib/rails-auth/strategy.rb
CHANGED
@@ -43,7 +43,7 @@ module Rails
|
|
43
43
|
require path
|
44
44
|
end
|
45
45
|
|
46
|
-
# The Rails::Authentication::Strategy is where all the action happens in the
|
46
|
+
# The Rails::Authentication::Strategy is where all the action happens in the rails-auth framework.
|
47
47
|
# Inherit from this class to setup your own strategy. The strategy will automatically
|
48
48
|
# be placed in the default_strategy_order array, and will be included in the strategy runs.
|
49
49
|
#
|
@@ -62,7 +62,7 @@ module Rails
|
|
62
62
|
#
|
63
63
|
#
|
64
64
|
class Strategy
|
65
|
-
attr_accessor :request
|
65
|
+
attr_accessor :request, :params
|
66
66
|
attr_writer :body
|
67
67
|
|
68
68
|
class << self
|
@@ -105,7 +105,8 @@ module Rails
|
|
105
105
|
|
106
106
|
end # End class << self
|
107
107
|
|
108
|
-
def initialize(request, params)
|
108
|
+
def initialize(request, params = {})
|
109
|
+
# @controller = controller
|
109
110
|
@request = request
|
110
111
|
@params = params
|
111
112
|
end
|
@@ -139,8 +140,8 @@ module Rails
|
|
139
140
|
self.headers["Location"] = url
|
140
141
|
self.status = opts[:permanent] ? 301 : 302
|
141
142
|
self.status = opts[:status] if opts[:status]
|
142
|
-
self.body = opts[:message] || "<div>You are being redirected to <a href='#{url}'>#{url}</a></div>"
|
143
143
|
halt!
|
144
|
+
# @controller.send(:redirect_to, url)
|
144
145
|
return true
|
145
146
|
end
|
146
147
|
|
@@ -198,7 +199,7 @@ module Rails
|
|
198
199
|
#
|
199
200
|
# @api overwritable
|
200
201
|
def user_class
|
201
|
-
Rails::Authentication.user_class
|
202
|
+
Rails::Authentication.user_class
|
202
203
|
end
|
203
204
|
|
204
205
|
end # Strategy
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: myobie-rails-auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Herald
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- lib/rails-auth/strategies
|
43
43
|
- lib/rails-auth/strategies/abstract_password.rb
|
44
44
|
- lib/rails-auth/strategies/password_form.rb
|
45
|
+
- lib/rails-auth/strategies/openid.rb
|
45
46
|
- lib/rails-auth/strategy.rb
|
46
47
|
- lib/rails-auth.rb
|
47
48
|
- test/rails-auth_test.rb
|
data/test/rails-auth_test.rb
DELETED