utils: raise APIError for wsdl schema loading errors (#35029)

This commit is contained in:
Benjamin Dauvergne 2019-07-24 16:30:51 +02:00
parent 47529acd9a
commit 676bf063e1
4 changed files with 59 additions and 6 deletions

View File

@ -21,7 +21,7 @@ import re
from itertools import islice, chain
import warnings
from requests import Session as RequestSession, Response as RequestResponse
from requests import Session as RequestSession, Response as RequestResponse, RequestException
from requests.structures import CaseInsensitiveDict
from urllib3.exceptions import InsecureRequestWarning
from django.utils.six.moves.urllib import parse as urlparse
@ -283,11 +283,16 @@ class SOAPTransport(Transport):
super(SOAPTransport, self).__init__(**kwargs)
def _load_remote_data(self, url):
if urlparse.urlparse(url).netloc != self.wsdl_host:
response = self.session.get(url, timeout=self.load_timeout, auth=None, cert=None)
response.raise_for_status()
return response.content
return super(SOAPTransport, self)._load_remote_data(url)
try:
if urlparse.urlparse(url).netloc != self.wsdl_host:
response = self.session.get(url, timeout=self.load_timeout, auth=None, cert=None)
response.raise_for_status()
return response.content
return super(SOAPTransport, self)._load_remote_data(url)
except RequestException as e:
# prevent import cycle
from passerelle.utils.soap import SOAPError
raise SOAPError('SOAP service is down, location %r cannot be loaded: %s' % (url, e), exception=e, url=url)
class SOAPClient(Client):

21
passerelle/utils/soap.py Normal file
View File

@ -0,0 +1,21 @@
# Copyright (C) 2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from passerelle.utils.jsonresponse import APIError
class SOAPError(APIError):
pass

View File

@ -175,3 +175,17 @@ CipherString = ALL''')
del os.environ['OPENSSL_CONF']
else:
os.environ['OPENSSL_CONF'] = old_value
@pytest.fixture(autouse=True)
def clear_cache():
from zeep.cache import InMemoryCache
# prevent silent change in zeep private interface
assert InMemoryCache._cache == {}
InMemoryCache._cache = {}
try:
yield
finally:
InMemoryCache._cache = {}

View File

@ -4,6 +4,9 @@ import os
import mock
import pytest
from requests.exceptions import ConnectionError
from requests import Request
from django.utils.encoding import force_text
from passerelle.apps.astregs.models import AstreGS, Link
@ -299,6 +302,16 @@ def test_get_contact_details(mocked_post, mocked_get, connector, app):
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError'
@mock.patch('passerelle.utils.Request.get', side_effect=ConnectionError('mocked error', request=Request()))
@mock.patch('passerelle.utils.Request.post', side_effect=NotImplementedError)
def test_low_level_connection_error(mocked_post, mocked_get, tiers_response, tiers_error_response,
connector, app):
resp = app.get('/astregs/test/get-association-by-id', params={'association_id': '487464'})
assert resp.json['err'] == 1
assert resp.json['data'] is None
assert 'mocked error' in resp.json['err_desc']
@mock.patch('passerelle.utils.Request.get', side_effect=contact_wsdl_side_effect)
@mock.patch('passerelle.utils.Request.post', side_effect=contact_side_effect)
def test_create_association_contact(mocked_post, mocked_get, connector, app):