soar_authentication_token 6.1.1 → 7.0.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: 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