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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5d433f29ea95649c1f3c82327cdf25585028d774
4
- data.tar.gz: 4a2e2944a3a75b5d263ecbf74cbc55e3327df5e0
3
+ metadata.gz: e1d5209e59fc6178372d91056feaa7f88db1c320
4
+ data.tar.gz: 03b19e3f8ccffee0f4d3452f4eb4a398f94c9913
5
5
  SHA512:
6
- metadata.gz: 070797815dead62c30f657efc56c5dfb3abdf8f0c792d68062469dcb67de9480907b204391a62b2a48bcf85e08f18e017b290fda9787bc0b3f6bd29bf762a280
7
- data.tar.gz: f2191d60b1b6f4e4f6acdf7f393c9e9bbf375a7214edd0ff986f2183f4f7f513c9bb4e8508ddb73355b6491007c9ac41528a77dcbdc80e86b93bb02e0b12417c
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
- # Configuring *AuthLane*
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
- :session_key => :authlane,
20
- :remember_cookie => :authlane_token,
21
- :serialize_user => [:id]
59
+ :session_key => :authlane,
60
+ :remember_cookie => :authlane_token,
61
+ :serialize_user => [:id]
22
62
  ```
23
63
 
24
- ### `:failed_route`
64
+ #### `:failed_route`
25
65
 
26
- The `:failed_route` sets the route String, where AuthLane should redirect to in case a route requires authorisation and the User ist 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 authorisation as well.
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
- ### `:seession_key`
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
- ### `:remember_cookie`
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 Auth and Remember Strategy.
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
- ### `:serialize_user`
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 useres 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.
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 = 'Easy User authentication and roles for Sinatra.'
12
- spec.description = 'The AuthLane Sinatra Extension allows easy User authentication with support for different User roles.'
13
- spec.homepage = ''
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
@@ -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
- remember_strat = self.instance_eval(&settings.authlane[:remember_strategy])
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
- @user[attrs] = user.__send__(attrs.to_sym) if user.respond_to? attrs
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
- hash = @user.to_h
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
 
@@ -2,5 +2,5 @@
2
2
  module Authlane
3
3
  ##
4
4
  # Current AuthLane version number.
5
- VERSION = '1.0.0'
5
+ VERSION = '1.2.0'
6
6
  end
@@ -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
- # ## `:seession_key`
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 => :authlane_token, # Cookie name to store 'Remember Me' token
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 (or whatever technique) is usually set in the **Auth** Strategy.
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
- # remember_token = cookies[:authlane_token]
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 '../helper.rb', __FILE__
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 { { id: 1 } }
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 '/authorized', {}, { 'rack.session' => { authlane: { id: 1 } } }
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 display protected route when logged in" do
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 '/unauthorize', {}, { 'rack.session' => { authlane: '1' } }
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 '/user', {}, { 'rack.session' => { authlane: '1' } }
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 '../helper.rb', __FILE__
1
+ require File.expand_path '../spec_helper.rb', __FILE__
2
2
 
3
3
  describe Sinatra::AuthLane::SerializedUser do
4
- def mock_user
5
- Sinatra::AuthLane::SerializedUser.new({ id: 1, name: 'rspec' })
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 = mock_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 = mock_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 = mock_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 = mock_user.to_h
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 = mock_user.to_h
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
@@ -1,4 +1,4 @@
1
- require File.expand_path '../helper.rb', __FILE__
1
+ require File.expand_path '../spec_helper.rb', __FILE__
2
2
 
3
3
  describe Sinatra::AuthLane do
4
4
  def strategy(type, &block)
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.0.0
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-08 00:00:00.000000000 Z
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: The AuthLane Sinatra Extension allows easy User authentication with support
98
- for different User roles.
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
- homepage: ''
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: '0'
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.1
141
+ rubygems_version: 2.4.5
141
142
  signing_key:
142
143
  specification_version: 4
143
- summary: Easy User authentication and roles for Sinatra.
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: