g5_authenticatable_api 0.4.1 → 1.0.0.pre.1
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/.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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75dde541965b5e6f7592ad1d4e8577a87132bfdf
|
4
|
+
data.tar.gz: 877a7828b65a3f995c2c4eddea47a45f545e4f62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3b25ec2f6b3b616fca70b0d0a986376350a00787f5a69f2dcd46cbb5fcc63bd6a8c464a76d7bc3c1bc218356c03627da9287439fe48b73914597a43e592210e
|
7
|
+
data.tar.gz: 90099f07198141a0a4289c22ed63a77c01b8bdb02e65953ad5bad41f21ea0aea3ea8e58663ca684c5b06af0a0ccc8a9f55a170235e3b902cfe238e4acdeb09f1
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.3.4
|
data/.travis.yml
CHANGED
@@ -1,13 +1,34 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.
|
4
|
-
- 2.
|
5
|
-
- 2.
|
6
|
-
|
7
|
-
-
|
8
|
-
-
|
9
|
-
|
10
|
-
-
|
3
|
+
- 2.2.7
|
4
|
+
- 2.3.4
|
5
|
+
- 2.4.1
|
6
|
+
gemfile:
|
7
|
+
- gemfiles/rails_4.1.gemfile
|
8
|
+
- gemfiles/rails_4.2.gemfile
|
9
|
+
- gemfiles/rails_5.0.gemfile
|
10
|
+
- gemfiles/rails_5.1.gemfile
|
11
|
+
matrix:
|
12
|
+
exclude:
|
13
|
+
- rvm: 2.4.1
|
14
|
+
gemfile: gemfiles/rails_4.1.gemfile
|
15
|
+
allow_failures:
|
16
|
+
- rvm: 2.4.1
|
17
|
+
cache:
|
18
|
+
bundler: true
|
19
|
+
dist: trusty
|
20
|
+
sudo: false
|
11
21
|
env:
|
12
22
|
global:
|
13
23
|
- DEVISE_SECRET_KEY=foo
|
24
|
+
before_script:
|
25
|
+
- cp spec/dummy/config/database.yml.ci spec/dummy/config/database.yml
|
26
|
+
- RAILS_ENV=test bundle exec rake app:db:create app:db:migrate
|
27
|
+
script:
|
28
|
+
- bundle exec rspec
|
29
|
+
after_script:
|
30
|
+
- bundle exec codeclimate-test-reporter
|
31
|
+
addons:
|
32
|
+
code_climate:
|
33
|
+
repo_token:
|
34
|
+
secure: "e2vpIAPiaVnWD1w0JcWV2gl1LyNPqlUomlUeBvyHCEzxDpMxoXOTfsLQhQ/LzQC1FH9Ph0lXPRHfM7wL/WJxHThqHFpCM784lbE/Zbp9W9u8btMhCEl8ZYSynm/5+Ycsh8tJD7UCduCqdNF3zXJ450BwoVBcQri4FqsyWXp5lcE="
|
data/Appraisals
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
appraise 'rails-4.1' do
|
4
|
+
gem 'rails', '~> 4.1.16'
|
5
|
+
end
|
6
|
+
|
7
|
+
appraise 'rails-4.2' do
|
8
|
+
gem 'rails', '~> 4.2.8'
|
9
|
+
end
|
10
|
+
|
11
|
+
appraise 'rails-5.0' do
|
12
|
+
gem 'rails', '~> 5.0.3'
|
13
|
+
end
|
14
|
+
|
15
|
+
appraise 'rails-5.1' do
|
16
|
+
gem 'rails', '~> 5.1.1'
|
17
|
+
end
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## v1.0.0.pre.1 (2017-06-12)
|
2
|
+
|
3
|
+
* **Backwards incompatible changes**
|
4
|
+
* Drop support for ruby < 2.2
|
5
|
+
* Drop support for rails < 4.1
|
6
|
+
* Enhancements
|
7
|
+
* Add support for ruby 2.3 and 2.4 (experimental)
|
8
|
+
* Add support for rails 5.0 and 5.1
|
9
|
+
|
1
10
|
## v0.4.0 (2015-05-22)
|
2
11
|
|
3
12
|
* Add helpers for retrieving current API user as well as more detailed token
|
data/Gemfile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source 'https://rubygems.org'
|
2
4
|
|
3
5
|
# Declare your gem's dependencies in g5_authenticatable_api.gemspec.
|
@@ -6,34 +8,31 @@ source 'https://rubygems.org'
|
|
6
8
|
gemspec
|
7
9
|
|
8
10
|
# Gems used by the dummy application
|
9
|
-
gem '
|
11
|
+
gem 'devise'
|
12
|
+
gem 'devise_g5_authenticatable', '1.0.0.pre.1'
|
13
|
+
gem 'grape'
|
10
14
|
gem 'jquery-rails'
|
11
15
|
gem 'pg'
|
12
|
-
gem '
|
13
|
-
gem 'devise'
|
14
|
-
gem 'devise_g5_authenticatable'
|
16
|
+
gem 'rails', '5.1.1'
|
15
17
|
|
16
18
|
group :test, :development do
|
17
|
-
gem '
|
18
|
-
gem 'pry'
|
19
|
+
gem 'appraisal'
|
20
|
+
gem 'pry-byebug'
|
21
|
+
gem 'rspec-rails', '~> 3.6'
|
19
22
|
end
|
20
23
|
|
21
24
|
group :test do
|
22
25
|
gem 'capybara'
|
26
|
+
gem 'codeclimate-test-reporter', '~> 1.0'
|
23
27
|
gem 'factory_girl_rails', '~> 4.3', require: false
|
28
|
+
gem 'rack-test'
|
29
|
+
gem 'shoulda-matchers', '~> 3.1'
|
24
30
|
gem 'simplecov', require: false
|
25
|
-
gem 'codeclimate-test-reporter', require: false
|
26
31
|
gem 'webmock'
|
27
|
-
gem 'shoulda-matchers', '~> 2.6'
|
28
|
-
gem 'rspec-http', require: false
|
29
|
-
gem 'rack-test'
|
30
32
|
end
|
31
33
|
|
32
34
|
# Declare any dependencies that are still in development here instead of in
|
33
35
|
# your gemspec. These might include edge Rails or gems from your path or
|
34
36
|
# Git. Remember to move these dependencies to your gemspec before releasing
|
35
37
|
# your gem to rubygems.org.
|
36
|
-
# gem 'g5_authentication_client',
|
37
|
-
|
38
|
-
# To use debugger
|
39
|
-
# gem 'debugger'
|
38
|
+
# gem 'g5_authentication_client', github: 'G5/g5_authentication_client'
|
data/README.md
CHANGED
@@ -9,14 +9,15 @@ service using token-based authentication.
|
|
9
9
|
|
10
10
|
## Current Version
|
11
11
|
|
12
|
-
0.
|
12
|
+
1.0.0.pre.1
|
13
13
|
|
14
14
|
## Requirements
|
15
15
|
|
16
|
-
*
|
16
|
+
* ruby >= 2.2 (support for ruby 2.4 is still experimental)
|
17
17
|
|
18
|
-
|
18
|
+
At least one of:
|
19
19
|
|
20
|
+
* [rails](http://rubyonrails.org/) >= 4.1
|
20
21
|
* [grape](https://github.com/intridea/grape)
|
21
22
|
|
22
23
|
## Installation
|
@@ -86,7 +87,7 @@ To require authentication for all API actions:
|
|
86
87
|
|
87
88
|
```ruby
|
88
89
|
class MyResourceController < ApplicationController
|
89
|
-
|
90
|
+
before_action :authenticate_api_user!
|
90
91
|
|
91
92
|
respond_to :json
|
92
93
|
|
@@ -98,7 +99,7 @@ To require authentication for some API actions:
|
|
98
99
|
|
99
100
|
```ruby
|
100
101
|
class MyResourceController < ApplicationController
|
101
|
-
|
102
|
+
before_action :authenticate_api_user!, only: [:create, :update]
|
102
103
|
|
103
104
|
respond_to :json
|
104
105
|
|
@@ -112,7 +113,7 @@ using the `token_data` helper:
|
|
112
113
|
|
113
114
|
```ruby
|
114
115
|
class MyResourceController < ApplicationController
|
115
|
-
|
116
|
+
before_action :authenticate_api_user!
|
116
117
|
|
117
118
|
respond_to :json
|
118
119
|
|
@@ -130,7 +131,7 @@ a [`G5AuthenticationClient::User`](https://github.com/G5/g5_authentication_clien
|
|
130
131
|
|
131
132
|
```ruby
|
132
133
|
class MyResourceController < ApplicationController
|
133
|
-
|
134
|
+
before_action :authenticate_api_user!
|
134
135
|
|
135
136
|
respond_to :json
|
136
137
|
|
@@ -147,7 +148,7 @@ by using the `access_token` helper:
|
|
147
148
|
|
148
149
|
```ruby
|
149
150
|
class MyResourceController < ApplicationController
|
150
|
-
|
151
|
+
before_action :authenticate_api_user!
|
151
152
|
|
152
153
|
respond_to :json
|
153
154
|
|
@@ -306,7 +307,7 @@ application:
|
|
306
307
|
|
307
308
|
```ruby
|
308
309
|
class WelcomeController < ApplicationController
|
309
|
-
|
310
|
+
before_action :authenticate_user!
|
310
311
|
|
311
312
|
def index
|
312
313
|
end
|
@@ -333,7 +334,7 @@ Protect your API actions in your controller:
|
|
333
334
|
|
334
335
|
```ruby
|
335
336
|
class Api::MyResourcesController < ApplicationController
|
336
|
-
|
337
|
+
before_action :authenticate_api_user!
|
337
338
|
|
338
339
|
respond_to :json
|
339
340
|
|
data/Rakefile
CHANGED
@@ -1 +1,21 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
|
10
|
+
load 'rails/tasks/engine.rake'
|
11
|
+
|
12
|
+
Bundler::GemHelper.install_tasks
|
13
|
+
|
14
|
+
Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each { |f| load f }
|
15
|
+
|
16
|
+
require 'rspec/core'
|
17
|
+
require 'rspec/core/rake_task'
|
18
|
+
|
19
|
+
desc 'Run all specs in spec directory (excluding plugin specs)'
|
20
|
+
RSpec::Core::RakeTask.new(spec: 'app:db:test:prepare')
|
21
|
+
task default: :spec
|
@@ -19,6 +19,6 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_dependency 'rack'
|
22
|
-
spec.add_dependency 'g5_authentication_client', '
|
22
|
+
spec.add_dependency 'g5_authentication_client', '1.0.0.pre.4'
|
23
23
|
spec.add_dependency 'activesupport', '>= 3.2'
|
24
24
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "devise"
|
6
|
+
gem "devise_g5_authenticatable", "1.0.0.pre.1"
|
7
|
+
gem "grape"
|
8
|
+
gem "jquery-rails"
|
9
|
+
gem "pg"
|
10
|
+
gem "rails", "~> 4.1.16"
|
11
|
+
|
12
|
+
group :test, :development do
|
13
|
+
gem "appraisal"
|
14
|
+
gem "pry-byebug"
|
15
|
+
gem "rspec-rails", "~> 3.6"
|
16
|
+
end
|
17
|
+
|
18
|
+
group :test do
|
19
|
+
gem "capybara"
|
20
|
+
gem "codeclimate-test-reporter", "~> 1.0"
|
21
|
+
gem "factory_girl_rails", "~> 4.3", require: false
|
22
|
+
gem "rack-test"
|
23
|
+
gem "shoulda-matchers", "~> 3.1"
|
24
|
+
gem "simplecov", require: false
|
25
|
+
gem "webmock"
|
26
|
+
end
|
27
|
+
|
28
|
+
gemspec path: "../"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "devise"
|
6
|
+
gem "devise_g5_authenticatable", "1.0.0.pre.1"
|
7
|
+
gem "grape"
|
8
|
+
gem "jquery-rails"
|
9
|
+
gem "pg"
|
10
|
+
gem "rails", "~> 4.2.8"
|
11
|
+
|
12
|
+
group :test, :development do
|
13
|
+
gem "appraisal"
|
14
|
+
gem "pry-byebug"
|
15
|
+
gem "rspec-rails", "~> 3.6"
|
16
|
+
end
|
17
|
+
|
18
|
+
group :test do
|
19
|
+
gem "capybara"
|
20
|
+
gem "codeclimate-test-reporter", "~> 1.0"
|
21
|
+
gem "factory_girl_rails", "~> 4.3", require: false
|
22
|
+
gem "rack-test"
|
23
|
+
gem "shoulda-matchers", "~> 3.1"
|
24
|
+
gem "simplecov", require: false
|
25
|
+
gem "webmock"
|
26
|
+
end
|
27
|
+
|
28
|
+
gemspec path: "../"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "devise"
|
6
|
+
gem "devise_g5_authenticatable", "1.0.0.pre.1"
|
7
|
+
gem "grape"
|
8
|
+
gem "jquery-rails"
|
9
|
+
gem "pg"
|
10
|
+
gem "rails", "~> 5.0.3"
|
11
|
+
|
12
|
+
group :test, :development do
|
13
|
+
gem "appraisal"
|
14
|
+
gem "pry-byebug"
|
15
|
+
gem "rspec-rails", "~> 3.6"
|
16
|
+
end
|
17
|
+
|
18
|
+
group :test do
|
19
|
+
gem "capybara"
|
20
|
+
gem "codeclimate-test-reporter", "~> 1.0"
|
21
|
+
gem "factory_girl_rails", "~> 4.3", require: false
|
22
|
+
gem "rack-test"
|
23
|
+
gem "shoulda-matchers", "~> 3.1"
|
24
|
+
gem "simplecov", require: false
|
25
|
+
gem "webmock"
|
26
|
+
end
|
27
|
+
|
28
|
+
gemspec path: "../"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "devise"
|
6
|
+
gem "devise_g5_authenticatable", "1.0.0.pre.1"
|
7
|
+
gem "grape"
|
8
|
+
gem "jquery-rails"
|
9
|
+
gem "pg"
|
10
|
+
gem "rails", "~> 5.1.1"
|
11
|
+
|
12
|
+
group :test, :development do
|
13
|
+
gem "appraisal"
|
14
|
+
gem "pry-byebug"
|
15
|
+
gem "rspec-rails", "~> 3.6"
|
16
|
+
end
|
17
|
+
|
18
|
+
group :test do
|
19
|
+
gem "capybara"
|
20
|
+
gem "codeclimate-test-reporter", "~> 1.0"
|
21
|
+
gem "factory_girl_rails", "~> 4.3", require: false
|
22
|
+
gem "rack-test"
|
23
|
+
gem "shoulda-matchers", "~> 3.1"
|
24
|
+
gem "simplecov", require: false
|
25
|
+
gem "webmock"
|
26
|
+
end
|
27
|
+
|
28
|
+
gemspec path: "../"
|
@@ -1,11 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'g5_authenticatable_api/services/token_validator'
|
2
4
|
require 'g5_authenticatable_api/services/user_fetcher'
|
3
5
|
|
4
6
|
module G5AuthenticatableApi
|
5
7
|
module Helpers
|
8
|
+
# Helper methods for securing a Grape API
|
6
9
|
module Grape
|
7
10
|
def authenticate_user!
|
8
|
-
raise_auth_error
|
11
|
+
raise_auth_error unless token_validator.valid?
|
9
12
|
end
|
10
13
|
|
11
14
|
def token_data
|
@@ -24,27 +27,35 @@ module G5AuthenticatableApi
|
|
24
27
|
env['warden']
|
25
28
|
end
|
26
29
|
|
27
|
-
private
|
28
30
|
def request
|
29
31
|
Rack::Request.new(env)
|
30
32
|
end
|
31
33
|
|
34
|
+
protected
|
35
|
+
|
32
36
|
def token_info
|
33
37
|
@token_info ||= Services::TokenInfo.new(request.params, headers, warden)
|
34
38
|
end
|
35
39
|
|
36
40
|
def token_validator
|
37
|
-
@token_validator ||= Services::TokenValidator.new(request.params,
|
41
|
+
@token_validator ||= Services::TokenValidator.new(request.params,
|
42
|
+
headers,
|
43
|
+
warden)
|
38
44
|
end
|
39
45
|
|
40
46
|
def user_fetcher
|
41
|
-
@user_fetcher ||= Services::UserFetcher.new(request.params,
|
47
|
+
@user_fetcher ||= Services::UserFetcher.new(request.params,
|
48
|
+
headers,
|
49
|
+
warden)
|
42
50
|
end
|
43
51
|
|
44
52
|
def raise_auth_error
|
53
|
+
auth_header = {
|
54
|
+
'WWW-Authenticate' => token_validator.auth_response_header
|
55
|
+
}
|
45
56
|
throw :error, message: 'Unauthorized',
|
46
57
|
status: 401,
|
47
|
-
headers:
|
58
|
+
headers: auth_header
|
48
59
|
end
|
49
60
|
end
|
50
61
|
end
|
@@ -1,11 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'g5_authenticatable_api/services/token_validator'
|
2
4
|
require 'g5_authenticatable_api/services/user_fetcher'
|
3
5
|
|
4
6
|
module G5AuthenticatableApi
|
5
7
|
module Helpers
|
8
|
+
# Helpers for rails API controllers
|
6
9
|
module Rails
|
7
10
|
def authenticate_api_user!
|
8
|
-
raise_auth_error
|
11
|
+
raise_auth_error unless token_validator.valid?
|
9
12
|
end
|
10
13
|
|
11
14
|
def token_data
|
@@ -25,21 +28,35 @@ module G5AuthenticatableApi
|
|
25
28
|
end
|
26
29
|
|
27
30
|
private
|
31
|
+
|
28
32
|
def token_info
|
29
|
-
@token_info ||= Services::TokenInfo.new(
|
33
|
+
@token_info ||= Services::TokenInfo.new(
|
34
|
+
request.params,
|
35
|
+
request.headers,
|
36
|
+
warden
|
37
|
+
)
|
30
38
|
end
|
31
39
|
|
32
40
|
def token_validator
|
33
|
-
@token_validator ||= Services::TokenValidator.new(
|
41
|
+
@token_validator ||= Services::TokenValidator.new(
|
42
|
+
request.params,
|
43
|
+
request.headers,
|
44
|
+
warden
|
45
|
+
)
|
34
46
|
end
|
35
47
|
|
36
48
|
def user_fetcher
|
37
|
-
@user_fetcher ||= Services::UserFetcher.new(
|
49
|
+
@user_fetcher ||= Services::UserFetcher.new(
|
50
|
+
request.params,
|
51
|
+
request.headers,
|
52
|
+
warden
|
53
|
+
)
|
38
54
|
end
|
39
55
|
|
40
56
|
def raise_auth_error
|
41
|
-
|
42
|
-
|
57
|
+
auth_header = token_validator.auth_response_header
|
58
|
+
response.headers['WWW-Authenticate'] = auth_header
|
59
|
+
render json: { error: 'Unauthorized' },
|
43
60
|
status: :unauthorized
|
44
61
|
end
|
45
62
|
end
|
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'g5_authenticatable_api/helpers/rails'
|
2
4
|
|
3
5
|
module G5AuthenticatableApi
|
6
|
+
# Hook into the rails app initialization
|
4
7
|
class Railtie < Rails::Railtie
|
5
8
|
initializer 'g5_authenticatable.helpers' do
|
6
9
|
ActiveSupport.on_load(:action_controller) do
|
@@ -1,18 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module G5AuthenticatableApi
|
2
4
|
module Services
|
5
|
+
# Extract access token from request to retrieve token data from G5 Auth
|
3
6
|
class TokenInfo
|
4
7
|
attr_reader :params, :headers, :warden
|
5
8
|
|
6
|
-
def initialize(params={},headers={},warden=nil)
|
9
|
+
def initialize(params = {}, headers = {}, warden = nil)
|
7
10
|
@params = params || {}
|
8
11
|
@headers = headers || {}
|
9
12
|
@warden = warden
|
10
13
|
end
|
11
14
|
|
12
15
|
def access_token
|
13
|
-
@access_token ||=
|
14
|
-
|
15
|
-
|
16
|
+
@access_token ||= begin
|
17
|
+
extract_token_from_header ||
|
18
|
+
extract_token_from_params ||
|
19
|
+
extract_token_from_warden
|
20
|
+
end
|
16
21
|
end
|
17
22
|
|
18
23
|
def token_data
|
@@ -20,16 +25,27 @@ module G5AuthenticatableApi
|
|
20
25
|
end
|
21
26
|
|
22
27
|
def auth_client
|
23
|
-
@auth_client ||= G5AuthenticationClient::Client.new(
|
24
|
-
|
28
|
+
@auth_client ||= G5AuthenticationClient::Client.new(
|
29
|
+
allow_password_credentials: 'false',
|
30
|
+
access_token: access_token
|
31
|
+
)
|
25
32
|
end
|
26
33
|
|
27
34
|
private
|
35
|
+
|
28
36
|
def extract_token_from_header
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
37
|
+
return unless authorization_header
|
38
|
+
parts = authorization_header.match(/Bearer (?<access_token>\S+)/)
|
39
|
+
parts['access_token']
|
40
|
+
end
|
41
|
+
|
42
|
+
def extract_token_from_params
|
43
|
+
return if params['access_token'].blank?
|
44
|
+
params['access_token']
|
45
|
+
end
|
46
|
+
|
47
|
+
def extract_token_from_warden
|
48
|
+
warden.try(:user).try(:g5_access_token)
|
33
49
|
end
|
34
50
|
|
35
51
|
def authorization_header
|
@@ -1,49 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'g5_authenticatable_api/services/token_info'
|
2
4
|
|
3
5
|
module G5AuthenticatableApi
|
4
6
|
module Services
|
7
|
+
# Validates an access token against the G5 Auth server
|
5
8
|
class TokenValidator < TokenInfo
|
6
9
|
attr_reader :error
|
7
10
|
|
8
11
|
def validate!
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
raise error
|
13
|
-
end
|
12
|
+
token_data unless skip_validation?
|
13
|
+
rescue StandardError => @error
|
14
|
+
raise error
|
14
15
|
end
|
15
16
|
|
16
17
|
def valid?
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
false
|
22
|
-
end
|
18
|
+
validate!
|
19
|
+
true
|
20
|
+
rescue StandardError
|
21
|
+
false
|
23
22
|
end
|
24
23
|
|
25
24
|
def auth_response_header
|
26
|
-
|
27
|
-
auth_header = "Bearer"
|
25
|
+
return unless error
|
28
26
|
|
29
|
-
|
30
|
-
auth_header << " error=\"#{error_code}\""
|
31
|
-
auth_header << ",error_description=\"#{error_description}\"" if error_description
|
32
|
-
end
|
27
|
+
auth_header = String.new('Bearer')
|
33
28
|
|
34
|
-
|
29
|
+
if access_token
|
30
|
+
auth_header << " error=\"#{error_code}\""
|
31
|
+
|
32
|
+
if error_description.present?
|
33
|
+
auth_header << ",error_description=\"#{error_description}\""
|
34
|
+
end
|
35
35
|
end
|
36
|
+
|
37
|
+
auth_header
|
36
38
|
end
|
37
39
|
|
38
40
|
private
|
41
|
+
|
39
42
|
def error_code
|
40
43
|
error_code = error.code if error.respond_to?(:code)
|
41
44
|
error_code || 'invalid_request'
|
42
45
|
end
|
43
46
|
|
44
47
|
def error_description
|
45
|
-
|
46
|
-
|
48
|
+
return unless error.respond_to?(:description)
|
49
|
+
error.description
|
47
50
|
end
|
48
51
|
|
49
52
|
def skip_validation?
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'g5_authenticatable_api/services/token_info'
|
2
4
|
|
3
5
|
module G5AuthenticatableApi
|
4
6
|
module Services
|
7
|
+
# Fetch user data from G5 Auth based on access token
|
5
8
|
class UserFetcher < TokenInfo
|
6
9
|
def current_user
|
7
10
|
if access_token == @warden.try(:user).try(:g5_access_token)
|