Add timeout for requests
Bandit emits errors for request methods without the timeout parameter.
It's better to follow the instruction to avoid hanging.
Added timeout parameters and config options to set timeout.
[1] https://bandit.readthedocs.io/en/1.7.5/plugins/b113_request_without_timeout.html
Change-Id: I0c022c3cc57f30530ebdef6e434753ece2bdf912
(cherry picked from commit 92cdf8a0a5
)
This commit is contained in:
parent
404b44320f
commit
b34fcefd3c
|
@ -44,6 +44,8 @@ keystone_ec2_opts = [
|
||||||
'CAs.'),
|
'CAs.'),
|
||||||
cfg.BoolOpt('insecure', default=False,
|
cfg.BoolOpt('insecure', default=False,
|
||||||
help='Disable SSL certificate verification.'),
|
help='Disable SSL certificate verification.'),
|
||||||
|
cfg.IntOpt('timeout', default=60,
|
||||||
|
help='Timeout to obtain token.'),
|
||||||
]
|
]
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
@ -172,9 +174,10 @@ class EC2Token(object):
|
||||||
elif CONF.keystone_ec2_token.certfile:
|
elif CONF.keystone_ec2_token.certfile:
|
||||||
cert = CONF.keystone_ec2_token.certfile
|
cert = CONF.keystone_ec2_token.certfile
|
||||||
|
|
||||||
response = requests.request('POST', CONF.keystone_ec2_token.url,
|
response = requests.post(CONF.keystone_ec2_token.url,
|
||||||
data=creds_json, headers=headers,
|
data=creds_json, headers=headers,
|
||||||
verify=verify, cert=cert)
|
verify=verify, cert=cert,
|
||||||
|
timeout=CONF.keystone_ec2_token.timeout)
|
||||||
|
|
||||||
# NOTE(vish): We could save a call to keystone by
|
# NOTE(vish): We could save a call to keystone by
|
||||||
# having keystone return token, tenant,
|
# having keystone return token, tenant,
|
||||||
|
|
|
@ -33,12 +33,21 @@ This WSGI component:
|
||||||
|
|
||||||
import webob
|
import webob
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
from oslo_utils import strutils
|
from oslo_utils import strutils
|
||||||
import requests
|
import requests
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
s3_opts = [
|
||||||
|
cfg.IntOpt('timeout', default=60,
|
||||||
|
help='Timeout to obtain token.'),
|
||||||
|
]
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
CONF.register_opts(s3_opts, group='s3_token')
|
||||||
|
|
||||||
PROTOCOL_NAME = 'S3 Token Authentication'
|
PROTOCOL_NAME = 'S3 Token Authentication'
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,7 +122,8 @@ class S3Token(object):
|
||||||
try:
|
try:
|
||||||
response = requests.post('%s/v2.0/s3tokens' % self._request_uri,
|
response = requests.post('%s/v2.0/s3tokens' % self._request_uri,
|
||||||
headers=headers, data=creds_json,
|
headers=headers, data=creds_json,
|
||||||
verify=self._verify)
|
verify=self._verify,
|
||||||
|
timeout=CONF.s3_token.timeout)
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
self._logger.info('HTTP connection exception: %s', e)
|
self._logger.info('HTTP connection exception: %s', e)
|
||||||
resp = self._deny_request('InvalidURI')
|
resp = self._deny_request('InvalidURI')
|
||||||
|
|
|
@ -73,7 +73,7 @@ class EC2TokenMiddlewareTestBase(utils.TestCase):
|
||||||
|
|
||||||
class EC2TokenMiddlewareTestGood(EC2TokenMiddlewareTestBase):
|
class EC2TokenMiddlewareTestGood(EC2TokenMiddlewareTestBase):
|
||||||
@mock.patch.object(
|
@mock.patch.object(
|
||||||
requests, 'request',
|
requests, 'post',
|
||||||
return_value=FakeResponse(EMPTY_RESPONSE, status_code=200))
|
return_value=FakeResponse(EMPTY_RESPONSE, status_code=200))
|
||||||
def test_protocol_old_versions(self, mock_request):
|
def test_protocol_old_versions(self, mock_request):
|
||||||
req = webob.Request.blank('/test')
|
req = webob.Request.blank('/test')
|
||||||
|
@ -85,9 +85,9 @@ class EC2TokenMiddlewareTestGood(EC2TokenMiddlewareTestBase):
|
||||||
self.assertEqual(TOKEN_ID, req.headers['X-Auth-Token'])
|
self.assertEqual(TOKEN_ID, req.headers['X-Auth-Token'])
|
||||||
|
|
||||||
mock_request.assert_called_with(
|
mock_request.assert_called_with(
|
||||||
'POST', 'http://localhost:5000/v3/ec2tokens',
|
'http://localhost:5000/v3/ec2tokens',
|
||||||
data=mock.ANY, headers={'Content-Type': 'application/json'},
|
data=mock.ANY, headers={'Content-Type': 'application/json'},
|
||||||
verify=True, cert=None)
|
verify=True, cert=None, timeout=mock.ANY)
|
||||||
|
|
||||||
data = jsonutils.loads(mock_request.call_args[1]['data'])
|
data = jsonutils.loads(mock_request.call_args[1]['data'])
|
||||||
expected_data = {
|
expected_data = {
|
||||||
|
@ -104,7 +104,7 @@ class EC2TokenMiddlewareTestGood(EC2TokenMiddlewareTestBase):
|
||||||
self.assertDictEqual(expected_data, data)
|
self.assertDictEqual(expected_data, data)
|
||||||
|
|
||||||
@mock.patch.object(
|
@mock.patch.object(
|
||||||
requests, 'request',
|
requests, 'post',
|
||||||
return_value=FakeResponse(EMPTY_RESPONSE, status_code=200))
|
return_value=FakeResponse(EMPTY_RESPONSE, status_code=200))
|
||||||
def test_protocol_v4(self, mock_request):
|
def test_protocol_v4(self, mock_request):
|
||||||
req = webob.Request.blank('/test')
|
req = webob.Request.blank('/test')
|
||||||
|
@ -120,9 +120,9 @@ class EC2TokenMiddlewareTestGood(EC2TokenMiddlewareTestBase):
|
||||||
self.assertEqual(TOKEN_ID, req.headers['X-Auth-Token'])
|
self.assertEqual(TOKEN_ID, req.headers['X-Auth-Token'])
|
||||||
|
|
||||||
mock_request.assert_called_with(
|
mock_request.assert_called_with(
|
||||||
'POST', 'http://localhost:5000/v3/ec2tokens',
|
'http://localhost:5000/v3/ec2tokens',
|
||||||
data=mock.ANY, headers={'Content-Type': 'application/json'},
|
data=mock.ANY, headers={'Content-Type': 'application/json'},
|
||||||
verify=True, cert=None)
|
verify=True, cert=None, timeout=mock.ANY)
|
||||||
|
|
||||||
data = jsonutils.loads(mock_request.call_args[1]['data'])
|
data = jsonutils.loads(mock_request.call_args[1]['data'])
|
||||||
expected_data = {
|
expected_data = {
|
||||||
|
@ -155,7 +155,7 @@ class EC2TokenMiddlewareTestBad(EC2TokenMiddlewareTestBase):
|
||||||
self._validate_ec2_error(resp, 400, 'AuthFailure')
|
self._validate_ec2_error(resp, 400, 'AuthFailure')
|
||||||
|
|
||||||
@mock.patch.object(requests,
|
@mock.patch.object(requests,
|
||||||
'request',
|
'post',
|
||||||
return_value=FakeResponse(EMPTY_RESPONSE))
|
return_value=FakeResponse(EMPTY_RESPONSE))
|
||||||
def test_communication_failure(self, mock_request):
|
def test_communication_failure(self, mock_request):
|
||||||
req = webob.Request.blank('/test')
|
req = webob.Request.blank('/test')
|
||||||
|
@ -163,12 +163,13 @@ class EC2TokenMiddlewareTestBad(EC2TokenMiddlewareTestBase):
|
||||||
req.GET['AWSAccessKeyId'] = 'test-key-id'
|
req.GET['AWSAccessKeyId'] = 'test-key-id'
|
||||||
resp = req.get_response(self.middleware)
|
resp = req.get_response(self.middleware)
|
||||||
self._validate_ec2_error(resp, 400, 'AuthFailure')
|
self._validate_ec2_error(resp, 400, 'AuthFailure')
|
||||||
mock_request.assert_called_with('POST', mock.ANY,
|
mock_request.assert_called_with(mock.ANY,
|
||||||
data=mock.ANY, headers=mock.ANY,
|
data=mock.ANY, headers=mock.ANY,
|
||||||
verify=mock.ANY, cert=mock.ANY)
|
verify=mock.ANY, cert=mock.ANY,
|
||||||
|
timeout=mock.ANY)
|
||||||
|
|
||||||
@mock.patch.object(requests,
|
@mock.patch.object(requests,
|
||||||
'request',
|
'post',
|
||||||
return_value=FakeResponse(EMPTY_RESPONSE))
|
return_value=FakeResponse(EMPTY_RESPONSE))
|
||||||
def test_no_result_data(self, mock_request):
|
def test_no_result_data(self, mock_request):
|
||||||
req = webob.Request.blank('/test')
|
req = webob.Request.blank('/test')
|
||||||
|
@ -176,6 +177,7 @@ class EC2TokenMiddlewareTestBad(EC2TokenMiddlewareTestBase):
|
||||||
req.GET['AWSAccessKeyId'] = 'test-key-id'
|
req.GET['AWSAccessKeyId'] = 'test-key-id'
|
||||||
resp = req.get_response(self.middleware)
|
resp = req.get_response(self.middleware)
|
||||||
self._validate_ec2_error(resp, 400, 'AuthFailure')
|
self._validate_ec2_error(resp, 400, 'AuthFailure')
|
||||||
mock_request.assert_called_with('POST', mock.ANY,
|
mock_request.assert_called_with(mock.ANY,
|
||||||
data=mock.ANY, headers=mock.ANY,
|
data=mock.ANY, headers=mock.ANY,
|
||||||
verify=mock.ANY, cert=mock.ANY)
|
verify=mock.ANY, cert=mock.ANY,
|
||||||
|
timeout=mock.ANY)
|
||||||
|
|
Loading…
Reference in New Issue