soar_authentication_token 0.0.4 → 0.1.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: 0f96b19d4ab690a6bfdd43d38c9c16795dbef257
4
- data.tar.gz: a91497c50df87f8adaaa76c6929e33a8f3afd9fe
3
+ metadata.gz: cba64c87af18ce0cacb4333430c2056b2a8dbf4d
4
+ data.tar.gz: 2b78253b2ce7ed01e483075950e81400c8d7435b
5
5
  SHA512:
6
- metadata.gz: 0230c1bbd09ba5887a6be2908824dc5d441f28da8e9128c4da1240f967a5d2588df2f42d3b94cb984abb9375a507ab5f312f36f5e6b624d9938c595084cd1db3
7
- data.tar.gz: e8dc6ceb4f1d612f40bc62b64c912a7b5085e77fe49edbeea3a40b29c0cbd209bb3b82da67d7805d50ef9d97bbaab8c7ff61bcfb04a53cbe866b731edafa677c
6
+ metadata.gz: 98fabb13ee0409d95199d7eceb98a1eed2af9c0f0b4a506e6e883ed9f762d488bdef6a5e786cac824f78a1437af3f32cd4b587e10a7ca1819e3a2d896a3512e5
7
+ data.tar.gz: ec3ec0e4f402d2effabe925dfbefe3e7b7413eb0462cd8e6b3765386828d40d690f95a21965241f6fd14c0e9f2d7b4bbb9bc8134d9eac7874358057cad1de56b
data/README.md CHANGED
@@ -25,7 +25,17 @@ Or install it yourself as:
25
25
 
26
26
  Run the rspec test tests using docker compose:
27
27
 
28
- $ docker-compose run soar-authentication-token /bin/bash -c 'sleep 10; bundle exec rspec -cfd spec'
28
+ $ docker-compose build
29
+ $ docker-compose run --rm soar-authentication-token
30
+
31
+ Properly clean up containers afterwards:
32
+
33
+ $ docker-compose down
34
+
35
+ Locally run a subset:
36
+
37
+ $ bundle exec rspec -cfd spec/rack_middleware_spec.rb
38
+
29
39
 
30
40
  ## Usage
31
41
 
data/docker-compose.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  version: '2.0'
2
2
  services:
3
3
  soar-authentication-token:
4
+ command: /bin/bash -c 'sleep 10; bundle exec rspec -cfd spec'
4
5
  build: .
5
6
  image: soar-authentication-token
6
7
  volumes:
@@ -1,97 +1,29 @@
1
- require 'browser'
2
- require 'cgi'
3
- require 'net/http'
4
- require 'nokogiri'
5
- require 'rack/request'
6
- require 'uri'
1
+ require 'rack'
7
2
 
8
3
  module SoarAuthenticationToken
9
-
10
4
  class RackMiddleware
11
-
12
- def initialize(app, config)
5
+ def initialize(app, configuration)
13
6
  @app = app
14
- @config = config
7
+ @configuration = configuration
15
8
  end
16
9
 
17
10
  def call(env)
18
11
  request = Rack::Request.new env
19
- if @config[:browsers_only] and !is_browser?(request)
12
+ session, params = request.session, request.params
13
+ valid, authenticated_identifier = validate_and_resolve_token(request.env['HTTP_AUTHORIZATION'],params['flow_identifier'])
14
+ if valid
15
+ session['user'] = authenticated_identifier
20
16
  @app.call env
21
17
  else
22
- session, params = request.session, request.params
23
- if session['user']
24
- @app.call env
25
- elsif params['logoutRequest']
26
- callback(:on_logout, env, st_from_logoutrequest(params['logoutRequest']))
27
- [200, {}, ['']]
28
- elsif user = signon(request)
29
- session['user'] = user
30
- callback(:on_login, env, request['ticket'])
31
- @app.call env
32
- else
33
- service = get_service request
34
- [302, {'Location' => signon_url(service)}, ['']]
35
- end
18
+ [401, {"Content-Type" => "text/html"}, ["401 - Not authenticated"]]
36
19
  end
37
20
  end
38
21
 
39
22
  private
