myobie-rails-auth 0.0.2 → 0.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/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