devise_token_auth 0.1.16 → 0.1.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +29 -8
- data/app/controllers/devise_token_auth/auth_controller.rb +1 -1
- data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +37 -15
- data/app/controllers/devise_token_auth/confirmations_controller.rb +1 -1
- data/app/controllers/devise_token_auth/registrations_controller.rb +1 -1
- data/app/controllers/devise_token_auth/sessions_controller.rb +1 -1
- data/app/models/user.rb +80 -6
- data/lib/devise_token_auth/engine.rb +12 -0
- data/lib/devise_token_auth/version.rb +1 -1
- data/lib/generators/devise_token_auth/USAGE +4 -3
- data/lib/generators/devise_token_auth/install_generator.rb +27 -0
- data/lib/generators/devise_token_auth/templates/devise_token_auth.rb +17 -0
- data/{db/migrate/20140628234942_devise_token_auth_create_users.rb → lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb} +1 -1
- data/test/controllers/demo_controller_test.rb +233 -0
- data/test/controllers/devise_token_auth/registrations_controller_test.rb +0 -1
- data/test/dummy/config/database.yml +22 -16
- data/test/dummy/config/initializers/devise_token_auth.rb +20 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/{20140705000006_devise_token_auth_create_users.devise_token_auth.rb → 20140713062503_devise_token_auth_create_users.rb} +1 -2
- data/test/dummy/db/schema.rb +8 -5
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +2129 -0
- data/test/dummy/log/test.log +54231 -0
- data/test/fixtures/users.yml +9 -2
- data/test/lib/generators/devise_token_auth/{devise_token_auth_generator_test.rb → install_generator_test.rb} +3 -3
- data/test/test_helper.rb +13 -0
- metadata +34 -15
- data/lib/generators/devise_token_auth/devise_token_auth_generator.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6fddec01685e543399f2fa156c7c5b3a1a00cc8
|
4
|
+
data.tar.gz: d51505ea9e19cac45f566c8a0159202363d34062
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf7d4346373fab8211fb5b09aaf7671178d17630a2ee7a496baa5fd528d0f10977acc64e1e28baa42103a371c3044f13ec606bec96caec69dc98824c22143818
|
7
|
+
data.tar.gz: 1812e0973a0bff3a54567b38cc862669b6cc7990383b9b48245ff6c38c0f2198934b4925e5305a88c3fa91adee221137f88af529fb7e1d26d5105e0bd9b713e9
|
data/README.md
CHANGED
@@ -31,19 +31,25 @@ Then install the gem using bundle:
|
|
31
31
|
bundle install
|
32
32
|
~~~
|
33
33
|
|
34
|
-
##
|
35
|
-
You will need to create a user model. Run the following to generate
|
34
|
+
## Configuration
|
35
|
+
You will need to create a user model, and you may want to alter some of the default settings. Run the following to generate the migrations and initializer files:
|
36
36
|
|
37
37
|
~~~bash
|
38
|
-
|
38
|
+
rails g devise_token_auth:install
|
39
39
|
~~~
|
40
40
|
|
41
|
-
|
41
|
+
This will create a migrations file in the `db/migrate` directory. Inspect the migrations file and add additional columns if necessary, then run the migration:
|
42
42
|
|
43
43
|
~~~bash
|
44
44
|
rake db:migrate
|
45
45
|
~~~
|
46
46
|
|
47
|
+
An initializer will also be created at `config/initializers/devise_token_auth.rb`. The following settings are available for configuration:
|
48
|
+
|
49
|
+
* **`change_headers_on_each_request`** _Default: true_. By default the authorization headers will change after each request. The client is responsible for keeping track of the changing tokens. The [ng-token-auth](https://github.com/lynndylanhurley/ng-token-auth) module for angular.js does this out of the box. While this implementation is more secure, it can be difficult to manage. Set this to false to prevent the `Authorization` header from changing after each request.
|
50
|
+
* **`token_lifespan`** _Default: 2.weeks_. Set the length of your tokens' lifespans. Users will need to re-authenticate after this duration of time has passed since their last login.
|
51
|
+
* **`batch_request_buffer_throttle`** _Default: 2.seconds_. Sometimes it's necessary to make several requests to the API at the same time. In this case, each request in the batch will need to share the same auth token. This setting determines how far apart the requests can be while still using the same auth token.
|
52
|
+
|
47
53
|
## Omniauth authentication
|
48
54
|
|
49
55
|
If you wish to use omniauth authentication, add all of your desired authentication provider gems as well.
|
@@ -165,19 +171,34 @@ The following routes are available for use by your client. These routes live rel
|
|
165
171
|
|
166
172
|
If you're using [ng-token-auth](https://github.com/lynndylanhurley/ng-token-auth) for angular.js, then your client is ready to go.
|
167
173
|
|
174
|
+
|
168
175
|
## Identifying users in controllers
|
169
176
|
|
170
177
|
The authentication information should be included by the client in the `Authorization` header of each request. The header should follow this format:
|
171
178
|
|
179
|
+
##### Authorization header example:
|
172
180
|
~~~
|
173
|
-
token=
|
181
|
+
token=wwwww client=xxxxx expiry=yyyyy uid=zzzzz
|
174
182
|
~~~
|
175
183
|
|
176
|
-
|
184
|
+
The `Authorization` header is made up of the following components:
|
185
|
+
|
186
|
+
* **`token`**: This serves as the user's password for each request. A hashed version of this value is stored in the database for later comparison. This value should be changed on each request.
|
187
|
+
* **`client`**: This enables the use of multiple simultaneous sessions on different clients. (For example, a user may want to be authenticated on both their phone and their laptop at the same time.)
|
188
|
+
* **`expiry`**: The date at which the current session will expire. This can be used by clients to invalidate expired tokens without the need for an API request.
|
189
|
+
* **`uid`**: A unique value that is used to identify the user. This is necessary because searching the DB for users by their access token will open the API up to timing attacks.
|
190
|
+
|
191
|
+
The `Authorization` header required for each request will be available in the response from the previous request. If you are using the [ng-token-auth](https://github.com/lynndylanhurley/ng-token-auth) module for angular.js, this functionality is already provided.
|
192
|
+
|
193
|
+
|
194
|
+
## The `User` model
|
177
195
|
|
178
|
-
|
196
|
+
The user model will contain the following public methods (read the above section for context on `token` and `client`):
|
197
|
+
* **`valid_token?`**: check if an authentication token is valid. Accepts `token` and `client` as arguments. Returns a boolean.
|
198
|
+
* **`create_new_auth_token`**: creates a new auth token with all of the necessary metadata. Accepts `client` as an optional argument. Will generate a new `client` if none is provided. Returns the `Authorization` header that should be sent by the client as a string.
|
199
|
+
* **`build_auth_header`**: generates the auth header that should be sent to the client with the next request. Accepts `token` and `client` as arguments. Returns a string.
|
179
200
|
|
180
|
-
|
201
|
+
## DeviseTokenAuth::Concerns::SetUserByToken
|
181
202
|
|
182
203
|
This gem includes a [Rails concern](http://api.rubyonrails.org/classes/ActiveSupport/Concern.html) that can be used to identify users by the `Authorization` header.
|
183
204
|
|
@@ -6,6 +6,7 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
6
6
|
after_action :update_auth_header
|
7
7
|
end
|
8
8
|
|
9
|
+
|
9
10
|
# user auth
|
10
11
|
def set_user_by_token
|
11
12
|
auth_header = request.headers["Authorization"]
|
@@ -13,35 +14,56 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
13
14
|
# missing auth token
|
14
15
|
return false unless auth_header
|
15
16
|
|
16
|
-
|
17
|
+
# parse header for values necessary for authentication
|
17
18
|
uid = auth_header[/uid=(.*?)$/,1]
|
19
|
+
@token = auth_header[/token=(.*?) /,1]
|
18
20
|
@client_id = auth_header[/client=(.*?) /,1]
|
19
21
|
|
22
|
+
# client_id isn't required, set to 'default' if absent
|
20
23
|
@client_id ||= 'default'
|
21
24
|
|
22
25
|
# mitigate timing attacks by finding by uid instead of auth token
|
23
26
|
@user = @current_user = uid && User.find_by_uid(uid)
|
24
27
|
|
25
|
-
if @user && @user.valid_token?(@
|
28
|
+
if @user && @user.valid_token?(@token, @client_id)
|
26
29
|
sign_in(:user, @user, store: false, bypass: true)
|
30
|
+
|
31
|
+
# check this now so that the duration of the request itself doesn't eat
|
32
|
+
# away the buffer
|
33
|
+
@is_batch_request = is_batch_request?(@user, @client_id)
|
34
|
+
|
27
35
|
else
|
28
|
-
|
36
|
+
# zero all values previously set values
|
37
|
+
@user = @current_user = @is_batch_request = nil
|
29
38
|
end
|
30
39
|
end
|
31
40
|
|
41
|
+
|
32
42
|
def update_auth_header
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
@user.
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
|
44
|
+
auth_header = nil
|
45
|
+
if not DeviseTokenAuth.change_headers_on_each_request
|
46
|
+
auth_header = @user.build_auth_header(@token, @client_id)
|
47
|
+
|
48
|
+
# extend expiration of batch buffer to account for the duration of
|
49
|
+
# this request
|
50
|
+
elsif @is_batch_request and @client_id and @user
|
51
|
+
auth_header = @user.extend_batch_buffer(@token, @client_id)
|
52
|
+
|
53
|
+
# update Authorization response header with new token
|
54
|
+
elsif @user and @client_id
|
55
|
+
auth_header = @user.create_new_auth_token(@client_id)
|
45
56
|
end
|
57
|
+
|
58
|
+
response.headers["Authorization"] = auth_header if auth_header
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def is_batch_request?(user, client_id)
|
65
|
+
user.tokens[client_id] and
|
66
|
+
user.tokens[client_id]['updated_at'] and
|
67
|
+
user.tokens[client_id]['updated_at'] > Time.now - DeviseTokenAuth.batch_request_buffer_throttle
|
46
68
|
end
|
47
69
|
end
|
data/app/models/user.rb
CHANGED
@@ -7,36 +7,110 @@ class User < ActiveRecord::Base
|
|
7
7
|
|
8
8
|
serialize :tokens, JSON
|
9
9
|
|
10
|
-
# only validate unique emails among email registration users
|
11
10
|
validates_presence_of :email, if: Proc.new { |u| u.provider == 'email' }
|
12
11
|
validates_presence_of :confirm_success_url, if: Proc.new {|u| u.provider == 'email'}
|
13
12
|
|
13
|
+
# only validate unique emails among email registration users
|
14
14
|
validate :unique_email_user, on: :create
|
15
15
|
|
16
|
-
def valid_token?(
|
17
|
-
|
18
|
-
|
16
|
+
def valid_token?(token, client_id='default')
|
17
|
+
client_id ||= 'default'
|
18
|
+
|
19
|
+
return true if (
|
20
|
+
# ensure that expiry and token are set
|
21
|
+
self.tokens[client_id]['expiry'] and
|
22
|
+
self.tokens[client_id]['token'] and
|
23
|
+
|
24
|
+
# ensure that the token was created within the last two weeks
|
25
|
+
self.tokens[client_id]['expiry'] > DeviseTokenAuth.token_lifespan.ago.to_f * 1000 and
|
26
|
+
|
27
|
+
# ensure that the token is valid
|
28
|
+
BCrypt::Password.new(self.tokens[client_id]['token']) == token
|
29
|
+
)
|
30
|
+
|
31
|
+
return true if (
|
32
|
+
# ensure that the last token and its creation time exist
|
33
|
+
self.tokens[client_id]['updated_at'] and
|
34
|
+
self.tokens[client_id]['last_token'] and
|
35
|
+
|
36
|
+
# ensure that previous token falls within the batch buffer throttle time of the last request
|
37
|
+
Time.parse(self.tokens[client_id]['updated_at']) > Time.now - DeviseTokenAuth.batch_request_buffer_throttle and
|
38
|
+
|
39
|
+
# ensure that the token is valid
|
40
|
+
BCrypt::Password.new(self.tokens[client_id]['last_token']) == token
|
41
|
+
)
|
42
|
+
|
43
|
+
# return false if none of the above conditions are met
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# update user's auth token (should happen on each request)
|
49
|
+
def create_new_auth_token(client_id=nil)
|
50
|
+
client_id ||= SecureRandom.urlsafe_base64(nil, false)
|
51
|
+
last_token ||= nil
|
52
|
+
token = SecureRandom.urlsafe_base64(nil, false)
|
53
|
+
token_hash = BCrypt::Password.create(token)
|
54
|
+
expiry = (Time.now.to_f + DeviseTokenAuth.token_lifespan).to_i * 1000
|
55
|
+
|
56
|
+
if self.tokens[client_id] and self.tokens[client_id]['token']
|
57
|
+
last_token = self.tokens[client_id]['token']
|
58
|
+
end
|
59
|
+
|
60
|
+
self.tokens[client_id] = {
|
61
|
+
token: token_hash,
|
62
|
+
expiry: expiry,
|
63
|
+
last_token: last_token,
|
64
|
+
updated_at: Time.now
|
65
|
+
}
|
66
|
+
|
67
|
+
self.save!
|
19
68
|
|
20
|
-
return
|
69
|
+
return build_auth_header(token, client_id)
|
21
70
|
end
|
22
71
|
|
72
|
+
|
73
|
+
def build_auth_header(token, client_id='default')
|
74
|
+
client_id ||= 'default'
|
75
|
+
|
76
|
+
# client may use expiry to prevent validation request if expired
|
77
|
+
expiry = self.tokens[client_id]['expiry']
|
78
|
+
|
79
|
+
return "token=#{token} client=#{client_id} expiry=#{expiry} uid=#{self.uid}"
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def extend_batch_buffer(token, client_id)
|
84
|
+
self.tokens[client_id]['updated_at'] = Time.now
|
85
|
+
self.save!
|
86
|
+
|
87
|
+
return build_auth_header(token, client_id)
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
|
23
94
|
def serializable_hash(options={})
|
24
95
|
options ||= {}
|
25
96
|
options[:except] ||= [:tokens]
|
26
97
|
super(options)
|
27
98
|
end
|
28
99
|
|
100
|
+
|
29
101
|
# don't use default devise email validation
|
30
102
|
def email_changed?
|
31
103
|
false
|
32
104
|
end
|
33
105
|
|
106
|
+
|
34
107
|
def unique_email_user
|
35
108
|
if provider == 'email' and User.where(provider: 'email', email: email).count > 0
|
36
|
-
errors.add(:email, "
|
109
|
+
errors.add(:email, "This email address is already in use")
|
37
110
|
end
|
38
111
|
end
|
39
112
|
|
113
|
+
|
40
114
|
def email_required?
|
41
115
|
provider == 'email'
|
42
116
|
end
|
@@ -2,4 +2,16 @@ module DeviseTokenAuth
|
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
isolate_namespace DeviseTokenAuth
|
4
4
|
end
|
5
|
+
|
6
|
+
mattr_accessor :change_headers_on_each_request,
|
7
|
+
:token_lifespan,
|
8
|
+
:batch_request_buffer_throttle
|
9
|
+
|
10
|
+
self.change_headers_on_each_request = true
|
11
|
+
self.token_lifespan = 2.weeks
|
12
|
+
self.batch_request_buffer_throttle = 2.seconds
|
13
|
+
|
14
|
+
def self.setup(&block)
|
15
|
+
yield self
|
16
|
+
end
|
5
17
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
Description:
|
2
|
-
|
2
|
+
This generator will install all the necessary configuration and migration files for the devies_token_auth gem
|
3
3
|
|
4
4
|
Example:
|
5
|
-
rails generate devise_token_auth
|
5
|
+
rails generate devise_token_auth:install
|
6
6
|
|
7
7
|
This will create:
|
8
|
-
|
8
|
+
config/initializers/devise_token_auth.rb
|
9
|
+
db/migrate/xxxxxxxx_create_devise_token_auth_user.rb
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module DeviseTokenAuth
|
2
|
+
class InstallGenerator < Rails::Generators::Base
|
3
|
+
include Rails::Generators::Migration
|
4
|
+
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
6
|
+
|
7
|
+
desc "This generator creates an initializer file at config/initializers/devise_token_auth.rb"
|
8
|
+
def create_initializer_file
|
9
|
+
copy_file("devise_token_auth.rb", "config/initializers/devise_token_auth.rb")
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "This generator creates a user migration file at db/migrate/<%= migration_id %>_devise_token_auth_create_users.rb"
|
13
|
+
def copy_migrations
|
14
|
+
if self.class.migration_exists?("db/migrate", "devise_token_auth_create_users")
|
15
|
+
say_status("skipped", "Migration 'devise_token_auth' already exists")
|
16
|
+
else
|
17
|
+
migration_template("devise_token_auth_create_users.rb", "db/migrate/devise_token_auth_create_users.rb")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def self.next_migration_number(path)
|
24
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
DeviseTokenAuth.setup do |config|
|
2
|
+
# By default the authorization headers will change after each request. The
|
3
|
+
# client is responsible for keeping track of the changing tokens. Change
|
4
|
+
# this to false to prevent the Authorization header from changing after
|
5
|
+
# each request.
|
6
|
+
#config.change_headers_on_each_request = true
|
7
|
+
|
8
|
+
# By default, users will need to re-authenticate after 2 weeks. This setting
|
9
|
+
# determines how long tokens will remain valid after they are issued.
|
10
|
+
#config.token_lifespan = 2.weeks
|
11
|
+
|
12
|
+
# Sometimes it's necessary to make several requests to the API at the same
|
13
|
+
# time. In this case, each request in the batch will need to share the same
|
14
|
+
# auth token. This setting determines how far apart the requests can be while
|
15
|
+
# still using the same auth token.
|
16
|
+
#config.batch_request_buffer_throttle = 2.seconds
|
17
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# was the web request successful?
|
4
|
+
# was the user redirected to the right page?
|
5
|
+
# was the user successfully authenticated?
|
6
|
+
# was the correct object stored in the response?
|
7
|
+
# was the appropriate message delivered in the json payload?
|
8
|
+
|
9
|
+
class DemoControllerTest < ActionController::TestCase
|
10
|
+
describe DemoController, "Token access" do
|
11
|
+
setup do
|
12
|
+
@routes = Dummy::Application.routes
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
@user = users(:confirmed_email_user)
|
17
|
+
@user.skip_confirmation!
|
18
|
+
@user.save!
|
19
|
+
|
20
|
+
@auth_header = @user.create_new_auth_token
|
21
|
+
|
22
|
+
@token = @auth_header[/token=(.*?) /,1]
|
23
|
+
@client_id = @auth_header[/client=(.*?) /,1]
|
24
|
+
@expiry = @auth_header[/expiry=(.*?) /,1]
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'successful request' do
|
28
|
+
before do
|
29
|
+
# ensure that request is not treated as batch request
|
30
|
+
age_token(@user, @client_id)
|
31
|
+
|
32
|
+
request.headers['Authorization'] = @auth_header
|
33
|
+
xhr :get, :members_only
|
34
|
+
|
35
|
+
@resp_auth_header = response.headers['Authorization']
|
36
|
+
@resp_token = @resp_auth_header[/token=(.*?) /,1]
|
37
|
+
@resp_client_id = @resp_auth_header[/client=(.*?) /,1]
|
38
|
+
@resp_expiry = @resp_auth_header[/expiry=(.*?) /,1]
|
39
|
+
@resp_uid = @resp_auth_header[/uid=(.*?)$/,1]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should return success status' do
|
43
|
+
assert_equal 200, response.status
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should receive new token after successful request' do
|
47
|
+
refute_equal @token, @resp_token
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should preserve the client id from the first request' do
|
51
|
+
assert_equal @client_id, @resp_client_id
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return the user's uid in the auth header" do
|
55
|
+
assert_equal @user.uid, @resp_uid
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should not treat this request as a batch request' do
|
59
|
+
refute assigns(:is_batch_request)
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'succesive requests' do
|
63
|
+
before do
|
64
|
+
@user.reload
|
65
|
+
# ensure that request is not treated as batch request
|
66
|
+
age_token(@user, @client_id)
|
67
|
+
|
68
|
+
request.headers['Authorization'] = @resp_auth_header
|
69
|
+
|
70
|
+
xhr :get, :members_only
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should not treat this request as a batch request' do
|
74
|
+
refute assigns(:is_batch_request)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should allow a new request to be made using new token" do
|
78
|
+
assert_equal 200, response.status
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'failed request' do
|
84
|
+
before do
|
85
|
+
request.headers['Authorization'] = "token=bogus client=#{@client_id} uid=#{@user.uid}"
|
86
|
+
xhr :get, :members_only
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should not return any auth headers' do
|
90
|
+
refute response.headers['Authorization']
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should return error: unauthorized status' do
|
94
|
+
assert_equal 401, response.status
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'disable change_headers_on_each_request' do
|
99
|
+
before do
|
100
|
+
DeviseTokenAuth.change_headers_on_each_request = false
|
101
|
+
@user.reload
|
102
|
+
age_token(@user, @client_id)
|
103
|
+
|
104
|
+
request.headers['Authorization'] = @auth_header
|
105
|
+
xhr :get, :members_only
|
106
|
+
|
107
|
+
@first_is_batch_request = assigns(:is_batch_request)
|
108
|
+
@first_user = assigns(:user).dup
|
109
|
+
@first_auth_headers = response.headers['Authorization'].clone
|
110
|
+
@first_response_status = response.status
|
111
|
+
|
112
|
+
@user.reload
|
113
|
+
age_token(@user, @client_id)
|
114
|
+
|
115
|
+
# use expired auth header
|
116
|
+
request.headers['Authorization'] = @auth_header
|
117
|
+
xhr :get, :members_only
|
118
|
+
|
119
|
+
@second_is_batch_request = assigns(:is_batch_request)
|
120
|
+
@second_user = assigns(:user)
|
121
|
+
@second_auth_headers = response.headers['Authorization']
|
122
|
+
@second_response_status = response.status
|
123
|
+
end
|
124
|
+
|
125
|
+
after do
|
126
|
+
DeviseTokenAuth.change_headers_on_each_request = true
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should allow the first request through' do
|
130
|
+
assert_equal 200, @first_response_status
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should allow the second request through' do
|
134
|
+
assert_equal 200, @second_response_status
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should return auth headers from the first request' do
|
138
|
+
assert @first_auth_headers
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should return auth headers from the second request' do
|
142
|
+
assert @second_auth_headers
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should define user during first request' do
|
146
|
+
assert @first_user
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should define user during second request' do
|
150
|
+
assert @second_user
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe 'batch requests' do
|
155
|
+
describe 'success' do
|
156
|
+
before do
|
157
|
+
request.headers['Authorization'] = @auth_header
|
158
|
+
xhr :get, :members_only
|
159
|
+
|
160
|
+
@first_is_batch_request = assigns(:is_batch_request)
|
161
|
+
@first_user = assigns(:user)
|
162
|
+
@first_auth_headers = response.headers['Authorization']
|
163
|
+
|
164
|
+
request.headers['Authorization'] = @auth_header
|
165
|
+
xhr :get, :members_only
|
166
|
+
|
167
|
+
@second_is_batch_request = assigns(:is_batch_request)
|
168
|
+
@second_user = assigns(:user)
|
169
|
+
@second_auth_headers = response.headers['Authorization']
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should allow both requests through' do
|
173
|
+
assert_equal 200, response.status
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'should return the same auth headers for both requests' do
|
177
|
+
assert_equal @first_auth_headers, @second_auth_headers
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe 'time out' do
|
182
|
+
before do
|
183
|
+
@user.reload
|
184
|
+
age_token(@user, @client_id)
|
185
|
+
|
186
|
+
request.headers['Authorization'] = @auth_header
|
187
|
+
xhr :get, :members_only
|
188
|
+
|
189
|
+
@first_is_batch_request = assigns(:is_batch_request)
|
190
|
+
@first_user = assigns(:user).dup
|
191
|
+
@first_auth_headers = response.headers['Authorization'].clone
|
192
|
+
@first_response_status = response.status
|
193
|
+
|
194
|
+
@user.reload
|
195
|
+
age_token(@user, @client_id)
|
196
|
+
|
197
|
+
# use expired auth header
|
198
|
+
request.headers['Authorization'] = @auth_header
|
199
|
+
xhr :get, :members_only
|
200
|
+
|
201
|
+
@second_is_batch_request = assigns(:is_batch_request)
|
202
|
+
@second_user = assigns(:user)
|
203
|
+
@second_auth_headers = response.headers['Authorization']
|
204
|
+
@second_response_status = response.status
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'should allow the first request through' do
|
208
|
+
assert_equal 200, @first_response_status
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should not allow the second request through' do
|
212
|
+
assert_equal 401, @second_response_status
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'should return auth headers from the first request' do
|
216
|
+
assert @first_auth_headers
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'should not return auth headers from the second request' do
|
220
|
+
refute @second_auth_headers
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'should define user during first request' do
|
224
|
+
assert @first_user
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'should not define user during second request' do
|
228
|
+
refute @second_user
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|