From 7c311e0b61cd007f0aa22cbc3d9695828aba4daa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Mon, 12 Aug 2019 14:14:50 +0200
Subject: [PATCH] utils: move SOAP-related classes to passerelle.utils.soap
 (#35369)

---
 passerelle/base/models.py    |  2 +-
 passerelle/utils/__init__.py | 40 +----------------------------------
 passerelle/utils/soap.py     | 41 ++++++++++++++++++++++++++++++++++++
 tests/test_soap.py           |  2 +-
 4 files changed, 44 insertions(+), 41 deletions(-)

diff --git a/passerelle/base/models.py b/passerelle/base/models.py
index aca12a72..a4630010 100644
--- a/passerelle/base/models.py
+++ b/passerelle/base/models.py
@@ -182,7 +182,7 @@ class BaseResource(models.Model):
                     resource_pk=self.id)
 
     def soap_client(self, **kwargs):
-        return passerelle.utils.SOAPClient(resource=self, **kwargs)
+        return passerelle.utils.soap.SOAPClient(resource=self, **kwargs)
 
     @classmethod
     def get_verbose_name(cls):
diff --git a/passerelle/utils/__init__.py b/passerelle/utils/__init__.py
index 8535250f..de4d280e 100644
--- a/passerelle/utils/__init__.py
+++ b/passerelle/utils/__init__.py
@@ -21,10 +21,9 @@ import re
 from itertools import islice, chain
 import warnings
 
-from requests import Session as RequestSession, Response as RequestResponse, RequestException
+from requests import Session as RequestSession, Response as RequestResponse
 from requests.structures import CaseInsensitiveDict
 from urllib3.exceptions import InsecureRequestWarning
-from django.utils.six.moves.urllib import parse as urlparse
 
 from django.conf import settings
 from django.core.cache import cache
@@ -35,9 +34,6 @@ from django.utils.decorators import available_attrs
 from django.views.generic.detail import SingleObjectMixin
 from django.contrib.contenttypes.models import ContentType
 from django.db import transaction
-from zeep import Client
-from zeep.cache import InMemoryCache
-from zeep.transports import Transport
 
 from passerelle.base.models import ApiUser, AccessRight, BaseResource
 from passerelle.base.signature import check_query, check_url
@@ -272,40 +268,6 @@ class Request(RequestSession):
         log_http_request(self.logger, request=request, response=response, exception=exception, error_log=error_log)
 
 
-class SOAPTransport(Transport):
-    """Wrapper around zeep.Transport
-
-    disable basic_authentication hosts unrelated to wsdl's endpoints
-    """
-    def __init__(self, resource, wsdl_url, **kwargs):
-        self.resource = resource
-        self.wsdl_host = urlparse.urlparse(wsdl_url).netloc
-        super(SOAPTransport, self).__init__(**kwargs)
-
-    def _load_remote_data(self, 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):
-    """Wrapper around zeep.Client
-
-    resource muste have a wsdl_url and a requests attribute
-    """
-    def __init__(self, resource, **kwargs):
-        wsdl_url = kwargs.pop('wsdl_url', None) or resource.wsdl_url
-        transport_class = getattr(resource, 'soap_transport_class', SOAPTransport)
-        transport = transport_class(resource, wsdl_url, session=resource.requests, cache=InMemoryCache())
-        super(SOAPClient, self).__init__(wsdl_url, transport=transport, **kwargs)
-
 
 def export_site():
     '''Dump passerelle configuration (users, resources and ACLs) to JSON dumpable dictionnary'''
diff --git a/passerelle/utils/soap.py b/passerelle/utils/soap.py
index e3af3428..6b28d942 100644
--- a/passerelle/utils/soap.py
+++ b/passerelle/utils/soap.py
@@ -1,3 +1,4 @@
+# passerelle - uniform access to multiple data sources and services
 # Copyright (C) 2019  Entr'ouvert
 #
 # This program is free software: you can redistribute it and/or modify it
@@ -13,9 +14,49 @@
 # 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 requests import RequestException
+
+from zeep import Client
+from zeep.cache import InMemoryCache
+from zeep.transports import Transport
+
+from django.utils.six.moves.urllib import parse as urlparse
 
 from passerelle.utils.jsonresponse import APIError
 
 
 class SOAPError(APIError):
     pass
+
+
+class SOAPClient(Client):
+    """Wrapper around zeep.Client
+
+    resource muste have a wsdl_url and a requests attribute
+    """
+    def __init__(self, resource, **kwargs):
+        wsdl_url = kwargs.pop('wsdl_url', None) or resource.wsdl_url
+        transport_class = getattr(resource, 'soap_transport_class', SOAPTransport)
+        transport = transport_class(resource, wsdl_url, session=resource.requests, cache=InMemoryCache())
+        super(SOAPClient, self).__init__(wsdl_url, transport=transport, **kwargs)
+
+
+class SOAPTransport(Transport):
+    """Wrapper around zeep.Transport
+
+    disable basic_authentication hosts unrelated to wsdl's endpoints
+    """
+    def __init__(self, resource, wsdl_url, **kwargs):
+        self.resource = resource
+        self.wsdl_host = urlparse.urlparse(wsdl_url).netloc
+        super(SOAPTransport, self).__init__(**kwargs)
+
+    def _load_remote_data(self, 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:
+            raise SOAPError('SOAP service is down, location %r cannot be loaded: %s' % (url, e), exception=e, url=url)
diff --git a/tests/test_soap.py b/tests/test_soap.py
index e077e0ea..7752707f 100644
--- a/tests/test_soap.py
+++ b/tests/test_soap.py
@@ -1,7 +1,7 @@
 import requests
 from zeep.plugins import Plugin
 
-from passerelle.utils import SOAPClient
+from passerelle.utils.soap import SOAPClient
 
 
 WSDL = 'tests/data/soap.wsdl'
-- 
2.23.0.rc1