40
23
 
41
- def callback(on_what, env, service_ticket)
42
- @config[on_what].call(env, service_ticket) if(@config[on_what])
43
- end
44
-
45
- def st_from_logoutrequest(logout_request)
46
- document = Nokogiri::XML::Document.parse(logout_request)
47
- document.xpath('/samlp:LogoutRequest/samlp:SessionIndex').text
24
+ def validate_and_resolve_token(authentication_token,flow_identifier)
25
+ token_validator = SoarAuthenticationToken::TokenValidator.new(@configuration)
26
+ token_validator.validate(authentication_token: authentication_token,flow_identifier: flow_identifier)
48
27
  end
49
-
50
-
51
- def is_browser?(request)
52
- ua = request.user_agent
53
- Browser.new(ua: ua).id != :other
54
- end
55
-
56
- def signon(request)
57
- ticket = request.params['ticket']
58
- service = get_service(request)
59
- if ticket and service
60
- redeem_service_ticket(ticket, service)
61
- end
62
- end
63
-
64
- def get_service(request)
65
- url = request.url
66
- url.gsub!(/\&ticket=ST-\w+/, '')
67
- url.gsub!(/\?ticket=ST-\w+/, '?')
68
- url.chomp('?')
69
- end
70
-
71
- def redeem_service_ticket(ticket, service)
72
- uri = URI.parse validation_url(ticket, service)
73
- req = Net::HTTP::Get.new(uri.to_s)
74
- verify_mode = @config[:ignore_certificate] ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
75
- Net::HTTP.start(uri.host, uri.port, :use_ssl => (uri.scheme == 'https'), :verify_mode => verify_mode) do |http|
76
- response = http.request(req)
77
- if response.code.to_i == 200
78
- response_xml = Nokogiri::XML::Document.parse(response.body)
79
- user_element = response_xml.xpath('/cas:serviceResponse/cas:authenticationSuccess/cas:user')
80
- unless user_element.empty?
81
- user_element.inner_text
82
- end
83
- end
84
- end
85
- end
86
-
87
- def signon_url(service = '')
88
- "#{@config[:prefix]}/login?service=#{CGI.escape service}"
89
- end
90
-
91
- def validation_url(ticket, service)
92
- "#{@config[:prefix]}/serviceValidate?ticket=#{ticket}&service=#{CGI.escape service}"
93
- end
94
-
95
28
  end
96
-
97
29
  end
@@ -1,3 +1,3 @@
1
1
  module SoarAuthenticationToken
2
- VERSION = '0.0.4'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -21,9 +21,11 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_dependency 'soar_xt', '~> 0.0.3'
23
23
  spec.add_dependency 'jwt', '~> 1.5', '>= 1.5.6'
24
+ spec.add_dependency "rack", '~> 1.6', '>= 1.6.4'
24
25
 
25
26
  spec.add_development_dependency 'pry', '~> 0'
26
- spec.add_development_dependency "bundler", "~> 1.3"
27
- spec.add_development_dependency "rake", "~> 10.0"
28
- spec.add_development_dependency "rspec", "~> 2.13"
27
+ spec.add_development_dependency 'bundler', '~> 1.3'
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'rspec', '~> 2.13'
30
+ spec.add_development_dependency "capybara", '~> 2.1', '>= 2.1.0'
29
31
  end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+ require 'rack'
3
+ require 'rack/test'
4
+
5
+ describe SoarAuthenticationToken::RackMiddleware do
6
+ include Rack::Test::Methods
7
+
8
+ def create_token_generator
9
+ keypair_generator = SoarAuthenticationToken::KeypairGenerator.new
10
+ private_key, public_key = keypair_generator.generate
11
+ configuration = {
12
+ 'mode' => 'local',
13
+ 'private_key' => private_key,
14
+ 'public_key' => public_key
15
+ }
16
+ [ SoarAuthenticationToken::TokenGenerator.new(configuration), private_key, public_key ]
17
+ end
18
+
19
+ before :all do
20
+ @local_valid_generator, @valid_private_key, @valid_public_key = create_token_generator
21
+ @local_invalid_generator, @imvalid_private_key, @invalid_public_key = create_token_generator
22
+ end
23
+
24
+ before :each do
25
+ @test_app = lambda do |env|
26
+ request = Rack::Request.new env
27
+ session = request.session
28
+ [200, {"Content-Type"=>"text/html"}, ["tested with authenticated user #{session['user']}"] ]
29
+ end
30
+ @iut_configuration = { 'mode' => 'local', 'public_key' => @valid_public_key}
31
+ @iut = SoarAuthenticationToken::RackMiddleware.new(@test_app, @iut_configuration)
32
+ end
33
+
34
+ it 'has a version number' do
35
+ expect(SoarAuthenticationToken::VERSION).not_to be nil
36
+ end
37
+
38
+ context "when initialized" do
39
+ it 'remembers the app provided' do
40
+ expect(@iut.instance_variable_get("@app")).to eq(@test_app)
41
+ end
42
+
43
+ it 'remembers the configuration provided' do
44
+ expect(@iut.instance_variable_get("@configuration")).to eq(@iut_configuration)
45
+ end
46
+ end
47
+
48
+ context "when called with an environment" do
49
+ it "should return 401 if the request contains no authentication token" do
50
+ opts = { }
51
+ code, env, body = @iut.call Rack::MockRequest.env_for('http://service', opts)
52
+ expect([code, env, body]).to eq([401, {"Content-Type" => "text/html"}, ["401 - Not authenticated"]])
53
+ end
54
+
55
+ it "should return 401 if the request contains an invalid authentication token" do
56
+ opts = { 'HTTP_AUTHORIZATION' => @local_invalid_generator.generate(authenticated_identifier: 'a@b.com') }
57
+ code, env, body = @iut.call Rack::MockRequest.env_for('http://service', opts)
58
+ expect([code, env, body]).to eq([401, {"Content-Type" => "text/html"}, ["401 - Not authenticated"]])
59
+ end
60
+
61
+ it "should pass requests that are authenticated through to the application" do
62
+ opts = { 'HTTP_AUTHORIZATION' => @local_valid_generator.generate(authenticated_identifier: 'a@b.com') }
63
+ code, env, body = @iut.call Rack::MockRequest.env_for('http://service', opts)
64
+ expect([code, env, body]).to eq([200, {"Content-Type"=>"text/html"}, ["tested with authenticated user a@b.com"] ])
65
+ end
66
+ end
67
+ 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: 0.0.4
4
+ version: 0.1.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: 2016-12-01 00:00:00.000000000 Z
11
+ date: 2016-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: soar_xt
@@ -44,6 +44,26 @@ dependencies:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: 1.5.6
47
+ - !ruby/object:Gem::Dependency
48
+ name: rack
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.6'
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 1.6.4
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '1.6'
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 1.6.4
47
67
  - !ruby/object:Gem::Dependency
48
68
  name: pry
49
69
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +120,26 @@ dependencies:
100
120
  - - "~>"
101
121
  - !ruby/object:Gem::Version
102
122
  version: '2.13'
123
+ - !ruby/object:Gem::Dependency
124
+ name: capybara
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '2.1'
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 2.1.0
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '2.1'
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: 2.1.0
103
143
  description: Interface to the authentication token service
104
144
  email:
105
145
  - barney.de.villiers@hetzner.co.za
@@ -137,6 +177,7 @@ files:
137
177
  - sanity/sanity_benchmark.rb
138
178
  - soar_authentication_token.gemspec
139
179
  - spec/keypair_generator_spec.rb
180
+ - spec/rack_middleware_spec.rb
140
181
  - spec/spec_helper.rb
141
182
  - spec/token_generator_spec.rb
142
183
  - spec/token_validator_spec.rb
@@ -166,6 +207,7 @@ specification_version: 4
166
207
  summary: Client library for Hetzner's authentication token service
167
208
  test_files:
168
209
  - spec/keypair_generator_spec.rb
210
+ - spec/rack_middleware_spec.rb
169
211
  - spec/spec_helper.rb
170
212
  - spec/token_generator_spec.rb
171
213
  - spec/token_validator_spec.rb