g5_authenticatable_api 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cd9ed6f231034a1d906d81e1fc66b0787fc7596e
4
- data.tar.gz: bed5680f12d4d43a28b7aff5f2b55773ce8d7dd5
3
+ metadata.gz: 1aa117f0b0c46d048619a8b7bffe14b1030b0e67
4
+ data.tar.gz: bbb88bf02f07f19c095ef2ab23d68df33783a205
5
5
  SHA512:
6
- metadata.gz: f77007e0fdeb669211365aa53a19bc011ab73c1297b9a6ae23155f7cc3a798f944517cbe1e72746c50cc430be45fecb9a6a2575e2e60981d816d30bbc6ac69a6
7
- data.tar.gz: 8f425de57b86817df5528822b914030892292b622c9af9382a946270d66c91752de9188bb57884e70aba10909cef315da293acf3b00d38fdd75d69246931aa01
6
+ metadata.gz: 4788c4eb67bc7139ffeb7664d68dd6816ed735bcca9fcd7b38f4a20153c9e1cf3b93cfd6c523e191658d4b331b0d2bd64d0b591c571be2d3cd6693f7e470368e
7
+ data.tar.gz: fb3fd459a31acc154515473e5c0e11734a9929f35c4051f3cf94d18138a4da6c89e03eb9a9b3fb9e4a194540d22ee605d60b872ec022b75400fededeb315ca26
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## v0.3.0 (2014-12-23)
2
+
3
+ * When there is already an authenticated session, validate the current
4
+ user's access token against the auth server on every API request
5
+ ([#5](https://github.com/G5/g5_authenticatable_api/pull/5))
6
+
1
7
  ## v0.2.0 (2014-03-12)
2
8
 
3
9
  * First open source release to [RubyGems](https://rubygems.org)
data/Gemfile CHANGED
@@ -6,7 +6,7 @@ source 'https://rubygems.org'
6
6
  gemspec
7
7
 
8
8
  # Gems used by the dummy application
9
- gem 'rails', '~> 4.0.2'
9
+ gem 'rails', '4.1.4'
10
10
  gem 'jquery-rails'
11
11
  gem 'pg'
12
12
  gem 'grape'
@@ -24,7 +24,7 @@ group :test do
24
24
  gem 'simplecov', require: false
25
25
  gem 'codeclimate-test-reporter', require: false
26
26
  gem 'webmock'
27
- gem 'shoulda-matchers'
27
+ gem 'shoulda-matchers', '~> 2.6'
28
28
  gem 'rspec-http', require: false
29
29
  end
30
30
 
data/README.md CHANGED
@@ -9,7 +9,7 @@ service using token-based authentication.
9
9
 
10
10
  ## Current Version
11
11
 
12
- 0.2.0
12
+ 0.3.0
13
13
 
14
14
  ## Requirements
15
15
 
data/circle.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  database:
2
2
  override:
3
3
  - cp spec/dummy/config/database.yml.ci spec/dummy/config/database.yml
4
- - (cd spec/dummy; RAILS_ENV=test rake db:drop db:setup)
4
+ - (cd spec/dummy; RAILS_ENV=test bundle exec rake db:drop db:create db:schema:load)
@@ -4,7 +4,7 @@ module G5AuthenticatableApi
4
4
  module Helpers
5
5
  module Grape
6
6
  def authenticate_user!
7
- raise_auth_error if !(warden.try(:authenticated?) || token_validator.valid?)
7
+ raise_auth_error if !token_validator.valid?
8
8
  end
9
9
 
10
10
  def warden
@@ -14,7 +14,7 @@ module G5AuthenticatableApi
14
14
  private
15
15
  def token_validator
16
16
  request = Rack::Request.new(env)
17
- @token_validator ||= TokenValidator.new(request.params, headers)
17
+ @token_validator ||= TokenValidator.new(request.params, headers, warden)
18
18
  end
19
19
 
20
20
  def raise_auth_error
@@ -4,7 +4,7 @@ module G5AuthenticatableApi
4
4
  module Helpers
5
5
  module Rails
6
6
  def authenticate_api_user!
7
- raise_auth_error if !(warden.try(:authenticated?) || token_validator.valid?)
7
+ raise_auth_error if !token_validator.valid?
8
8
  end
9
9
 
10
10
  def warden
@@ -13,7 +13,7 @@ module G5AuthenticatableApi
13
13
 
14
14
  private
15
15
  def token_validator
16
- @token_validator ||= TokenValidator.new(request.params, request.headers)
16
+ @token_validator ||= TokenValidator.new(request.params, request.headers, warden)
17
17
  end
18
18
 
19
19
  def raise_auth_error
@@ -2,9 +2,10 @@ module G5AuthenticatableApi
2
2
  class TokenValidator
3
3
  attr_reader :error
4
4
 
5
- def initialize(params={},headers={})
5
+ def initialize(params={},headers={},warden=nil)
6
6
  @params = params || {}
7
7
  @headers = headers || {}
8
+ @warden = warden
8
9
  end
9
10
 
10
11
  def validate!
@@ -25,12 +26,9 @@ module G5AuthenticatableApi
25
26
  end
26
27
 
27
28
  def access_token
28
- @access_token ||= if @headers['Authorization']
29
- parts = @headers['Authorization'].match(/Bearer (?<access_token>\S+)/)
30
- parts['access_token']
31
- else
32
- @params['access_token']
33
- end
29
+ @access_token ||= (extract_token_from_header ||
30
+ @params['access_token'] ||
31
+ @warden.try(:user).try(:g5_access_token))
34
32
  end
35
33
 
36
34
  def auth_response_header
@@ -61,5 +59,12 @@ module G5AuthenticatableApi
61
59
  error_description = error.description if error.respond_to?(:description)
62
60
  error_description
63
61
  end
62
+
63
+ def extract_token_from_header
64
+ if @headers['Authorization']
65
+ parts = @headers['Authorization'].match(/Bearer (?<access_token>\S+)/)
66
+ parts['access_token']
67
+ end
68
+ end
64
69
  end
65
70
  end
@@ -1,3 +1,3 @@
1
1
  module G5AuthenticatableApi
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -3,11 +3,12 @@ require 'spec_helper'
3
3
  describe G5AuthenticatableApi::TokenValidator do
4
4
  subject { validator }
5
5
 
6
- let(:validator) { described_class.new(params, headers) }
6
+ let(:validator) { described_class.new(params, headers, warden) }
7
7
 
8
8
  let(:headers) {}
9
9
  let(:params) { {'access_token' => token_value} }
10
10
  let(:token_value) { 'abc123' }
11
+ let(:warden) {}
11
12
 
12
13
  describe '#access_token' do
13
14
  subject(:access_token) { validator.access_token }
@@ -29,6 +30,29 @@ describe G5AuthenticatableApi::TokenValidator do
29
30
  expect(access_token).to eq(token_value)
30
31
  end
31
32
  end
33
+
34
+ context 'with warden user' do
35
+ let(:warden) { double(:warden, user: user) }
36
+ let(:user) { FactoryGirl.build_stubbed(:user) }
37
+
38
+ context 'without token on request' do
39
+ let(:params) {}
40
+ let(:headers) {}
41
+
42
+ it 'should extract the token value from the session user' do
43
+ expect(access_token).to eq(user.g5_access_token)
44
+ end
45
+ end
46
+
47
+ context 'with auth param' do
48
+ let(:params) { {'access_token' => token_value} }
49
+ let(:headers) {}
50
+
51
+ it 'should give precedence to the token on the request' do
52
+ expect(access_token).to eq(token_value)
53
+ end
54
+ end
55
+ end
32
56
  end
33
57
 
34
58
  describe '#validate!' do
@@ -1,60 +1,3 @@
1
- shared_examples_for 'token validation' do
2
- context 'when token is valid' do
3
- include_context 'valid access token'
4
-
5
- before { subject }
6
-
7
- it 'should be successful' do
8
- expect(response).to be_success
9
- end
10
-
11
- it 'should validate the access token against the auth server' do
12
- expect(a_request(:get, 'auth.g5search.com/oauth/token/info').
13
- with(headers: {'Authorization' => "Bearer #{token_value}"})).to have_been_made
14
- end
15
- end
16
-
17
- context 'when token is invalid' do
18
- include_context 'invalid access token'
19
-
20
- before { subject }
21
-
22
- it 'should be unauthorized' do
23
- expect(response).to be_http_unauthorized
24
- end
25
-
26
- it 'should return an authenticate header' do
27
- expect(response.headers).to have_key('WWW-Authenticate')
28
- end
29
-
30
- it 'should return the authentication error' do
31
- expect(response.headers['WWW-Authenticate']).to match("error=\"#{error_code}\"")
32
- end
33
-
34
- it 'should return the authentication error description' do
35
- expect(response.headers['WWW-Authenticate']).to match("error_description=\"#{error_description}\"")
36
- end
37
- end
38
-
39
- context 'when some other oauth error occurs' do
40
- include_context 'OAuth2 error'
41
-
42
- before { subject }
43
-
44
- it 'should be unauthorized' do
45
- expect(response).to be_http_unauthorized
46
- end
47
-
48
- it 'should return an authenticate header' do
49
- expect(response.headers).to have_key('WWW-Authenticate')
50
- end
51
-
52
- it 'should return the default authentication error code' do
53
- expect(response.headers['WWW-Authenticate']).to match('error="invalid_request"')
54
- end
55
- end
56
- end
57
-
58
1
  shared_examples_for 'a token authenticatable api' do
59
2
  let(:token_value) { 'abc123' }
60
3
 
@@ -0,0 +1,56 @@
1
+ shared_examples_for 'token validation' do
2
+ context 'when token is valid' do
3
+ include_context 'valid access token'
4
+
5
+ before { subject }
6
+
7
+ it 'should be successful' do
8
+ expect(response).to be_success
9
+ end
10
+
11
+ it 'should validate the access token against the auth server' do
12
+ expect(a_request(:get, 'auth.g5search.com/oauth/token/info').
13
+ with(headers: {'Authorization' => "Bearer #{token_value}"})).to have_been_made
14
+ end
15
+ end
16
+
17
+ context 'when token is invalid' do
18
+ include_context 'invalid access token'
19
+
20
+ before { subject }
21
+
22
+ it 'should be unauthorized' do
23
+ expect(response).to be_http_unauthorized
24
+ end
25
+
26
+ it 'should return an authenticate header' do
27
+ expect(response.headers).to have_key('WWW-Authenticate')
28
+ end
29
+
30
+ it 'should return the authentication error' do
31
+ expect(response.headers['WWW-Authenticate']).to match("error=\"#{error_code}\"")
32
+ end
33
+
34
+ it 'should return the authentication error description' do
35
+ expect(response.headers['WWW-Authenticate']).to match("error_description=\"#{error_description}\"")
36
+ end
37
+ end
38
+
39
+ context 'when some other oauth error occurs' do
40
+ include_context 'OAuth2 error'
41
+
42
+ before { subject }
43
+
44
+ it 'should be unauthorized' do
45
+ expect(response).to be_http_unauthorized
46
+ end
47
+
48
+ it 'should return an authenticate header' do
49
+ expect(response.headers).to have_key('WWW-Authenticate')
50
+ end
51
+
52
+ it 'should return the default authentication error code' do
53
+ expect(response.headers['WWW-Authenticate']).to match('error="invalid_request"')
54
+ end
55
+ end
56
+ end
@@ -3,15 +3,12 @@ require 'spec_helper'
3
3
  shared_examples_for 'a warden authenticatable api' do
4
4
  context 'when user is authenticated' do
5
5
  let(:user) { create(:user) }
6
+ let(:token_value) { user.g5_access_token }
6
7
 
7
- before do
8
- login_as(user, scope: :user)
9
- subject
10
- end
8
+ before { login_as(user, scope: :user) }
9
+ after { logout }
11
10
 
12
- it 'should be successful' do
13
- expect(response).to be_success
14
- end
11
+ include_examples 'token validation'
15
12
  end
16
13
 
17
14
  context 'when user is not authenticated' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: g5_authenticatable_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maeve Revels
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-12 00:00:00.000000000 Z
11
+ date: 2014-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -47,6 +47,7 @@ extra_rdoc_files: []
47
47
  files:
48
48
  - ".gitignore"
49
49
  - ".rspec"
50
+ - ".ruby-version"
50
51
  - CHANGELOG.md
51
52
  - Gemfile
52
53
  - LICENSE.txt
@@ -126,6 +127,7 @@ files:
126
127
  - spec/support/shared_contexts/invalid_access_token.rb
127
128
  - spec/support/shared_contexts/valid_access_token.rb
128
129
  - spec/support/shared_examples/token_authenticatable_api.rb
130
+ - spec/support/shared_examples/token_validation.rb
129
131
  - spec/support/shared_examples/warden_authenticatable_api.rb
130
132
  - spec/support/warden.rb
131
133
  homepage: https://github.com/G5/g5_authenticatable_api
@@ -148,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
150
  version: '0'
149
151
  requirements: []
150
152
  rubyforge_project:
151
- rubygems_version: 2.2.0
153
+ rubygems_version: 2.2.2
152
154
  signing_key:
153
155
  specification_version: 4
154
156
  summary: Helpers for securing APIs with G5
@@ -219,5 +221,6 @@ test_files:
219
221
  - spec/support/shared_contexts/invalid_access_token.rb
220
222
  - spec/support/shared_contexts/valid_access_token.rb
221
223
  - spec/support/shared_examples/token_authenticatable_api.rb
224
+ - spec/support/shared_examples/token_validation.rb
222
225
  - spec/support/shared_examples/warden_authenticatable_api.rb
223
226
  - spec/support/warden.rb