authlane 1.0.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +51 -11
- data/authlane.gemspec +8 -4
- data/lib/authlane/helper.rb +2 -1
- data/lib/authlane/serializeduser.rb +20 -3
- data/lib/authlane/version.rb +1 -1
- data/lib/sinatra/authlane.rb +5 -6
- data/spec/authlane_helper_spec.rb +44 -12
- data/spec/authlane_serializeduser_spec.rb +26 -8
- data/spec/sinatra_authlane_spec.rb +1 -1
- data/spec/{helper.rb → spec_helper.rb} +0 -0
- metadata +15 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1d5209e59fc6178372d91056feaa7f88db1c320
|
4
|
+
data.tar.gz: 03b19e3f8ccffee0f4d3452f4eb4a398f94c9913
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62780ea9f8bf9756688a915d84718f2da5326c042467e3fa4cca395b77e6d6fad7ec6cb132237b1e6a23240e19cd5e6f9284924eaee22fff75c94cb63a5719bd
|
7
|
+
data.tar.gz: 52c700e8b936048bdd8c8c2d992b20527226dc52301e1579be95b1a34b025496d2f59d23ce1f698a7e08f47f99464debdcd68b511c98d2cf731df5f174d1494a
|
data/README.md
CHANGED
@@ -4,7 +4,47 @@ 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
|
-
|
7
|
+
## Setting up *Sinatra*
|
8
|
+
|
9
|
+
**AuthLane** utilizes the standard Sinatra Extension format for *classic*-style applications:
|
10
|
+
|
11
|
+
```
|
12
|
+
require 'sinatra'
|
13
|
+
require 'sinatra/authlane'
|
14
|
+
|
15
|
+
get '/user' do
|
16
|
+
protect!
|
17
|
+
|
18
|
+
# Application stuff for signed in users ....
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
As well as `modular`-style applications:
|
23
|
+
|
24
|
+
```
|
25
|
+
require 'sinatra/base'
|
26
|
+
require 'sinatra/cookies'
|
27
|
+
require 'sinatra/authlane'
|
28
|
+
|
29
|
+
class App < Sinatra::Base
|
30
|
+
register Sinatra::AuthLane
|
31
|
+
helpers Sinatra::Cookies
|
32
|
+
|
33
|
+
get '/user' do
|
34
|
+
protect!
|
35
|
+
|
36
|
+
# Application stuff for signed in users ....
|
37
|
+
end
|
38
|
+
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*
|
46
|
+
|
47
|
+
### General configuration values
|
8
48
|
|
9
49
|
**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.
|
10
50
|
|
@@ -16,23 +56,23 @@ The following settings can be customize (the used values are their defaults):
|
|
16
56
|
|
17
57
|
```
|
18
58
|
set :authlane, :failed_route => '/user/unauthorized',
|
19
|
-
|
20
|
-
|
21
|
-
|
59
|
+
:session_key => :authlane,
|
60
|
+
:remember_cookie => :authlane_token,
|
61
|
+
:serialize_user => [:id]
|
22
62
|
```
|
23
63
|
|
24
|
-
|
64
|
+
#### `:failed_route`
|
25
65
|
|
26
|
-
The `:failed_route` sets the route String, where AuthLane should redirect to in case a route requires
|
66
|
+
The `:failed_route` sets the route String, where AuthLane should redirect to in case a route requires authorization and the User is not logged in. It typically is the route to display the login form, but can be set to anything that is needed, as long the it is not protected by authorization as well.
|
27
67
|
|
28
|
-
|
68
|
+
#### `:session_key`
|
29
69
|
|
30
70
|
The `:session_key` sets the name (as a Symbol) of the Session variable where User credentials of a logged in User are stored. The stored User data are wrapped inside a `SerializedUser` object and can be retrieved by using Sinatra's `session` helper and giving it the key that is defined here `session[:authlane]`. Alternatively, the AuthLane Helper exposes the method `current_user` to provide easy access to User data.
|
31
71
|
|
32
|
-
|
72
|
+
#### `:remember_cookie`
|
33
73
|
|
34
|
-
Customize the Cookie's name that stores the token hash used for the *Remember Me* functionality. The setting (and creation) of the token needs to be implemented by the Extension user in both the
|
74
|
+
Customize the Cookie's name that stores the token hash used for the *Remember Me* functionality. The setting (and creation) of the token needs to be implemented by the Extension user in both the *auth* and *remember* strategy.
|
35
75
|
|
36
|
-
|
76
|
+
#### `:serialize_user`
|
37
77
|
|
38
|
-
The `:serialized_user` settings contains an Array of Symbols telling AuthLane which attributes of the User model that is used to identify Application
|
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.
|
data/authlane.gemspec
CHANGED
@@ -8,9 +8,11 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Authlane::VERSION
|
9
9
|
spec.authors = ['Patrick Lam']
|
10
10
|
spec.email = ['zidizei@gmail.com']
|
11
|
-
spec.summary = '
|
12
|
-
spec.description =
|
13
|
-
|
11
|
+
spec.summary = 'Simple User authentication and roles for Sinatra.'
|
12
|
+
spec.description = <<-EOF
|
13
|
+
The AuthLane Sinatra Extension allows simple User authentication with support
|
14
|
+
for different User roles. It comes with Sinatra helpers for easy integration into routes.
|
15
|
+
EOF
|
14
16
|
spec.license = 'MIT'
|
15
17
|
|
16
18
|
spec.files = `git ls-files -z`.split("\x0")
|
@@ -18,11 +20,13 @@ Gem::Specification.new do |spec|
|
|
18
20
|
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
19
21
|
spec.require_paths = ['lib']
|
20
22
|
|
23
|
+
spec.required_ruby_version = '>= 2.0.0'
|
24
|
+
|
21
25
|
spec.add_dependency 'sinatra'
|
22
26
|
spec.add_dependency 'sinatra-contrib'
|
23
27
|
|
24
28
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
25
29
|
spec.add_development_dependency 'rake', '~> 10.1'
|
26
30
|
spec.add_development_dependency 'rspec', '~> 2.6'
|
27
|
-
spec.add_development_dependency 'yard'
|
31
|
+
spec.add_development_dependency 'yard', '~> 0.8'
|
28
32
|
end
|
data/lib/authlane/helper.rb
CHANGED
@@ -75,7 +75,8 @@ module Sinatra
|
|
75
75
|
# we're home, otherwise, see if the 'Remember Me' strategy
|
76
76
|
# can come up with some User credentials.
|
77
77
|
if session[settings.authlane[:session_key]].nil?
|
78
|
-
|
78
|
+
remember_token = cookies[settings.authlane[:remember_cookie]]
|
79
|
+
remember_strat = self.instance_exec(remember_token, &settings.authlane[:remember_strategy])
|
79
80
|
|
80
81
|
if remember_strat
|
81
82
|
user = Sinatra::AuthLane::SerializedUser.new(remember_strat, settings.authlane[:serialize_user])
|
@@ -24,7 +24,11 @@ module Sinatra
|
|
24
24
|
@user = Hash.new
|
25
25
|
|
26
26
|
attributes.each do |attrs|
|
27
|
-
|
27
|
+
if user.respond_to? attrs
|
28
|
+
@user[attrs] = user.__send__(attrs.to_sym)
|
29
|
+
elsif user.is_a?(Hash) and user.key? attrs
|
30
|
+
@user[attrs] = user[attrs]
|
31
|
+
end
|
28
32
|
end
|
29
33
|
end
|
30
34
|
end
|
@@ -63,7 +67,11 @@ module Sinatra
|
|
63
67
|
##
|
64
68
|
# Return a Hash representing the serialized object's attributes and values.
|
65
69
|
#
|
66
|
-
# If the whole Object was stored its `to_h` will be called.
|
70
|
+
# If the whole Object that was stored is a Hash itself, its `to_h` will be called.
|
71
|
+
# Otherwise, the Object's instance methods are called and mapped to a Hash. This is
|
72
|
+
# only the case when the passed user object is not a Hash and no specific **attributes**
|
73
|
+
# for storage are set (see {#initialize})
|
74
|
+
#
|
67
75
|
# In either case, attribute names can be accessed by Symbol or String
|
68
76
|
# key alike.
|
69
77
|
#
|
@@ -71,7 +79,16 @@ module Sinatra
|
|
71
79
|
#
|
72
80
|
def to_h
|
73
81
|
universal_hash = Hash.new
|
74
|
-
|
82
|
+
|
83
|
+
if @user.is_a? Hash
|
84
|
+
hash = @user.to_h
|
85
|
+
else
|
86
|
+
hash = {}
|
87
|
+
@user.class.instance_methods(false).each do |key|
|
88
|
+
hash[key] = @user.__send__ key
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
75
92
|
hash.each_pair do |key, value|
|
76
93
|
universal_hash[key.to_s] = value if key.is_a? Symbol
|
77
94
|
|
data/lib/authlane/version.rb
CHANGED
data/lib/sinatra/authlane.rb
CHANGED
@@ -42,7 +42,7 @@ module Sinatra
|
|
42
42
|
# to display the login form, but can be set to anything that is needed, as long the it is
|
43
43
|
# not protected by authorisation as well.
|
44
44
|
#
|
45
|
-
# ## `:
|
45
|
+
# ## `:session_key`
|
46
46
|
#
|
47
47
|
# The `:session_key` sets the name (as a Symbol) of the Session variable where User credentials of a logged in
|
48
48
|
# User are stored. The stored User data are wrapped inside a {Sinatra::AuthLane::SerializedUser SerializedUser}
|
@@ -84,7 +84,7 @@ module Sinatra
|
|
84
84
|
app.set :authlane,
|
85
85
|
:failed_route => '/user/unauthorized', # route to redirect to if the user is required to login
|
86
86
|
:session_key => :authlane, # name of the Session key to store the login data
|
87
|
-
:remember_cookie => :
|
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
89
|
:role_strategy => 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
|
@@ -166,12 +166,11 @@ module Sinatra
|
|
166
166
|
# required by the implemented strategy to follow these to be usable by AuthLane.
|
167
167
|
#
|
168
168
|
# @note The **Remember** Strategy is only responsible for automatically logging in a user.
|
169
|
-
# The necessary Cookie token (
|
169
|
+
# The necessary Cookie token (plus any additional logic) is usually set in the **Auth** Strategy.
|
170
170
|
#
|
171
171
|
# @example
|
172
|
-
# Sinatra::AuthLane.create_remember_strategy do
|
173
|
-
#
|
174
|
-
# remembered_user = User.find_by_token(remember_token)
|
172
|
+
# Sinatra::AuthLane.create_remember_strategy do |token|
|
173
|
+
# remembered_user = User.find_by_token(token)
|
175
174
|
#
|
176
175
|
# (remembered_user.nil?) ? false : remembered_user
|
177
176
|
# end
|
@@ -1,14 +1,19 @@
|
|
1
|
-
require File.expand_path '../
|
1
|
+
require File.expand_path '../spec_helper.rb', __FILE__
|
2
2
|
|
3
3
|
describe Sinatra::AuthLane::Helpers do
|
4
4
|
before :all do
|
5
|
+
build_rack_test_session 'rspec'
|
6
|
+
|
5
7
|
mock_app do
|
6
8
|
helpers Sinatra::Cookies
|
7
9
|
register Sinatra::AuthLane
|
8
10
|
|
9
11
|
use Rack::Session::Cookie, :secret => 'rspec'
|
10
12
|
|
11
|
-
Sinatra::AuthLane.create_auth_strategy
|
13
|
+
Sinatra::AuthLane.create_auth_strategy do
|
14
|
+
cookies[:'authlane.token'] = 'rspec'
|
15
|
+
{ id: '1' }
|
16
|
+
end
|
12
17
|
|
13
18
|
get '/protected' do
|
14
19
|
protect!
|
@@ -35,13 +40,30 @@ describe Sinatra::AuthLane::Helpers do
|
|
35
40
|
get '/user' do
|
36
41
|
protect!
|
37
42
|
user = current_user
|
38
|
-
user
|
43
|
+
user[:id]
|
39
44
|
end
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
48
|
+
before :each do
|
49
|
+
clear_cookies
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
it "should authorize a User" do
|
54
|
+
get '/authorize'
|
55
|
+
last_response.should be_ok
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should remember a User by setting the token cookie" do
|
59
|
+
expect(rack_mock_session.cookie_jar['authlane.token']).to be(nil)
|
60
|
+
get '/authorize'
|
61
|
+
expect(rack_mock_session.cookie_jar['authlane.token']).to eq('rspec')
|
62
|
+
end
|
63
|
+
|
43
64
|
it "should be able to recognize authorized states" do
|
44
|
-
get '/
|
65
|
+
get '/authorize'
|
66
|
+
get '/authorized'
|
45
67
|
expect(last_response.body).to eq('authorized')
|
46
68
|
end
|
47
69
|
|
@@ -55,23 +77,33 @@ describe Sinatra::AuthLane::Helpers do
|
|
55
77
|
expect(last_response.headers['location']).to eq('http://example.org/user/unauthorized')
|
56
78
|
end
|
57
79
|
|
58
|
-
it "should
|
59
|
-
get '/protected', {}, { 'rack.session' => { authlane: '1' } }
|
60
|
-
last_response.should be_ok
|
61
|
-
end
|
62
|
-
|
63
|
-
it "should authorize a User" do
|
80
|
+
it "should show protected route when logged in" do
|
64
81
|
get '/authorize'
|
82
|
+
get '/protected'
|
65
83
|
last_response.should be_ok
|
66
84
|
end
|
67
85
|
|
68
86
|
it "should unauthorize a User" do
|
69
|
-
get '/
|
87
|
+
get '/authorize'
|
88
|
+
get '/authorized'
|
89
|
+
expect(last_response.body).to eq('authorized')
|
90
|
+
get '/unauthorize'
|
70
91
|
expect(last_response.headers['location']).to eq('http://example.org/user/unauthorized')
|
92
|
+
get '/authorized'
|
93
|
+
expect(last_response.body).to eq('unauthorized')
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should forget a User's remember token" do
|
97
|
+
get '/authorize'
|
98
|
+
expect(rack_mock_session.cookie_jar['authlane.token']).to eq('rspec')
|
99
|
+
|
100
|
+
get '/unauthorize'
|
101
|
+
expect(rack_mock_session.cookie_jar['authlane.token']).to eq('')
|
71
102
|
end
|
72
103
|
|
73
104
|
it "should be able to get the current User's serialized credentials" do
|
74
|
-
get '/
|
105
|
+
get '/authorize'
|
106
|
+
get '/user'#, {}, { 'rack.session' => { authlane: '1' } }
|
75
107
|
expect(last_response.body).to eq('1')
|
76
108
|
end
|
77
109
|
end
|
@@ -1,38 +1,56 @@
|
|
1
|
-
require File.expand_path '../
|
1
|
+
require File.expand_path '../spec_helper.rb', __FILE__
|
2
2
|
|
3
3
|
describe Sinatra::AuthLane::SerializedUser do
|
4
|
-
|
5
|
-
|
4
|
+
class MockUser
|
5
|
+
def id
|
6
|
+
1
|
7
|
+
end
|
8
|
+
|
9
|
+
def name
|
10
|
+
'rspec'
|
11
|
+
end
|
6
12
|
end
|
7
13
|
|
8
14
|
it 'can be accessed like a Hash' do
|
9
|
-
user =
|
15
|
+
user = Sinatra::AuthLane::SerializedUser.new({ id: 1, name: 'rspec' })
|
10
16
|
user.should respond_to(:[])
|
11
17
|
user[:id].should eql(1)
|
12
18
|
user[:name].should eql('rspec')
|
13
19
|
end
|
14
20
|
|
15
21
|
it 'can be accessed like an Object' do
|
16
|
-
user =
|
22
|
+
user = Sinatra::AuthLane::SerializedUser.new({ id: 1, name: 'rspec' })
|
17
23
|
user.should respond_to(:method_missing)
|
18
24
|
user.id.should eql(1)
|
19
25
|
user.name.should eql('rspec')
|
20
26
|
end
|
21
27
|
|
22
28
|
it 'should return Hash of the serialized User object' do
|
23
|
-
user =
|
29
|
+
user = Sinatra::AuthLane::SerializedUser.new(MockUser.new)
|
24
30
|
user.to_h.should be_a(Hash)
|
25
31
|
end
|
26
32
|
|
27
33
|
it 'should return Hash of the serialized User object with String keys' do
|
28
|
-
user =
|
34
|
+
user = Sinatra::AuthLane::SerializedUser.new({ id: 1, name: 'rspec' }).to_h
|
29
35
|
user['id'].should eql(1)
|
30
36
|
user['name'].should eql('rspec')
|
31
37
|
end
|
32
38
|
|
33
39
|
it 'should return Hash of the serialized User object with Symbol keys' do
|
34
|
-
user =
|
40
|
+
user = Sinatra::AuthLane::SerializedUser.new({ id: 1, name: 'rspec' }).to_h
|
35
41
|
user[:id].should eql(1)
|
36
42
|
user[:name].should eql('rspec')
|
37
43
|
end
|
44
|
+
|
45
|
+
it 'can serialize specific attribute names from a Hash' do
|
46
|
+
user = Sinatra::AuthLane::SerializedUser.new({ id: 1, name: 'rspec' }, [:id])
|
47
|
+
user[:id].should eql(1)
|
48
|
+
user[:name].should be(nil)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'can serialize specific attribute names from an Object' do
|
52
|
+
user = Sinatra::AuthLane::SerializedUser.new(MockUser.new, [:id])
|
53
|
+
user[:id].should eql(1)
|
54
|
+
user[:name].should be(nil)
|
55
|
+
end
|
38
56
|
end
|
File without changes
|
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.
|
4
|
+
version: 1.2.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-
|
11
|
+
date: 2015-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -84,18 +84,19 @@ dependencies:
|
|
84
84
|
name: yard
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
89
|
+
version: '0.8'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
description:
|
98
|
-
|
96
|
+
version: '0.8'
|
97
|
+
description: |2
|
98
|
+
The AuthLane Sinatra Extension allows simple User authentication with support
|
99
|
+
for different User roles. It comes with Sinatra helpers for easy integration into routes.
|
99
100
|
email:
|
100
101
|
- zidizei@gmail.com
|
101
102
|
executables: []
|
@@ -115,9 +116,9 @@ files:
|
|
115
116
|
- lib/sinatra/authlane.rb
|
116
117
|
- spec/authlane_helper_spec.rb
|
117
118
|
- spec/authlane_serializeduser_spec.rb
|
118
|
-
- spec/helper.rb
|
119
119
|
- spec/sinatra_authlane_spec.rb
|
120
|
-
|
120
|
+
- spec/spec_helper.rb
|
121
|
+
homepage:
|
121
122
|
licenses:
|
122
123
|
- MIT
|
123
124
|
metadata: {}
|
@@ -129,7 +130,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
129
130
|
requirements:
|
130
131
|
- - ">="
|
131
132
|
- !ruby/object:Gem::Version
|
132
|
-
version:
|
133
|
+
version: 2.0.0
|
133
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
135
|
requirements:
|
135
136
|
- - ">="
|
@@ -137,13 +138,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
138
|
version: '0'
|
138
139
|
requirements: []
|
139
140
|
rubyforge_project:
|
140
|
-
rubygems_version: 2.4.
|
141
|
+
rubygems_version: 2.4.5
|
141
142
|
signing_key:
|
142
143
|
specification_version: 4
|
143
|
-
summary:
|
144
|
+
summary: Simple User authentication and roles for Sinatra.
|
144
145
|
test_files:
|
145
146
|
- spec/authlane_helper_spec.rb
|
146
147
|
- spec/authlane_serializeduser_spec.rb
|
147
|
-
- spec/helper.rb
|
148
148
|
- spec/sinatra_authlane_spec.rb
|
149
|
+
- spec/spec_helper.rb
|
149
150
|
has_rdoc:
|