shutl_auth 0.8.5 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -1,79 +1,84 @@
1
1
  module Shutl
2
2
  module Auth
3
- class Shutl::Error < ::StandardError; end
4
- class InvalidUrl < Shutl::Error; end
5
- class InvalidCredentials < Shutl::Error; end
6
- class InternalServerError < Shutl::Error; end
3
+ class AccessTokenRequest
7
4
 
8
- def access_token!
9
- access_token_response!.access_token
10
- end
5
+ def initialize(opts)
6
+ self.client_id = opts.fetch :client_id
7
+ self.client_secret = opts.fetch :client_secret
8
+ self.url = opts.fetch :url
9
+ end
11
10
 
12
- def access_token_response!
13
- c = client
11
+ def access_token
12
+ access_token_response.access_token
13
+ end
14
14
 
15
- Shutl::NetworkRetry.retry "Authentication Service Error" do
16
- handling_exceptions do
17
- Shutl::Auth.logger.debug "executing Rack::OAuth2::Client request"
18
- c.access_token!
19
- end
20
- end
21
- end
15
+ def access_token_response
16
+ c = client
22
17
 
23
- private
24
-
25
- def handling_exceptions
26
- yield
27
- rescue Rack::OAuth2::Client::Error => e
28
- Shutl::Auth.logger.error "Rack::OAuth2::Client::Error: #{e.message}"
29
- case e.message
30
- when /The client identifier provided is invalid, the client failed to authenticate, the client did not include its credentials, provided multiple client credentials, or used unsupported credentials type\./
31
- raise_invalid_credentials
32
- else
33
- raise_internal_server_error e
18
+ Shutl::NetworkRetry.retry "Authentication Service Error" do
19
+ handling_exceptions do
20
+ Shutl::Auth.logger.debug "executing Rack::OAuth2::Client request"
21
+ c.access_token!
22
+ end
23
+ end
34
24
  end
35
- end
36
25
 
37
- def client
38
- check uri
26
+ private
39
27
 
40
- Rack::OAuth2::Client.new \
41
- identifier: Shutl::Auth.client_id,
42
- secret: Shutl::Auth.client_secret,
43
- token_endpoint: '/token',
44
- host: uri.host,
45
- port: uri.port,
46
- scheme: uri.scheme
47
- end
28
+ attr_accessor :client_id, :client_secret, :url
48
29
 
49
30
 
50
- def uri
51
- URI Shutl::Auth.url
52
- rescue
53
- raise_invalid_uri
54
- end
31
+ def handling_exceptions
32
+ yield
33
+ rescue Rack::OAuth2::Client::Error => e
34
+ Shutl::Auth.logger.error "Rack::OAuth2::Client::Error: #{e.message}"
35
+ case e.message
36
+ when /The client identifier provided is invalid, the client failed to authenticate, the client did not include its credentials, provided multiple client credentials, or used unsupported credentials type\./
37
+ raise_invalid_credentials
38
+ else
39
+ raise_internal_server_error e
40
+ end
41
+ end
55
42
 
56
- def check uri
57
- return uri if uri and uri.host and uri.scheme
58
- raise_invalid_uri
43
+ def client
44
+ check uri
59
45
 
60
- rescue
61
- raise_invalid_uri
62
- end
46
+ Rack::OAuth2::Client.new \
47
+ identifier: client_id,
48
+ secret: client_secret,
49
+ token_endpoint: '/token',
50
+ host: uri.host,
51
+ port: uri.port,
52
+ scheme: uri.scheme
53
+ end
63
54
 
64
- def raise_invalid_uri
65
- raise Shutl::Auth::InvalidUrl, "Please set value of Shutl::Auth.url"
66
- end
67
55
 
68
- def raise_invalid_credentials
69
- raise Shutl::Auth::InvalidCredentials, "Invalid credentials set, please see https://github.com/shutl/shutl_auth/blob/master/README.md"
70
- end
56
+ def uri
57
+ URI url
58
+ rescue
59
+ raise_invalid_uri
60
+ end
71
61
 
72
- def raise_internal_server_error e
73
- Shutl.notify e
74
- raise Shutl::Auth::InternalServerError
75
- end
62
+ def check uri
63
+ return uri if uri and uri.host and uri.scheme
64
+ raise_invalid_uri
65
+
66
+ rescue
67
+ raise_invalid_uri
68
+ end
76
69
 
77
- extend self
70
+ def raise_invalid_uri
71
+ raise Shutl::Auth::InvalidUrl, "Please set value of Shutl::Auth.url"
72
+ end
73
+
74
+ def raise_invalid_credentials
75
+ raise Shutl::Auth::InvalidCredentials, "Invalid credentials set, please see https://github.com/shutl/shutl_auth/blob/master/README.md"
76
+ end
77
+
78
+ def raise_internal_server_error e
79
+ Shutl.notify e
80
+ raise Shutl::Auth::InternalServerError
81
+ end
82
+ end
78
83
  end
79
84
  end
@@ -2,6 +2,29 @@
2
2
  #authenticating requests
3
3
  module Shutl
4
4
  module Auth
5
+ module AuthenticatedRequest
6
+ def self.included base
7
+ end
8
+
9
+ def access_token
10
+ authenticator.access_token
11
+ end
12
+
13
+ def authenticated_request &blk
14
+ authenticator.authenticated_request &blk
15
+ end
16
+
17
+ def request_access_token
18
+ authenticator.request_access_token
19
+ end
20
+
21
+ protected
22
+
23
+ def authenticator
24
+ @authenticator ||= Authenticator.new client_id: Shutl::Auth.client_id, client_secret: Shutl::Auth.client_secret , url: Shutl::Auth.url
25
+ end
26
+ end
27
+
5
28
  class Cache
6
29
  def initialize
7
30
  @cache = {}
@@ -29,42 +52,5 @@ module Shutl
29
52
  Cache.new
30
53
  end
31
54
  end
32
-
33
- module AuthenticatedRequest
34
- def self.included base
35
-
36
- end
37
-
38
- def request_access_token
39
- return read_token if read_token
40
- Shutl::Auth.logger.debug "request_access_token: cached? #{!!read_token}"
41
-
42
- Shutl::Auth.access_token!
43
- end
44
-
45
- def access_token
46
- return read_token if read_token
47
- set_token request_access_token
48
- end
49
-
50
- def authenticated_request &blk
51
- begin
52
- yield
53
- rescue Shutl::UnauthorizedAccess => e
54
- Shutl::Auth.logger.debug "Shutl::UnauthorizedAccess - resetting access token"
55
- set_token nil
56
- access_token
57
- yield
58
- end
59
- end
60
-
61
- def read_token
62
- Shutl::Auth.cache.read(:access_token)
63
- end
64
-
65
- def set_token(token)
66
- Shutl::Auth.cache.write(:access_token, token)
67
- end
68
- end
69
55
  end
70
56
  end
@@ -0,0 +1,58 @@
1
+
2
+ module Shutl
3
+ module Auth
4
+ class Authenticator
5
+
6
+ def initialize(options = {})
7
+ Shutl::Auth.logger.debug "building a new authenticator"
8
+ self.cache_key = options.fetch(:cache_key) { :access_token }
9
+ self.client_id = options.fetch(:client_id)
10
+ self.client_secret = options.fetch(:client_secret)
11
+ self.url = options.fetch(:url)
12
+ end
13
+
14
+ def access_token
15
+ return read_token if read_token
16
+ set_token request_access_token
17
+ end
18
+
19
+ def authenticated_request &blk
20
+ begin
21
+ yield
22
+ rescue Shutl::UnauthorizedAccess => e
23
+ Shutl::Auth.logger.debug "Shutl::UnauthorizedAccess - resetting access token"
24
+ set_token nil
25
+ access_token
26
+ yield
27
+ end
28
+ end
29
+
30
+ def request_access_token
31
+ return read_token if read_token
32
+ Shutl::Auth.logger.debug "request_access_token: cached? #{!!read_token}"
33
+
34
+ AccessTokenRequest.new(opts).access_token
35
+ end
36
+
37
+ private
38
+
39
+ attr_accessor :cache_key, :client_id, :client_secret, :url
40
+
41
+ def read_token
42
+ Shutl::Auth.cache.read(cache_key)
43
+ end
44
+
45
+ def set_token(token)
46
+ Shutl::Auth.cache.write(cache_key, token)
47
+ end
48
+
49
+ def opts
50
+ {
51
+ client_id: client_id,
52
+ client_secret: client_secret,
53
+ url: url
54
+ }
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,5 +1,5 @@
1
1
  module Shutl
2
2
  module Auth
3
- VERSION = "0.8.5"
3
+ VERSION = "0.9.0"
4
4
  end
5
5
  end
data/lib/shutl_auth.rb CHANGED
@@ -5,11 +5,19 @@ require "shutl/network_retry"
5
5
  require "shutl/auth/version"
6
6
  require "shutl/auth/access_token_request"
7
7
  require "shutl/auth/authenticated_request"
8
+ require "shutl/auth/authenticator"
8
9
 
9
10
  require 'logger'
10
11
 
11
12
  module Shutl
13
+ class UnauthorizedAccess < ::StandardError ; end
14
+ class Error < ::StandardError; end
15
+
12
16
  module Auth
17
+ class InvalidUrl < Shutl::Error; end
18
+ class InvalidCredentials < Shutl::Error; end
19
+ class InternalServerError < Shutl::Error; end
20
+
13
21
  extend self
14
22
 
15
23
  attr_accessor :client_id, :client_secret, :url
@@ -24,4 +32,4 @@ module Shutl
24
32
  Logger.new('/dev/null')
25
33
  end
26
34
  end
27
- end
35
+ end
@@ -2,18 +2,16 @@ require 'spec_helper'
2
2
 
3
3
 
4
4
  describe "Integration" do
5
- subject { Shutl::Auth }
6
-
7
- def set_auth
8
- Shutl::Auth.config do |c|
9
- c.url = "http://localhost:3000"
10
- c.client_id = "QUOTE_SERVICE_CLIENT_ID"
11
- c.client_secret = "QUOTE_SERVICE_CLIENT_SECRET"
12
- end
13
- end
14
-
15
- before do
16
- set_auth
5
+ subject { Shutl::Auth::AccessTokenRequest.new opts }
6
+ let(:client_id) { "QUOTE_SERVICE_CLIENT_ID" }
7
+ let(:url) { "http://localhost:3000" }
8
+
9
+ let(:opts) do
10
+ {
11
+ client_id: client_id,
12
+ client_secret: "QUOTE_SERVICE_CLIENT_SECRET",
13
+ url: url
14
+ }
17
15
  end
18
16
 
19
17
  context 'successful request to authentication service' do
@@ -21,29 +19,22 @@ describe "Integration" do
21
19
 
22
20
  specify do
23
21
  VCR.use_cassette 'get_token' do
24
- Shutl::Auth.access_token!.should == token
22
+ subject.access_token.should == token
25
23
  end
26
24
  end
27
25
 
28
- specify "with invalid auth service url" do
29
- Shutl::Auth.url = ''
30
-
31
- expect {Shutl::Auth.access_token!}.to raise_error Shutl::Auth::InvalidUrl
32
-
33
- Shutl::Auth.url = 'http://'
34
- expect {Shutl::Auth.access_token!}.to raise_error Shutl::Auth::InvalidUrl
35
-
36
- Shutl::Auth.url = 'http://localhost:3000'
26
+ describe "with invalid auth service url" do
27
+ specify do
28
+ expect { Shutl::Auth::AccessTokenRequest.new(client_id: '', client_secret: '', url: '').access_token}.to raise_error Shutl::Auth::InvalidUrl
29
+ end
37
30
 
38
- VCR.use_cassette 'get_token' do
39
- Shutl::Auth.access_token!.should == token
31
+ specify do
32
+ expect {Shutl::Auth::AccessTokenRequest.new(client_id: '', client_secret: '', url: 'http://').access_token}.to raise_error Shutl::Auth::InvalidUrl
40
33
  end
41
34
  end
42
35
 
43
36
  specify "with 500 from auth server" do
44
- set_auth
45
-
46
- stub_request(:post, /.*#{Shutl::Auth.url}.*/).to_return(
37
+ stub_request(:post, /.*#{url}.*/).to_return(
47
38
  { body: '',
48
39
  status: 500,
49
40
  headers: {"CONTENT_TYPE" => 'application/json'}}
@@ -51,24 +42,21 @@ describe "Integration" do
51
42
 
52
43
  Airbrake.should_receive(:notify)
53
44
 
54
- expect{ Shutl::Auth.access_token!}.to raise_error Shutl::Auth::InternalServerError
45
+ expect{ subject.access_token}.to raise_error Shutl::Auth::InternalServerError
55
46
  end
56
47
 
57
- specify "with invalid credentials" do
58
- set_auth
59
- Shutl::Auth.client_id = 'egg'
48
+ describe "with invalid credentials" do
49
+ let(:client_id) { 'egg' }
60
50
 
61
- VCR.use_cassette 'invalid_credentials' do
62
- expect { Shutl::Auth.access_token!}.to raise_error Shutl::Auth::InvalidCredentials
63
- end
64
-
65
- set_auth
66
- Shutl::Auth.client_id = 'egg'
51
+ specify do
52
+ VCR.use_cassette 'invalid_credentials' do
53
+ expect { subject.access_token}.to raise_error Shutl::Auth::InvalidCredentials
54
+ end
67
55
 
68
- VCR.use_cassette 'invalid_credentials' do
69
- expect { Shutl::Auth.access_token!}.to raise_error Shutl::Auth::InvalidCredentials
56
+ VCR.use_cassette 'invalid_credentials' do
57
+ expect { subject.access_token}.to raise_error Shutl::Auth::InvalidCredentials
58
+ end
70
59
  end
71
-
72
60
  end
73
61
  end
74
62
  end
@@ -1,18 +1,20 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Shutl::Auth do
4
- subject { Shutl::Auth }
3
+ describe Shutl::Auth::AccessTokenRequest do
4
+ subject { Shutl::Auth::AccessTokenRequest.new opts }
5
+
6
+ let(:opts) do
7
+ {
8
+ client_id: "QUOTE_SERVICE_CLIENT_ID",
9
+ client_secret: "QUOTE_SERVICE_CLIENT_SECRET",
10
+ url: "http://localhost:3000"
11
+ }
12
+ end
5
13
 
6
14
  let(:oauth_client) { mock 'oauth client' }
7
15
 
8
16
  before do
9
17
  Rack::OAuth2::Client.stub(:new).and_return oauth_client
10
-
11
- Shutl::Auth.config do |c|
12
- c.url = "http://localhost:3000"
13
- c.client_id = "QUOTE_SERVICE_CLIENT_ID"
14
- c.client_secret = "QUOTE_SERVICE_CLIENT_SECRET"
15
- end
16
18
  end
17
19
 
18
20
  context 'successful request to authentication service' do
@@ -21,7 +23,7 @@ describe Shutl::Auth do
21
23
  end
22
24
 
23
25
  specify do
24
- subject.access_token_response!.should == 'token response'
26
+ subject.access_token_response.should == 'token response'
25
27
  end
26
28
  end
27
29
 
@@ -34,7 +36,7 @@ describe Shutl::Auth do
34
36
  let(:number_of_failures) { 2 }
35
37
 
36
38
  specify do
37
- Shutl::Auth.access_token_response!.should == 'token'
39
+ subject.access_token_response.should == 'token'
38
40
  end
39
41
  end
40
42
 
@@ -42,7 +44,7 @@ describe Shutl::Auth do
42
44
  let(:number_of_failures) { 3 }
43
45
 
44
46
  specify do
45
- Shutl::Auth.access_token_response!.should be_nil
47
+ subject.access_token_response.should be_nil
46
48
  end
47
49
  end
48
50
 
@@ -1,8 +1,6 @@
1
1
  require 'spec_helper'
2
+ require 'ostruct'
2
3
 
3
- module Shutl
4
- class UnauthorizedAccess < StandardError ; end
5
- end
6
4
  describe Shutl::Auth::AuthenticatedRequest do
7
5
 
8
6
  class ToTestAuthenticatedRequest
@@ -11,56 +9,48 @@ describe Shutl::Auth::AuthenticatedRequest do
11
9
 
12
10
  subject { ToTestAuthenticatedRequest.new }
13
11
 
14
- let(:token) { 'abcd' }
15
- let(:spare_token) { '1234' }
12
+ let(:authenticator) { OpenStruct.new(access_token: '123', request_access_token: '456')}
16
13
 
17
14
  before do
18
- Shutl::Auth.stub(:access_token!).and_return(token, spare_token)
15
+ Shutl::Auth::Authenticator.stub(:new).and_return(authenticator)
19
16
  end
20
17
 
21
18
  describe 'access_token' do
22
- it 'requests the token' do
23
- subject.access_token.should == token
24
- end
25
-
26
- it 'caches the token' do
27
- subject.access_token
28
-
29
- subject.access_token.should == token
19
+ it 'delegates the call to the authenticator' do
20
+ subject.access_token.should == '123'
30
21
  end
31
22
  end
32
23
 
33
24
  describe 'authenticated_request' do
34
- it 'execute the block' do
35
- block = -> { 'test' }
25
+ it 'delegates the call to the authenticator' do
26
+ block = -> { 'abcd' }
27
+ authenticator.stub(:authenticated_request).with(&block).and_return('abcd')
36
28
 
37
- result = subject.authenticated_request &block
29
+ subject.authenticated_request { block }.should == 'abcd'
30
+ end
31
+ end
38
32
 
39
- result.should == 'test'
33
+ describe 'request_access_token' do
34
+ it 'delegates the call to the authenticator' do
35
+ subject.request_access_token.should == '456'
40
36
  end
37
+ end
41
38
 
42
- it 'retries if the block raise an UnauthorizedAccess' do
43
- call = 0
44
- block = -> do
45
- t = subject.access_token
46
- if call == 0
47
- call += 1
48
- raise Shutl::UnauthorizedAccess
49
- end
50
- t
39
+ describe 'default configuration' do
40
+ before do
41
+ Shutl::Auth.config do |s|
42
+ s.url = 'http://localhost:3000'
43
+ s.client_id = 'CLIENT_ID'
44
+ s.client_secret = 'CLIENT_SECRET'
51
45
  end
52
-
53
- result = subject.authenticated_request &block
54
-
55
- result.should == spare_token
56
46
  end
57
47
 
58
- it 'caches the token' do
59
- block = -> { subject.access_token }
60
-
61
- 2.times { subject.authenticated_request &block }
48
+ it 'uses the default Shutl::Auth value to authenticate' do
49
+ Shutl::Auth::Authenticator.should_receive(:new).
50
+ with(client_id: 'CLIENT_ID', client_secret: 'CLIENT_SECRET', url: 'http://localhost:3000').
51
+ and_return(authenticator)
62
52
 
63
- subject.cache.read(:access_token).should == token
53
+ subject.request_access_token
64
54
  end
65
55
  end
66
56
  end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shutl::Auth::Authenticator do
4
+ subject { described_class.new opts }
5
+
6
+ let(:token) { 'abcd' }
7
+ let(:spare_token) { '1234' }
8
+ let(:access_token_request) { stub :access_request }
9
+
10
+ let(:opts) do
11
+ {
12
+ client_id: "QUOTE_SERVICE_CLIENT_ID",
13
+ client_secret: "QUOTE_SERVICE_CLIENT_SECRET",
14
+ url: "http://localhost:3000"
15
+ }
16
+ end
17
+
18
+ before do
19
+ Shutl::Auth.cache.write(:access_token, nil)
20
+
21
+ Shutl::Auth::AccessTokenRequest.stub(:new).and_return(access_token_request)
22
+ access_token_request.stub(:access_token).and_return(token, spare_token)
23
+ end
24
+
25
+ describe 'access_token' do
26
+ it 'requests the token' do
27
+ subject.access_token.should == token
28
+ end
29
+
30
+ it 'caches the token' do
31
+ subject.access_token
32
+
33
+ subject.access_token.should == token
34
+ end
35
+ end
36
+
37
+ describe 'authenticated_request' do
38
+ it 'execute the block' do
39
+ block = -> { 'test' }
40
+
41
+ result = subject.authenticated_request &block
42
+
43
+ result.should == 'test'
44
+ end
45
+
46
+ it 'retries if the block raise an UnauthorizedAccess' do
47
+ call = 0
48
+ block = -> do
49
+ t = subject.access_token
50
+ if call == 0
51
+ call += 1
52
+ raise Shutl::UnauthorizedAccess
53
+ end
54
+ t
55
+ end
56
+
57
+ result = subject.authenticated_request &block
58
+
59
+ result.should == spare_token
60
+ end
61
+
62
+ it 'caches the token' do
63
+ block = -> { subject.access_token }
64
+
65
+ 2.times { subject.authenticated_request &block }
66
+
67
+ Shutl::Auth.cache.read(:access_token).should == token
68
+ end
69
+ end
70
+
71
+ describe 'token cache' do
72
+ subject { described_class.new(opts.merge(cache_key: :an_other_cache)) }
73
+
74
+ it 'caches the token with the provided value' do
75
+ block = -> { subject.access_token }
76
+
77
+ 2.times { subject.authenticated_request &block }
78
+
79
+ Shutl::Auth.cache.read(:an_other_cache).should == token
80
+ end
81
+ end
82
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shutl_auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.5
4
+ version: 0.9.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-08 00:00:00.000000000 Z
12
+ date: 2013-10-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: retriable
@@ -147,6 +147,7 @@ extensions: []
147
147
  extra_rdoc_files: []
148
148
  files:
149
149
  - .gitignore
150
+ - .rspec
150
151
  - .ruby-version
151
152
  - .rvmrc
152
153
  - .travis.yml
@@ -160,15 +161,17 @@ files:
160
161
  - doc/dependencies.html
161
162
  - lib/shutl/auth/access_token_request.rb
162
163
  - lib/shutl/auth/authenticated_request.rb
164
+ - lib/shutl/auth/authenticator.rb
163
165
  - lib/shutl/auth/version.rb
164
166
  - lib/shutl/network_retry.rb
165
167
  - lib/shutl_auth.rb
166
168
  - shutl_auth.gemspec
167
- - spec/access_token_request_spec.rb
168
169
  - spec/config_spec.rb
169
170
  - spec/integration/integration_spec.rb
170
171
  - spec/spec_helper.rb
172
+ - spec/unit/access_token_request_spec.rb
171
173
  - spec/unit/authenticated_request_spec.rb
174
+ - spec/unit/authenticator_spec.rb
172
175
  - spec/vcr/get_token.yml
173
176
  - spec/vcr/invalid_credentials.yml
174
177
  homepage: ''
@@ -185,7 +188,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
185
188
  version: '0'
186
189
  segments:
187
190
  - 0
188
- hash: 1526403474588545504
191
+ hash: 3338059309435403024
189
192
  required_rubygems_version: !ruby/object:Gem::Requirement
190
193
  none: false
191
194
  requirements:
@@ -194,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
197
  version: '0'
195
198
  segments:
196
199
  - 0
197
- hash: 1526403474588545504
200
+ hash: 3338059309435403024
198
201
  requirements: []
199
202
  rubyforge_project:
200
203
  rubygems_version: 1.8.23
@@ -202,10 +205,11 @@ signing_key:
202
205
  specification_version: 3
203
206
  summary: Used by various gems/services for communicating with shutl oauth server
204
207
  test_files:
205
- - spec/access_token_request_spec.rb
206
208
  - spec/config_spec.rb
207
209
  - spec/integration/integration_spec.rb
208
210
  - spec/spec_helper.rb
211
+ - spec/unit/access_token_request_spec.rb
209
212
  - spec/unit/authenticated_request_spec.rb
213
+ - spec/unit/authenticator_spec.rb
210
214
  - spec/vcr/get_token.yml
211
215
  - spec/vcr/invalid_credentials.yml