g5_authenticatable_api 0.4.1 → 1.0.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +29 -8
- data/Appraisals +17 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile +13 -14
- data/README.md +11 -10
- data/Rakefile +21 -1
- data/g5_authenticatable_api.gemspec +1 -1
- data/gemfiles/rails_4.1.gemfile +28 -0
- data/gemfiles/rails_4.2.gemfile +28 -0
- data/gemfiles/rails_5.0.gemfile +28 -0
- data/gemfiles/rails_5.1.gemfile +28 -0
- data/lib/g5_authenticatable_api/helpers/grape.rb +16 -5
- data/lib/g5_authenticatable_api/helpers/rails.rb +23 -6
- data/lib/g5_authenticatable_api/railtie.rb +3 -0
- data/lib/g5_authenticatable_api/services/token_info.rb +26 -10
- data/lib/g5_authenticatable_api/services/token_validator.rb +23 -20
- data/lib/g5_authenticatable_api/services/user_fetcher.rb +3 -0
- data/lib/g5_authenticatable_api/version.rb +3 -1
- data/lib/g5_authenticatable_api.rb +3 -0
- data/spec/dummy/app/controllers/rails_api/articles_controller.rb +1 -1
- data/spec/dummy/config/environments/test.rb +18 -2
- data/spec/dummy/config/initializers/rails_compatibility.rb +10 -0
- data/spec/dummy/db/migrate/20140217124048_devise_create_users.rb +4 -2
- data/spec/dummy/db/migrate/20140223194521_create_articles.rb +3 -1
- data/spec/dummy/db/schema.rb +11 -13
- data/spec/factories/user.rb +2 -0
- data/spec/lib/g5_authenticatable_api/helpers/grape_spec.rb +36 -28
- data/spec/lib/g5_authenticatable_api/helpers/rails_spec.rb +39 -33
- data/spec/lib/g5_authenticatable_api/services/token_info_spec.rb +25 -19
- data/spec/lib/g5_authenticatable_api/services/token_validator_spec.rb +20 -12
- data/spec/lib/g5_authenticatable_api/services/user_fetcher_spec.rb +5 -3
- data/spec/lib/g5_authenticatable_api/version_spec.rb +4 -2
- data/spec/rails_helper.rb +39 -0
- data/spec/requests/grape_api_spec.rb +6 -4
- data/spec/requests/rails_api_spec.rb +5 -3
- data/spec/spec_helper.rb +18 -38
- data/spec/support/controller_test_helpers.rb +26 -0
- data/spec/support/factory_girl.rb +2 -0
- data/spec/support/shared_contexts/current_auth_user.rb +8 -6
- data/spec/support/shared_contexts/invalid_access_token.rb +12 -10
- data/spec/support/shared_contexts/valid_access_token.rb +9 -7
- data/spec/support/shared_examples/auth_user.rb +3 -1
- data/spec/support/shared_examples/token_authenticatable_api.rb +9 -7
- data/spec/support/shared_examples/token_validation.rb +14 -8
- data/spec/support/shared_examples/warden_authenticatable_api.rb +8 -7
- data/spec/support/warden.rb +2 -0
- metadata +20 -10
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support'
|
2
4
|
require 'active_support/core_ext/module/attribute_accessors'
|
3
5
|
|
@@ -7,6 +9,7 @@ require 'g5_authenticatable_api/railtie' if defined?(Rails)
|
|
7
9
|
|
8
10
|
require 'g5_authentication_client'
|
9
11
|
|
12
|
+
# Token-based authentication for protecting rails API endpoints with G5 Auth
|
10
13
|
module G5AuthenticatableApi
|
11
14
|
# When enabled, strict token validation will validate the session user's
|
12
15
|
# access_token against the auth server for every request (if there is
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
Dummy::Application.configure do
|
2
4
|
# Settings specified here will take precedence over those in config/application.rb.
|
3
5
|
|
@@ -13,8 +15,22 @@ Dummy::Application.configure do
|
|
13
15
|
config.eager_load = false
|
14
16
|
|
15
17
|
# Configure static asset server for tests with Cache-Control for performance.
|
16
|
-
|
17
|
-
|
18
|
+
cache_header_value = 'public, max-age=3600'
|
19
|
+
|
20
|
+
if config.respond_to?(:public_file_server)
|
21
|
+
config.public_file_server.enabled = true
|
22
|
+
config.public_file_server.headers = {
|
23
|
+
'Cache-Control' => cache_header_value
|
24
|
+
}
|
25
|
+
else
|
26
|
+
config.static_cache_control = cache_header_value
|
27
|
+
|
28
|
+
if config.respond_to?(:serve_static_files=)
|
29
|
+
config.serve_static_files = true
|
30
|
+
else
|
31
|
+
config.serve_static_assets = true
|
32
|
+
end
|
33
|
+
end
|
18
34
|
|
19
35
|
# Show full error reports and disable caching.
|
20
36
|
config.consider_all_requests_local = true
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Support migration version syntax in rails 4
|
4
|
+
ActiveSupport.on_load(:active_record) do
|
5
|
+
unless ActiveRecord::Migration.respond_to?(:[])
|
6
|
+
ActiveRecord::Migration.define_singleton_method(:[]) do |version|
|
7
|
+
self if version.to_s.starts_with?('4')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class DeviseCreateUsers < ActiveRecord::Migration[4.2]
|
2
4
|
def change
|
3
5
|
create_table(:users) do |t|
|
4
6
|
t.string :email, null: false, default: ''
|
@@ -10,6 +12,6 @@ class DeviseCreateUsers < ActiveRecord::Migration
|
|
10
12
|
end
|
11
13
|
|
12
14
|
add_index :users, :email, unique: true
|
13
|
-
add_index :users, [
|
15
|
+
add_index :users, %i[provider uid], unique: true
|
14
16
|
end
|
15
17
|
end
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
1
|
# This file is auto-generated from the current state of the database. Instead
|
3
2
|
# of editing this file, please use the migrations feature of Active Record to
|
4
3
|
# incrementally modify your database, and then regenerate this schema definition.
|
@@ -16,24 +15,23 @@ ActiveRecord::Schema.define(version: 20140223194521) do
|
|
16
15
|
# These are extensions that must be enabled in order to support this database
|
17
16
|
enable_extension "plpgsql"
|
18
17
|
|
19
|
-
create_table "articles", force:
|
20
|
-
t.string
|
21
|
-
t.text
|
22
|
-
t.string
|
18
|
+
create_table "articles", id: :serial, force: :cascade do |t|
|
19
|
+
t.string "title"
|
20
|
+
t.text "body"
|
21
|
+
t.string "tags"
|
23
22
|
t.datetime "created_at"
|
24
23
|
t.datetime "updated_at"
|
25
24
|
end
|
26
25
|
|
27
|
-
create_table "users", force:
|
28
|
-
t.string
|
29
|
-
t.string
|
30
|
-
t.string
|
31
|
-
t.string
|
26
|
+
create_table "users", id: :serial, force: :cascade do |t|
|
27
|
+
t.string "email", default: "", null: false
|
28
|
+
t.string "provider", default: "g5", null: false
|
29
|
+
t.string "uid", null: false
|
30
|
+
t.string "g5_access_token"
|
32
31
|
t.datetime "created_at"
|
33
32
|
t.datetime "updated_at"
|
33
|
+
t.index ["email"], name: "index_users_on_email", unique: true
|
34
|
+
t.index ["provider", "uid"], name: "index_users_on_provider_and_uid", unique: true
|
34
35
|
end
|
35
36
|
|
36
|
-
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
37
|
-
add_index "users", ["provider", "uid"], name: "index_users_on_provider_and_uid", unique: true, using: :btree
|
38
|
-
|
39
37
|
end
|
data/spec/factories/user.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe G5AuthenticatableApi::Helpers::Grape do
|
4
6
|
include Rack::Test::Methods
|
5
7
|
|
6
|
-
|
8
|
+
let(:app) do
|
7
9
|
Class.new(Grape::API) do
|
8
10
|
helpers G5AuthenticatableApi::Helpers::Grape
|
9
11
|
|
@@ -26,13 +28,15 @@ describe G5AuthenticatableApi::Helpers::Grape do
|
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
|
-
let(:env) { {'warden' => warden} }
|
31
|
+
let(:env) { { 'warden' => warden } }
|
30
32
|
let(:warden) { double(:warden) }
|
31
33
|
|
32
|
-
let(:params) { {'access_token' => token_value} }
|
34
|
+
let(:params) { { 'access_token' => token_value } }
|
33
35
|
let(:token_value) { 'abc123' }
|
34
36
|
|
35
|
-
let(:headers)
|
37
|
+
let(:headers) do
|
38
|
+
{ 'Host' => 'example.org', 'Cookie' => '' }
|
39
|
+
end
|
36
40
|
|
37
41
|
describe '#authenticate_user!' do
|
38
42
|
subject(:authenticate_user!) { get '/authenticate', params, env }
|
@@ -43,8 +47,8 @@ describe G5AuthenticatableApi::Helpers::Grape do
|
|
43
47
|
access_token: token_value)
|
44
48
|
end
|
45
49
|
before do
|
46
|
-
allow(G5AuthenticatableApi::Services::TokenValidator).to receive(:new)
|
47
|
-
and_return(token_validator)
|
50
|
+
allow(G5AuthenticatableApi::Services::TokenValidator).to receive(:new)
|
51
|
+
.and_return(token_validator)
|
48
52
|
end
|
49
53
|
|
50
54
|
context 'when token is valid' do
|
@@ -53,18 +57,19 @@ describe G5AuthenticatableApi::Helpers::Grape do
|
|
53
57
|
|
54
58
|
it 'initializes the token validator correctly' do
|
55
59
|
authenticate_user!
|
56
|
-
expect(G5AuthenticatableApi::Services::TokenValidator)
|
57
|
-
|
60
|
+
expect(G5AuthenticatableApi::Services::TokenValidator)
|
61
|
+
.to have_received(:new)
|
62
|
+
.with(params, headers, warden)
|
58
63
|
end
|
59
64
|
|
60
65
|
it 'is successful' do
|
61
66
|
authenticate_user!
|
62
|
-
expect(last_response).to
|
67
|
+
expect(last_response.status).to eq(200)
|
63
68
|
end
|
64
69
|
|
65
70
|
it 'does not set the authenticate response header' do
|
66
71
|
authenticate_user!
|
67
|
-
expect(last_response).to_not
|
72
|
+
expect(last_response.headers).to_not have_key('WWW-Authenticate')
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
@@ -74,7 +79,7 @@ describe G5AuthenticatableApi::Helpers::Grape do
|
|
74
79
|
|
75
80
|
it 'is unauthorized' do
|
76
81
|
authenticate_user!
|
77
|
-
expect(last_response).to
|
82
|
+
expect(last_response.status).to eq(401)
|
78
83
|
end
|
79
84
|
|
80
85
|
it 'renders an error message' do
|
@@ -84,25 +89,28 @@ describe G5AuthenticatableApi::Helpers::Grape do
|
|
84
89
|
|
85
90
|
it 'sets the authenticate response header' do
|
86
91
|
authenticate_user!
|
87
|
-
expect(last_response).to
|
92
|
+
expect(last_response.headers).to include(
|
93
|
+
'WWW-Authenticate' => auth_response_header
|
94
|
+
)
|
88
95
|
end
|
89
96
|
end
|
90
97
|
end
|
91
98
|
|
92
99
|
describe '#token_data' do
|
93
100
|
subject(:token_data) { get '/token_data', params, env }
|
94
|
-
|
95
101
|
before do
|
96
|
-
allow(G5AuthenticatableApi::Services::TokenInfo).to receive(:new)
|
97
|
-
and_return(token_info)
|
102
|
+
allow(G5AuthenticatableApi::Services::TokenInfo).to receive(:new)
|
103
|
+
.and_return(token_info)
|
98
104
|
end
|
99
105
|
let(:token_info) { double(:token_info, token_data: mock_token_data) }
|
100
|
-
let(:mock_token_data)
|
106
|
+
let(:mock_token_data) do
|
107
|
+
double(:token_data, to_json: '{result: mock_token_data_json}')
|
108
|
+
end
|
101
109
|
|
102
110
|
it 'initializes the token info service correctly' do
|
103
111
|
token_data
|
104
|
-
expect(G5AuthenticatableApi::Services::TokenInfo).to have_received(:new)
|
105
|
-
with(params, headers, warden)
|
112
|
+
expect(G5AuthenticatableApi::Services::TokenInfo).to have_received(:new)
|
113
|
+
.with(params, headers, warden)
|
106
114
|
end
|
107
115
|
|
108
116
|
it 'returns the token info from the service' do
|
@@ -115,16 +123,16 @@ describe G5AuthenticatableApi::Helpers::Grape do
|
|
115
123
|
subject(:current_user) { get '/current_user', params, env }
|
116
124
|
|
117
125
|
before do
|
118
|
-
allow(G5AuthenticatableApi::Services::UserFetcher).to receive(:new)
|
119
|
-
and_return(user_fetcher)
|
126
|
+
allow(G5AuthenticatableApi::Services::UserFetcher).to receive(:new)
|
127
|
+
.and_return(user_fetcher)
|
120
128
|
end
|
121
129
|
let(:user_fetcher) { double(:user_fetcher, current_user: user) }
|
122
130
|
let(:user) { double(:user, to_json: '{result: mock_user_json}') }
|
123
131
|
|
124
132
|
it 'initializes the user fetcher service correctly' do
|
125
133
|
current_user
|
126
|
-
expect(G5AuthenticatableApi::Services::UserFetcher).to have_received(:new)
|
127
|
-
with(params, headers, warden)
|
134
|
+
expect(G5AuthenticatableApi::Services::UserFetcher).to have_received(:new)
|
135
|
+
.with(params, headers, warden)
|
128
136
|
end
|
129
137
|
|
130
138
|
it 'returns the user from the service' do
|
@@ -137,15 +145,15 @@ describe G5AuthenticatableApi::Helpers::Grape do
|
|
137
145
|
subject(:access_token) { get '/access_token', params, env }
|
138
146
|
|
139
147
|
before do
|
140
|
-
allow(G5AuthenticatableApi::Services::TokenInfo).to receive(:new)
|
141
|
-
and_return(token_info)
|
148
|
+
allow(G5AuthenticatableApi::Services::TokenInfo).to receive(:new)
|
149
|
+
.and_return(token_info)
|
142
150
|
end
|
143
151
|
let(:token_info) { double(:token_info, access_token: token_value) }
|
144
152
|
|
145
153
|
it 'initializes the token info service correctly' do
|
146
154
|
access_token
|
147
|
-
expect(G5AuthenticatableApi::Services::TokenInfo).to have_received(:new)
|
148
|
-
with(params, headers, warden)
|
155
|
+
expect(G5AuthenticatableApi::Services::TokenInfo).to have_received(:new)
|
156
|
+
.with(params, headers, warden)
|
149
157
|
end
|
150
158
|
|
151
159
|
it 'returns the access token from the service' do
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe G5AuthenticatableApi::Helpers::Rails, type: :controller do
|
4
6
|
controller(ActionController::Base) do
|
5
7
|
before_action :authenticate_api_user!, only: :index
|
6
8
|
|
@@ -17,7 +19,9 @@ describe G5AuthenticatableApi::Helpers::Rails, type: :controller do
|
|
17
19
|
before { request.env['warden'] = warden }
|
18
20
|
|
19
21
|
describe '#authenticate_api_user!' do
|
20
|
-
subject(:authenticate_api_user!)
|
22
|
+
subject(:authenticate_api_user!) do
|
23
|
+
safe_get :index, access_token: token_value
|
24
|
+
end
|
21
25
|
|
22
26
|
let(:token_value) { 'abc123' }
|
23
27
|
|
@@ -27,8 +31,8 @@ describe G5AuthenticatableApi::Helpers::Rails, type: :controller do
|
|
27
31
|
access_token: token_value)
|
28
32
|
end
|
29
33
|
before do
|
30
|
-
allow(G5AuthenticatableApi::Services::TokenValidator).to receive(:new)
|
31
|
-
and_return(token_validator)
|
34
|
+
allow(G5AuthenticatableApi::Services::TokenValidator).to receive(:new)
|
35
|
+
.and_return(token_validator)
|
32
36
|
end
|
33
37
|
|
34
38
|
context 'when token is valid' do
|
@@ -37,10 +41,11 @@ describe G5AuthenticatableApi::Helpers::Rails, type: :controller do
|
|
37
41
|
|
38
42
|
it 'initializes the token validator correctly' do
|
39
43
|
authenticate_api_user!
|
40
|
-
expect(G5AuthenticatableApi::Services::TokenValidator)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
expect(G5AuthenticatableApi::Services::TokenValidator)
|
45
|
+
.to have_received(:new)
|
46
|
+
.with(request.params,
|
47
|
+
an_instance_of(ActionDispatch::Http::Headers),
|
48
|
+
warden)
|
44
49
|
end
|
45
50
|
|
46
51
|
it 'is successful' do
|
@@ -50,9 +55,8 @@ describe G5AuthenticatableApi::Helpers::Rails, type: :controller do
|
|
50
55
|
|
51
56
|
it 'does not set the authenticate response header' do
|
52
57
|
authenticate_api_user!
|
53
|
-
expect(response).to_not
|
58
|
+
expect(response.headers).to_not have_key('WWW-Authenticate')
|
54
59
|
end
|
55
|
-
|
56
60
|
end
|
57
61
|
|
58
62
|
context 'when token is invalid' do
|
@@ -61,7 +65,7 @@ describe G5AuthenticatableApi::Helpers::Rails, type: :controller do
|
|
61
65
|
|
62
66
|
it 'is unauthorized' do
|
63
67
|
authenticate_api_user!
|
64
|
-
expect(response).to
|
68
|
+
expect(response.status).to eq(401)
|
65
69
|
end
|
66
70
|
|
67
71
|
it 'renders an error message' do
|
@@ -75,20 +79,21 @@ describe G5AuthenticatableApi::Helpers::Rails, type: :controller do
|
|
75
79
|
subject(:token_data) { controller.token_data }
|
76
80
|
|
77
81
|
before do
|
78
|
-
allow(G5AuthenticatableApi::Services::TokenInfo).to receive(:new)
|
79
|
-
and_return(token_info)
|
82
|
+
allow(G5AuthenticatableApi::Services::TokenInfo).to receive(:new)
|
83
|
+
.and_return(token_info)
|
80
84
|
end
|
81
85
|
let(:token_info) { double(:user_fetcher, token_data: mock_token_data) }
|
82
86
|
let(:mock_token_data) { double(:token_info) }
|
83
87
|
|
84
|
-
before {
|
88
|
+
before { safe_get :new, access_token: 'abc123' }
|
85
89
|
|
86
90
|
it 'initializes the token info service correctly' do
|
87
91
|
token_data
|
88
|
-
expect(G5AuthenticatableApi::Services::TokenInfo)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
+
expect(G5AuthenticatableApi::Services::TokenInfo)
|
93
|
+
.to have_received(:new)
|
94
|
+
.with(request.params,
|
95
|
+
an_instance_of(ActionDispatch::Http::Headers),
|
96
|
+
warden)
|
92
97
|
end
|
93
98
|
|
94
99
|
it 'returns the token data from the service' do
|
@@ -100,20 +105,21 @@ describe G5AuthenticatableApi::Helpers::Rails, type: :controller do
|
|
100
105
|
subject(:access_token) { controller.access_token }
|
101
106
|
|
102
107
|
before do
|
103
|
-
allow(G5AuthenticatableApi::Services::TokenInfo).to receive(:new)
|
104
|
-
and_return(token_info)
|
108
|
+
allow(G5AuthenticatableApi::Services::TokenInfo).to receive(:new)
|
109
|
+
.and_return(token_info)
|
105
110
|
end
|
106
111
|
let(:token_info) { double(:token_info, access_token: token_value) }
|
107
112
|
let(:token_value) { 'abc123' }
|
108
113
|
|
109
|
-
before {
|
114
|
+
before { safe_get :new, access_token: token_value }
|
110
115
|
|
111
116
|
it 'initializes the token info service correctly' do
|
112
117
|
access_token
|
113
|
-
expect(G5AuthenticatableApi::Services::TokenInfo)
|
114
|
-
|
115
|
-
|
116
|
-
|
118
|
+
expect(G5AuthenticatableApi::Services::TokenInfo)
|
119
|
+
.to have_received(:new)
|
120
|
+
.with(request.params,
|
121
|
+
an_instance_of(ActionDispatch::Http::Headers),
|
122
|
+
warden)
|
117
123
|
end
|
118
124
|
|
119
125
|
it 'returns the access token from the service' do
|
@@ -125,20 +131,20 @@ describe G5AuthenticatableApi::Helpers::Rails, type: :controller do
|
|
125
131
|
subject(:current_api_user) { controller.current_api_user }
|
126
132
|
|
127
133
|
before do
|
128
|
-
allow(G5AuthenticatableApi::Services::UserFetcher).to receive(:new)
|
129
|
-
and_return(user_fetcher)
|
134
|
+
allow(G5AuthenticatableApi::Services::UserFetcher).to receive(:new)
|
135
|
+
.and_return(user_fetcher)
|
130
136
|
end
|
131
137
|
let(:user_fetcher) { double(:user_fetcher, current_user: user) }
|
132
138
|
let(:user) { double(:user) }
|
133
139
|
|
134
|
-
before {
|
140
|
+
before { safe_get :new, access_token: 'abc123' }
|
135
141
|
|
136
142
|
it 'initializes the user fetcher service correctly' do
|
137
143
|
current_api_user
|
138
|
-
expect(G5AuthenticatableApi::Services::UserFetcher).to have_received(:new)
|
139
|
-
with(request.params,
|
140
|
-
|
141
|
-
|
144
|
+
expect(G5AuthenticatableApi::Services::UserFetcher).to have_received(:new)
|
145
|
+
.with(request.params,
|
146
|
+
an_instance_of(ActionDispatch::Http::Headers),
|
147
|
+
warden)
|
142
148
|
end
|
143
149
|
|
144
150
|
it 'returns the user from the service' do
|
@@ -1,16 +1,18 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe G5AuthenticatableApi::Services::TokenInfo do
|
4
6
|
subject(:token_info) { described_class.new(params, headers, warden) }
|
5
|
-
let(:params) { {'access_token' => token_value} }
|
6
|
-
let(:headers) {
|
7
|
+
let(:params) { { 'access_token' => token_value } }
|
8
|
+
let(:headers) { {} }
|
7
9
|
let(:warden) {}
|
8
10
|
|
9
11
|
let(:token_value) { 'abc123' }
|
10
12
|
|
11
13
|
describe '#initialize' do
|
12
|
-
let(:params) { {'foo' => 'bar'} }
|
13
|
-
let(:headers) { {'Content-Type' => 'application/json'} }
|
14
|
+
let(:params) { { 'foo' => 'bar' } }
|
15
|
+
let(:headers) { { 'Content-Type' => 'application/json' } }
|
14
16
|
|
15
17
|
context 'with warden' do
|
16
18
|
let(:warden) { double(:warden) }
|
@@ -49,7 +51,7 @@ describe G5AuthenticatableApi::Services::TokenInfo do
|
|
49
51
|
subject(:access_token) { token_info.access_token }
|
50
52
|
|
51
53
|
context 'with auth header' do
|
52
|
-
let(:headers) { {'Authorization' => "Bearer #{token_value}"} }
|
54
|
+
let(:headers) { { 'Authorization' => "Bearer #{token_value}" } }
|
53
55
|
let(:params) {}
|
54
56
|
|
55
57
|
it 'should extract the token value from the header' do
|
@@ -58,7 +60,7 @@ describe G5AuthenticatableApi::Services::TokenInfo do
|
|
58
60
|
end
|
59
61
|
|
60
62
|
context 'with all caps authorization key' do
|
61
|
-
let(:headers) { {'AUTHORIZATION' => "Bearer #{token_value}"} }
|
63
|
+
let(:headers) { { 'AUTHORIZATION' => "Bearer #{token_value}" } }
|
62
64
|
let(:params) {}
|
63
65
|
|
64
66
|
it 'should extract the token value from the header' do
|
@@ -67,7 +69,7 @@ describe G5AuthenticatableApi::Services::TokenInfo do
|
|
67
69
|
end
|
68
70
|
|
69
71
|
context 'with auth param' do
|
70
|
-
let(:params) { {'access_token' => token_value} }
|
72
|
+
let(:params) { { 'access_token' => token_value } }
|
71
73
|
let(:headers) {}
|
72
74
|
|
73
75
|
it 'should extract the token value from the access_token parameter' do
|
@@ -89,7 +91,7 @@ describe G5AuthenticatableApi::Services::TokenInfo do
|
|
89
91
|
end
|
90
92
|
|
91
93
|
context 'with auth param' do
|
92
|
-
let(:params) { {'access_token' => token_value} }
|
94
|
+
let(:params) { { 'access_token' => token_value } }
|
93
95
|
let(:headers) {}
|
94
96
|
|
95
97
|
it 'should give precedence to the token on the request' do
|
@@ -106,19 +108,23 @@ describe G5AuthenticatableApi::Services::TokenInfo do
|
|
106
108
|
include_context 'valid access token'
|
107
109
|
|
108
110
|
it 'includes the resource_owner_id' do
|
109
|
-
expect(token_data.resource_owner_id)
|
111
|
+
expect(token_data.resource_owner_id)
|
112
|
+
.to eq(raw_token_info['resource_owner_id'])
|
110
113
|
end
|
111
114
|
|
112
115
|
it 'includes the expires_in_seconds' do
|
113
|
-
expect(token_data.expires_in_seconds)
|
116
|
+
expect(token_data.expires_in_seconds)
|
117
|
+
.to eq(raw_token_info['expires_in_seconds'])
|
114
118
|
end
|
115
119
|
|
116
120
|
it 'includes the application_uid' do
|
117
|
-
expect(token_data.application_uid)
|
121
|
+
expect(token_data.application_uid)
|
122
|
+
.to eq(raw_token_info['application']['uid'])
|
118
123
|
end
|
119
124
|
|
120
125
|
it 'includes the scopes' do
|
121
|
-
expect(token_data.scopes)
|
126
|
+
expect(token_data.scopes)
|
127
|
+
.to eq(raw_token_info['scopes'])
|
122
128
|
end
|
123
129
|
end
|
124
130
|
|
@@ -126,7 +132,7 @@ describe G5AuthenticatableApi::Services::TokenInfo do
|
|
126
132
|
include_context 'invalid access token'
|
127
133
|
|
128
134
|
it 'raises an error' do
|
129
|
-
expect { token_data }.to raise_error
|
135
|
+
expect { token_data }.to raise_error(OAuth2::Error)
|
130
136
|
end
|
131
137
|
end
|
132
138
|
end
|
@@ -145,14 +151,14 @@ describe G5AuthenticatableApi::Services::TokenInfo do
|
|
145
151
|
|
146
152
|
it 'initializes the client with the token' do
|
147
153
|
auth_client
|
148
|
-
expect(G5AuthenticationClient::Client).to have_received(:new)
|
149
|
-
with(hash_including(access_token: token_value))
|
154
|
+
expect(G5AuthenticationClient::Client).to have_received(:new)
|
155
|
+
.with(hash_including(access_token: token_value))
|
150
156
|
end
|
151
157
|
|
152
158
|
it 'disables password access on the client' do
|
153
159
|
auth_client
|
154
|
-
expect(G5AuthenticationClient::Client).to have_received(:new)
|
155
|
-
with(hash_including(allow_password_credentials: 'false'))
|
160
|
+
expect(G5AuthenticationClient::Client).to have_received(:new)
|
161
|
+
.with(hash_including(allow_password_credentials: 'false'))
|
156
162
|
end
|
157
163
|
end
|
158
164
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe G5AuthenticatableApi::Services::TokenValidator do
|
4
6
|
subject { validator }
|
5
7
|
|
6
8
|
let(:validator) { described_class.new(params, headers, warden) }
|
7
9
|
|
8
10
|
let(:headers) {}
|
9
|
-
let(:params) { {'access_token' => token_value} }
|
11
|
+
let(:params) { { 'access_token' => token_value } }
|
10
12
|
let(:token_value) { 'abc123' }
|
11
13
|
let(:warden) {}
|
12
14
|
|
@@ -19,8 +21,9 @@ describe G5AuthenticatableApi::Services::TokenValidator do
|
|
19
21
|
|
20
22
|
it 'should initialize the auth client with the access token' do
|
21
23
|
validate!
|
22
|
-
expect(a_request(:get, 'auth.g5search.com/oauth/token/info')
|
23
|
-
|
24
|
+
expect(a_request(:get, 'auth.g5search.com/oauth/token/info')
|
25
|
+
.with(headers: { 'Authorization' => "Bearer #{token_value}" }))
|
26
|
+
.to have_been_made
|
24
27
|
end
|
25
28
|
|
26
29
|
it 'should not raise errors during validation' do
|
@@ -52,7 +55,9 @@ describe G5AuthenticatableApi::Services::TokenValidator do
|
|
52
55
|
|
53
56
|
context 'when token is on the warden user' do
|
54
57
|
let(:warden) { double(:warden, user: user) }
|
55
|
-
let(:user)
|
58
|
+
let(:user) do
|
59
|
+
FactoryGirl.build_stubbed(:user, g5_access_token: token_value)
|
60
|
+
end
|
56
61
|
let(:params) {}
|
57
62
|
let(:headers) {}
|
58
63
|
|
@@ -64,8 +69,9 @@ describe G5AuthenticatableApi::Services::TokenValidator do
|
|
64
69
|
|
65
70
|
it 'should validate the access token against the auth server' do
|
66
71
|
validate!
|
67
|
-
expect(a_request(:get, 'auth.g5search.com/oauth/token/info')
|
68
|
-
|
72
|
+
expect(a_request(:get, 'auth.g5search.com/oauth/token/info')
|
73
|
+
.with(headers: { 'Authorization' => "Bearer #{token_value}" }))
|
74
|
+
.to have_been_made
|
69
75
|
end
|
70
76
|
|
71
77
|
it 'should not raise errors during validation' do
|
@@ -87,7 +93,8 @@ describe G5AuthenticatableApi::Services::TokenValidator do
|
|
87
93
|
|
88
94
|
it 'should not validate the access token against the auth server' do
|
89
95
|
validate!
|
90
|
-
expect(a_request(:get, 'authg5search.com/oauth/token/info'))
|
96
|
+
expect(a_request(:get, 'authg5search.com/oauth/token/info'))
|
97
|
+
.to_not have_been_made
|
91
98
|
end
|
92
99
|
|
93
100
|
it 'should not raise errors during validation' do
|
@@ -138,7 +145,8 @@ describe G5AuthenticatableApi::Services::TokenValidator do
|
|
138
145
|
end
|
139
146
|
|
140
147
|
it 'should set an error on the validator' do
|
141
|
-
expect { valid? }.to change { validator.error }
|
148
|
+
expect { valid? }.to change { validator.error }
|
149
|
+
.from(nil).to(an_instance_of(OAuth2::Error))
|
142
150
|
end
|
143
151
|
end
|
144
152
|
|
@@ -151,8 +159,8 @@ describe G5AuthenticatableApi::Services::TokenValidator do
|
|
151
159
|
end
|
152
160
|
|
153
161
|
it 'should set an error on the validator' do
|
154
|
-
expect { valid? }.to change { validator.error }
|
155
|
-
from(nil).to(an_instance_of(RuntimeError))
|
162
|
+
expect { valid? }.to change { validator.error }
|
163
|
+
.from(nil).to(an_instance_of(RuntimeError))
|
156
164
|
end
|
157
165
|
end
|
158
166
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe G5AuthenticatableApi::Services::UserFetcher do
|
4
6
|
subject(:user_fetcher) { described_class.new(params, headers, warden) }
|
5
|
-
let(:params) { {'access_token' => token_value} }
|
7
|
+
let(:params) { { 'access_token' => token_value } }
|
6
8
|
let(:token_value) { 'abc123' }
|
7
9
|
let(:headers) {}
|
8
10
|
let(:warden) {}
|