@@ -14,27 +14,34 @@ def hostname
1414 'somehost.somedomain.org:9000'
1515 end
1616
17- def request_factory ( kind , path )
17+ def request_factory ( kind , path , env = { } )
1818 body = mock ( )
1919 body . stubs ( :read ) . returns ( "" )
20- env = {
20+ env = env . merge (
2121 'REQUEST_METHOD' => kind ,
2222 'rack.request.query_hash' => { } ,
23- 'HTTP_HOST' => hostname
24- }
25- OpenStruct . new ( :env => env , :body => body , :path => '/dynflow' + path )
23+ 'HTTP_HOST' => hostname ,
24+ 'PATH_INFO' => "/dynflow#{ path } "
25+ )
26+ Sinatra ::Request . new ( env ) . tap do |r |
27+ r . stubs ( :body ) . returns ( body )
28+ end
2629 end
2730
2831 let ( :new_request ) { Net ::HTTP ::Get . new 'example.org' }
2932
30- it 'relays GET requests' do
33+ def mock_core_service ( method , path , response )
3134 factory = mock ( )
32- factory . expects ( :create_get ) . with ( '/tasks/count' , { } ) . returns ( new_request )
35+ factory . expects ( method ) . with { | p | p == path } . returns ( new_request )
3336 Proxy ::Dynflow ::Callback ::Core . any_instance . expects ( :request_factory ) . returns ( factory )
3437 Proxy ::Dynflow ::Callback ::Core . any_instance
35- . expects ( :send_request ) . with ( new_request )
36- . returns ( OpenStruct . new ( :code => 200 , :body => { 'count' => 0 } ) )
37- Sinatra ::Base . any_instance . expects ( :request ) . times ( 4 ) . returns ( request_factory ( 'GET' , '/tasks/count' ) )
38+ . expects ( :send_request ) . with ( new_request )
39+ . returns ( OpenStruct . new ( response ) )
40+ end
41+
42+ it 'relays GET requests' do
43+ mock_core_service ( :create_get , '/tasks/count' , :code => 200 , :body => { 'count' => 0 } )
44+ Proxy ::Dynflow ::Api . any_instance . stubs ( :request ) . returns ( request_factory ( 'GET' , '/tasks/count' ) )
3845 get '/tasks/count'
3946 new_request [ 'X-Forwarded-For' ] . must_equal hostname
4047 end
@@ -46,9 +53,64 @@ def request_factory(kind, path)
4653 Proxy ::Dynflow ::Callback ::Core . any_instance
4754 . expects ( :send_request ) . with ( new_request )
4855 . returns ( OpenStruct . new ( :code => 200 , :body => { 'count' => 0 } ) )
49- Sinatra :: Base . any_instance . expects ( :request ) . times ( 4 ) . returns ( request_factory ( 'POST' , '/tasks/12345/cancel' ) )
56+ Proxy :: Dynflow :: Api . any_instance . stubs ( :request ) . returns ( request_factory ( 'POST' , '/tasks/12345/cancel' ) )
5057 post '/tasks/12345/cancel' , { }
5158 new_request [ 'X-Forwarded-For' ] . must_equal hostname
5259 end
60+
61+ it 'refuses unauthorized http connections (using remote_fqdn)' do
62+ Proxy ::Dynflow ::Api . any_instance . stubs ( :request ) . returns ( request_factory ( 'POST' , '/tasks' ) )
63+ Proxy ::Dynflow ::Api . any_instance . stubs ( :remote_fqdn ) . returns ( 'unauthorized_host.example.com' )
64+ Proxy ::SETTINGS . stubs ( :trusted_hosts ) . returns ( [ "mytrustedhost.example.com" ] )
65+ post '/tasks'
66+ assert ( last_response . forbidden? , 'The request should be forbidden' )
67+ end
68+
69+ it 'accepts authorized http connections (using remote_fqdn)' do
70+ mock_core_service ( :create_post , '/tasks' , :code => 200 , :body => { } )
71+ Proxy ::Dynflow ::Api . any_instance . stubs ( :request ) . returns ( request_factory ( 'POST' , '/tasks' ) )
72+ Proxy ::Dynflow ::Api . any_instance . stubs ( :remote_fqdn ) . returns ( 'mytrustedhost.example.com' )
73+ Proxy ::SETTINGS . stubs ( :trusted_hosts ) . returns ( [ "mytrustedhost.example.com" ] )
74+ post '/tasks'
75+ assert ( last_response . ok? , 'The response should be ok' )
76+ end
77+
78+ it 'refuses unauthorized https connections (using https_cert_cn)' do
79+ Proxy ::Dynflow ::Api . any_instance . stubs ( :request ) .
80+ returns ( request_factory ( 'POST' , '/tasks' , 'HTTPS' => 'yes' , 'SSL_CLIENT_CERT' => 'mytrustedcert' ) )
81+ Proxy ::Dynflow ::Api . any_instance . stubs ( :https_cert_cn ) . returns ( 'unauthorized_host.example.com' )
82+ Proxy ::SETTINGS . stubs ( :trusted_hosts ) . returns ( [ "mytrustedhost.example.com" ] )
83+ post '/tasks'
84+ assert ( last_response . forbidden? , 'The request should be forbidden' )
85+ end
86+
87+ it 'accepts unauthorized https connections (using https_cert_cn)' do
88+ mock_core_service ( :create_post , '/tasks' , :code => 200 , :body => { } )
89+ Proxy ::Dynflow ::Api . any_instance . stubs ( :request ) .
90+ returns ( request_factory ( 'POST' , '/tasks' , 'HTTPS' => 'yes' , 'SSL_CLIENT_CERT' => 'mytrustedcert' ) )
91+ Proxy ::Dynflow ::Api . any_instance . stubs ( :https_cert_cn ) . returns ( 'mytrustedhost.example.com' )
92+ Proxy ::SETTINGS . stubs ( :trusted_hosts ) . returns ( [ "mytrustedhost.example.com" ] )
93+ post '/tasks'
94+ assert ( last_response . ok? , 'The response should be ok' )
95+ end
96+
97+ it 'refuses unauthorized https connections (when client cert is not supplied)' do
98+ Proxy ::Dynflow ::Api . any_instance . stubs ( :request ) .
99+ returns ( request_factory ( 'POST' , '/tasks' , 'HTTPS' => 'yes' ) )
100+ Proxy ::Dynflow ::Api . any_instance . stubs ( :https_cert_cn ) . returns ( 'mytrustedhost.example.com' )
101+ Proxy ::SETTINGS . stubs ( :trusted_hosts ) . returns ( [ "mytrustedhost.example.com" ] )
102+ post '/tasks'
103+ assert ( last_response . forbidden? , 'The request should be forbidden' )
104+ end
105+
106+ it 'passes the done requests to the core service, when authorization keys are provided' do
107+ mock_core_service ( :create_post , '/tasks/123/done' , :code => 200 , :body => { } )
108+ Proxy ::Dynflow ::Api . any_instance . stubs ( :request ) .
109+ returns ( request_factory ( 'POST' , '/tasks/123/done' , 'HTTPS' => 'yes' , 'HTTP_AUTHORIZATION' => 'Basic ValidToken' ) )
110+ Proxy ::Dynflow ::Api . any_instance . stubs ( :https_cert_cn ) . returns ( 'mytrustedhost.example.com' )
111+ Proxy ::SETTINGS . stubs ( :trusted_hosts ) . returns ( [ "mytrustedhost.example.com" ] )
112+ post '/tasks'
113+ assert ( last_response . ok? , 'The response should be ok' )
114+ end
53115 end
54116end
0 commit comments