soar_authentication_token 6.1.1 → 7.0.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: 92fc0e5a387e08484ae5b0c48a466d46bed16244
4
- data.tar.gz: 9b1cbc9f2f41572daf9ed0a917f996f11bf4f141
3
+ metadata.gz: 92c8dc7a3dbedcf217cd7573c32d50c5d38d2c0c
4
+ data.tar.gz: de77e06ab5a8a930c88aa713a8e32ccfcc63373c
5
5
  SHA512:
6
- metadata.gz: af46ea8e47641f8efde6130ed715b2332e47dc15fdf7203d282859fe70759079df9d721b1e43273a7584482d3d76f7664f4ffbd197cd80e37ee15c0a9d42d9b7
7
- data.tar.gz: 611a3f9db6afe3e9e1d00fafab33cc7eaad33bba69e695a083cdecf3b43abedc8cafafd83660461f30354b5ce229aea1a57b8b2e6184aa8098d045288ef858c7
6
+ metadata.gz: 57a51e1c0ea4fda47b35f1fa3988d3717efd106dfdbab932010d0255abb1f31c3d8b82947997abb85d51fb42c8ae4773d0220b8de479d7170aab3637458751c1
7
+ data.tar.gz: f97c53ba7e18ca910c5468a4f7ed5c83059e5cb50b08ed8f31daa48ade8387bf38713ff204966345a2c88f03792418ded04a1026dac0f961bc3b1bcc5856a12d
data/docker-compose.yml CHANGED
@@ -1,56 +1,9 @@
1
1
  version: '2.0'
2
2
  services:
3
3
  soar-authentication-token:
4
- command: /bin/bash -c 'sleep 30; bundle exec rspec -cfd ./spec/'
4
+ command: /bin/bash -c 'bundle exec rspec -cfd ./spec/'
5
5
  user: $UID:$UID
6
6
  build: .
7
7
  image: soar-authentication-token
8
8
  volumes:
9
9
  - .:/usr/local/src/
10
- links:
11
- - authentication-token-generator-service
12
- - authentication-token-validator-service
13
- authentication-token-generator-service:
14
- build: authentication-token-generator-service
15
- image: authentication-token-generator-service
16
- command: soaring start -e production
17
- user: $UID:$UID
18
- expose:
19
- - "9393"
20
- volumes:
21
- - ./authentication-token-generator-service:/usr/local/src/
22
- environment:
23
- - RACK_ENV=production
24
- - ENVIRONMENT_FILE=environment_local_ecosystem.yml
25
- links:
26
- - authentication-token-store
27
- authentication-token-validator-service:
28
- build: authentication-token-validator-service
29
- image: authentication-token-validator-service
30
- command: soaring start -e production
31
- user: $UID:$UID
32
- expose:
33
- - "9393"
34
- volumes:
35
- - ./authentication-token-validator-service:/usr/local/src/
36
- environment:
37
- - RACK_ENV=production
38
- - ENVIRONMENT_FILE=environment_local_ecosystem.yml
39
- links:
40
- - authentication-token-store
41
- authentication-token-store:
42
- build: authentication-token-store
43
- image: authentication-token-store
44
- command: soaring start -e production
45
- user: $UID:$UID
46
- expose:
47
- - "9393"
48
- volumes:
49
- - ./authentication-token-store:/usr/local/src/
50
- environment:
51
- - RACK_ENV=production
52
- - ENVIRONMENT_FILE=environment_local_ecosystem.yml
53
- links:
54
- - authentication-token-redis-store
55
- authentication-token-redis-store:
56
- image: redis
@@ -6,6 +6,10 @@ require 'soar_authentication_token/providers/jwt_token_validator'
6
6
  require 'soar_authentication_token/providers/remote_token_generator'
7
7
  require 'soar_authentication_token/providers/remote_token_validator'
8
8
  require 'soar_authentication_token/providers/static_token_validator'
9
+ require 'soar_authentication_token/token_provider'
10
+ require 'soar_authentication_token/providers/cookie_provider'
11
+ require 'soar_authentication_token/providers/authorization_header_provider'
12
+ require 'soar_authentication_token/providers/cascade_provider'
9
13
  require 'soar_authentication_token/keypair_generator'
10
14
  require 'soar_authentication_token/config_rotator'
11
15
  require 'soar_authentication_token/token_generator'
@@ -0,0 +1,18 @@
1
+ module SoarAuthenticationToken
2
+ class AuthorizationHeaderProvider
3
+ def initialize(configuration)
4
+ @configuration = configuration
5
+ validate_configuration
6
+ end
7
+
8
+ def fetch(request)
9
+ return false unless request.env[@configuration['header_name']]
10
+
11
+ request.env[@configuration['header_name']]
12
+ end
13
+
14
+ def validate_configuration
15
+ raise "'cookie_name' must be configured" unless @configuration['header_name']
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ module SoarAuthenticationToken
2
+ class CascadeProvider
3
+ def initialize(configuration)
4
+ @configuration = configuration
5
+ validate_configuration
6
+ end
7
+
8
+ def fetch(request)
9
+ # TODO: refactor this functionality into modules - DON'T DUPLICATE!
10
+ fetch_by_cookie(request) || fetch_by_auth_header(request)
11
+ end
12
+
13
+ private
14
+ def fetch_by_cookie(request)
15
+ return false unless request.env.has_key?('HTTP_COOKIE')
16
+
17
+ cookies = HTTP::CookieJar.new.parse(request.env['HTTP_COOKIE'], 'http://irrelevant')
18
+ auth_cookie = cookies.find { |cookie| cookie.name == @configuration['cookie_name'] }
19
+ return false unless auth_cookie.is_a?(HTTP::Cookie)
20
+
21
+ auth_cookie.value
22
+ end
23
+
24
+ def fetch_by_auth_header(request)
25
+ return false unless request.env[@configuration['header_name']]
26
+
27
+ request.env[@configuration['header_name']]
28
+ end
29
+
30
+ def validate_configuration
31
+ raise "'cookie_name' must be configured" unless @configuration['header_name']
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ require 'http-cookie'
2
+
3
+ module SoarAuthenticationToken
4
+ class CookieProvider
5
+ def initialize(configuration)
6
+ @configuration = configuration
7
+ validate_configuration
8
+ end
9
+
10
+ def fetch(request)
11
+ return false unless request.env.has_key?('HTTP_COOKIE')
12
+
13
+ cookies = HTTP::CookieJar.new.parse(request.env['HTTP_COOKIE'], 'http://irrelevant')
14
+ auth_cookie = cookies.find { |cookie| cookie.name == @configuration['cookie_name'] }
15
+ return false unless auth_cookie.is_a?(HTTP::Cookie)
16
+
17
+ auth_cookie.value
18
+ end
19
+
20
+ def validate_configuration
21
+ raise "'cookie_name' must be configured" unless @configuration['cookie_name']
22
+ end
23
+ end
24
+ end
@@ -26,9 +26,11 @@ module SoarAuthenticationToken
26
26
 
27
27
  def get_request_information(env)
28
28
  request = Rack::Request.new env
29
+ auth_token = SoarAuthenticationToken::TokenProvider.new(@configuration).fetch(request)
30
+
29
31
  [ request.session,
30
32
  request.params,
31
- request.env['HTTP_AUTHORIZATION'],
33
+ auth_token,
32
34
  request.params['flow_identifier'],
33
35
  { 'source_address' => request.ip,
34
36
  'user_agent' => request.user_agent,
@@ -42,6 +44,8 @@ module SoarAuthenticationToken
42
44
  end
43
45
 
44
46
  def validate_and_resolve_token(authentication_token, request_information, flow_identifier)
47
+ return false, nil, 'No token provided or retrievable from request' unless authentication_token
48
+
45
49
  token_validator = SoarAuthenticationToken::TokenValidator.new(@configuration)
46
50
  token_validator.validate(authentication_token: authentication_token,
47
51
  request_information: request_information,
@@ -0,0 +1,25 @@
1
+ module SoarAuthenticationToken
2
+ class TokenProvider
3
+ def initialize(configuration)
4
+ @configuration = configuration
5
+ validate_configuration
6
+ instantiate_provider
7
+ end
8
+
9
+ def fetch(request)
10
+ @provider.fetch(request)
11
+ end
12
+
13
+ private
14
+
15
+ def instantiate_provider
16
+ @provider = Object::const_get(@configuration['authentication_token']['provider'])
17
+ .new(@configuration['authentication_token'])
18
+ end
19
+
20
+ def validate_configuration
21
+ raise 'authentication_token provider must be configured' if @configuration['authentication_token'].nil? or
22
+ @configuration['authentication_token']['provider'].nil?
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module SoarAuthenticationToken
2
- VERSION = '6.1.1'
2
+ VERSION = '7.0.0'
3
3
  end
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'jwt', '~> 1.5', '>= 1.5.6'
24
24
  spec.add_dependency "rack", '>= 1.6.4', '< 3.0.0'
25
25
  spec.add_dependency 'authenticated_client', '~> 0.0.2'
26
+ spec.add_dependency 'http-cookie', '~> 1.0', '>= 1.0.3'
26
27
 
27
28
  spec.add_development_dependency 'auth_token_store_provider', "~> 1.0"
28
29
  spec.add_development_dependency 'pry', '~> 0'
@@ -32,4 +33,6 @@ Gem::Specification.new do |spec|
32
33
  spec.add_development_dependency "capybara", '~> 2.1', '>= 2.1.0'
33
34
  spec.add_development_dependency "simplecov", '~> 0'
34
35
  spec.add_development_dependency "simplecov-rcov", '~> 0'
36
+ spec.add_development_dependency 'webmock', '~> 3.0'
37
+ spec.add_development_dependency 'byebug'
35
38
  end
@@ -149,7 +149,7 @@ describe SoarAuthenticationToken::JwtTokenValidator do
149
149
 
150
150
  context 'given invalid token (garbage or different key)' do
151
151
  let!(:token_validation_result) {
152
- token, token_generator_meta = @remote_generator.generate(authenticated_identifier: @test_identifier)
152
+ token, token_generator_meta = @local_invalid_generator.generate(authenticated_identifier: @test_identifier)
153
153
  iut.validate(authentication_token: token)
154
154
  }
155
155
  let!(:token_validity) { token_validation_result[0] }
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'rack'
3
3
  require 'rack/test'
4
+ require 'webmock/rspec'
4
5
 
5
6
  describe SoarAuthenticationToken::RackMiddleware do
6
7
  include Rack::Test::Methods
@@ -38,7 +39,7 @@ describe SoarAuthenticationToken::RackMiddleware do
38
39
 
39
40
  before :all do
40
41
  @local_valid_generator, @valid_private_key, @valid_public_key = create_valid_token_generator
41
- @local_invalid_generator, @imvalid_private_key, @invalid_public_key = create_invalid_token_generator
42
+ @local_invalid_generator, @invalid_private_key, @invalid_public_key = create_invalid_token_generator
42
43
  @failure_response_json = [ { 'status' => 'fail', 'data' => {
43
44
  'notifications' => ['Not authenticated']
44
45
  }
@@ -58,7 +59,11 @@ describe SoarAuthenticationToken::RackMiddleware do
58
59
  end
59
60
  @iut_configuration = {
60
61
  'provider' => 'SoarAuthenticationToken::RemoteTokenValidator',
61
- 'validator-url' => 'http://authentication-token-validator-service:9393/validate'
62
+ 'validator-url' => 'http://authentication-token-validator-service:9393/validate',
63
+ 'authentication_token' => {
64
+ 'provider' => 'SoarAuthenticationToken::AuthorizationHeaderProvider',
65
+ 'header_name' => 'HTTP_AUTHORIZATION'
66
+ }
62
67
  }
63
68
  @iut = SoarAuthenticationToken::RackMiddleware.new(@test_app, @iut_configuration, "test-service", nil)
64
69
  end
@@ -80,7 +85,13 @@ describe SoarAuthenticationToken::RackMiddleware do
80
85
  context "when called with a request environment" do
81
86
  context 'with no authentication token' do
82
87
  it "return with 401" do
83
- opts = { 'REMOTE_ADDR' => '1.1.1.1' }
88
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => false, 'token_meta' => nil, 'notifications' => ['none'] }}.to_json
89
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
90
+ with(body: "{\"authentication_token\":null,\"request_information\":{\"source_address\":\"1.1.1.1\",\"user_agent\":null,\"service\":\"test-service\",\"resource\":\"/\",\"method\":\"GET\",\"base_url\":\"http://service\",\"version\":\"7.0.0\"}}",
91
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
92
+ to_return(status: 200, body: stub_response_body, headers: {})
93
+
94
+ opts = { 'REMOTE_ADDR' => '1.1.1.1', 'HTTP_AUTHORIZATION' => nil }
84
95
  code, env, body = @iut.call Rack::MockRequest.env_for('http://service', opts)
85
96
  expect([code, env, body]).to eq([401, {"Content-Type" => "application/json"}, @failure_response_json])
86
97
  end
@@ -88,7 +99,13 @@ describe SoarAuthenticationToken::RackMiddleware do
88
99
 
89
100
  context 'with an invalid authentication token' do
90
101
  it "return with 401" do
91
- opts = { 'REMOTE_ADDR' => '1.1.1.1', 'HTTP_AUTHORIZATION' => @local_invalid_generator.generate(authenticated_identifier: 'a@b.com') }
102
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => false, 'token_meta' => nil, 'notifications' => ['none'] }}.to_json
103
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
104
+ with(body: "{\"authentication_token\":\"bad_token\",\"request_information\":{\"source_address\":\"1.1.1.1\",\"user_agent\":null,\"service\":\"test-service\",\"resource\":\"/\",\"method\":\"GET\",\"base_url\":\"http://service\",\"version\":\"7.0.0\"}}",
105
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
106
+ to_return(status: 200, body: stub_response_body, headers: {})
107
+
108
+ opts = { 'REMOTE_ADDR' => '1.1.1.1', 'HTTP_AUTHORIZATION' => 'bad_token' }
92
109
  code, env, body = @iut.call Rack::MockRequest.env_for('http://service', opts)
93
110
  expect([code, env, body]).to eq([401, {"Content-Type" => "application/json"}, @failure_response_json])
94
111
  end
@@ -96,19 +113,37 @@ describe SoarAuthenticationToken::RackMiddleware do
96
113
 
97
114
  context 'with a valid authentiation token' do
98
115
  it "pass requests to the application" do
99
- opts = { 'REMOTE_ADDR' => '1.1.1.1', 'HTTP_AUTHORIZATION' => @local_valid_generator.generate(authenticated_identifier: 'a@b.com') }
116
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => true, 'token_meta' => { 'authenticated_identifier' => 'a@b.com' }, 'notifications' => ['none'] }}.to_json
117
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
118
+ with(body: "{\"authentication_token\":\"valid_token\",\"request_information\":{\"source_address\":\"1.1.1.1\",\"user_agent\":null,\"service\":\"test-service\",\"resource\":\"/\",\"method\":\"GET\",\"base_url\":\"http://service\",\"version\":\"7.0.0\"}}",
119
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
120
+ to_return(status: 200, body: stub_response_body, headers: {})
121
+
122
+ opts = { 'REMOTE_ADDR' => '1.1.1.1', 'HTTP_AUTHORIZATION' => 'valid_token' }
100
123
  code, env, body = @iut.call Rack::MockRequest.env_for('http://service', opts)
101
124
  expect([code, env, body['message']]).to eq([200, {"Content-Type"=>"application/json"}, "tested with authenticated user a@b.com" ])
102
125
  end
103
126
 
104
127
  it "populate the 'user' key in the rack session with the authenticated user" do
105
- opts = { 'REMOTE_ADDR' => '1.1.1.1', 'HTTP_AUTHORIZATION' => @local_valid_generator.generate(authenticated_identifier: 'a@b.com') }
128
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => true, 'token_meta' => { 'authenticated_identifier' => 'a@b.com' }, 'notifications' => ['none'] }}.to_json
129
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
130
+ with(body: "{\"authentication_token\":\"valid_token\",\"request_information\":{\"source_address\":\"1.1.1.1\",\"user_agent\":null,\"service\":\"test-service\",\"resource\":\"/\",\"method\":\"GET\",\"base_url\":\"http://service\",\"version\":\"7.0.0\"}}",
131
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
132
+ to_return(status: 200, body: stub_response_body, headers: {})
133
+
134
+ opts = { 'REMOTE_ADDR' => '1.1.1.1', 'HTTP_AUTHORIZATION' => 'valid_token' }
106
135
  code, env, body = @iut.call Rack::MockRequest.env_for('http://service', opts)
107
136
  expect(body['user']).to eq('a@b.com')
108
137
  end
109
138
 
110
139
  it "populate the 'auth_token_meta' key in the rack session with the hash containing the token meta" do
111
- opts = { 'REMOTE_ADDR' => '1.1.1.1', 'HTTP_AUTHORIZATION' => @local_valid_generator.generate(authenticated_identifier: 'a@b.com') }
140
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => true, 'token_meta' => { 'authenticated_identifier' => 'a@b.com' }, 'notifications' => ['none'] }}.to_json
141
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
142
+ with(body: "{\"authentication_token\":\"valid_token\",\"request_information\":{\"source_address\":\"1.1.1.1\",\"user_agent\":null,\"service\":\"test-service\",\"resource\":\"/\",\"method\":\"GET\",\"base_url\":\"http://service\",\"version\":\"7.0.0\"}}",
143
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
144
+ to_return(status: 200, body: stub_response_body, headers: {})
145
+
146
+ opts = { 'REMOTE_ADDR' => '1.1.1.1', 'HTTP_AUTHORIZATION' => 'valid_token' }
112
147
  code, env, body = @iut.call Rack::MockRequest.env_for('http://service', opts)
113
148
  expect(body['auth_token_meta']['authenticated_identifier']).to eq('a@b.com')
114
149
  end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'yaml'
3
+ require 'webmock/rspec'
3
4
 
4
5
  describe SoarAuthenticationToken::RemoteTokenValidator do
5
6
  subject { SoarAuthenticationToken::RemoteTokenValidator }
@@ -36,67 +37,92 @@ describe SoarAuthenticationToken::RemoteTokenValidator do
36
37
  describe "#validate" do
37
38
  let!(:iut) { subject.new(@remote_validator_configuration) }
38
39
  context 'given valid token' do
39
- let!(:token_validation_result) {
40
- token, token_generator_meta = @remote_generator.generate(authenticated_identifier: @test_identifier)
41
- iut.validate(authentication_token: token, request_information: request_information_from_valid_source, flow_identifier: nil)
42
- }
43
- let!(:token_validity) { token_validation_result[0] }
44
- let!(:token_meta) { token_validation_result[1] }
45
- let!(:message) { token_validation_result[2] }
46
-
47
40
  it 'should indicate valid if the token is valid' do
41
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => true, 'token_meta' => { 'authenticated_identifier' => @test_identifier }, 'notifications' => ['none'] }}.to_json
42
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
43
+ with(body: "{\"authentication_token\":\"valid_token\",\"request_information\":{\"source_address\":\"1.1.1.1\",\"user_agent\":\"some shiny browser\",\"service\":\"test-service\",\"resource\":\"/\"}}",
44
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
45
+ to_return(status: 200, body: stub_response_body, headers: {})
46
+
47
+ token = 'valid_token'
48
+ token_validity, token_meta, message = iut.validate(authentication_token: token, request_information: request_information_from_valid_source, flow_identifier: nil)
49
+
48
50
  expect(token_validity).to eq true
49
51
  end
50
52
 
51
53
  it 'should provide the authenticated_identifier if the token is valid' do
54
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => true, 'token_meta' => { 'authenticated_identifier' => @test_identifier }, 'notifications' => ['none'] }}.to_json
55
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
56
+ with(body: "{\"authentication_token\":\"valid_token\",\"request_information\":{\"source_address\":\"1.1.1.1\",\"user_agent\":\"some shiny browser\",\"service\":\"test-service\",\"resource\":\"/\"}}",
57
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
58
+ to_return(status: 200, body: stub_response_body, headers: {})
59
+
60
+ token = 'valid_token'
61
+ token_validity, token_meta, message = iut.validate(authentication_token: token, request_information: request_information_from_valid_source, flow_identifier: nil)
62
+
52
63
  expect(token_meta['authenticated_identifier']).to eq @test_identifier
53
64
  end
54
65
  end
55
66
 
56
67
  context 'given invalid (generalized) token' do
57
- let!(:token_validation_result) {
58
- token, token_generator_meta = @local_invalid_generator.generate(authenticated_identifier: @test_identifier)
59
- iut.validate(authentication_token: token, request_information: request_information_from_valid_source, flow_identifier: nil)
60
- }
61
- let!(:token_validity) { token_validation_result[0] }
62
- let!(:token_meta) { token_validation_result[1] }
63
- let!(:message) { token_validation_result[2] }
64
-
65
68
  it 'indicate token is invalid' do
69
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => false, 'token_meta' => nil, 'notifications' => ['Token decode/verification failure'] }}.to_json
70
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
71
+ with(body: "{\"authentication_token\":\"invalid_token\",\"request_information\":{\"source_address\":\"1.1.1.1\",\"user_agent\":\"some shiny browser\",\"service\":\"test-service\",\"resource\":\"/\"}}",
72
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
73
+ to_return(status: 200, body: stub_response_body, headers: {})
74
+
75
+ token = 'invalid_token'
76
+ token_validity, token_meta, message = iut.validate(authentication_token: token, request_information: request_information_from_valid_source, flow_identifier: nil)
77
+
66
78
  expect(token_validity).to eq false
67
79
  end
68
80
 
69
81
  it 'does not provide the token meta' do
82
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => false, 'token_meta' => nil, 'notifications' => ['Token decode/verification failure'] }}.to_json
83
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
84
+ with(body: "{\"authentication_token\":\"invalid_token\",\"request_information\":{\"source_address\":\"1.1.1.1\",\"user_agent\":\"some shiny browser\",\"service\":\"test-service\",\"resource\":\"/\"}}",
85
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
86
+ to_return(status: 200, body: stub_response_body, headers: {})
87
+
88
+ token = 'invalid_token'
89
+ token_validity, token_meta, message = iut.validate(authentication_token: token, request_information: request_information_from_valid_source, flow_identifier: nil)
90
+
70
91
  expect(token_meta).to eq nil
71
92
  end
72
93
 
73
94
  it 'provides a message indicating the token is invalid' do
95
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => false, 'token_meta' => nil, 'notifications' => ['Token decode/verification failure'] }}.to_json
96
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
97
+ with(body: "{\"authentication_token\":\"invalid_token\",\"request_information\":{\"source_address\":\"1.1.1.1\",\"user_agent\":\"some shiny browser\",\"service\":\"test-service\",\"resource\":\"/\"}}",
98
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
99
+ to_return(status: 200, body: stub_response_body, headers: {})
100
+
101
+ token = 'invalid_token'
102
+ token_validity, token_meta, message = iut.validate(authentication_token: token, request_information: request_information_from_valid_source, flow_identifier: nil)
103
+
74
104
  expect(message).to match /Token decode\/verification failure/
75
105
  end
76
106
  end
77
107
 
78
108
  context 'given invalid token validator url that will result in timeouts' do
79
- let!(:invalid_validator_configuration) {{
80
- 'provider' => 'SoarAuthenticationToken::RemoteTokenValidator',
81
- 'validator-url' => 'http://auth-token-validator.auto-h.net/validate',
82
- 'generator-client-auth-token' => 'test_ecosystem_token_for_auth_token_aaapi_authenticator_service'
83
- }}
84
- let!(:iut) { subject.new(invalid_validator_configuration) }
85
- let!(:valid_token) {
86
- token, token_generator_meta = @remote_generator.generate(authenticated_identifier: @test_identifier)
87
- token
88
- }
89
109
  it 'raise error after attempt that timeout has occured' do
110
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => false, 'token_meta' => nil, 'notifications' => ['Token decode/verification failure'] }}.to_json
111
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
112
+ to_timeout.times(2)
113
+
90
114
  expect{
91
- iut.validate(authentication_token: valid_token, request_information: request_information_from_valid_source, flow_identifier: nil)
115
+ iut.validate(authentication_token: 'some_token', request_information: {}, flow_identifier: nil)
92
116
  }.to raise_error Timeout::Error
93
117
  end
94
118
  it 'by default attempts 2 times with 3 second timeout' do
95
- start_time = Time.now
119
+ stub_response_body = {'status' => 'success', 'data' => { 'token_validity' => false, 'token_meta' => nil, 'notifications' => ['Token decode/verification failure'] }}.to_json
120
+ stub_request(:post, "http://authentication-token-validator-service:9393/validate?flow_identifier").
121
+ to_timeout.times(2)
122
+
96
123
  expect{
97
- iut.validate(authentication_token: valid_token, request_information: request_information_from_valid_source, flow_identifier: nil)
124
+ iut.validate(authentication_token: 'some_token', request_information: {}, flow_identifier: nil)
98
125
  }.to raise_error Timeout::Error
99
- expect(Time.now - start_time).to be_within(1).of 6
100
126
  end
101
127
  end
102
128
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'webmock/rspec'
2
3
 
3
4
  describe SoarAuthenticationToken::TokenGenerator do
4
5
  before :all do
@@ -59,18 +60,16 @@ describe SoarAuthenticationToken::TokenGenerator do
59
60
 
60
61
  context "when generating a new token remotely" do
61
62
  it 'should request the token from the configured remote service' do
63
+ stub_response_body = {'status' => 'success', 'data' => { 'token' => 'abc' }}.to_json
64
+ stub_request(:post, "http://authentication-token-generator-service:9393/generate?flow_identifier=test-flow-id").
65
+ with(body: "{\"authenticated_identifier\":\"a@b.co.za\"}",
66
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'test_ecosystem_token_for_auth_token_aaapi_authenticator_service', 'User-Agent'=>'Ruby'}).
67
+ to_return(status: 200, body: stub_response_body, headers: {})
68
+
62
69
  @iut = SoarAuthenticationToken::TokenGenerator.new(@configuration_remote_generator)
63
70
  @iut.inject_store_provider(@test_store)
64
-
65
71
  token, token_generator_meta = @iut.generate(authenticated_identifier: @test_authenticated_identifier, flow_identifier: 'test-flow-id')
66
-
67
- @validator = SoarAuthenticationToken::TokenValidator.new(@configuration_remote_validator)
68
- @iut.inject_store_provider(@test_store)
69
- token_validity, token_validator_meta, messages = @validator.validate(authentication_token: token, request_information: request_information_from_valid_source, flow_identifier: 'test-flow-id')
70
-
71
- expect(token_validity).to eq(true)
72
- expect(token_validator_meta['authenticated_identifier']).to eq(@test_authenticated_identifier)
73
- expect(messages).to match(/Valid token/)
72
+ expect(token).to eq('abc')
74
73
  end
75
74
  end
76
75
 
@@ -82,16 +81,22 @@ describe SoarAuthenticationToken::TokenGenerator do
82
81
  }}
83
82
  let!(:iut) { SoarAuthenticationToken::TokenGenerator.new(invalid_generator_configuration) }
84
83
  it 'raise error after attempt that timeout has occured' do
84
+ stub_request(:post, "http://auth-token-generator.auto-h.net/generate?flow_identifier=test-flow-id").
85
+ with(body: "{\"authenticated_identifier\":\"a@b.co.za\"}",
86
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'test_ecosystem_token_for_auth_token_aaapi_authenticator_service', 'User-Agent'=>'Ruby'}).
87
+ to_timeout.times(2)
85
88
  expect{
86
89
  iut.generate(authenticated_identifier: @test_authenticated_identifier, flow_identifier: 'test-flow-id')
87
90
  }.to raise_error Timeout::Error
