g5_authenticatable 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|