simple_token_authentication 1.8.0 → 1.9.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 +4 -4
- data/README.md +12 -0
- data/lib/simple_token_authentication.rb +1 -1
- data/lib/simple_token_authentication/acts_as_token_authenticatable.rb +6 -41
- data/lib/simple_token_authentication/entities_manager.rb +2 -2
- data/lib/simple_token_authentication/entity.rb +5 -4
- data/lib/simple_token_authentication/token_authenticatable.rb +43 -0
- data/lib/simple_token_authentication/token_authentication_handler.rb +3 -2
- data/lib/simple_token_authentication/version.rb +1 -1
- data/spec/configuration/action_controller_callbacks_options_spec.rb +40 -0
- data/spec/lib/simple_token_authentication/acts_as_token_authenticatable_spec.rb +35 -59
- data/spec/lib/simple_token_authentication/acts_as_token_authentication_handler_spec.rb +0 -11
- data/spec/lib/simple_token_authentication/entities_manager_spec.rb +13 -4
- data/spec/lib/simple_token_authentication/entity_spec.rb +6 -0
- data/spec/lib/simple_token_authentication/token_authenticatable_spec.rb +68 -0
- data/spec/lib/simple_token_authentication/token_authentication_handler_spec.rb +79 -2
- data/spec/support/spec_for_token_authenticatable_interface.rb +8 -0
- metadata +31 -27
- data/lib/tasks/simple_token_authentication_tasks.rake +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aff7351e0178a92409d1092d897fba3190bf7931
|
4
|
+
data.tar.gz: 13cf3934848704cb786c32a88d2811ca957e2907
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 554b98719aee74a692f8bb5d80089f22ff1ce8ea85f2abdb3071b441a9decf87525d3e3f64aa24726e29f3fe0ed4b148352633ade88ffa0af8f49ede34003244
|
7
|
+
data.tar.gz: a15f550bac6dd2776aed33aebf543f8ee1806818817c6ed37fb8a965cb2ced54df1f618c6c3445cb6cb3e193341987c6bec1faa8291dfe95b0dd30ff98154fec
|
data/README.md
CHANGED
@@ -106,6 +106,10 @@ class ApplicationController < ActionController::Base # or ActionController::API
|
|
106
106
|
# The token authentication requirement can target specific controller actions:
|
107
107
|
# acts_as_token_authentication_handler_for User, only: [:create, :update, :destroy]
|
108
108
|
# acts_as_token_authentication_handler_for User, except: [:index, :show]
|
109
|
+
#
|
110
|
+
# Or target specific controller conditions:
|
111
|
+
# acts_as_token_authentication_handler_for User, unless: lambda { |controller| controller.request.format.html? }
|
112
|
+
# acts_as_token_authentication_handler_for User, if: lambda { |controller| controller.request.format.json? }
|
109
113
|
|
110
114
|
# Several token authenticatable models can be handled by the same controller.
|
111
115
|
# If so, for all of them except the last, the fallback_to_devise should be disabled.
|
@@ -116,6 +120,14 @@ class ApplicationController < ActionController::Base # or ActionController::API
|
|
116
120
|
# acts_as_token_authentication_handler_for SpecialUser, fallback_to_devise: false
|
117
121
|
# acts_as_token_authentication_handler_for User # the last fallback is up to you
|
118
122
|
|
123
|
+
# Aliases can be defined for namespaced models:
|
124
|
+
#
|
125
|
+
# acts_as_token_authentication_handler_for Customer::Representative, as: :facilitator
|
126
|
+
# acts_as_token_authentication_handler_for SpecialUser, as: :user
|
127
|
+
#
|
128
|
+
# When defined, aliases are used to define both the params and the header names to watch.
|
129
|
+
# E.g. facilitator_token, X-Facilitator-Token
|
130
|
+
|
119
131
|
# ...
|
120
132
|
end
|
121
133
|
```
|
@@ -11,7 +11,7 @@ module SimpleTokenAuthentication
|
|
11
11
|
|
12
12
|
def self.ensure_models_can_act_as_token_authenticatables model_adapters
|
13
13
|
model_adapters.each do |model_adapter|
|
14
|
-
model_adapter.base_class.send :
|
14
|
+
model_adapter.base_class.send :extend, SimpleTokenAuthentication::ActsAsTokenAuthenticatable
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -1,49 +1,14 @@
|
|
1
|
-
require '
|
2
|
-
require 'simple_token_authentication/token_generator'
|
1
|
+
require 'simple_token_authentication/token_authenticatable'
|
3
2
|
|
4
3
|
module SimpleTokenAuthentication
|
5
4
|
module ActsAsTokenAuthenticatable
|
6
|
-
extend ::ActiveSupport::Concern
|
7
5
|
|
8
|
-
#
|
9
|
-
#
|
6
|
+
# This module ensures that no TokenAuthenticatable behaviour
|
7
|
+
# is added before the class actually `acts_as_token_authenticatable`.
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
private :token_generator
|
15
|
-
end
|
16
|
-
|
17
|
-
# Set an authentication token if missing
|
18
|
-
#
|
19
|
-
# Because it is intended to be used as a filter,
|
20
|
-
# this method is -and should be kept- idempotent.
|
21
|
-
def ensure_authentication_token
|
22
|
-
if authentication_token.blank?
|
23
|
-
self.authentication_token = generate_authentication_token(token_generator)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def generate_authentication_token(token_generator)
|
28
|
-
loop do
|
29
|
-
token = token_generator.generate_token
|
30
|
-
break token if token_suitable?(token)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def token_suitable?(token)
|
35
|
-
self.class.where(authentication_token: token).count == 0
|
36
|
-
end
|
37
|
-
|
38
|
-
# Private: Get one (always the same) object which behaves as a token generator
|
39
|
-
def token_generator
|
40
|
-
@token_generator ||= TokenGenerator.new
|
41
|
-
end
|
42
|
-
|
43
|
-
module ClassMethods
|
44
|
-
def acts_as_token_authenticatable(options = {})
|
45
|
-
before_save :ensure_authentication_token
|
46
|
-
end
|
9
|
+
def acts_as_token_authenticatable(options = {})
|
10
|
+
include SimpleTokenAuthentication::TokenAuthenticatable
|
11
|
+
before_save :ensure_authentication_token
|
47
12
|
end
|
48
13
|
end
|
49
14
|
end
|
@@ -2,9 +2,9 @@ require 'simple_token_authentication/entity'
|
|
2
2
|
|
3
3
|
module SimpleTokenAuthentication
|
4
4
|
class EntitiesManager
|
5
|
-
def find_or_create_entity(model)
|
5
|
+
def find_or_create_entity(model, model_alias=nil)
|
6
6
|
@entities ||= {}
|
7
|
-
@entities[model.name] ||= Entity.new(model)
|
7
|
+
@entities[model.name] ||= Entity.new(model, model_alias)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
module SimpleTokenAuthentication
|
2
2
|
class Entity
|
3
|
-
def initialize
|
3
|
+
def initialize(model, model_alias=nil)
|
4
4
|
@model = model
|
5
5
|
@name = model.name
|
6
|
+
@name_underscore = model_alias.to_s unless model_alias.nil?
|
6
7
|
end
|
7
8
|
|
8
9
|
def model
|
@@ -14,7 +15,7 @@ module SimpleTokenAuthentication
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def name_underscore
|
17
|
-
name.underscore
|
18
|
+
@name_underscore || name.underscore
|
18
19
|
end
|
19
20
|
|
20
21
|
# Private: Return the name of the header to watch for the token authentication param
|
@@ -23,7 +24,7 @@ module SimpleTokenAuthentication
|
|
23
24
|
&& token_header_name = SimpleTokenAuthentication.header_names["#{name_underscore}".to_sym][:authentication_token]
|
24
25
|
token_header_name
|
25
26
|
else
|
26
|
-
"X-#{
|
27
|
+
"X-#{name_underscore.camelize}-Token"
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
@@ -33,7 +34,7 @@ module SimpleTokenAuthentication
|
|
33
34
|
&& identifier_header_name = SimpleTokenAuthentication.header_names["#{name_underscore}".to_sym][identifier]
|
34
35
|
identifier_header_name
|
35
36
|
else
|
36
|
-
"X-#{
|
37
|
+
"X-#{name_underscore.camelize}-#{identifier.to_s.camelize}"
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'simple_token_authentication/token_generator'
|
3
|
+
|
4
|
+
module SimpleTokenAuthentication
|
5
|
+
module TokenAuthenticatable
|
6
|
+
extend ::ActiveSupport::Concern
|
7
|
+
|
8
|
+
# Please see https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
|
9
|
+
# before editing this file, the discussion is very interesting.
|
10
|
+
|
11
|
+
included do
|
12
|
+
private :generate_authentication_token
|
13
|
+
private :token_suitable?
|
14
|
+
private :token_generator
|
15
|
+
end
|
16
|
+
|
17
|
+
# Set an authentication token if missing
|
18
|
+
#
|
19
|
+
# Because it is intended to be used as a filter,
|
20
|
+
# this method is -and should be kept- idempotent.
|
21
|
+
def ensure_authentication_token
|
22
|
+
if authentication_token.blank?
|
23
|
+
self.authentication_token = generate_authentication_token(token_generator)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate_authentication_token(token_generator)
|
28
|
+
loop do
|
29
|
+
token = token_generator.generate_token
|
30
|
+
break token if token_suitable?(token)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def token_suitable?(token)
|
35
|
+
self.class.where(authentication_token: token).count == 0
|
36
|
+
end
|
37
|
+
|
38
|
+
# Private: Get one (always the same) object which behaves as a token generator
|
39
|
+
def token_generator
|
40
|
+
@token_generator ||= TokenGenerator.new
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -92,7 +92,8 @@ module SimpleTokenAuthentication
|
|
92
92
|
#
|
93
93
|
# Returns nothing.
|
94
94
|
def handle_token_authentication_for(model, options = {})
|
95
|
-
|
95
|
+
model_alias = options[:as] || options['as']
|
96
|
+
entity = entities_manager.find_or_create_entity(model, model_alias)
|
96
97
|
options = SimpleTokenAuthentication.parse_options(options)
|
97
98
|
define_token_authentication_helpers_for(entity, fallback_authentication_handler)
|
98
99
|
set_token_authentication_hooks(entity, options)
|
@@ -141,7 +142,7 @@ module SimpleTokenAuthentication
|
|
141
142
|
else
|
142
143
|
:"authenticate_#{entity.name_underscore}_from_token"
|
143
144
|
end
|
144
|
-
before_filter authenticate_method, options.slice(:only, :except)
|
145
|
+
before_filter authenticate_method, options.slice(:only, :except, :if, :unless)
|
145
146
|
end
|
146
147
|
end
|
147
148
|
end
|
@@ -50,4 +50,44 @@ describe 'ActionController', action_controller_callbacks_options: true do
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
53
|
+
|
54
|
+
describe ':if option' do
|
55
|
+
|
56
|
+
context 'when provided to `acts_as_token_authentication_hanlder_for`' do
|
57
|
+
|
58
|
+
it 'is applied to the corresponding callback (1)', rspec_3_error: true, private: true do
|
59
|
+
some_class = @subjects.first
|
60
|
+
|
61
|
+
expect(some_class).to receive(:before_filter).with(:authenticate_user_from_token!, { if: lambda { |controller| 'some condition' } })
|
62
|
+
some_class.acts_as_token_authentication_handler_for User, if: lambda { |controller| 'some condition' }
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'is applied to the corresponding callback (2)', rspec_3_error: true, private: true do
|
66
|
+
some_child_class = @subjects.last
|
67
|
+
|
68
|
+
expect(some_child_class).to receive(:before_filter).with(:authenticate_user_from_token!, { if: lambda { |controller| 'some condition' } })
|
69
|
+
some_child_class.acts_as_token_authentication_handler_for User, if: lambda { |controller| 'some condition' }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe ':unless option' do
|
75
|
+
|
76
|
+
context 'when provided to `acts_as_token_authentication_hanlder_for`' do
|
77
|
+
|
78
|
+
it 'is applied to the corresponding callback (1)', rspec_3_error: true, private: true do
|
79
|
+
some_class = @subjects.first
|
80
|
+
|
81
|
+
expect(some_class).to receive(:before_filter).with(:authenticate_user_from_token!, { unless: lambda { |controller| 'some condition' } })
|
82
|
+
some_class.acts_as_token_authentication_handler_for User, unless: lambda { |controller| 'some condition' }
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'is applied to the corresponding callback (2)', rspec_3_error: true, private: true do
|
86
|
+
some_child_class = @subjects.last
|
87
|
+
|
88
|
+
expect(some_child_class).to receive(:before_filter).with(:authenticate_user_from_token!, { unless: lambda { |controller| 'some condition' } })
|
89
|
+
some_child_class.acts_as_token_authentication_handler_for User, unless: lambda { |controller| 'some condition' }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
53
93
|
end
|
@@ -15,14 +15,22 @@ describe DummyTokenGenerator do
|
|
15
15
|
it_behaves_like 'a token generator'
|
16
16
|
end
|
17
17
|
|
18
|
-
describe '
|
18
|
+
describe 'Any class which extends SimpleTokenAuthentication::ActsAsTokenAuthenticatable (or any if its children)' do
|
19
19
|
|
20
20
|
after(:each) do
|
21
21
|
ensure_examples_independence
|
22
22
|
end
|
23
23
|
|
24
24
|
before(:each) do
|
25
|
-
|
25
|
+
define_test_subjects_for_extension_of(SimpleTokenAuthentication::ActsAsTokenAuthenticatable)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'doesn\'t behave like a token authenticatable', public: true do
|
29
|
+
stub_const('SimpleTokenAuthentication::TokenAuthenticatable', Module.new)
|
30
|
+
|
31
|
+
@subjects.each do |subject|
|
32
|
+
expect(subject).not_to be_include SimpleTokenAuthentication::TokenAuthenticatable
|
33
|
+
end
|
26
34
|
end
|
27
35
|
|
28
36
|
it 'responds to :acts_as_token_authenticatable', public: true do
|
@@ -31,77 +39,45 @@ describe 'A token authenticatable class (or one of its children)' do
|
|
31
39
|
end
|
32
40
|
end
|
33
41
|
|
34
|
-
|
35
|
-
|
36
|
-
context 'when it acts as token authenticatable' do
|
37
|
-
it 'ensures its instances have an authentication token before being saved (1)', rspec_3_error: true, public: true do
|
38
|
-
some_class = @subjects.first
|
39
|
-
|
40
|
-
expect(some_class).to receive(:before_save).with(:ensure_authentication_token)
|
41
|
-
some_class.acts_as_token_authenticatable
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'ensures its instances have an authentication token before being saved (2)', rspec_3_error: true, public: true do
|
45
|
-
some_child_class = @subjects.last
|
42
|
+
context 'when it explicitely acts as a token authenticatable' do
|
46
43
|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
44
|
+
it 'behaves like a token authenticatable (1)', rspec_3_error: true, public: true do
|
45
|
+
stub_const('SimpleTokenAuthentication::TokenAuthenticatable', Module.new)
|
52
46
|
|
53
|
-
|
47
|
+
some_class = @subjects.first
|
48
|
+
allow(some_class).to receive(:before_save)
|
54
49
|
|
55
|
-
|
56
|
-
|
57
|
-
@subjects.each do |subject|
|
58
|
-
expect(subject).to respond_to :ensure_authentication_token
|
59
|
-
end
|
50
|
+
some_class.acts_as_token_authenticatable
|
51
|
+
expect(some_class).to be_include SimpleTokenAuthentication::TokenAuthenticatable
|
60
52
|
end
|
61
53
|
|
62
|
-
|
63
|
-
|
64
|
-
before(:each) do
|
65
|
-
TOKENS_IN_USE = ['ExampleTok3n', '4notherTokeN']
|
54
|
+
it 'behaves like a token authenticatable (2)', rspec_3_error: true, public: true do
|
55
|
+
stub_const('SimpleTokenAuthentication::TokenAuthenticatable', Module.new)
|
66
56
|
|
67
|
-
|
68
|
-
|
57
|
+
some_child_class = @subjects.last
|
58
|
+
allow(some_child_class).to receive(:before_save)
|
69
59
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
60
|
+
some_child_class.acts_as_token_authenticatable
|
61
|
+
expect(some_child_class).to be_include SimpleTokenAuthentication::TokenAuthenticatable
|
62
|
+
end
|
63
|
+
end
|
75
64
|
|
76
|
-
|
77
|
-
@authentication_token = value
|
78
|
-
end
|
65
|
+
describe '.acts_as_token_authenticatable' do
|
79
66
|
|
80
|
-
|
81
|
-
@authentication_token
|
82
|
-
end
|
67
|
+
context 'when the class supports the :before_save hook' do
|
83
68
|
|
84
|
-
|
85
|
-
|
86
|
-
not TOKENS_IN_USE.include? token
|
87
|
-
end
|
69
|
+
it 'ensures its instances have an authentication token before being saved (1)', rspec_3_error: true, public: true do
|
70
|
+
some_class = @subjects.first
|
88
71
|
|
89
|
-
|
90
|
-
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
@subjects.map!{ |subject| subject.new }
|
72
|
+
expect(some_class).to receive(:before_save).with(:ensure_authentication_token)
|
73
|
+
some_class.acts_as_token_authenticatable
|
95
74
|
end
|
96
75
|
|
97
|
-
it 'ensures its authentication token
|
98
|
-
@subjects.
|
99
|
-
subject.ensure_authentication_token
|
76
|
+
it 'ensures its instances have an authentication token before being saved (2)', rspec_3_error: true, public: true do
|
77
|
+
some_child_class = @subjects.last
|
100
78
|
|
101
|
-
|
102
|
-
|
103
|
-
expect(subject.authentication_token).to eq 'Dist1nCt-Tok3N'
|
104
|
-
end
|
79
|
+
expect(some_child_class).to receive(:before_save).with(:ensure_authentication_token)
|
80
|
+
some_child_class.acts_as_token_authenticatable
|
105
81
|
end
|
106
82
|
end
|
107
83
|
end
|
@@ -1,16 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
def ignore_cucumber_hack
|
4
|
-
skip_rails_test_environment_code
|
5
|
-
end
|
6
|
-
|
7
|
-
# Skip the code intended to be run in the Rails test environment
|
8
|
-
def skip_rails_test_environment_code
|
9
|
-
rails = double()
|
10
|
-
stub_const('Rails', rails)
|
11
|
-
allow(rails).to receive_message_chain(:env, :test?).and_return(false)
|
12
|
-
end
|
13
|
-
|
14
3
|
describe 'Any class which extends SimpleTokenAuthentication::ActsAsTokenAuthenticationHandler (or any if its children)' do
|
15
4
|
|
16
5
|
after(:each) do
|
@@ -19,10 +19,10 @@ describe SimpleTokenAuthentication::EntitiesManager do
|
|
19
19
|
stub_const('SuperUser', super_user)
|
20
20
|
end
|
21
21
|
|
22
|
-
context 'when a model is provided for the first time' do
|
22
|
+
context 'when a model is provided for the first time', token_authenticatable_aliases_option: true do
|
23
23
|
|
24
24
|
it 'creates an Entity instance for the model', private: true do
|
25
|
-
expect(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser)
|
25
|
+
expect(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser, nil) # no alias
|
26
26
|
expect(subject.find_or_create_entity(SuperUser)).to eq 'an Entity instance'
|
27
27
|
end
|
28
28
|
|
@@ -35,13 +35,22 @@ describe SimpleTokenAuthentication::EntitiesManager do
|
|
35
35
|
stub_const('Admin', admin)
|
36
36
|
# ensure its Entity instance exists
|
37
37
|
subject.find_or_create_entity(Admin)
|
38
|
-
allow(SimpleTokenAuthentication::Entity).to receive(:new).and_return('some new Entity instance')
|
38
|
+
allow(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser, nil).and_return('some new Entity instance')
|
39
|
+
allow(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser, 'some_alias').and_return('some new Entity instance with an alias')
|
39
40
|
end
|
40
41
|
|
41
42
|
it 'creates an Entity instance for the model', private: true do
|
42
|
-
expect(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser)
|
43
|
+
expect(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser, nil)
|
43
44
|
expect(subject.find_or_create_entity(SuperUser)).to eq 'some new Entity instance'
|
44
45
|
end
|
46
|
+
|
47
|
+
context 'when a model alias was provided' do
|
48
|
+
|
49
|
+
it 'creates an Entity instance with that alias for the model', private: true do
|
50
|
+
expect(SimpleTokenAuthentication::Entity).to receive(:new).with(SuperUser, 'some_alias')
|
51
|
+
expect(subject.find_or_create_entity(SuperUser, 'some_alias')).to eq 'some new Entity instance with an alias'
|
52
|
+
end
|
53
|
+
end
|
45
54
|
end
|
46
55
|
end
|
47
56
|
|
@@ -64,6 +64,12 @@ describe SimpleTokenAuthentication::Entity do
|
|
64
64
|
expect(@subject.name_underscore).to be_instance_of String
|
65
65
|
expect(@subject.name_underscore).to eq @subject.name_underscore.underscore
|
66
66
|
end
|
67
|
+
|
68
|
+
it 'can be predefined', token_authenticatable_aliases_option: true do
|
69
|
+
@subject = SimpleTokenAuthentication::Entity.new(SuperUser, 'incognito_super_user')
|
70
|
+
|
71
|
+
expect(@subject.name_underscore).to eq 'incognito_super_user'
|
72
|
+
end
|
67
73
|
end
|
68
74
|
|
69
75
|
describe '#token_header_name', protected: true do
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class DummyTokenGenerator
|
4
|
+
def initialize(args={})
|
5
|
+
@tokens_to_be_generated = args[:tokens_to_be_generated]
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate_token
|
9
|
+
@tokens_to_be_generated.shift
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe DummyTokenGenerator do
|
14
|
+
it_behaves_like 'a token generator'
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'Any instance of a class which includes SimpleTokenAuthentication::TokenAuthenticatable' do
|
18
|
+
|
19
|
+
let(:described_class) do
|
20
|
+
define_dummy_class_which_includes SimpleTokenAuthentication::TokenAuthenticatable
|
21
|
+
end
|
22
|
+
|
23
|
+
after(:each) do
|
24
|
+
# ensure_examples_independence
|
25
|
+
SimpleTokenAuthentication.send(:remove_const, :SomeClass)
|
26
|
+
end
|
27
|
+
|
28
|
+
it_behaves_like 'a token authenticatable'
|
29
|
+
|
30
|
+
let(:subject) { described_class.new() }
|
31
|
+
|
32
|
+
describe '#ensure_authentication_token' do
|
33
|
+
|
34
|
+
context 'when some authentication tokens are already in use' do
|
35
|
+
|
36
|
+
before(:each) do
|
37
|
+
TOKENS_IN_USE = ['ExampleTok3n', '4notherTokeN']
|
38
|
+
|
39
|
+
subject.instance_eval do
|
40
|
+
|
41
|
+
@token_generator = DummyTokenGenerator.new(
|
42
|
+
tokens_to_be_generated: TOKENS_IN_USE + ['Dist1nCt-Tok3N'])
|
43
|
+
|
44
|
+
def authentication_token=(value)
|
45
|
+
@authentication_token = value
|
46
|
+
end
|
47
|
+
|
48
|
+
def authentication_token
|
49
|
+
@authentication_token
|
50
|
+
end
|
51
|
+
|
52
|
+
# the 'ExampleTok3n' is already in use
|
53
|
+
def token_suitable?(token)
|
54
|
+
not TOKENS_IN_USE.include? token
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'ensures its authentication token is unique', public: true do
|
60
|
+
subject.ensure_authentication_token
|
61
|
+
|
62
|
+
expect(subject.authentication_token).not_to eq 'ExampleTok3n'
|
63
|
+
expect(subject.authentication_token).not_to eq '4notherTokeN'
|
64
|
+
expect(subject.authentication_token).to eq 'Dist1nCt-Tok3N'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -40,8 +40,8 @@ describe 'Any class which includes SimpleTokenAuthentication::TokenAuthenticatio
|
|
40
40
|
it 'ensures token authentication is handled for the given (token authenticatable) models', public: true do
|
41
41
|
double_super_admin_model
|
42
42
|
entities_manager = double()
|
43
|
-
allow(entities_manager).to receive(:find_or_create_entity).with(User).and_return('User entity')
|
44
|
-
allow(entities_manager).to receive(:find_or_create_entity).with(SuperAdmin).and_return('SuperAdmin entity')
|
43
|
+
allow(entities_manager).to receive(:find_or_create_entity).with(User, nil).and_return('User entity')
|
44
|
+
allow(entities_manager).to receive(:find_or_create_entity).with(SuperAdmin, nil).and_return('SuperAdmin entity')
|
45
45
|
|
46
46
|
# skip steps which are not relevant in this example
|
47
47
|
allow(SimpleTokenAuthentication).to receive(:fallback).and_return('default')
|
@@ -55,6 +55,24 @@ describe 'Any class which includes SimpleTokenAuthentication::TokenAuthenticatio
|
|
55
55
|
subject.handle_token_authentication_for(SuperAdmin, {option: 'some specific value'})
|
56
56
|
end
|
57
57
|
end
|
58
|
+
|
59
|
+
context 'when an alias is provided for the model', token_authenticatable_aliases_option: true do
|
60
|
+
|
61
|
+
it 'creates an Entity with that alias', private: true do
|
62
|
+
entities_manager = double()
|
63
|
+
allow(entities_manager).to receive(:find_or_create_entity)
|
64
|
+
|
65
|
+
# skip steps which are not relevant in this example
|
66
|
+
allow(subject).to receive(:entities_manager).and_return(entities_manager)
|
67
|
+
allow(subject).to receive(:set_token_authentication_hooks)
|
68
|
+
allow(subject).to receive(:define_token_authentication_helpers_for)
|
69
|
+
|
70
|
+
expect(entities_manager).to receive(:find_or_create_entity).with(User, 'some_alias')
|
71
|
+
subject.handle_token_authentication_for(User, {option: 'value', as: 'some_alias'})
|
72
|
+
expect(entities_manager).to receive(:find_or_create_entity).with(User, 'another_alias')
|
73
|
+
subject.handle_token_authentication_for(User, {option: 'value', 'as' => 'another_alias'})
|
74
|
+
end
|
75
|
+
end
|
58
76
|
end
|
59
77
|
|
60
78
|
describe '.entities_manager' do
|
@@ -447,6 +465,65 @@ describe 'Any class which includes SimpleTokenAuthentication::TokenAuthenticatio
|
|
447
465
|
expect(subject.new).not_to respond_to :authenticate_user_from_token!
|
448
466
|
end
|
449
467
|
end
|
468
|
+
|
469
|
+
context 'with the :admin alias', token_authenticatable_aliases_option: true do
|
470
|
+
|
471
|
+
let(:options) do
|
472
|
+
{ 'as' => :admin }
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'ensures its instances require admin to authenticate from token or any Devise strategy before any action', public: true do
|
476
|
+
expect(subject).to receive(:before_filter).with(:authenticate_admin_from_token!, {})
|
477
|
+
subject.handle_token_authentication_for SuperAdmin, options
|
478
|
+
end
|
479
|
+
|
480
|
+
context 'and disables the fallback to Devise authentication' do
|
481
|
+
|
482
|
+
let(:options) do
|
483
|
+
{ as: 'admin', fallback_to_devise: false }
|
484
|
+
end
|
485
|
+
|
486
|
+
it 'ensures its instances require admin to authenticate from token before any action', public: true do
|
487
|
+
expect(subject).to receive(:before_filter).with(:authenticate_admin_from_token, {})
|
488
|
+
subject.handle_token_authentication_for SuperAdmin, options
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
describe 'instance' do
|
493
|
+
|
494
|
+
before(:each) do
|
495
|
+
double_super_admin_model
|
496
|
+
|
497
|
+
subject.class_eval do
|
498
|
+
handle_token_authentication_for SuperAdmin, as: :admin
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
it 'responds to :authenticate_admin_from_token', protected: true do
|
503
|
+
expect(subject.new).to respond_to :authenticate_admin_from_token
|
504
|
+
end
|
505
|
+
|
506
|
+
it 'responds to :authenticate_admin_from_token!', protected: true do
|
507
|
+
expect(subject.new).to respond_to :authenticate_admin_from_token!
|
508
|
+
end
|
509
|
+
|
510
|
+
it 'does not respond to :authenticate_super_admin_from_token', protected: true do
|
511
|
+
expect(subject.new).not_to respond_to :authenticate_super_admin_from_token
|
512
|
+
end
|
513
|
+
|
514
|
+
it 'does not respond to :authenticate_super_admin_from_token!', protected: true do
|
515
|
+
expect(subject.new).not_to respond_to :authenticate_super_admin_from_token!
|
516
|
+
end
|
517
|
+
|
518
|
+
it 'does not respond to :authenticate_user_from_token', protected: true do
|
519
|
+
expect(subject.new).not_to respond_to :authenticate_user_from_token
|
520
|
+
end
|
521
|
+
|
522
|
+
it 'does not respond to :authenticate_user_from_token!', protected: true do
|
523
|
+
expect(subject.new).not_to respond_to :authenticate_user_from_token!
|
524
|
+
end
|
525
|
+
end
|
526
|
+
end
|
450
527
|
end
|
451
528
|
end
|
452
529
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_token_authentication
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gonzalo Bulnes Guilpain
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionmailer
|
@@ -156,11 +156,11 @@ files:
|
|
156
156
|
- lib/simple_token_authentication/entity.rb
|
157
157
|
- lib/simple_token_authentication/fallback_authentication_handler.rb
|
158
158
|
- lib/simple_token_authentication/sign_in_handler.rb
|
159
|
+
- lib/simple_token_authentication/token_authenticatable.rb
|
159
160
|
- lib/simple_token_authentication/token_authentication_handler.rb
|
160
161
|
- lib/simple_token_authentication/token_comparator.rb
|
161
162
|
- lib/simple_token_authentication/token_generator.rb
|
162
163
|
- lib/simple_token_authentication/version.rb
|
163
|
-
- lib/tasks/simple_token_authentication_tasks.rake
|
164
164
|
- spec/configuration/action_controller_callbacks_options_spec.rb
|
165
165
|
- spec/configuration/fallback_to_devise_option_spec.rb
|
166
166
|
- spec/configuration/header_names_option_spec.rb
|
@@ -179,6 +179,7 @@ files:
|
|
179
179
|
- spec/lib/simple_token_authentication/errors_spec.rb
|
180
180
|
- spec/lib/simple_token_authentication/fallback_authentication_handler_spec.rb
|
181
181
|
- spec/lib/simple_token_authentication/sign_in_handler_spec.rb
|
182
|
+
- spec/lib/simple_token_authentication/token_authenticatable_spec.rb
|
182
183
|
- spec/lib/simple_token_authentication/token_authentication_handler_spec.rb
|
183
184
|
- spec/lib/simple_token_authentication/token_comparator_spec.rb
|
184
185
|
- spec/lib/simple_token_authentication/token_generator_spec.rb
|
@@ -190,6 +191,7 @@ files:
|
|
190
191
|
- spec/support/spec_for_configuration_option_interface.rb
|
191
192
|
- spec/support/spec_for_entities_manager_interface.rb
|
192
193
|
- spec/support/spec_for_sign_in_handler_interface.rb
|
194
|
+
- spec/support/spec_for_token_authenticatable_interface.rb
|
193
195
|
- spec/support/spec_for_token_comparator_interface.rb
|
194
196
|
- spec/support/spec_for_token_generator_interface.rb
|
195
197
|
- spec/support/specs_for_token_authentication_handler_interface.rb
|
@@ -218,36 +220,38 @@ signing_key:
|
|
218
220
|
specification_version: 4
|
219
221
|
summary: Simple (but safe) token authentication for Rails apps or API with Devise.
|
220
222
|
test_files:
|
221
|
-
- spec/configuration/skip_devise_trackable_option_spec.rb
|
222
|
-
- spec/configuration/header_names_option_spec.rb
|
223
|
-
- spec/configuration/sign_in_token_option_spec.rb
|
224
|
-
- spec/configuration/action_controller_callbacks_options_spec.rb
|
225
|
-
- spec/configuration/fallback_to_devise_option_spec.rb
|
226
|
-
- spec/support/spec_for_configuration_option_interface.rb
|
227
|
-
- spec/support/spec_for_token_comparator_interface.rb
|
228
|
-
- spec/support/spec_for_authentication_handler_interface.rb
|
229
|
-
- spec/support/spec_for_entities_manager_interface.rb
|
230
|
-
- spec/support/dummy_classes_helper.rb
|
231
|
-
- spec/support/specs_for_token_authentication_handler_interface.rb
|
232
|
-
- spec/support/spec_for_token_generator_interface.rb
|
233
|
-
- spec/support/spec_for_adapter.rb
|
234
|
-
- spec/support/spec_for_sign_in_handler_interface.rb
|
235
223
|
- spec/lib/simple_token_authentication_spec.rb
|
224
|
+
- spec/lib/simple_token_authentication/entities_manager_spec.rb
|
225
|
+
- spec/lib/simple_token_authentication/sign_in_handler_spec.rb
|
236
226
|
- spec/lib/simple_token_authentication/fallback_authentication_handler_spec.rb
|
237
|
-
- spec/lib/simple_token_authentication/
|
238
|
-
- spec/lib/simple_token_authentication/adapter_spec.rb
|
227
|
+
- spec/lib/simple_token_authentication/token_comparator_spec.rb
|
239
228
|
- spec/lib/simple_token_authentication/configuration_spec.rb
|
240
|
-
- spec/lib/simple_token_authentication/
|
241
|
-
- spec/lib/simple_token_authentication/
|
242
|
-
- spec/lib/simple_token_authentication/adapters/mongoid_adapter_spec.rb
|
243
|
-
- spec/lib/simple_token_authentication/adapters/rails_adapter_spec.rb
|
229
|
+
- spec/lib/simple_token_authentication/token_generator_spec.rb
|
230
|
+
- spec/lib/simple_token_authentication/acts_as_token_authenticatable_spec.rb
|
244
231
|
- spec/lib/simple_token_authentication/acts_as_token_authentication_handler_spec.rb
|
232
|
+
- spec/lib/simple_token_authentication/token_authenticatable_spec.rb
|
245
233
|
- spec/lib/simple_token_authentication/token_authentication_handler_spec.rb
|
246
|
-
- spec/lib/simple_token_authentication/sign_in_handler_spec.rb
|
247
|
-
- spec/lib/simple_token_authentication/acts_as_token_authenticatable_spec.rb
|
248
234
|
- spec/lib/simple_token_authentication/errors_spec.rb
|
249
|
-
- spec/lib/simple_token_authentication/
|
250
|
-
- spec/lib/simple_token_authentication/
|
235
|
+
- spec/lib/simple_token_authentication/adapters/active_record_adapter_spec.rb
|
236
|
+
- spec/lib/simple_token_authentication/adapters/mongoid_adapter_spec.rb
|
237
|
+
- spec/lib/simple_token_authentication/adapters/rails_adapter_spec.rb
|
238
|
+
- spec/lib/simple_token_authentication/adapters/rails_api_adapter_spec.rb
|
251
239
|
- spec/lib/simple_token_authentication/entity_spec.rb
|
240
|
+
- spec/lib/simple_token_authentication/adapter_spec.rb
|
241
|
+
- spec/configuration/action_controller_callbacks_options_spec.rb
|
242
|
+
- spec/configuration/header_names_option_spec.rb
|
243
|
+
- spec/configuration/fallback_to_devise_option_spec.rb
|
244
|
+
- spec/configuration/skip_devise_trackable_option_spec.rb
|
245
|
+
- spec/configuration/sign_in_token_option_spec.rb
|
252
246
|
- spec/spec_helper.rb
|
247
|
+
- spec/support/spec_for_authentication_handler_interface.rb
|
248
|
+
- spec/support/spec_for_entities_manager_interface.rb
|
249
|
+
- spec/support/spec_for_adapter.rb
|
250
|
+
- spec/support/spec_for_token_authenticatable_interface.rb
|
251
|
+
- spec/support/specs_for_token_authentication_handler_interface.rb
|
252
|
+
- spec/support/spec_for_token_comparator_interface.rb
|
253
|
+
- spec/support/spec_for_configuration_option_interface.rb
|
254
|
+
- spec/support/spec_for_sign_in_handler_interface.rb
|
255
|
+
- spec/support/dummy_classes_helper.rb
|
256
|
+
- spec/support/spec_for_token_generator_interface.rb
|
253
257
|
has_rdoc:
|