httpi-adapter-win32sspi 0.0.1.rc1-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/License.txt +8 -0
- data/Rakefile +40 -0
- data/Readme.md +7 -0
- data/example/httpi_adapter_client.rb +22 -0
- data/httpi_adapter_win32sspi.gemspec +26 -0
- data/lib/httpi-adapter-win32sspi.rb +2 -0
- data/lib/httpi/adapter/win32sspi.rb +136 -0
- data/lib/httpi/auth/config_sspi.rb +22 -0
- data/test/all_tests.rb +2 -0
- data/test/test_httpi_adapter_win32sspi.rb +260 -0
- data/test/test_httpi_auth.rb +17 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f5c8d1eafaeeef8bcf09d2c83ab3d2668ed414b7
|
4
|
+
data.tar.gz: aaf878b1c5f1efb4cf77889c9c78748a31e82d18
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fdaf85e6b0d6046e20e45c973df115d6fd34e1d62f51e4ed7bd600b9b86ac3e38dd762755e5d97ab74754293de4dc8217fa80777ada178c37dd01d513ec14acd
|
7
|
+
data.tar.gz: cfb7844536b4b8b569447fa361476fd269356ed9d131cee7cb33b5145d26c4f63e11741da2fd422c95ba7476c76a6594092fc07d562c0ea0a1ba32ca0b0e4e43
|
data/License.txt
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
MIT License
|
2
|
+
Copyright (c) 2015 Gary Sick
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
5
|
+
|
6
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
7
|
+
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'rubygems/package'
|
6
|
+
|
7
|
+
CLEAN.include('**/*.gem')
|
8
|
+
|
9
|
+
namespace :gem do
|
10
|
+
desc "Create the httpi-adapter-win32sspi gem"
|
11
|
+
task :create => [:clean] do
|
12
|
+
spec = eval(IO.read('httpi_adapter_win32sspi.gemspec'))
|
13
|
+
Gem::Package.build(spec)
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Install the httpi-adapter-win32sspi gem"
|
17
|
+
task :install => [:create] do
|
18
|
+
file = Dir["*.gem"].first
|
19
|
+
sh "gem install #{file} -l --no-document"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
namespace :test do
|
24
|
+
Rake::TestTask.new(:win32_adapter) do |t|
|
25
|
+
t.test_files = FileList['test/test_httpi_adapter_win32sspi.rb']
|
26
|
+
t.verbose = true
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::TestTask.new(:httpi_auth) do |t|
|
30
|
+
t.test_files = FileList['test/test_httpi_auth.rb']
|
31
|
+
t.verbose = true
|
32
|
+
end
|
33
|
+
|
34
|
+
Rake::TestTask.new(:all) do |t|
|
35
|
+
t.test_files = FileList['test/test_httpi*']
|
36
|
+
t.verbose = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => 'test:all'
|
data/Readme.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'httpi'
|
3
|
+
require 'httpi-adapter-win32sspi'
|
4
|
+
|
5
|
+
class HttpiAdapterClient
|
6
|
+
def self.run(url)
|
7
|
+
uri = URI.parse(url)
|
8
|
+
request = HTTPI::Request.new(url)
|
9
|
+
request.auth.sspi(spn:"HTTP/#{uri.host}")
|
10
|
+
response = HTTPI::get(request, :win32_sspi)
|
11
|
+
pp response
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if __FILE__ == $0
|
16
|
+
if ARGV.length < 1
|
17
|
+
puts "usage: ruby httpi_adapter_client url"
|
18
|
+
exit(0)
|
19
|
+
end
|
20
|
+
|
21
|
+
HttpiAdapterClient.run(ARGV[0])
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'httpi-adapter-win32sspi'
|
5
|
+
spec.summary = 'A HTTPI Adapter the uses Win32SSPI'
|
6
|
+
spec.version = '0.0.1.rc1'
|
7
|
+
spec.author = 'Gary Sick'
|
8
|
+
spec.license = 'MIT'
|
9
|
+
spec.email = 'garys361@gmail.com'
|
10
|
+
spec.platform = Gem::Platform::CURRENT
|
11
|
+
spec.required_ruby_version = '>=1.9'
|
12
|
+
spec.homepage = 'https://github.com/garysick/httpi_adapter_win32sspi'
|
13
|
+
spec.files = Dir['**/*'].reject{ |f| f.include?('git') || f.include?('Notes.txt') }
|
14
|
+
spec.test_files = Dir['test/*.rb']
|
15
|
+
spec.has_rdoc = false
|
16
|
+
|
17
|
+
spec.add_dependency('win32-sspi', '=0.0.1.rc1')
|
18
|
+
spec.add_development_dependency('test-unit','~>3.0')
|
19
|
+
spec.requirements << "This gem will only work in a Windows Environment"
|
20
|
+
|
21
|
+
spec.description = <<-EOF
|
22
|
+
A HTTPI Adapter the uses Win32SSPI library.
|
23
|
+
Support the Negotiate protocols.
|
24
|
+
See examples for usage.
|
25
|
+
EOF
|
26
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'httpi'
|
3
|
+
require 'net/http'
|
4
|
+
require 'win32-sspi'
|
5
|
+
require 'negotiate/client'
|
6
|
+
require_relative '../auth/config_sspi'
|
7
|
+
|
8
|
+
module HTTPI
|
9
|
+
module Adapter
|
10
|
+
class Win32SSPI < Base
|
11
|
+
register :win32_sspi
|
12
|
+
|
13
|
+
def initialize(req)
|
14
|
+
@request = req
|
15
|
+
@sspi_client = create_sspi_client(req)
|
16
|
+
@client = create_http_client(req)
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :client
|
20
|
+
attr_reader :sspi_client
|
21
|
+
|
22
|
+
def request(method)
|
23
|
+
unless REQUEST_METHODS.include? method
|
24
|
+
raise NotSupportedError, "Net::HTTP does not support custom HTTP methods"
|
25
|
+
end
|
26
|
+
|
27
|
+
http_req = convert_to_http_request(method,@request)
|
28
|
+
response = dispatch_request(@client, @sspi_client, http_req)
|
29
|
+
convert_to_httpi_response(response)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def create_sspi_client(request)
|
35
|
+
return nil unless :sspi == request.auth.type
|
36
|
+
|
37
|
+
options = request.auth.sspi.first
|
38
|
+
Win32::SSPI::Negotiate::Client.new(options)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create_http_client(request)
|
42
|
+
if request.auth.digest?
|
43
|
+
raise NotSupportedError, "Net::HTTP does not support HTTP digest authentication"
|
44
|
+
end
|
45
|
+
|
46
|
+
if request.proxy
|
47
|
+
http = Net::HTTP.new(request.url.host, request.url.port,
|
48
|
+
request.proxy.host, request.proxy.port, request.proxy.user, request.proxy.password)
|
49
|
+
else
|
50
|
+
http = Net::HTTP.new(request.url.host, request.url.port)
|
51
|
+
end
|
52
|
+
|
53
|
+
http.open_timeout = request.open_timeout if request.open_timeout
|
54
|
+
http.read_timeout = request.read_timeout if request.read_timeout
|
55
|
+
|
56
|
+
if request.auth.ssl?
|
57
|
+
ssl = request.auth.ssl
|
58
|
+
unless ssl.verify_mode == :none
|
59
|
+
http.ca_file = ssl.ca_cert_file if ssl.ca_cert_file
|
60
|
+
end
|
61
|
+
|
62
|
+
http.key = ssl.cert_key
|
63
|
+
http.cert = ssl.cert
|
64
|
+
|
65
|
+
http.verify_mode = ssl.openssl_verify_mode
|
66
|
+
http.ssl_version = ssl.ssl_version if ssl.ssl_version
|
67
|
+
end
|
68
|
+
|
69
|
+
http
|
70
|
+
end
|
71
|
+
|
72
|
+
def dispatch_request(http_client,sspi_client,http_req)
|
73
|
+
if sspi_client
|
74
|
+
perform_authenticated_request(http_client,sspi_client,http_req)
|
75
|
+
else
|
76
|
+
perform_http_request(http_client,http_req)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def perform_authenticated_request(http_client,sspi_client,http_req)
|
81
|
+
http_resp = nil
|
82
|
+
http_client.start do |http|
|
83
|
+
sspi_client.http_authenticate do |header|
|
84
|
+
http_req['Authorization'] = header
|
85
|
+
http_resp = perform_request(http,http_req)
|
86
|
+
http_resp['www-authenticate']
|
87
|
+
end
|
88
|
+
end
|
89
|
+
http_resp
|
90
|
+
end
|
91
|
+
|
92
|
+
def perform_http_request(http_client,http_req)
|
93
|
+
http_resp = nil
|
94
|
+
http_client.start do |http|
|
95
|
+
http_resp = perform_request(http,http_req)
|
96
|
+
end
|
97
|
+
http_resp
|
98
|
+
end
|
99
|
+
|
100
|
+
def perform_request(http,http_req)
|
101
|
+
if @request.on_body
|
102
|
+
http.request(http_req) do |r|
|
103
|
+
r.read_body do |seg|
|
104
|
+
@request.on_body.call(seg)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
else
|
108
|
+
http.request(http_req)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def convert_to_http_request(type,req)
|
113
|
+
request_class = case type
|
114
|
+
when :get then Net::HTTP::Get
|
115
|
+
when :post then Net::HTTP::Post
|
116
|
+
when :head then Net::HTTP::Head
|
117
|
+
when :put then Net::HTTP::Put
|
118
|
+
when :delete then Net::HTTP::Delete
|
119
|
+
end
|
120
|
+
|
121
|
+
request = request_class.new(req.url, req.headers)
|
122
|
+
request.body = req.body
|
123
|
+
request
|
124
|
+
end
|
125
|
+
|
126
|
+
def convert_to_httpi_response(resp)
|
127
|
+
headers = resp.to_hash
|
128
|
+
headers.each do |key, value|
|
129
|
+
headers[key] = value[0] if value.size <= 1
|
130
|
+
end
|
131
|
+
body = (resp.body.kind_of?(Net::ReadAdapter) ? "" : resp.body)
|
132
|
+
Response.new(resp.code, headers, body)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'httpi/auth/config'
|
2
|
+
|
3
|
+
module ConfigSSPI
|
4
|
+
def self.included(mod)
|
5
|
+
if HTTPI::Auth::Config == mod
|
6
|
+
mod::TYPES << :sspi unless mod::TYPES.include?(:sspi)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def sspi(*args)
|
11
|
+
return @sspi if args.empty?
|
12
|
+
|
13
|
+
@sspi = args.flatten.compact
|
14
|
+
@type = :sspi
|
15
|
+
end
|
16
|
+
|
17
|
+
def sspi?
|
18
|
+
@type == :sspi
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
HTTPI::Auth::Config.include(ConfigSSPI)
|
data/test/all_tests.rb
ADDED
@@ -0,0 +1,260 @@
|
|
1
|
+
require 'httpi'
|
2
|
+
require 'httpi/adapter/win32sspi'
|
3
|
+
require 'test-unit'
|
4
|
+
|
5
|
+
HTTPI.log = false
|
6
|
+
|
7
|
+
class TC_HttpiAdapterWin32SSPI < Test::Unit::TestCase
|
8
|
+
RequestURI = "http://virtual-server.gas.local:3005/test"
|
9
|
+
RequestSPN = "HTTP/virtual-server.gas.local"
|
10
|
+
TestHeaderName = "Test-Header"
|
11
|
+
TestHeader = "some junk"
|
12
|
+
RemoteUserHdrName = "Remote-User"
|
13
|
+
RemoteUserHdr = "johny d"
|
14
|
+
FakeAuth = 'YIIxckdlsleodllsleoeoo49dldleo490'
|
15
|
+
AuthenticateHdrName = "www-authenticate"
|
16
|
+
AuthenticateHdr = "Negotiate #{FakeAuth}"
|
17
|
+
AuthorizationHdrName = "Authorization"
|
18
|
+
AuthorizationHdr = AuthenticateHdr
|
19
|
+
MockRespSegments = ["Segment 1","Segment 2","Segment 3"]
|
20
|
+
|
21
|
+
def test_load_adapter
|
22
|
+
request = HTTPI::Request.new(RequestURI)
|
23
|
+
request.auth.sspi(spn:RequestSPN)
|
24
|
+
adapter = HTTPI.send(:load_adapter,:win32_sspi,request)
|
25
|
+
assert_equal "HTTPI::Adapter::Win32SSPI", adapter.class.name
|
26
|
+
assert_equal "Win32::SSPI::Negotiate::Client", adapter.sspi_client.class.name
|
27
|
+
assert_equal URI.parse(RequestURI), request.url
|
28
|
+
end
|
29
|
+
|
30
|
+
def with_mock_adapter(adapter_klass = create_mock_adapter)
|
31
|
+
HTTPI::Adapter.register(:win32_sspi, adapter_klass, {})
|
32
|
+
|
33
|
+
yield adapter_klass if block_given?
|
34
|
+
|
35
|
+
ensure
|
36
|
+
HTTPI::Adapter.register(:win32_sspi,HTTPI::Adapter::Win32SSPI,{})
|
37
|
+
end
|
38
|
+
|
39
|
+
def assert_request_response_attributes(request,response,adapter_klass)
|
40
|
+
assert_equal 'HTTPI::Response', response.class.name
|
41
|
+
assert_equal 200, response.code
|
42
|
+
assert_equal 'hello test', response.body unless request.on_body
|
43
|
+
assert_equal 1, response.headers.size
|
44
|
+
assert_equal AuthenticateHdr, response.headers[AuthenticateHdrName]
|
45
|
+
|
46
|
+
assert_equal request, adapter_klass.read_state(:httpi_request)
|
47
|
+
|
48
|
+
sspi_client = adapter_klass.read_state(:sspi_client)
|
49
|
+
if sspi_client
|
50
|
+
assert_equal "Win32::SSPI::Negotiate::Client", sspi_client.class.name
|
51
|
+
assert_equal 'Negotiate', sspi_client.auth_type
|
52
|
+
assert_equal RequestSPN, sspi_client.spn
|
53
|
+
end
|
54
|
+
|
55
|
+
http_req = adapter_klass.read_state(:http_request)
|
56
|
+
assert_equal "virtual-server.gas.local", http_req.uri.host
|
57
|
+
assert_equal 3005, http_req.uri.port
|
58
|
+
assert_equal "/test", http_req.uri.path
|
59
|
+
|
60
|
+
yield(http_req) if block_given?
|
61
|
+
|
62
|
+
assert_equal TestHeader, http_req[TestHeaderName]
|
63
|
+
assert_equal RemoteUserHdr, http_req[RemoteUserHdrName]
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_get
|
67
|
+
with_mock_adapter do |adapter_klass|
|
68
|
+
request = HTTPI::Request.new(RequestURI)
|
69
|
+
request.auth.sspi(spn:RequestSPN)
|
70
|
+
request.headers[TestHeaderName] = TestHeader
|
71
|
+
request.headers[RemoteUserHdrName] = RemoteUserHdr
|
72
|
+
|
73
|
+
response = HTTPI::get(request, :win32_sspi)
|
74
|
+
|
75
|
+
assert_request_response_attributes(request,response,adapter_klass) do |http_req|
|
76
|
+
assert_equal 'Net::HTTP::Get', http_req.class.name
|
77
|
+
assert_equal 3, adapter_klass.read_state(:perform_authenticated_request_args).length
|
78
|
+
assert_nil adapter_klass.read_state(:perform_http_request_args)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_get_with_query_parameter
|
84
|
+
with_mock_adapter do |adapter_klass|
|
85
|
+
request = HTTPI::Request.new(RequestURI)
|
86
|
+
request.auth.sspi(spn:RequestSPN)
|
87
|
+
request.query ="q=query"
|
88
|
+
request.headers[TestHeaderName] = TestHeader
|
89
|
+
request.headers[RemoteUserHdrName] = RemoteUserHdr
|
90
|
+
|
91
|
+
response = HTTPI::get(request, :win32_sspi)
|
92
|
+
|
93
|
+
assert_request_response_attributes(request,response,adapter_klass) do |http_req|
|
94
|
+
assert_equal 'Net::HTTP::Get', http_req.class.name
|
95
|
+
assert_equal "q=query", http_req.uri.query
|
96
|
+
assert_equal 3, adapter_klass.read_state(:perform_authenticated_request_args).length
|
97
|
+
assert_nil adapter_klass.read_state(:perform_http_request_args)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_post
|
103
|
+
with_mock_adapter do |adapter_klass|
|
104
|
+
request = HTTPI::Request.new(RequestURI)
|
105
|
+
request.auth.sspi(spn:RequestSPN)
|
106
|
+
request.body = "firstname=tom&lastname=johnson"
|
107
|
+
request.headers[TestHeaderName] = TestHeader
|
108
|
+
request.headers[RemoteUserHdrName] = RemoteUserHdr
|
109
|
+
|
110
|
+
response = HTTPI::post(request, :win32_sspi)
|
111
|
+
|
112
|
+
assert_request_response_attributes(request,response,adapter_klass) do |http_req|
|
113
|
+
assert_equal 'Net::HTTP::Post', http_req.class.name
|
114
|
+
assert_equal "firstname=tom&lastname=johnson", http_req.body
|
115
|
+
assert_equal 3, adapter_klass.read_state(:perform_authenticated_request_args).length
|
116
|
+
assert_nil adapter_klass.read_state(:perform_http_request_args)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_request_without_sspi_client
|
122
|
+
with_mock_adapter do |adapter_klass|
|
123
|
+
request = HTTPI::Request.new(RequestURI)
|
124
|
+
request.headers[TestHeaderName] = TestHeader
|
125
|
+
request.headers[RemoteUserHdrName] = RemoteUserHdr
|
126
|
+
|
127
|
+
response = HTTPI::get(request, :win32_sspi)
|
128
|
+
|
129
|
+
assert_request_response_attributes(request,response,adapter_klass) do |http_req|
|
130
|
+
assert_equal 'Net::HTTP::Get', http_req.class.name
|
131
|
+
assert_nil adapter_klass.read_state(:sspi_client)
|
132
|
+
assert_equal 2, adapter_klass.read_state(:perform_http_request_args).length
|
133
|
+
assert_nil adapter_klass.read_state(:perform_authenticated_request_args)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_get_with_request_block
|
139
|
+
with_mock_adapter do |adapter_klass|
|
140
|
+
request = HTTPI::Request.new(RequestURI)
|
141
|
+
request.auth.sspi(spn:RequestSPN)
|
142
|
+
request.headers[TestHeaderName] = TestHeader
|
143
|
+
request.headers[RemoteUserHdrName] = RemoteUserHdr
|
144
|
+
response_segments = []
|
145
|
+
request.on_body do |seg|
|
146
|
+
response_segments << seg
|
147
|
+
end
|
148
|
+
|
149
|
+
response = HTTPI::get(request, :win32_sspi)
|
150
|
+
|
151
|
+
assert_request_response_attributes(request,response,adapter_klass) do |http_req|
|
152
|
+
assert_equal 'Net::HTTP::Get', http_req.class.name
|
153
|
+
assert_equal 3, adapter_klass.read_state(:perform_authenticated_request_args).length
|
154
|
+
assert_nil adapter_klass.read_state(:perform_http_request_args)
|
155
|
+
|
156
|
+
assert_equal 3, response_segments.length
|
157
|
+
assert_equal MockRespSegments, response_segments
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def create_mock_adapter
|
163
|
+
Class.new(MockWin32SSPIAdapter)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class MockWin32SSPIAdapter < HTTPI::Adapter::Win32SSPI
|
168
|
+
def create_sspi_client(request)
|
169
|
+
sspi_client = super
|
170
|
+
if sspi_client
|
171
|
+
self.class.capture_state(:sspi_client,sspi_client)
|
172
|
+
sspi_client = self
|
173
|
+
end
|
174
|
+
sspi_client
|
175
|
+
end
|
176
|
+
|
177
|
+
def http_authenticate
|
178
|
+
yield(TC_HttpiAdapterWin32SSPI::AuthorizationHdr) if block_given?
|
179
|
+
end
|
180
|
+
|
181
|
+
def create_http_client(request)
|
182
|
+
self.class.capture_state(:httpi_request,request)
|
183
|
+
self
|
184
|
+
end
|
185
|
+
|
186
|
+
def perform_authenticated_request(*args)
|
187
|
+
self.class.capture_state(:perform_authenticated_request_args,args)
|
188
|
+
super
|
189
|
+
end
|
190
|
+
|
191
|
+
def perform_http_request(*args)
|
192
|
+
self.class.capture_state(:perform_http_request_args,args)
|
193
|
+
super
|
194
|
+
end
|
195
|
+
|
196
|
+
def start
|
197
|
+
yield self if block_given?
|
198
|
+
end
|
199
|
+
|
200
|
+
def request(req)
|
201
|
+
return super if req.kind_of?(Symbol)
|
202
|
+
|
203
|
+
self.class.capture_state(:http_request, req)
|
204
|
+
|
205
|
+
segmented_body = false
|
206
|
+
if block_given?
|
207
|
+
yield self
|
208
|
+
segmented_body = true
|
209
|
+
end
|
210
|
+
|
211
|
+
self.class.create_mock_response(segmented_body)
|
212
|
+
end
|
213
|
+
|
214
|
+
def read_body(dest=nil,&segment_handler)
|
215
|
+
if segment_handler
|
216
|
+
3.times do |ii|
|
217
|
+
segment_handler.call(TC_HttpiAdapterWin32SSPI::MockRespSegments[ii])
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def self.state
|
223
|
+
@state ||= Hash.new
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.capture_state(key,value)
|
227
|
+
state[key] = value
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.read_state(key)
|
231
|
+
state[key]
|
232
|
+
end
|
233
|
+
|
234
|
+
def self.create_mock_response(segmented_body=false)
|
235
|
+
resp = Class.new(::Hash) do
|
236
|
+
def code
|
237
|
+
@code ||= 200
|
238
|
+
end
|
239
|
+
def code=(rhs)
|
240
|
+
@code = rhs
|
241
|
+
end
|
242
|
+
def body
|
243
|
+
@body ||= ""
|
244
|
+
end
|
245
|
+
def body=(rhs)
|
246
|
+
@body = rhs
|
247
|
+
end
|
248
|
+
def headers
|
249
|
+
self
|
250
|
+
end
|
251
|
+
def to_hash
|
252
|
+
self
|
253
|
+
end
|
254
|
+
end.new
|
255
|
+
|
256
|
+
resp.body = "hello test" unless segmented_body
|
257
|
+
resp[TC_HttpiAdapterWin32SSPI::AuthenticateHdrName] = [TC_HttpiAdapterWin32SSPI::AuthenticateHdr]
|
258
|
+
resp
|
259
|
+
end
|
260
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'httpi'
|
2
|
+
require 'httpi/auth/config_sspi'
|
3
|
+
require 'test-unit'
|
4
|
+
|
5
|
+
HTTPI.log = false
|
6
|
+
|
7
|
+
class TC_HttpiAuth < Test::Unit::TestCase
|
8
|
+
def test_auth_sspi
|
9
|
+
req = HTTPI::Request.new("http://virttual-server.gas.local:3005/test")
|
10
|
+
req.auth.sspi( {:spn => "HTTP/virtual-server.gas.local"} )
|
11
|
+
|
12
|
+
assert req.auth.sspi?
|
13
|
+
refute req.auth.sspi.empty?
|
14
|
+
assert_equal "HTTP/virtual-server.gas.local", req.auth.sspi.first[:spn]
|
15
|
+
assert HTTPI::Auth::Config::TYPES.include?(:sspi)
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: httpi-adapter-win32sspi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.rc1
|
5
|
+
platform: x86-mingw32
|
6
|
+
authors:
|
7
|
+
- Gary Sick
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-11-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: win32-sspi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.1.rc1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.1.rc1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: test-unit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
description: |2
|
42
|
+
A HTTPI Adapter the uses Win32SSPI library.
|
43
|
+
Support the Negotiate protocols.
|
44
|
+
See examples for usage.
|
45
|
+
email: garys361@gmail.com
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- License.txt
|
51
|
+
- Rakefile
|
52
|
+
- Readme.md
|
53
|
+
- example/httpi_adapter_client.rb
|
54
|
+
- httpi_adapter_win32sspi.gemspec
|
55
|
+
- lib/httpi-adapter-win32sspi.rb
|
56
|
+
- lib/httpi/adapter/win32sspi.rb
|
57
|
+
- lib/httpi/auth/config_sspi.rb
|
58
|
+
- test/all_tests.rb
|
59
|
+
- test/test_httpi_adapter_win32sspi.rb
|
60
|
+
- test/test_httpi_auth.rb
|
61
|
+
homepage: https://github.com/garysick/httpi_adapter_win32sspi
|
62
|
+
licenses:
|
63
|
+
- MIT
|
64
|
+
metadata: {}
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '1.9'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">"
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.3.1
|
79
|
+
requirements:
|
80
|
+
- This gem will only work in a Windows Environment
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 2.4.5
|
83
|
+
signing_key:
|
84
|
+
specification_version: 4
|
85
|
+
summary: A HTTPI Adapter the uses Win32SSPI
|
86
|
+
test_files:
|
87
|
+
- test/all_tests.rb
|
88
|
+
- test/test_httpi_adapter_win32sspi.rb
|
89
|
+
- test/test_httpi_auth.rb
|