g5_authenticatable_api 0.2.0 → 0.3.0

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