g5_authenticatable 0.3.0 → 0.4.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/.ruby-version +1 -1
- data/CHANGELOG.md +13 -1
- data/Gemfile +3 -3
- data/README.md +100 -17
- data/app/controllers/g5_authenticatable/sessions_controller.rb +4 -0
- data/circle.yml +1 -1
- data/config/initializers/devise.rb +1 -1
- data/config/routes.rb +5 -0
- data/g5_authenticatable.gemspec +2 -2
- data/lib/g5_authenticatable/rspec.rb +1 -0
- data/lib/g5_authenticatable/test/feature_helpers.rb +1 -0
- data/lib/g5_authenticatable/test/request_helpers.rb +10 -1
- data/lib/g5_authenticatable/test/token_validation_helpers.rb +25 -0
- data/lib/g5_authenticatable/version.rb +1 -1
- data/lib/g5_authenticatable.rb +12 -0
- data/lib/generators/g5_authenticatable/install/install_generator.rb +4 -0
- data/lib/generators/g5_authenticatable/install/templates/g5_authenticatable.rb +8 -0
- data/lib/tasks/g5_authenticatable/purge_users.rake +6 -0
- data/spec/dummy/app/views/layouts/application.html.erb +1 -0
- data/spec/features/token_validation_spec.rb +51 -0
- data/spec/lib/generators/g5_authenticatable/install_generator_spec.rb +13 -1
- data/spec/requests/sign_out_spec.rb +44 -0
- data/spec/requests/token_validation_spec.rb +47 -0
- data/spec/routing/sign_out_routing_spec.rb +10 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/shared_contexts/rake.rb +21 -0
- data/spec/support/token_validation.rb +3 -0
- data/spec/tasks/purge_users_spec.rb +33 -0
- metadata +24 -8
- data/lib/tasks/g5_authenticatable_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: 01d16764300ca8cf106601e9bc00625631f1feb0
|
4
|
+
data.tar.gz: bba2757fa2298839be4230713b1804adde562198
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 776f2f806c5f29953799728e93503f5947424b426f64f45283b750f290dddbaecece6015c9d2d6acf0b77e3110714b6849ccf5f1754fd3d113deb857dfe8b12c
|
7
|
+
data.tar.gz: 30d6470860d0f7c0a504ca37d056133a9ed44eb57bebc33a0d2630e2078da0432ce80bb5d31f0402f78577ab4719dcbcf4501e699e2c7e926da4616c232c650e
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1.
|
1
|
+
2.1.2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## v0.4.0 (2015-01-20)
|
2
|
+
|
3
|
+
* Several fixes around sign-out, including accepting GET requests and
|
4
|
+
enabling strict token validation
|
5
|
+
([#21](https://github.com/G5/g5_authenticatable/pull/21))
|
6
|
+
* Improved documentation around controller test helpers
|
7
|
+
([#22](https://github.com/G5/g5_authenticatable/pull/22))
|
8
|
+
* Added `g5_authenticatable:purge_users` rake task to purge local user data;
|
9
|
+
primarily used for configuring demo/dev environments built on a production
|
10
|
+
clone or DB dump
|
11
|
+
([#23](https://github.com/G5/g5_authenticatable/pull/23))
|
12
|
+
|
1
13
|
## v0.3.0 (2014-03-13)
|
2
14
|
|
3
15
|
* First open source release to [RubyGems](https://rubygems.org)
|
@@ -17,7 +29,7 @@
|
|
17
29
|
|
18
30
|
## v0.1.2 (2014-03-05)
|
19
31
|
|
20
|
-
* Set G5_AUTH_USERNAME and G5_AUTH_PASSWORD on auth client defaults
|
32
|
+
* Set `G5_AUTH_USERNAME` and `G5_AUTH_PASSWORD` on auth client defaults
|
21
33
|
|
22
34
|
## v0.1.0 (2014-02-26)
|
23
35
|
|
data/Gemfile
CHANGED
@@ -6,13 +6,13 @@ source 'https://rubygems.org'
|
|
6
6
|
gemspec
|
7
7
|
|
8
8
|
# Gems used by the dummy application
|
9
|
-
gem 'rails', '
|
9
|
+
gem 'rails', '4.1.4'
|
10
10
|
gem 'jquery-rails'
|
11
11
|
gem 'pg'
|
12
12
|
gem 'grape'
|
13
13
|
|
14
14
|
group :test, :development do
|
15
|
-
gem 'rspec-rails', '~> 2.
|
15
|
+
gem 'rspec-rails', '~> 2.99'
|
16
16
|
gem 'pry'
|
17
17
|
gem 'dotenv-rails'
|
18
18
|
end
|
@@ -23,7 +23,7 @@ group :test do
|
|
23
23
|
gem 'simplecov', require: false
|
24
24
|
gem 'codeclimate-test-reporter', require: false
|
25
25
|
gem 'webmock'
|
26
|
-
gem 'shoulda-matchers'
|
26
|
+
gem 'shoulda-matchers', '~> 2.6'
|
27
27
|
gem 'generator_spec'
|
28
28
|
gem 'rspec-http', require: 'rspec/http'
|
29
29
|
end
|
data/README.md
CHANGED
@@ -18,7 +18,7 @@ library in isolation.
|
|
18
18
|
|
19
19
|
## Current Version
|
20
20
|
|
21
|
-
0.
|
21
|
+
0.4.0
|
22
22
|
|
23
23
|
## Requirements
|
24
24
|
|
@@ -85,7 +85,7 @@ root :to => 'home#index'
|
|
85
85
|
For non-production environments, this redirect URI does not have to
|
86
86
|
be publicly accessible, but it must be accessible from the browser
|
87
87
|
where you will be testing (so using something like
|
88
|
-
http://localhost:3000/users/auth/g5/callback is fine if your browser
|
88
|
+
http://localhost:3000/g5_auth/users/auth/g5/callback is fine if your browser
|
89
89
|
and client application server are both local).
|
90
90
|
|
91
91
|
If you are using the production G5 Auth server, the redirect URI **MUST**
|
@@ -103,13 +103,31 @@ environment variables for your client application:
|
|
103
103
|
* `G5_AUTH_CLIENT_ID` - the OAuth 2.0 application ID from the auth server
|
104
104
|
* `G5_AUTH_CLIENT_SECRET` - the OAuth 2.0 application secret from the auth server
|
105
105
|
* `G5_AUTH_REDIRECT_URI` - the OAuth 2.0 redirect URI registered with the auth server
|
106
|
-
* `G5_AUTH_ENDPOINT` - the endpoint URL for the G5 auth server
|
106
|
+
* `G5_AUTH_ENDPOINT` - the endpoint URL (without any path info) for the G5 auth server.
|
107
|
+
Generally, this will be set to either `https://dev-auth.g5search.com` or
|
108
|
+
`https://auth.g5search.com` (the default).
|
107
109
|
|
108
|
-
|
110
|
+
If you need to make server-to-server API calls that are not associated with an
|
111
|
+
end user, you can also set up a default user's credentials with:
|
109
112
|
|
110
113
|
* `G5_AUTH_USERNAME` - the G5 auth server user name
|
111
114
|
* `G5_AUTH_PASSWORD` - the G5 auth server user's password
|
112
115
|
|
116
|
+
### Token validation
|
117
|
+
|
118
|
+
By default, G5 Authenticatable only validates access tokens on incoming API
|
119
|
+
requests. If you are relying on session-based authentication instead, it is
|
120
|
+
possible for the local application's session to remain active after the
|
121
|
+
global access token has been revoked.
|
122
|
+
|
123
|
+
If you want to guarantee that the local session is destroyed when the access
|
124
|
+
token is revoked, add the following to
|
125
|
+
`config/initializers/g5_authenticatable.rb`:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
G5Authenticatable.strict_token_validation = true
|
129
|
+
```
|
130
|
+
|
113
131
|
## Usage
|
114
132
|
|
115
133
|
### Controller filters and helpers
|
@@ -255,6 +273,32 @@ following line in your `spec/spec_helper.rb`:
|
|
255
273
|
require 'g5_authenticatable/rspec'
|
256
274
|
```
|
257
275
|
|
276
|
+
Note that the example code assumes you are using Rspec 3 metadata syntax. If you are
|
277
|
+
using Rspec 2.x, you can either:
|
278
|
+
|
279
|
+
* Enable this syntax with the following config in your `spec/spec_helper.rb`:
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
RSpec.configure do |config|
|
283
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
284
|
+
end
|
285
|
+
```
|
286
|
+
|
287
|
+
* Or you can replace every instance of a bare symbol in the metadata with a full
|
288
|
+
key-value pair. For example:
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
# This won't work out of the box with Rspec 2
|
292
|
+
context 'my secure context', :auth do
|
293
|
+
it 'can see my secrets'
|
294
|
+
end
|
295
|
+
|
296
|
+
# But this will...
|
297
|
+
context 'my secure context', auth: true do
|
298
|
+
it 'can see my secrets'
|
299
|
+
end
|
300
|
+
```
|
301
|
+
|
258
302
|
#### Feature Specs ####
|
259
303
|
|
260
304
|
The easiest way to use g5_authenticatable in feature specs is through
|
@@ -360,23 +404,40 @@ To use the shared context, tag your example group with the `:auth_controller`
|
|
360
404
|
Rspec metadata:
|
361
405
|
|
362
406
|
```ruby
|
363
|
-
describe 'my secure action'
|
407
|
+
describe 'my secure action' do
|
364
408
|
context 'when the user is authenticated' do
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
409
|
+
it 'can access some secure path' do
|
410
|
+
get :my_action
|
411
|
+
expect(response). to be_success
|
412
|
+
end
|
369
413
|
end
|
370
414
|
|
371
|
-
context '
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
415
|
+
context 'when there is no authenticated user', :auth_controller do
|
416
|
+
it 'cannot access the secure path' do
|
417
|
+
get :my_action
|
418
|
+
expect(reponse).to be_redirect
|
419
|
+
end
|
376
420
|
end
|
377
421
|
end
|
378
422
|
```
|
379
423
|
|
424
|
+
### Purging local user data
|
425
|
+
|
426
|
+
G5 Authenticatable automatically maintains user data locally via the
|
427
|
+
`G5Authenticatable::User` model. This local data can be purged
|
428
|
+
using the following rake task:
|
429
|
+
|
430
|
+
```console
|
431
|
+
$ rake g5_authenticatable:purge_users
|
432
|
+
```
|
433
|
+
|
434
|
+
Executing this task does not affect any remote user data on the
|
435
|
+
auth server.
|
436
|
+
|
437
|
+
It is especially important to purge the local user data
|
438
|
+
when reconfiguring a client application to use a different auth endpoint
|
439
|
+
(for example, when cloning a demo environment from production).
|
440
|
+
|
380
441
|
## Examples
|
381
442
|
|
382
443
|
### Protecting a particular Rails controller action
|
@@ -404,11 +465,10 @@ In your view template, add the following:
|
|
404
465
|
|
405
466
|
### Adding a link to sign out
|
406
467
|
|
407
|
-
In
|
408
|
-
but must also use the DELETE HTTP method:
|
468
|
+
In your view template, add the following:
|
409
469
|
|
410
470
|
```html+erb
|
411
|
-
<%= link_to('Logout', destroy_session_path(:user)
|
471
|
+
<%= link_to('Logout', destroy_session_path(:user)) %>
|
412
472
|
```
|
413
473
|
|
414
474
|
### Selectively securing Grape API methods
|
@@ -460,6 +520,29 @@ In the code above, we assume that HTML requests come from a client that
|
|
460
520
|
can display the auth server's sign in page to the end user, while all other
|
461
521
|
formats are assumed to be API requests.
|
462
522
|
|
523
|
+
If HTML requests do not imply a client capable of providing a user to interact with
|
524
|
+
a signup form, you can try something like this:
|
525
|
+
|
526
|
+
```ruby
|
527
|
+
class MyMixedUpController < ApplicationController
|
528
|
+
before_filter :authenticate_api_user!, if: :is_api_request?
|
529
|
+
before_filter :authenticate_user!, unless: :is_api_request?
|
530
|
+
|
531
|
+
respond_to :html
|
532
|
+
|
533
|
+
def show
|
534
|
+
resource = MyResource.find(params[:id])
|
535
|
+
respond_with(resource)
|
536
|
+
end
|
537
|
+
|
538
|
+
private
|
539
|
+
|
540
|
+
def is_api_request?
|
541
|
+
!G5Authenticatable::TokenValidator.new(params, headers).access_token.nil?
|
542
|
+
end
|
543
|
+
end
|
544
|
+
```
|
545
|
+
|
463
546
|
## Authors
|
464
547
|
|
465
548
|
* Maeve Revels / [@maeve](https://github.com/maeve)
|
data/circle.yml
CHANGED
@@ -222,7 +222,7 @@ Devise.setup do |config|
|
|
222
222
|
# config.navigational_formats = ['*/*', :html]
|
223
223
|
|
224
224
|
# The default HTTP method used to sign out a resource. Default is :delete.
|
225
|
-
config.sign_out_via = :
|
225
|
+
config.sign_out_via = :get
|
226
226
|
|
227
227
|
# ==> OmniAuth
|
228
228
|
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
data/config/routes.rb
CHANGED
@@ -2,5 +2,10 @@ G5Authenticatable::Engine.routes.draw do
|
|
2
2
|
devise_for :users, class_name: 'G5Authenticatable::User',
|
3
3
|
module: :devise,
|
4
4
|
controllers: {sessions: 'g5_authenticatable/sessions'}
|
5
|
+
|
6
|
+
devise_scope :user do
|
7
|
+
delete '/users/sign_out', to: redirect('users/sign_out')
|
8
|
+
end
|
9
|
+
|
5
10
|
get '/auth_error', to: 'error#auth_error'
|
6
11
|
end
|
data/g5_authenticatable.gemspec
CHANGED
@@ -20,6 +20,6 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.add_dependency 'devise_g5_authenticatable', '~> 0.
|
24
|
-
spec.add_dependency 'g5_authenticatable_api', '~> 0.
|
23
|
+
spec.add_dependency 'devise_g5_authenticatable', '~> 0.2'
|
24
|
+
spec.add_dependency 'g5_authenticatable_api', '~> 0.3.1'
|
25
25
|
end
|
@@ -19,7 +19,16 @@ shared_context 'auth request', auth_request: true do
|
|
19
19
|
|
20
20
|
let(:user) { FactoryGirl.create(:g5_authenticatable_user) }
|
21
21
|
|
22
|
-
|
22
|
+
let!(:orig_auth_endpoint) { ENV['G5_AUTH_ENDPOINT'] }
|
23
|
+
let(:auth_endpoint) { 'https://test.auth.host' }
|
24
|
+
before { ENV['G5_AUTH_ENDPOINT'] = auth_endpoint }
|
25
|
+
after { ENV['G5_AUTH_ENDPOINT'] = orig_auth_endpoint }
|
26
|
+
|
27
|
+
before do
|
28
|
+
login_user(user)
|
29
|
+
stub_valid_access_token(user.g5_access_token)
|
30
|
+
end
|
31
|
+
|
23
32
|
after { logout_user }
|
24
33
|
end
|
25
34
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module G5Authenticatable
|
2
|
+
module Test
|
3
|
+
module TokenValidationHelpers
|
4
|
+
def stub_valid_access_token(token_value)
|
5
|
+
stub_request(:get, "#{ENV['G5_AUTH_ENDPOINT']}/oauth/token/info").
|
6
|
+
with(headers: {'Authorization'=>"Bearer #{token_value}"}).
|
7
|
+
to_return(status: 200, body: '', headers: {})
|
8
|
+
end
|
9
|
+
|
10
|
+
def stub_invalid_access_token(token_value)
|
11
|
+
stub_request(:get, "#{ENV['G5_AUTH_ENDPOINT']}/oauth/token/info").
|
12
|
+
with(headers: {'Authorization'=>"Bearer #{token_value}"}).
|
13
|
+
to_return(status: 401,
|
14
|
+
headers: {'Content-Type' => 'application/json; charset=utf-8',
|
15
|
+
'Cache-Control' => 'no-cache'},
|
16
|
+
body: {'error' => 'invalid_token',
|
17
|
+
'error_description' => 'The access token expired'}.to_json)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
RSpec.configure do |config|
|
24
|
+
config.include G5Authenticatable::Test::TokenValidationHelpers
|
25
|
+
end
|
data/lib/g5_authenticatable.rb
CHANGED
@@ -4,4 +4,16 @@ require 'devise_g5_authenticatable'
|
|
4
4
|
require 'g5_authenticatable_api'
|
5
5
|
|
6
6
|
module G5Authenticatable
|
7
|
+
# When enabled, access tokens are always validated against the auth
|
8
|
+
# server, even when that token is associated with an authenticated user.
|
9
|
+
# Disabled by default, meaning that tokens are only validated if
|
10
|
+
# they are explicitly passed in on an API request.
|
11
|
+
@@strict_token_validation = false
|
12
|
+
mattr_reader :strict_token_validation
|
13
|
+
|
14
|
+
def self.strict_token_validation=(validate)
|
15
|
+
@@strict_token_validation =
|
16
|
+
G5AuthenticatableApi.strict_token_validation =
|
17
|
+
Devise.g5_strict_token_validation = validate
|
18
|
+
end
|
7
19
|
end
|
@@ -17,4 +17,8 @@ class G5Authenticatable::InstallGenerator < Rails::Generators::Base
|
|
17
17
|
def mount_engine
|
18
18
|
route "mount G5Authenticatable::Engine => '/g5_auth'"
|
19
19
|
end
|
20
|
+
|
21
|
+
def create_initializer
|
22
|
+
template 'g5_authenticatable.rb', 'config/initializers/g5_authenticatable.rb'
|
23
|
+
end
|
20
24
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# Enable strict token validation to guarantee that an authenticated
|
2
|
+
# user's access token is still valid on the global auth server, at the
|
3
|
+
# cost of performance. When disabled, the user's access token will
|
4
|
+
# not be repeatedly validated, but this means that the local
|
5
|
+
# session may persist long after the access token is revoked on the
|
6
|
+
# auth server. Disabled by default.
|
7
|
+
#
|
8
|
+
# G5Authenticatable.strict_token_validation = true
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'UI Token validation' do
|
4
|
+
let!(:old_auth_endpoint) { ENV['G5_AUTH_ENDPOINT'] }
|
5
|
+
before { ENV['G5_AUTH_ENDPOINT'] = auth_endpoint }
|
6
|
+
after { ENV['G5_AUTH_ENDPOINT'] = old_auth_endpoint }
|
7
|
+
let(:auth_endpoint) { 'https://auth.test.host' }
|
8
|
+
|
9
|
+
let(:user) { FactoryGirl.create(:g5_authenticatable_user) }
|
10
|
+
|
11
|
+
before do
|
12
|
+
stub_g5_omniauth(user)
|
13
|
+
visit protected_page_path
|
14
|
+
|
15
|
+
# Now that we're logged in, any subsequent attempts to
|
16
|
+
# authenticate with the auth server will trigger an omniauth
|
17
|
+
# failure, which is a condition we can test for
|
18
|
+
stub_g5_invalid_credentials
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when token validation is enabled' do
|
22
|
+
before { G5Authenticatable.strict_token_validation = true }
|
23
|
+
|
24
|
+
context 'when user has a valid g5 access token' do
|
25
|
+
before { stub_valid_access_token(user.g5_access_token) }
|
26
|
+
|
27
|
+
it 'should allow the user to visit a protected page' do
|
28
|
+
visit protected_page_path
|
29
|
+
expect(current_path).to eq(protected_page_path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when user has an invalid g5 access token' do
|
34
|
+
before { stub_invalid_access_token(user.g5_access_token) }
|
35
|
+
|
36
|
+
it 'should force the user to re-authenticate' do
|
37
|
+
visit protected_page_path
|
38
|
+
expect(current_path).to_not eq(protected_page_path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when token validation is disabled' do
|
44
|
+
before { G5Authenticatable.strict_token_validation = false }
|
45
|
+
|
46
|
+
it 'should allow the user to visit a protected page' do
|
47
|
+
visit protected_page_path
|
48
|
+
expect(current_path).to eq(protected_page_path)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -7,7 +7,7 @@ require 'spec_helper'
|
|
7
7
|
require 'generators/g5_authenticatable/install/install_generator'
|
8
8
|
|
9
9
|
describe G5Authenticatable::InstallGenerator, type: :generator do
|
10
|
-
destination File.expand_path('
|
10
|
+
destination File.expand_path('../../../../tmp', __FILE__)
|
11
11
|
|
12
12
|
before do
|
13
13
|
prepare_destination
|
@@ -27,6 +27,18 @@ describe G5Authenticatable::InstallGenerator, type: :generator do
|
|
27
27
|
}
|
28
28
|
end
|
29
29
|
|
30
|
+
it 'should copy the initializer' do
|
31
|
+
expect(destination_root).to have_structure {
|
32
|
+
directory 'config' do
|
33
|
+
directory 'initializers' do
|
34
|
+
file 'g5_authenticatable.rb' do
|
35
|
+
contains '# G5Authenticatable.strict_token_validation = true'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
30
42
|
it 'should mount the engine' do
|
31
43
|
expect(destination_root).to have_structure {
|
32
44
|
directory 'config' do
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Normally, we'd do this as a feature spec, but there's
|
4
|
+
# currently no easy way to get capybara to play along nicely
|
5
|
+
# with mocks for external redirects (the capybara-mechanize driver
|
6
|
+
# comes closest, but not quite)
|
7
|
+
describe 'Signing out' do
|
8
|
+
before { ENV['G5_AUTH_ENDPOINT'] = auth_endpoint }
|
9
|
+
after { ENV['G5_AUTH_ENDPOINT'] = nil }
|
10
|
+
let(:auth_endpoint) { 'https://auth.test.host' }
|
11
|
+
|
12
|
+
let(:auth_sign_out_url) do
|
13
|
+
"#{auth_endpoint}/users/sign_out?redirect_url=http%3A%2F%2Fwww.example.com%2F"
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'GET /g5_auth/users/sign_out' do
|
17
|
+
subject(:sign_out) { get '/g5_auth/users/sign_out' }
|
18
|
+
|
19
|
+
context 'when user is logged in', :auth_request do
|
20
|
+
it 'should redirect to the auth server' do
|
21
|
+
expect(sign_out).to redirect_to(auth_sign_out_url)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should not allow the user to access protected pages' do
|
25
|
+
sign_out
|
26
|
+
expect(get '/protected_page').to redirect_to('/g5_auth/users/sign_in')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when user is not logged in' do
|
31
|
+
it 'should redirect to the auth server' do
|
32
|
+
expect(sign_out).to redirect_to(auth_sign_out_url)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'DELETE /g5_auth/users/sign_out', :auth_request do
|
38
|
+
subject(:sign_out) { delete '/g5_auth/users/sign_out' }
|
39
|
+
|
40
|
+
it 'should redirect to GET' do
|
41
|
+
expect(sign_out).to redirect_to('/g5_auth/users/sign_out')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'API Token validation' do
|
4
|
+
let!(:old_auth_endpoint) { ENV['G5_AUTH_ENDPOINT'] }
|
5
|
+
before { ENV['G5_AUTH_ENDPOINT'] = auth_endpoint }
|
6
|
+
after { ENV['G5_AUTH_ENDPOINT'] = old_auth_endpoint }
|
7
|
+
let(:auth_endpoint) { 'https://auth.test.host' }
|
8
|
+
|
9
|
+
let(:token_info_url) { URI.join(auth_endpoint, '/oauth/token/info') }
|
10
|
+
|
11
|
+
let(:user) { FactoryGirl.create(:g5_authenticatable_user) }
|
12
|
+
before { login_user(user) }
|
13
|
+
after { logout_user }
|
14
|
+
|
15
|
+
subject(:api_call) { get '/rails_api/secure_resource.json' }
|
16
|
+
|
17
|
+
context 'when token validation is enabled' do
|
18
|
+
before { G5Authenticatable.strict_token_validation = true }
|
19
|
+
|
20
|
+
context 'when user has a valid g5 access token' do
|
21
|
+
before { stub_valid_access_token(user.g5_access_token) }
|
22
|
+
|
23
|
+
it 'should allow the user to make the api call' do
|
24
|
+
api_call
|
25
|
+
expect(response).to be_success
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when user has an invalid g5 access token' do
|
30
|
+
before { stub_invalid_access_token(user.g5_access_token) }
|
31
|
+
|
32
|
+
it 'should return a 401' do
|
33
|
+
api_call
|
34
|
+
expect(response).to be_http_unauthorized
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when token validation is disabled' do
|
40
|
+
before { G5Authenticatable.strict_token_validation = false }
|
41
|
+
|
42
|
+
it 'should allow the user to make the api call' do
|
43
|
+
api_call
|
44
|
+
expect(response).to be_success
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Sign out routes' do
|
4
|
+
routes {G5Authenticatable::Engine.routes}
|
5
|
+
|
6
|
+
it 'should route GET /g5_auth/users/sign_out' do
|
7
|
+
expect(get('/users/sign_out')).to route_to(controller: 'g5_authenticatable/sessions',
|
8
|
+
action: 'destroy')
|
9
|
+
end
|
10
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Based on: http://robots.thoughtbot.com/test-rake-tasks-like-a-boss
|
2
|
+
# Modified for a non-Rails environment
|
3
|
+
require 'rake'
|
4
|
+
|
5
|
+
shared_context 'rake' do
|
6
|
+
let(:rake) { Rake::Application.new }
|
7
|
+
let(:task_name) { self.class.top_level_description }
|
8
|
+
let(:task_path) { "lib/tasks/#{task_name.split(':').first}/#{task_name.split(':').last}" }
|
9
|
+
let(:root_path) { File.expand_path('../../../..', __FILE__) }
|
10
|
+
subject(:task) { rake[task_name] }
|
11
|
+
|
12
|
+
def loaded_files_excluding_current_rake_file
|
13
|
+
$".reject {|file| file =~ /#{task_path}\.rake$/ }
|
14
|
+
end
|
15
|
+
|
16
|
+
before do
|
17
|
+
Rake.application = rake
|
18
|
+
Rake.application.rake_require(task_path, [root_path], loaded_files_excluding_current_rake_file)
|
19
|
+
Rake::Task.define_task(:environment)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'g5_authenticatable:purge_users' do
|
4
|
+
include_context 'rake'
|
5
|
+
|
6
|
+
context 'when there are no local users' do
|
7
|
+
it 'should not raise any errors' do
|
8
|
+
expect { task.invoke }.to_not raise_error
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should not leave any user data in the db' do
|
12
|
+
task.invoke
|
13
|
+
expect(G5Authenticatable::User.count).to eq(0)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when there is one local user' do
|
18
|
+
let!(:user) { FactoryGirl.create(:g5_authenticatable_user) }
|
19
|
+
|
20
|
+
it 'should delete the user data from the db' do
|
21
|
+
expect { task.invoke }.to change { G5Authenticatable::User.count }.from(1).to(0)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when there are multiple local users' do
|
26
|
+
let!(:user1) { FactoryGirl.create(:g5_authenticatable_user) }
|
27
|
+
let!(:user2) { FactoryGirl.create(:g5_authenticatable_user) }
|
28
|
+
|
29
|
+
it 'should delete the user data from the db' do
|
30
|
+
expect { task.invoke }.to change { G5Authenticatable::User.count }.from(2).to(0)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: g5_authenticatable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- maeve
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: devise_g5_authenticatable
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: g5_authenticatable_api
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.3.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 0.3.1
|
41
41
|
description: |-
|
42
42
|
An engine that provides a basic User model,
|
43
43
|
authentication logic, and remote credential
|
@@ -79,11 +79,13 @@ files:
|
|
79
79
|
- lib/g5_authenticatable/test/factory.rb
|
80
80
|
- lib/g5_authenticatable/test/feature_helpers.rb
|
81
81
|
- lib/g5_authenticatable/test/request_helpers.rb
|
82
|
+
- lib/g5_authenticatable/test/token_validation_helpers.rb
|
82
83
|
- lib/g5_authenticatable/version.rb
|
83
84
|
- lib/generators/g5_authenticatable/install/USAGE
|
84
85
|
- lib/generators/g5_authenticatable/install/install_generator.rb
|
85
86
|
- lib/generators/g5_authenticatable/install/templates/create_g5_authenticatable_users.rb
|
86
|
-
- lib/
|
87
|
+
- lib/generators/g5_authenticatable/install/templates/g5_authenticatable.rb
|
88
|
+
- lib/tasks/g5_authenticatable/purge_users.rake
|
87
89
|
- script/rails
|
88
90
|
- spec/config/application_spec.rb
|
89
91
|
- spec/controllers/.gitkeep
|
@@ -131,15 +133,22 @@ files:
|
|
131
133
|
- spec/dummy/script/rails
|
132
134
|
- spec/features/auth_error_path_spec.rb
|
133
135
|
- spec/features/sign_in_spec.rb
|
136
|
+
- spec/features/token_validation_spec.rb
|
134
137
|
- spec/g5_authenticatable/version_spec.rb
|
135
138
|
- spec/lib/generators/g5_authenticatable/install_generator_spec.rb
|
136
139
|
- spec/models/.gitkeep
|
137
140
|
- spec/models/g5_authenticatable/user_spec.rb
|
138
141
|
- spec/requests/grape_api_spec.rb
|
139
142
|
- spec/requests/rails_api_spec.rb
|
143
|
+
- spec/requests/sign_out_spec.rb
|
144
|
+
- spec/requests/token_validation_spec.rb
|
140
145
|
- spec/routing/auth_error_routing_spec.rb
|
146
|
+
- spec/routing/sign_out_routing_spec.rb
|
141
147
|
- spec/spec_helper.rb
|
142
148
|
- spec/support/devise.rb
|
149
|
+
- spec/support/shared_contexts/rake.rb
|
150
|
+
- spec/support/token_validation.rb
|
151
|
+
- spec/tasks/purge_users_spec.rb
|
143
152
|
homepage: https://github.com/G5/g5_authenticatable
|
144
153
|
licenses:
|
145
154
|
- MIT
|
@@ -160,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
169
|
version: '0'
|
161
170
|
requirements: []
|
162
171
|
rubyforge_project:
|
163
|
-
rubygems_version: 2.2.
|
172
|
+
rubygems_version: 2.2.2
|
164
173
|
signing_key:
|
165
174
|
specification_version: 4
|
166
175
|
summary: An authentication engine for G5 applications.
|
@@ -211,12 +220,19 @@ test_files:
|
|
211
220
|
- spec/dummy/script/rails
|
212
221
|
- spec/features/auth_error_path_spec.rb
|
213
222
|
- spec/features/sign_in_spec.rb
|
223
|
+
- spec/features/token_validation_spec.rb
|
214
224
|
- spec/g5_authenticatable/version_spec.rb
|
215
225
|
- spec/lib/generators/g5_authenticatable/install_generator_spec.rb
|
216
226
|
- spec/models/.gitkeep
|
217
227
|
- spec/models/g5_authenticatable/user_spec.rb
|
218
228
|
- spec/requests/grape_api_spec.rb
|
219
229
|
- spec/requests/rails_api_spec.rb
|
230
|
+
- spec/requests/sign_out_spec.rb
|
231
|
+
- spec/requests/token_validation_spec.rb
|
220
232
|
- spec/routing/auth_error_routing_spec.rb
|
233
|
+
- spec/routing/sign_out_routing_spec.rb
|
221
234
|
- spec/spec_helper.rb
|
222
235
|
- spec/support/devise.rb
|
236
|
+
- spec/support/shared_contexts/rake.rb
|
237
|
+
- spec/support/token_validation.rb
|
238
|
+
- spec/tasks/purge_users_spec.rb
|