authlane 1.2.0 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e1d5209e59fc6178372d91056feaa7f88db1c320
4
- data.tar.gz: 03b19e3f8ccffee0f4d3452f4eb4a398f94c9913
3
+ metadata.gz: 60d5057e5de15303320296fc4968ee7e2e4599b1
4
+ data.tar.gz: 37bcce0af17f5e6061c380d622de64648f4fce9a
5
5
  SHA512:
6
- metadata.gz: 62780ea9f8bf9756688a915d84718f2da5326c042467e3fa4cca395b77e6d6fad7ec6cb132237b1e6a23240e19cd5e6f9284924eaee22fff75c94cb63a5719bd
7
- data.tar.gz: 52c700e8b936048bdd8c8c2d992b20527226dc52301e1579be95b1a34b025496d2f59d23ce1f698a7e08f47f99464debdcd68b511c98d2cf731df5f174d1494a
6
+ metadata.gz: f7e5575bfdf4a157890f5653c1ef53b8d3d5843ff068fe7ed48d6863da4613e6208102ebc22d958062b5c8019cb842a35614f45b53bc971a7e488699032e59e2
7
+ data.tar.gz: e5bc08034ee0ffe129238e1d04c3df7c13ef0cb0688b0b644536385d75e558baf9bac0314172bff973c2208c4cef17e95e5f790882e28d4df53e747a50ab0e5f
data/README.md CHANGED
@@ -4,11 +4,24 @@ The **AuthLane** Sinatra Extension allows easy User authentication with support
4
4
 
5
5
  The actual authentication logic (*strategy*) is defined by the Application using a namespaced DSL provided by this extension, while the general Extension configuration is handled with Sinatra's `set` method, which will be described in more detail below.
6
6
 
7
- ## Setting up *Sinatra*
7
+ ## Installation
8
8
 
9
- **AuthLane** utilizes the standard Sinatra Extension format for *classic*-style applications:
9
+ Get the Gem:
10
10
 
11
11
  ```
12
+ gem install authlane
13
+ ```
14
+
15
+ Or let Bundler do the work:
16
+
17
+ ``` ruby
18
+ # Gemfile
19
+ gem 'authlane'
20
+ ```
21
+
22
+ **AuthLane** utilizes the standard Sinatra Extension format for *classic*-style applications:
23
+
24
+ ``` ruby
12
25
  require 'sinatra'
13
26
  require 'sinatra/authlane'
14
27
 
@@ -21,7 +34,7 @@ end
21
34
 
22
35
  As well as `modular`-style applications:
23
36
 
24
- ```
37
+ ``` ruby
25
38
  require 'sinatra/base'
26
39
  require 'sinatra/cookies'
27
40
  require 'sinatra/authlane'
@@ -33,28 +46,22 @@ class App < Sinatra::Base
33
46
  get '/user' do
34
47
  protect!
35
48
 
36
- # Application stuff for signed in users ....
49
+ # Application stuff for signed in users
37
50
  end
38
51
  end
39
- ```
40
-
41
- Both setups however require a separate **Session** *Rack middleware*, like `Rack::Session::Cookies`, which you need to provide for your *Sinatra* application (refer to [Sinatra's documentation](http://www.sinatrarb.com/intro.html#Using%20Sessions) on using Sessions).
42
-
43
- > **Note:** The inclusion of `sinatra/cookies` helper methods is a requirement by *AuthLane*, which currently it - at least when used modular - does not do automatically.
44
-
45
- ## Configuring *AuthLane*
52
+ ```
46
53
 
47
- ### General configuration values
54
+ ## Configuration
48
55
 
49
56
  **AuthLane**'s configuration data is available under Sinatra's `settings` object with the key `:authlane` as a Hash, so changing config values is simply done with Sinatra's `set` method.
50
57
 
51
- ```
58
+ ``` ruby
52
59
  set :authlane, :failed_route => '/login'
53
60
  ```
54
61
 
55
62
  The following settings can be customize (the used values are their defaults):
56
63
 
57
- ```
64
+ ``` ruby
58
65
  set :authlane, :failed_route => '/user/unauthorized',
59
66
  :session_key => :authlane,
60
67
  :remember_cookie => :authlane_token,
@@ -75,4 +82,24 @@ Customize the Cookie's name that stores the token hash used for the *Remember Me
75
82
 
76
83
  #### `:serialize_user`
77
84
 
78
- The `:serialized_user` settings contains an Array of Symbols telling AuthLane which attributes of the User model that is used to identify Application users should be serialized into `SerializedUser`. It is recommended to not store the whole User object, but note that the *id* (or however the unique identifier of the object is named) attribute is required.
85
+ The `:serialized_user` settings contains an Array of Symbols telling AuthLane which attributes of the User model that is used to identify Application users should be serialized into a `SerializedUser` object. It is recommended to not store the whole User object, but note that the *id* (or however the unique identifier of the object is named) attribute is required.
86
+
87
+ Alternatively, you can specify your own Class to be used.
88
+
89
+ ``` ruby
90
+ set :authlane, :serialize_user => CustomUser
91
+ ```
92
+
93
+ The `CustomUser`'s `initialize` method receives one argument, which is the User object. What that object is exactly depends on your **Auth strategy** implementation. Basically, it's the User data coming from your application's persisting backend, like a database.
94
+
95
+ ``` ruby
96
+ class CustomUser
97
+ attr_reader :id
98
+
99
+ def initialize(user)
100
+ @id = user.id
101
+ end
102
+ end
103
+ ```
104
+
105
+ It is possible to have attribute accessors in your custom Class, but beware that **AuthLane** will *not* save changes back to your backend.
@@ -8,7 +8,8 @@ module Sinatra
8
8
  #
9
9
  module Helpers
10
10
  ##
11
- # @note This method uses {#authorized?} to decide, whether to redirect users to `failed_route`.
11
+ # @note This method uses {#authorized?} to decide, whether to redirect users to your app's `failed_route`.
12
+ #
12
13
  # Check if a user is authorized to view a route.
13
14
  #
14
15
  # It utilizes the *Role* and *Remember Strategy* to see if a user can access the route this
@@ -33,17 +34,16 @@ module Sinatra
33
34
  # mustache :admin
34
35
  # end
35
36
  #
36
- # @param [Array] roles A list of role/privilege requirements for a route, set to `nil` to ignore user roles
37
- # @param [String] failed_route Custom route to redirect to in case the user is not authorized
37
+ # @param [Hash] roles A Hash specifying the **Role Strategy** to be used with its key and optional arguments as the value.
38
+ # **Example:** `protect! :rolename => arguments`
39
+ #
40
+ # @return [void]
38
41
  #
39
42
  # @see Sinatra::AuthLane.create_role_strategy create_role_strategy
40
43
  # @see Sinatra::AuthLane.create_remember_strategy create_remember_strategy
41
44
  #
42
- def protect!(roles: nil, failed_route: nil)
43
- # check for custom :failed_route option
44
- failed_route ||= settings.authlane[:failed_route]
45
-
46
- redirect failed_route unless authorized?(roles: roles)
45
+ def protect!(*roles)
46
+ redirect settings.authlane[:failed_route] unless authorized?(*roles)
47
47
  end
48
48
 
49
49
  alias_method :protected, :protect!
@@ -64,22 +64,23 @@ module Sinatra
64
64
  # end
65
65
  # end
66
66
  #
67
- # @param [Array] roles A list of role/privilege requirements for a route, set to `nil` to ignore user roles
67
+ # @param [Hash] roles A Hash specifying the **Role Strategy** to be used with its key and optional arguments as the value.
68
+ # **Example:** `protect! :rolename => arguments`
68
69
  #
69
70
  # @return [Boolean] `true` if the user is authorized to view a route, `false` otherwise.
70
71
  #
71
72
  # @see Sinatra::AuthLane::Helpers#protect! protect!
72
73
  #
73
- def authorized?(roles: nil)
74
+ def authorized?(*roles)
74
75
  # So, if session[settings.authlane[:session_key]] is available
75
76
  # we're home, otherwise, see if the 'Remember Me' strategy
76
77
  # can come up with some User credentials.
77
78
  if session[settings.authlane[:session_key]].nil?
78
79
  remember_token = cookies[settings.authlane[:remember_cookie]]
79
- remember_strat = self.instance_exec(remember_token, &settings.authlane[:remember_strategy])
80
+ remember_strat = (remember_token.nil?) ? false : self.instance_exec(remember_token, &settings.authlane[:remember_strategy])
80
81
 
81
82
  if remember_strat
82
- user = Sinatra::AuthLane::SerializedUser.new(remember_strat, settings.authlane[:serialize_user])
83
+ user = serialize_user(remember_strat)
83
84
 
84
85
  # The strategy doesn't log in a User,
85
86
  # it just comes up with the credentials to do that.
@@ -95,11 +96,19 @@ module Sinatra
95
96
  return false
96
97
  else
97
98
  # User is logged in ...
98
- unless roles.nil?
99
+ if roles.size == 1
99
100
  # ... but hold up, he might not have the necessary
100
101
  # privileges to access this particular route.
101
102
  # Let's ask the 'Role' strategy.
102
- strat = self.instance_exec roles, &settings.authlane[:role_strategy]
103
+ if roles.first.is_a? Hash
104
+ role_name = roles.first.keys.first
105
+ role_args = roles.first[role_name]
106
+ else
107
+ role_name = roles.first
108
+ role_args = nil
109
+ end
110
+
111
+ strat = self.instance_exec role_args, &settings.authlane[:role_strategy][role_name]
103
112
  return false unless strat
104
113
  end
105
114
  end
@@ -139,7 +148,7 @@ module Sinatra
139
148
  redirect settings.authlane[:failed_route], 303
140
149
  end
141
150
 
142
- session[settings.authlane[:session_key]] = Sinatra::AuthLane::SerializedUser.new(strat, settings.authlane[:serialize_user])
151
+ session[settings.authlane[:session_key]] = serialize_user(strat)
143
152
  end
144
153
 
145
154
  ##
@@ -182,11 +191,24 @@ module Sinatra
182
191
  # mustache :account
183
192
  # end
184
193
  #
185
- # @return [SerializedUser] the user data serialized into the Session.
194
+ # @return [SerializedUser, Object] the user data serialized into the Session, either as `SerializedUser`
195
+ # or a custom class set by the developer.
186
196
  #
187
197
  def current_user
188
198
  session[settings.authlane[:session_key]]
189
199
  end
200
+
201
+ private
202
+
203
+ ##
204
+ #
205
+ def serialize_user(obj)
206
+ if settings.authlane[:serialize_user].is_a? Array
207
+ Sinatra::AuthLane::SerializedUser.new(obj, settings.authlane[:serialize_user])
208
+ elsif settings.authlane[:serialize_user].is_a? Class
209
+ settings.authlane[:serialize_user].new(obj)
210
+ end
211
+ end
190
212
  end
191
213
  end
192
214
  end
@@ -45,6 +45,14 @@ module Sinatra
45
45
  (@user.is_a? Hash) ? @user[a] : @user.__send__(a.to_sym)
46
46
  end
47
47
 
48
+ ##
49
+ #
50
+ #
51
+ def []=(key, value)
52
+ return if key.to_s == 'id'
53
+ (@user.is_a? Hash) ? @user[key] = value : @user.__send__(key.to_sym, value)
54
+ end
55
+
48
56
  ##
49
57
  # Enables Object-like access to the
50
58
  # stored attributes.
@@ -58,9 +66,13 @@ module Sinatra
58
66
  #
59
67
  def method_missing(m, *args, &block)
60
68
  if @user.is_a? Hash
61
- @user[m]
69
+ if m.to_s.index('=').nil?
70
+ @user[m]
71
+ elsif m.to_s.index('id').nil?
72
+ @user[m] = args[1]
73
+ end
62
74
  else
63
- @user.__send__(m.to_sym, args)
75
+ @user.__send__(m, args)
64
76
  end
65
77
  end
66
78
 
@@ -2,5 +2,5 @@
2
2
  module Authlane
3
3
  ##
4
4
  # Current AuthLane version number.
5
- VERSION = '1.2.0'
5
+ VERSION = '1.3.0'
6
6
  end
@@ -86,10 +86,11 @@ module Sinatra
86
86
  :session_key => :authlane, # name of the Session key to store the login data
87
87
  :remember_cookie => :'authlane.token', # Cookie name to store 'Remember Me' token
88
88
  :auth_strategy => Proc.new { false }, # strategy to be executed to log in users
89
- :role_strategy => Proc.new { true }, # strategy to be executed to check permissions and roles
89
+ :role_strategy => { roles: Proc.new { true } }, # strategy to be executed to check permissions and roles
90
90
  :remember_strategy => Proc.new { false }, # strategy to be executed to log in users via 'Remember Me' token
91
91
  :forget_strategy => Proc.new { false }, # strategy to be executed when logging out and 'forgetting' the user
92
92
  :serialize_user => [:id] # specify User model fields to be serialized into the login session
93
+ # or define a custom class which receives the whole User model to handle by itself
93
94
  end
94
95
 
95
96
  class << self
@@ -100,14 +101,12 @@ module Sinatra
100
101
  # to be used by passing the implementation as a Code block. It is then
101
102
  # stored as a `Proc` object and will be called by AuthLane when needed.
102
103
  #
103
- # The following describes the `Proc` objects API requirements. It is
104
- # required by the implemented strategy to follow these to be usable by AuthLane.
104
+ # To see the code block's objects API requirements, refer to the {https://github.com/zidizei/authlane/wiki Wiki}.
105
105
  #
106
106
  # @note While the **Auth** Strategy is primarily responsible for logging in users,
107
107
  # it usually needs to implement some *Remember Me* logic as well.
108
108
  #
109
- # @return [False, Object] The strategy needs to return the User Model object of
110
- # the user that successfully logged in or - in case of failure - `false`.
109
+ # @return [Proc] the `Proc` object of the strategy.
111
110
  #
112
111
  # @example
113
112
  # Sinatra::AuthLane.create_auth_strategy do
@@ -121,7 +120,10 @@ module Sinatra
121
120
  # @api AuthLane
122
121
  #
123
122
  def create_auth_strategy
124
- @app.set :authlane, :auth_strategy => Proc.new
123
+ strat = Proc.new
124
+
125
+ @app.set :authlane, :auth_strategy => strat
126
+ strat
125
127
  end
126
128
 
127
129
  ##
@@ -131,8 +133,7 @@ module Sinatra
131
133
  # to be used by passing the implementation as a Code block. It is then
132
134
  # stored as a `Proc` object and will be called by AuthLane when needed.
133
135
  #
134
- # The following describes the `Proc` objects API requirements. It is
135
- # required by the implemented strategy to follow these to be usable by AuthLane.
136
+ # To see the code block's API requirements, refer to the {https://github.com/zidizei/authlane/wiki Wiki}.
136
137
  #
137
138
  # @example
138
139
  # Sinatra::AuthLane.create_role_strategy do |roles|
@@ -141,18 +142,19 @@ module Sinatra
141
142
  # roles.include? user.role # See if the list of role names in `roles` contains the user's role
142
143
  # end
143
144
  #
144
- # @param [Array] roles The `Proc` receives a list of role names (e.g. as Symbols) a User needs to fullfill
145
- # to be allowed to see the route. The list is passed by the {Sinatra::AuthLane::Helpers#authorized? authorized?}
146
- # helper.
145
+ # @param [Symbol] name The name of the role strategy.
147
146
  #
148
- # @return [Boolean] The strategy returns `true`, if the user met the necessary role requirements or `false` otherwise.
147
+ # @return [Proc] the `Proc` object of the strategy.
149
148
  #
150
149
  # @see Sinatra::AuthLane::Helpers#authorized? authorized?
151
150
  #
152
151
  # @api AuthLane
153
152
  #
154
- def create_role_strategy
155
- @app.set :authlane, :role_strategy => Proc.new
153
+ def create_role_strategy(name = :roles)
154
+ strat = Proc.new
155
+
156
+ @app.settings.authlane[:role_strategy][name] = strat
157
+ strat
156
158
  end
157
159
 
158
160
  ##
@@ -162,8 +164,7 @@ module Sinatra
162
164
  # to be used by passing the implementation as a Code block. It is then
163
165
  # stored as a `Proc` object and will be called by AuthLane when needed.
164
166
  #
165
- # The following describes the `Proc` objects API requirements. It is
166
- # required by the implemented strategy to follow these to be usable by AuthLane.
167
+ # To see the code block's API requirements, refer to the {https://github.com/zidizei/authlane/wiki Wiki}.
167
168
  #
168
169
  # @note The **Remember** Strategy is only responsible for automatically logging in a user.
169
170
  # The necessary Cookie token (plus any additional logic) is usually set in the **Auth** Strategy.
@@ -175,15 +176,17 @@ module Sinatra
175
176
  # (remembered_user.nil?) ? false : remembered_user
176
177
  # end
177
178
  #
178
- # @return [False, Object] The strategy needs to return the User Model object of
179
- # the user that successfully logged in or - in case of failure - `false`.
179
+ # @return [Proc] the `Proc` object of the strategy.
180
180
  #
181
181
  # @see Sinatra::AuthLane::Helpers#authorized? authorized?
182
182
  #
183
183
  # @api AuthLane
184
184
  #
185
185
  def create_remember_strategy
186
- @app.set :authlane, :remember_strategy => Proc.new
186
+ strat = Proc.new
187
+
188
+ @app.set :authlane, :remember_strategy => strat
189
+ strat
187
190
  end
188
191
 
189
192
  ##
@@ -193,13 +196,12 @@ module Sinatra
193
196
  # to be used by passing the implementation as a Code block. It is then
194
197
  # stored as a `Proc` object and will be called by AuthLane when needed.
195
198
  #
196
- # The following describes the `Proc` objects API requirements. It is
197
- # required by the implemented strategy to follow these to be usable by AuthLane.
199
+ # To see the code block's API requirements, refer to the {https://github.com/zidizei/authlane/wiki Wiki}.
198
200
  #
199
201
  # @note The **Forget** Strategy is the counter-part to the **Remember** Strategy.
200
202
  # It's responsible for disabling the auto login technique and is called when logging out.
201
203
  #
202
- # @note While the *Auth* and *Remember Strategy* needs to interact with the Cookie token directly,
204
+ # @note While the *Auth Strategy* needs to interact with the Cookie token directly,
203
205
  # the *Forget Strategy* does not need to implement the deletion of the Cookie.
204
206
  # This is done automatically by AuthLane behind the scenes.
205
207
  #
@@ -209,16 +211,17 @@ module Sinatra
209
211
  # user.token = nil if user.token == token
210
212
  # end
211
213
  #
212
- # @param [Object] token The `Proc` object receives the *Remember Me* token of the current user.
213
- #
214
214
  # @see Sinatra::AuthLane::Helpers#unauthorize! unauthorize!
215
215
  #
216
- # @return [void]
216
+ # @return [Proc] the `Proc` object of the strategy.
217
217
  #
218
218
  # @api AuthLane
219
219
  #
220
220
  def create_forget_strategy
221
- @app.set :authlane, :forget_strategy => Proc.new
221
+ strat = Proc.new
222
+
223
+ @app.set :authlane, :forget_strategy => strat
224
+ strat
222
225
  end
223
226
  end
224
227
  end
@@ -10,9 +10,19 @@ describe Sinatra::AuthLane::Helpers do
10
10
 
11
11
  use Rack::Session::Cookie, :secret => 'rspec'
12
12
 
13
+ set :authlane, :serialize_user => [:id, :rank]
14
+
13
15
  Sinatra::AuthLane.create_auth_strategy do
14
16
  cookies[:'authlane.token'] = 'rspec'
15
- { id: '1' }
17
+ { id: '1', rank: 1 }
18
+ end
19
+
20
+ Sinatra::AuthLane.create_role_strategy do |ranks|
21
+ current_user[:rank] == ((ranks.nil?) ? 1 : ranks)
22
+ end
23
+
24
+ Sinatra::AuthLane.create_role_strategy(:roles2) do |ranks|
25
+ current_user[:rank] == ((ranks.nil?) ? 2 : ranks)
16
26
  end
17
27
 
18
28
  get '/protected' do
@@ -32,6 +42,22 @@ describe Sinatra::AuthLane::Helpers do
32
42
  protect!
33
43
  end
34
44
 
45
+ get '/role1' do
46
+ protect! :roles
47
+ end
48
+
49
+ get '/role1a' do
50
+ protect! :roles => 2
51
+ end
52
+
53
+ get '/role2' do
54
+ protect! :roles2
55
+ end
56
+
57
+ get '/role2a' do
58
+ protect! :roles2 => 1
59
+ end
60
+
35
61
  get '/unauthorize' do
36
62
  unauthorize!
37
63
  protect!
@@ -106,4 +132,28 @@ describe Sinatra::AuthLane::Helpers do
106
132
  get '/user'#, {}, { 'rack.session' => { authlane: '1' } }
107
133
  expect(last_response.body).to eq('1')
108
134
  end
135
+
136
+ it "should be able to use role strategy" do
137
+ get '/authorize'
138
+ get '/role1'
139
+ last_response.should be_ok
140
+ end
141
+
142
+ it "should be able to use role strategy with arguments" do
143
+ get '/authorize'
144
+ get '/role1a'
145
+ expect(last_response.headers['location']).to eq('http://example.org/user/unauthorized')
146
+ end
147
+
148
+ it "should be able to use named role strategy" do
149
+ get '/authorize'
150
+ get '/role2'
151
+ expect(last_response.headers['location']).to eq('http://example.org/user/unauthorized')
152
+ end
153
+
154
+ it "should be able to use named role strategy with arguments" do
155
+ get '/authorize'
156
+ get '/role2a'
157
+ last_response.should be_ok
158
+ end
109
159
  end
@@ -53,4 +53,27 @@ describe Sinatra::AuthLane::SerializedUser do
53
53
  user[:id].should eql(1)
54
54
  user[:name].should be(nil)
55
55
  end
56
+
57
+ it 'can change specific attributes after initialization from an Object' do
58
+ user = Sinatra::AuthLane::SerializedUser.new(MockUser.new, [:id])
59
+ user[:id].should eql(1)
60
+ user[:name].should be(nil)
61
+ user[:name] = 'Rspec'
62
+ user[:name].should eql('Rspec')
63
+ end
64
+
65
+ it 'can change specific attributes after initialization from a Hash' do
66
+ user = Sinatra::AuthLane::SerializedUser.new({ id: 1, name: nil }, [:id])
67
+ user[:id].should eql(1)
68
+ user[:name].should be(nil)
69
+ user[:name] = 'Rspec'
70
+ user[:name].should eql('Rspec')
71
+ end
72
+
73
+ it 'can not change id attribute after initialization' do
74
+ user = Sinatra::AuthLane::SerializedUser.new(MockUser.new, [:id])
75
+ user[:id].should eql(1)
76
+ user[:id] = 2
77
+ user[:id].should eql(1)
78
+ end
56
79
  end
@@ -1,16 +1,41 @@
1
1
  require File.expand_path '../spec_helper.rb', __FILE__
2
2
 
3
3
  describe Sinatra::AuthLane do
4
- def strategy(type, &block)
4
+ def create_auth_strategy(&block)
5
5
  mock_app do
6
6
  register Sinatra::AuthLane
7
7
 
8
- Sinatra::AuthLane.send "create_#{type}_strategy", &block
8
+ Sinatra::AuthLane.create_auth_strategy &block
9
9
  end
10
10
  end
11
11
 
12
+ def create_role_strategy(name = :roles, &block)
13
+ mock_app do
14
+ register Sinatra::AuthLane
15
+
16
+ Sinatra::AuthLane.create_role_strategy(name, &block)
17
+ end
18
+ end
19
+
20
+ def create_remember_strategy(&block)
21
+ mock_app do
22
+ register Sinatra::AuthLane
23
+
24
+ Sinatra::AuthLane.create_remember_strategy &block
25
+ end
26
+ end
27
+
28
+ def create_forget_strategy(&block)
29
+ mock_app do
30
+ register Sinatra::AuthLane
31
+
32
+ Sinatra::AuthLane.create_forget_strategy &block
33
+ end
34
+ end
35
+
36
+
12
37
  it "should allow definition of auth strategy" do
13
- strategy(:auth) do
38
+ create_auth_strategy do
14
39
  'rspec'
15
40
  end
16
41
 
@@ -18,15 +43,23 @@ describe Sinatra::AuthLane do
18
43
  end
19
44
 
20
45
  it "should allow definition of role strategy" do
21
- strategy(:role) do
46
+ create_role_strategy do
22
47
  'rspec'
23
48
  end
24
49
 
25
- settings.authlane[:role_strategy].yield.should == 'rspec'
50
+ settings.authlane[:role_strategy][:roles].yield.should == 'rspec'
51
+ end
52
+
53
+ it "should allow definition of named role strategies" do
54
+ create_role_strategy(:rspec1) do
55
+ 'rspec1'
56
+ end
57
+
58
+ settings.authlane[:role_strategy][:rspec1].yield.should == 'rspec1'
26
59
  end
27
60
 
28
61
  it "should allow definition of remember strategy" do
29
- strategy(:remember) do
62
+ create_remember_strategy do
30
63
  'rspec'
31
64
  end
32
65
 
@@ -34,7 +67,7 @@ describe Sinatra::AuthLane do
34
67
  end
35
68
 
36
69
  it "should allow definition of forget strategy" do
37
- strategy(:forget) do
70
+ create_forget_strategy do
38
71
  'rspec'
39
72
  end
40
73
 
@@ -0,0 +1,52 @@
1
+ require File.expand_path '../spec_helper.rb', __FILE__
2
+
3
+ describe Sinatra::AuthLane do
4
+ class Serialized
5
+ attr_reader :id
6
+
7
+ def initialize(user)
8
+ serialize(user)
9
+ end
10
+
11
+ def serialize(user)
12
+ @id = user[:id]
13
+ end
14
+ end
15
+
16
+ before :all do
17
+ build_rack_test_session 'rspec'
18
+
19
+ mock_app do
20
+ helpers Sinatra::Cookies
21
+ register Sinatra::AuthLane
22
+
23
+ use Rack::Session::Cookie, :secret => 'rspec'
24
+
25
+ set :authlane, serialize_user: Serialized
26
+
27
+ Sinatra::AuthLane.create_auth_strategy do
28
+ cookies[:'authlane.token'] = 'rspec'
29
+ { id: '1', name: 'rspec' }
30
+ end
31
+
32
+ get '/authorize' do
33
+ authorize!
34
+ protect!
35
+ end
36
+ end
37
+ end
38
+
39
+ before :each do
40
+ clear_cookies
41
+ end
42
+
43
+ def current_user
44
+ Marshal.load(rack_mock_session.cookie_jar['rack.session'].unpack('m*').first)
45
+ end
46
+
47
+ it 'uses custom SerializedUser class instead of the built-in one when specified' do
48
+ get '/authorize'
49
+ last_response.should be_ok
50
+ expect(current_user['authlane']).to be_a Serialized
51
+ end
52
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Lam
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-12 00:00:00.000000000 Z
11
+ date: 2015-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -117,6 +117,7 @@ files:
117
117
  - spec/authlane_helper_spec.rb
118
118
  - spec/authlane_serializeduser_spec.rb
119
119
  - spec/sinatra_authlane_spec.rb
120
+ - spec/sinatra_custom_serializeduser_spec.rb
120
121
  - spec/spec_helper.rb
121
122
  homepage:
122
123
  licenses:
@@ -138,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
139
  version: '0'
139
140
  requirements: []
140
141
  rubyforge_project:
141
- rubygems_version: 2.4.5
142
+ rubygems_version: 2.4.1
142
143
  signing_key:
143
144
  specification_version: 4
144
145
  summary: Simple User authentication and roles for Sinatra.
@@ -146,5 +147,6 @@ test_files:
146
147
  - spec/authlane_helper_spec.rb
147
148
  - spec/authlane_serializeduser_spec.rb
148
149
  - spec/sinatra_authlane_spec.rb
150
+ - spec/sinatra_custom_serializeduser_spec.rb
149
151
  - spec/spec_helper.rb
150
152
  has_rdoc: