merb-auth-core 1.1.0 → 1.1.1
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/Rakefile +1 -1
- data/lib/merb-auth-core.rb +1 -1
- data/lib/merb-auth-core/authenticated_helper.rb +12 -12
- data/lib/merb-auth-core/authentication.rb +35 -35
- data/lib/merb-auth-core/bootloader.rb +2 -2
- data/lib/merb-auth-core/callbacks.rb +6 -6
- data/lib/merb-auth-core/customizations.rb +5 -5
- data/lib/merb-auth-core/errors.rb +1 -1
- data/lib/merb-auth-core/responses.rb +8 -8
- data/lib/merb-auth-core/router_helper.rb +6 -6
- data/lib/merb-auth-core/session_mixin.rb +10 -10
- data/lib/merb-auth-core/strategy.rb +37 -37
- data/lib/merb-auth-core/version.rb +1 -1
- data/spec/helpers/authentication_helper_spec.rb +22 -22
- data/spec/merb-auth-core/authentication_spec.rb +66 -66
- data/spec/merb-auth-core/callbacks_spec.rb +16 -16
- data/spec/merb-auth-core/customizations_spec.rb +5 -5
- data/spec/merb-auth-core/errors_spec.rb +9 -9
- data/spec/merb-auth-core/failed_login_spec.rb +16 -16
- data/spec/merb-auth-core/merb-auth-core_spec.rb +1 -1
- data/spec/merb-auth-core/router_helper_spec.rb +23 -23
- data/spec/merb-auth-core/strategy_spec.rb +54 -54
- data/spec/spec_helper.rb +7 -7
- metadata +14 -6
data/Rakefile
CHANGED
@@ -27,7 +27,7 @@ begin
|
|
27
27
|
gemspec.files = %w(LICENSE Rakefile README.textile TODO) + Dir['{lib,spec}/**/*']
|
28
28
|
|
29
29
|
# Runtime dependencies
|
30
|
-
gemspec.add_dependency 'merb-core',
|
30
|
+
gemspec.add_dependency 'merb-core', '~> 1.1'
|
31
31
|
|
32
32
|
# Development dependencies
|
33
33
|
gemspec.add_development_dependency 'rspec', ">= 1.2.9"
|
data/lib/merb-auth-core.rb
CHANGED
@@ -12,7 +12,7 @@ require "merb-auth-core/router_helper"
|
|
12
12
|
require "merb-auth-core/callbacks"
|
13
13
|
|
14
14
|
Merb::BootLoader.before_app_loads do
|
15
|
-
# require code that must be loaded before the application
|
15
|
+
# require code that must be loaded before the application
|
16
16
|
Merb::Controller.send(:include, Merb::AuthenticatedHelper)
|
17
17
|
end
|
18
18
|
|
@@ -1,33 +1,33 @@
|
|
1
1
|
module Merb
|
2
2
|
class Controller::Unauthenticated < ControllerExceptions::Unauthorized; end
|
3
|
-
|
4
|
-
module AuthenticatedHelper
|
3
|
+
|
4
|
+
module AuthenticatedHelper
|
5
5
|
protected
|
6
6
|
# This is the main method to use as a before filter. You can call it with options
|
7
7
|
# and strategies to use. It will check if a user is logged in, and failing that
|
8
|
-
# will run through either specified.
|
9
|
-
#
|
10
|
-
# @params all are optional. A list of strategies, optionally followed by a
|
11
|
-
# options hash.
|
8
|
+
# will run through either specified.
|
9
|
+
#
|
10
|
+
# @params all are optional. A list of strategies, optionally followed by a
|
11
|
+
# options hash.
|
12
12
|
#
|
13
13
|
# If used with no options, or only the hash, the default strategies will be used
|
14
|
-
# see Authentictaion.default_strategy_order.
|
14
|
+
# see Authentictaion.default_strategy_order.
|
15
15
|
#
|
16
16
|
# If a list of strategies is passed in, the default strategies are ignored, and
|
17
|
-
# the passed in strategies are used in order until either one is found, or all fail.
|
17
|
+
# the passed in strategies are used in order until either one is found, or all fail.
|
18
18
|
#
|
19
|
-
# A failed login will result in an Unauthenticated exception being raised.
|
19
|
+
# A failed login will result in an Unauthenticated exception being raised.
|
20
20
|
#
|
21
21
|
# Use the :message key in the options hash to pass in a failure message to the
|
22
22
|
# exception.
|
23
|
-
#
|
23
|
+
#
|
24
24
|
# === Example
|
25
25
|
#
|
26
26
|
# class MyController < Application
|
27
27
|
# before :ensure_authenticated, :with => [OpenID,FormPassword, :message => "Failz!"]
|
28
28
|
# #... <snip>
|
29
29
|
# end
|
30
|
-
#
|
30
|
+
#
|
31
31
|
def ensure_authenticated(*strategies)
|
32
32
|
session.authenticate!(request, params, *strategies) unless session.authenticated?
|
33
33
|
auth = session.authentication
|
@@ -37,6 +37,6 @@ module Merb
|
|
37
37
|
throw :halt, auth.body
|
38
38
|
end
|
39
39
|
session.user
|
40
|
-
end
|
40
|
+
end
|
41
41
|
end
|
42
42
|
end
|
@@ -4,11 +4,11 @@ module Merb
|
|
4
4
|
include Extlib::Hook
|
5
5
|
attr_accessor :session
|
6
6
|
attr_writer :error_message
|
7
|
-
|
7
|
+
|
8
8
|
class DuplicateStrategy < Exception; end
|
9
9
|
class MissingStrategy < Exception; end
|
10
10
|
class NotImplemented < Exception; end
|
11
|
-
|
11
|
+
|
12
12
|
# This method returns the default user class to use throughout the
|
13
13
|
# merb-auth authentication framework. Merb::Authentication.user_class can
|
14
14
|
# be used by other plugins, and by default by strategies.
|
@@ -20,40 +20,40 @@ module Merb
|
|
20
20
|
#
|
21
21
|
# @api overwritable
|
22
22
|
cattr_accessor :user_class
|
23
|
-
|
23
|
+
|
24
24
|
def initialize(session)
|
25
25
|
@session = session
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
# Returns true if there is an authenticated user attached to this session
|
29
29
|
#
|
30
30
|
# @return <TrueClass|FalseClass>
|
31
|
-
#
|
31
|
+
#
|
32
32
|
def authenticated?
|
33
33
|
!!session[:user]
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
# This method will retrieve the user object stored in the session or nil if there
|
37
37
|
# is no user logged in.
|
38
|
-
#
|
38
|
+
#
|
39
39
|
# @return <User class>|NilClass
|
40
40
|
def user
|
41
41
|
return nil if !session[:user]
|
42
42
|
@user ||= fetch_user(session[:user])
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
# This method will store the user provided into the session
|
46
46
|
# and set the user as the currently logged in user
|
47
47
|
# @return <User Class>|NilClass
|
48
48
|
def user=(user)
|
49
49
|
session[:user] = nil && return if user.nil?
|
50
50
|
session[:user] = store_user(user)
|
51
|
-
@user = session[:user] ? user : session[:user]
|
51
|
+
@user = session[:user] ? user : session[:user]
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
# The workhorse of the framework. The authentiate! method is where
|
55
55
|
# the work is done. authenticate! will try each strategy in order
|
56
|
-
# either passed in, or in the default_strategy_order.
|
56
|
+
# either passed in, or in the default_strategy_order.
|
57
57
|
#
|
58
58
|
# If a strategy returns some kind of user object, this will be stored
|
59
59
|
# in the session, otherwise a Merb::Controller::Unauthenticated exception is raised
|
@@ -61,7 +61,7 @@ module Merb
|
|
61
61
|
# @params Merb::Request, [List,Of,Strategies, optional_options_hash]
|
62
62
|
#
|
63
63
|
# Pass in a list of strategy objects to have this list take precedence over the normal defaults
|
64
|
-
#
|
64
|
+
#
|
65
65
|
# Use an options hash to provide an error message to be passed into the exception.
|
66
66
|
#
|
67
67
|
# @return user object of the verified user. An exception is raised if no user is found
|
@@ -69,9 +69,9 @@ module Merb
|
|
69
69
|
def authenticate!(request, params, *rest)
|
70
70
|
opts = rest.last.kind_of?(Hash) ? rest.pop : {}
|
71
71
|
rest = rest.flatten
|
72
|
-
|
72
|
+
|
73
73
|
strategies = if rest.empty?
|
74
|
-
if request.session[:authentication_strategies]
|
74
|
+
if request.session[:authentication_strategies]
|
75
75
|
request.session[:authentication_strategies]
|
76
76
|
else
|
77
77
|
Merb::Authentication.default_strategy_order
|
@@ -82,15 +82,15 @@ module Merb
|
|
82
82
|
request.session[:authentication_strategies].flatten!.uniq!
|
83
83
|
request.session[:authentication_strategies]
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
msg = opts[:message] || error_message
|
87
|
-
user = nil
|
87
|
+
user = nil
|
88
88
|
# This one should find the first one that matches. It should not run antother
|
89
89
|
strategies.detect do |s|
|
90
90
|
s = Merb::Authentication.lookup_strategy[s] # Get the strategy from string or class
|
91
91
|
unless s.abstract?
|
92
92
|
strategy = s.new(request, params)
|
93
|
-
user = strategy.run!
|
93
|
+
user = strategy.run!
|
94
94
|
if strategy.halted?
|
95
95
|
self.headers, self.status, self.body = [strategy.headers, strategy.status, strategy.body]
|
96
96
|
halt!
|
@@ -99,26 +99,26 @@ module Merb
|
|
99
99
|
user
|
100
100
|
end
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
# Check after callbacks to make sure the user is still cool
|
104
104
|
user = run_after_authentication_callbacks(user, request, params) if user
|
105
|
-
|
105
|
+
|
106
106
|
# Finally, Raise an error if there is no user found, or set it in the session if there is.
|
107
107
|
raise Merb::Controller::Unauthenticated, msg unless user
|
108
|
-
session[:authentication_strategies] = nil # clear the session of Failed Strategies if login is successful
|
108
|
+
session[:authentication_strategies] = nil # clear the session of Failed Strategies if login is successful
|
109
109
|
self.user = user
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
# "Logs Out" a user from the session. Also clears out all session data
|
113
113
|
def abandon!
|
114
114
|
@user = nil
|
115
115
|
session.clear
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
# A simple error message mechanism to provide general information. For more specific information
|
119
119
|
#
|
120
120
|
# This message is the default message passed to the Merb::Controller::Unauthenticated exception
|
121
|
-
# during authentication.
|
121
|
+
# during authentication.
|
122
122
|
#
|
123
123
|
# This is a very simple mechanism for error messages. For more detailed control see Authenticaiton#errors
|
124
124
|
#
|
@@ -126,16 +126,16 @@ module Merb
|
|
126
126
|
def error_message
|
127
127
|
@error_message || "Could not log in"
|
128
128
|
end
|
129
|
-
|
130
|
-
# Tells the framework how to store your user object into the session so that it can be re-created
|
131
|
-
# on the next login.
|
129
|
+
|
130
|
+
# Tells the framework how to store your user object into the session so that it can be re-created
|
131
|
+
# on the next login.
|
132
132
|
# You must overwrite this method for use in your projects. Slices and plugins may set this.
|
133
133
|
#
|
134
134
|
# @api overwritable
|
135
135
|
def store_user(user)
|
136
136
|
raise NotImplemented
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
# Tells the framework how to reconstitute a user from the data stored by store_user.
|
140
140
|
#
|
141
141
|
# You must overwrite this method for user in your projects. Slices and plugins may set this.
|
@@ -144,7 +144,7 @@ module Merb
|
|
144
144
|
def fetch_user(session_contents = session[:user])
|
145
145
|
raise NotImplemented
|
146
146
|
end
|
147
|
-
|
147
|
+
|
148
148
|
# Keeps track of strategies by class or string
|
149
149
|
# When loading from string, strategies are loaded withing the Merb::Authentication::Strategies namespace
|
150
150
|
# When loaded by class, the class is stored directly
|
@@ -152,26 +152,26 @@ module Merb
|
|
152
152
|
def self.lookup_strategy
|
153
153
|
@strategy_lookup || reset_strategy_lookup!
|
154
154
|
end
|
155
|
-
|
155
|
+
|
156
156
|
# Restets the strategy lookup. Useful in specs
|
157
157
|
def self.reset_strategy_lookup!
|
158
|
-
@strategy_lookup = Mash.new do |h,k|
|
158
|
+
@strategy_lookup = Mash.new do |h,k|
|
159
159
|
case k
|
160
160
|
when Class
|
161
161
|
h[k] = k
|
162
162
|
when String, Symbol
|
163
|
-
h[k] = Merb::Authentication::Strategies.full_const_get(k.to_s)
|
163
|
+
h[k] = Merb::Authentication::Strategies.full_const_get(k.to_s)
|
164
164
|
end
|
165
165
|
end
|
166
166
|
end
|
167
|
-
|
168
|
-
# Maintains a list of keys to maintain when needing to keep some state
|
167
|
+
|
168
|
+
# Maintains a list of keys to maintain when needing to keep some state
|
169
169
|
# in the face of session.abandon! You need to maintain this state yourself
|
170
170
|
# @public
|
171
171
|
def self.maintain_session_keys
|
172
172
|
@maintain_session_keys ||= [:authentication_strategies]
|
173
173
|
end
|
174
|
-
|
174
|
+
|
175
175
|
private
|
176
176
|
def run_after_authentication_callbacks(user, request, params)
|
177
177
|
Merb::Authentication.after_callbacks.each do |cb|
|
@@ -185,6 +185,6 @@ module Merb
|
|
185
185
|
end
|
186
186
|
user
|
187
187
|
end
|
188
|
-
|
188
|
+
|
189
189
|
end # Merb::Authentication
|
190
190
|
end # Merb
|
@@ -2,14 +2,14 @@ module Merb
|
|
2
2
|
class Authentication
|
3
3
|
cattr_accessor :after_callbacks
|
4
4
|
@@after_callbacks = []
|
5
|
-
|
5
|
+
|
6
6
|
# Use the after_authentication callbacks to setup things that should occur after the
|
7
|
-
# user is authenticated.
|
7
|
+
# user is authenticated.
|
8
8
|
#
|
9
9
|
# Pass in symbols, procs and or a block to the method to setup the callbacks.
|
10
|
-
# Callbacks are executed in the order they are added.
|
10
|
+
# Callbacks are executed in the order they are added.
|
11
11
|
#
|
12
|
-
# @params
|
12
|
+
# @params
|
13
13
|
# <*callbacks:[Symbol|Proc]> The callback.. Symbol == method on the user object
|
14
14
|
# Proc will be passed the user, request and param objects
|
15
15
|
# <&block> A block to check. The user, request and params will be passed into the block
|
@@ -24,11 +24,11 @@ module Merb
|
|
24
24
|
# end
|
25
25
|
#
|
26
26
|
# @api public
|
27
|
-
|
27
|
+
|
28
28
|
def self.after_authentication(*callbacks, &block)
|
29
29
|
self.after_callbacks = after_callbacks + callbacks.flatten unless callbacks.blank?
|
30
30
|
after_callbacks << block if block_given?
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
end
|
34
34
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Merb
|
2
2
|
class Authentication
|
3
|
-
|
3
|
+
|
4
4
|
class << self
|
5
|
-
|
5
|
+
|
6
6
|
# Adds any customizations just before the after_app_loads boot loader
|
7
7
|
# so that plugins can offer default customization. This will still allow
|
8
8
|
# for a user to overwrite any customizations if required in the after_app_loads
|
@@ -12,13 +12,13 @@ module Merb
|
|
12
12
|
default_customizations << block
|
13
13
|
default_customizations
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
# Gets the list of declared customizations
|
17
17
|
def default_customizations
|
18
18
|
@custom_default_blocks ||= []
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
end # Merb::Authentication
|
24
24
|
end # Merb
|
@@ -2,35 +2,35 @@ module Merb
|
|
2
2
|
# These are not intended to be used directly
|
3
3
|
class Authentication
|
4
4
|
attr_accessor :body
|
5
|
-
|
5
|
+
|
6
6
|
def redirected?
|
7
7
|
!!headers["Location"]
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def headers
|
11
11
|
@headers ||= {}
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def status
|
15
15
|
@status ||= 200
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def status=(sts)
|
19
19
|
@status = sts
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def halted?
|
23
23
|
!!@halt
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def headers=(headers)
|
27
27
|
raise ArgumentError, "Need to supply a hash to headers. Got #{headers.class}" unless headers.kind_of?(Hash)
|
28
28
|
@headers = headers
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
def halt!
|
32
32
|
@halt = true
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
end # Merb::Authentication
|
36
36
|
end # Merb
|
@@ -5,17 +5,17 @@ Merb::Router.extensions do
|
|
5
5
|
# as an argument to the authenticate method.
|
6
6
|
#
|
7
7
|
# ===Example
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# authenticate(OpenID) do
|
10
10
|
# resource :posts
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# authenticate do
|
13
13
|
# match("/").to(:controller => "home")
|
14
14
|
# end
|
15
15
|
# end
|
16
|
-
#
|
16
|
+
#
|
17
17
|
# This is a simple example that shows protecting the entire set of routes for
|
18
|
-
# the posts resource with the OpenID strategy.
|
18
|
+
# the posts resource with the OpenID strategy.
|
19
19
|
#
|
20
20
|
# The match on "/" is protected, _first_ by the OpenID strategy,
|
21
21
|
# then by the dfeeault set of stratgies. Strategies are applied from the
|
@@ -30,7 +30,7 @@ Merb::Router.extensions do
|
|
30
30
|
else
|
31
31
|
result = request.session.authenticate!(request, params, *strategies)
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
if request.session.authentication.halted?
|
35
35
|
auth = request.session.authentication
|
36
36
|
[auth.status, auth.headers, auth.body]
|
@@ -41,5 +41,5 @@ Merb::Router.extensions do
|
|
41
41
|
end
|
42
42
|
defer(p, &block)
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
end
|
@@ -1,45 +1,45 @@
|
|
1
1
|
module Merb
|
2
2
|
module Session
|
3
|
-
|
3
|
+
|
4
4
|
# Access to the authentication object directly. Particularly useful
|
5
5
|
# for accessing the errors.
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# === Example
|
8
8
|
#
|
9
9
|
# <%= error_messages_for session.authentication %>
|
10
|
-
#
|
10
|
+
#
|
11
11
|
def authentication
|
12
12
|
@authentication ||= Merb::Authentication.new(self)
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
# Check to see if the current session is authenticated
|
16
16
|
# @return true if authenticated. false otherwise
|
17
17
|
def authenticated?
|
18
18
|
authentication.authenticated?
|
19
19
|
end
|
20
|
-
|
21
|
-
# Authenticates the session via the authentication object.
|
20
|
+
|
21
|
+
# Authenticates the session via the authentication object.
|
22
22
|
#
|
23
23
|
# See Merb::Authentication#authenticate for usage
|
24
24
|
def authenticate!(request, params, *rest)
|
25
25
|
authentication.authenticate!(request, params, *rest)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
# Provides access to the currently authenticated user.
|
29
29
|
def user
|
30
30
|
authentication.user
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# set the currently authenticated user manually
|
34
34
|
# Merb::Authentication#store_user should know how to store the object into the session
|
35
35
|
def user=(the_user)
|
36
36
|
authentication.user = the_user
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
# Remove the user from the session and clear all data.
|
40
40
|
def abandon!
|
41
41
|
authentication.abandon!
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
end # Session
|
45
45
|
end # Merb
|