88
91
  end
89
92
  it 'by default attempts 2 times with 3 second timeout' do
90
- start_time = Time.now
93
+ stub_request(:post, "http://auth-token-generator.auto-h.net/generate?flow_identifier=test-flow-id").
94
+ with(body: "{\"authenticated_identifier\":\"a@b.co.za\"}",
95
+ headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'test_ecosystem_token_for_auth_token_aaapi_authenticator_service', 'User-Agent'=>'Ruby'}).
96
+ to_timeout.times(2)
91
97
  expect{
92
98
  iut.generate(authenticated_identifier: @test_authenticated_identifier, flow_identifier: 'test-flow-id')
93
99
  }.to raise_error Timeout::Error
94
- expect(Time.now - start_time).to be_within(1).of 6
95
100
  end
96
101
  end
97
102
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: soar_authentication_token
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.1
4
+ version: 7.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Barney de Villiers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-12 00:00:00.000000000 Z
11
+ date: 2017-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: soar_xt
@@ -78,6 +78,26 @@ dependencies:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
80
  version: 0.0.2
81
+ - !ruby/object:Gem::Dependency
82
+ name: http-cookie
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '1.0'
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 1.0.3
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.0'
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 1.0.3
81
101
  - !ruby/object:Gem::Dependency
82
102
  name: auth_token_store_provider
83
103
  requirement: !ruby/object:Gem::Requirement
@@ -196,6 +216,34 @@ dependencies:
196
216
  - - "~>"
197
217
  - !ruby/object:Gem::Version
198
218
  version: '0'
219
+ - !ruby/object:Gem::Dependency
220
+ name: webmock
221
+ requirement: !ruby/object:Gem::Requirement
222
+ requirements:
223
+ - - "~>"
224
+ - !ruby/object:Gem::Version
225
+ version: '3.0'
226
+ type: :development
227
+ prerelease: false
228
+ version_requirements: !ruby/object:Gem::Requirement
229
+ requirements:
230
+ - - "~>"
231
+ - !ruby/object:Gem::Version
232
+ version: '3.0'
233
+ - !ruby/object:Gem::Dependency
234
+ name: byebug
235
+ requirement: !ruby/object:Gem::Requirement
236
+ requirements:
237
+ - - ">="
238
+ - !ruby/object:Gem::Version
239
+ version: '0'
240
+ type: :development
241
+ prerelease: false
242
+ version_requirements: !ruby/object:Gem::Requirement
243
+ requirements:
244
+ - - ">="
245
+ - !ruby/object:Gem::Version
246
+ version: '0'
199
247
  description: Interface to the authentication token service
200
248
  email:
201
249
  - barney.de.villiers@hetzner.co.za
@@ -208,7 +256,6 @@ extensions: []
208
256
  extra_rdoc_files: []
209
257
  files:
210
258
  - ".gitignore"
211
- - ".gitmodules"
212
259
  - ".rspec"
213
260
  - ".ruby-gemset"
214
261
  - ".ruby-version"
@@ -225,6 +272,9 @@ files:
225
272
  - lib/soar_authentication_token.rb
226
273
  - lib/soar_authentication_token/config_rotator.rb
227
274
  - lib/soar_authentication_token/keypair_generator.rb
275
+ - lib/soar_authentication_token/providers/authorization_header_provider.rb
276
+ - lib/soar_authentication_token/providers/cascade_provider.rb
277
+ - lib/soar_authentication_token/providers/cookie_provider.rb
228
278
  - lib/soar_authentication_token/providers/jwt_token_generator.rb
229
279
  - lib/soar_authentication_token/providers/jwt_token_validator.rb
230
280
  - lib/soar_authentication_token/providers/remote_token_generator.rb
@@ -232,6 +282,7 @@ files:
232
282
  - lib/soar_authentication_token/providers/static_token_validator.rb
233
283
  - lib/soar_authentication_token/rack_middleware.rb
234
284
  - lib/soar_authentication_token/token_generator.rb
285
+ - lib/soar_authentication_token/token_provider.rb
235
286
  - lib/soar_authentication_token/token_validator.rb
236
287
  - lib/soar_authentication_token/version.rb
237
288
  - retry.sh
@@ -244,7 +295,7 @@ files:
244
295
  - spec/config_rotator_spec.rb
245
296
  - spec/jwt_token_validator_spec.rb
246
297
  - spec/keypair_generator_spec.rb
247
- - spec/rack_middleware_spec.rb
298
+ - spec/rack_middleware/authorization_header_spec.rb
248
299
  - spec/remote_token_validator_spec.rb
249
300
  - spec/spec_helper.rb
250
301
  - spec/static_token_validator_spec.rb
@@ -278,7 +329,7 @@ test_files:
278
329
  - spec/config_rotator_spec.rb
279
330
  - spec/jwt_token_validator_spec.rb
280
331
  - spec/keypair_generator_spec.rb
281
- - spec/rack_middleware_spec.rb
332
+ - spec/rack_middleware/authorization_header_spec.rb
282
333
  - spec/remote_token_validator_spec.rb
283
334
  - spec/spec_helper.rb
284
335
  - spec/static_token_validator_spec.rb
data/.gitmodules DELETED
@@ -1,12 +0,0 @@
1
- [submodule "authentication-token-generator-service"]
2
- path = authentication-token-generator-service
3
- url = git@gitlab.host-h.net:hetznerZA/authentication-token-generator-service.git
4
- branch = master
5
- [submodule "authentication-token-validator-service"]
6
- path = authentication-token-validator-service
7
- url = git@gitlab.host-h.net:hetznerZA/authentication-token-validator-service.git
8
- branch = master
9
- [submodule "authentication-token-store"]
10
- path = authentication-token-store
11
- url = git@gitlab.host-h.net:hetznerZA/authentication-token-store.git
12
- branch = master