soar_authentication_token 0.0.4 → 0.1.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: 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