0001-iparapheur-add-handling-of-invalid-response-content.patch
passerelle/contrib/iparapheur/models.py | ||
---|---|---|
16 | 16 |
import base64 |
17 | 17 |
import json |
18 | 18 |
import magic |
19 |
from xml.sax._exceptions import SAXParseException |
|
19 | 20 | |
20 | 21 |
from django.db import models |
21 | 22 | |
... | ... | |
44 | 45 |
http_status = 404 |
45 | 46 | |
46 | 47 | |
48 |
class InvalidResponseContent(Exception): |
|
49 |
http_status = 200 |
|
50 |
log_error = False |
|
51 | ||
52 | ||
47 | 53 |
class IParapheur(BaseResource): |
48 | 54 |
wsdl_url = models.CharField(max_length=128, blank=False, |
49 | 55 |
verbose_name=_('WSDL URL'), |
... | ... | |
71 | 77 |
def get_verbose_name(cls): |
72 | 78 |
return cls._meta.verbose_name |
73 | 79 | |
80 |
def call(self, service, *args, **kwargs): |
|
81 |
client = get_client(self) |
|
82 |
try: |
|
83 |
result = getattr(client.service, service)(*args, **kwargs) |
|
84 |
except(Exception,) as e: |
|
85 |
raise InvalidResponseContent('Invalid Response Content, XML expected') |
|
86 |
return result |
|
87 | ||
74 | 88 |
@endpoint(serializer_type='json-api') |
75 | 89 |
def types(self, request): |
76 |
c = get_client(self) |
|
77 |
return [format_type(t) for t in c.service.GetListeTypes()] |
|
90 |
return [format_type(t) for t in self.call('GetListeTypes')] |
|
78 | 91 | |
79 | 92 |
@endpoint(serializer_type='json-api') |
80 | 93 |
def ping(self, request): |
81 |
c = get_client(self) |
|
82 |
return c.service.echo('ping') |
|
94 |
return self.call('echo', 'ping') |
|
83 | 95 | |
84 | 96 |
@endpoint(serializer_type='json-api') |
85 | 97 |
def subtypes(self, request, type=None): |
86 |
c = get_client(self) |
|
87 | 98 |
if type: |
88 |
return [format_type(t) for t in c.service.GetListeSousTypes(type)]
|
|
89 |
return [format_type(t) for t in c.service.GetListeSousTypes()]
|
|
99 |
return [format_type(t) for t in self.call('GetListeSousTypes', type)]
|
|
100 |
return [format_type(t) for t in self.call('GetListeSousTypes')]
|
|
90 | 101 | |
91 | 102 |
@endpoint(serializer_type='json-api') |
92 | 103 |
def files(self, status=None): |
93 |
c = get_client(self) |
|
94 | 104 |
if status: |
95 |
return [format_status(f) for f in c.service.RechercherDossiers(Status=status)]
|
|
96 |
return [format_status(f) for f in c.service.RechercherDossiers()]
|
|
105 |
return [format_status(f) for f in self.call('RechercherDossiers', Status=status)]
|
|
106 |
return [format_status(f) for f in self.call('RechercherDossiers')]
|
|
97 | 107 | |
98 | 108 |
@endpoint(serializer_type='json-api', name='create-file', methods=['post']) |
99 | 109 |
def create_file(self, request, email=None): |
... | ... | |
131 | 141 | |
132 | 142 |
@endpoint(serializer_type='json-api', name='get-file', pattern='(?P<file_id>[\w-]+)') |
133 | 143 |
def get_file(self, request, file_id): |
134 |
client = get_client(self) |
|
135 |
resp = client.service.GetDossier(file_id) |
|
144 |
resp = self.call('GetDossier', file_id) |
|
136 | 145 |
if resp.MessageRetour.codeRetour == 'KO': |
137 | 146 |
if 'inconnu' in resp.MessageRetour.message: |
138 | 147 |
raise Http404(resp.MessageRetour.message) |
... | ... | |
144 | 153 | |
145 | 154 |
@endpoint(serializer_type='json-api', name='get-file-status', pattern='(?P<file_id>[\w-]+)') |
146 | 155 |
def get_file_status(self, request, file_id): |
147 |
c = get_client(self) |
|
148 |
resp = c.service.GetHistoDossier(file_id) |
|
156 |
resp = self.call('GetHistoDossier', file_id) |
|
149 | 157 |
if resp.MessageRetour.codeRetour == 'KO': |
150 | 158 |
if 'inconnu' in resp.MessageRetour.message: |
151 | 159 |
raise Http404(resp.MessageRetour.message) |
passerelle/contrib/iparapheur/soap.py | ||
---|---|---|
23 | 23 | |
24 | 24 |
from suds.client import Client |
25 | 25 |
from suds.transport.http import HttpAuthenticated |
26 |
from suds.transport import Reply |
|
26 |
from suds.transport import Reply, TransportError
|
|
27 | 27 |
from suds.plugin import MessagePlugin, DocumentPlugin |
28 | 28 | |
29 | 29 |
from suds.sudsobject import asdict |
... | ... | |
75 | 75 |
self.addcredentials(request) |
76 | 76 |
resp = self.model.requests.post(request.url, data=request.message, |
77 | 77 |
headers=request.headers, **self.get_requests_kwargs()) |
78 |
return Reply(resp.status_code, resp.headers, resp.content) |
|
78 | ||
79 |
if resp.status_code in (202, 204): |
|
80 |
return None |
|
81 |
elif not resp.ok: |
|
82 |
raise TransportError( |
|
83 |
resp.reason, |
|
84 |
resp.status_code, fp=StringIO.StringIO(resp.content)) |
|
85 |
else: |
|
86 |
return Reply(resp.status_code, resp.headers, resp.content) |
|
79 | 87 | |
80 | 88 |
def get_client(instance): |
81 | 89 |
transport = Transport(instance) |
tests/test_iparapheur.py | ||
---|---|---|
154 | 154 |
file_sent = os.path.join(os.path.dirname(__file__), 'data/iparapheur_test.pdf') |
155 | 155 |
assert resp.headers['Content-Type'] == 'application/pdf' |
156 | 156 |
assert hashlib.md5(resp.body[:8192]).hexdigest() == hashlib.md5(file(file_sent).read()[:8192]).hexdigest() |
157 | ||
158 | ||
159 |
@mock.patch('passerelle.utils.LoggedRequest.get') |
|
160 |
@mock.patch('passerelle.utils.LoggedRequest.post') |
|
161 |
@mock.patch('passerelle.contrib.iparapheur.soap.HttpAuthenticated.open') |
|
162 |
def test_invalid_response(http_open, mocked_post, mocked_get, setup, xmlmime, wsdl_file): |
|
163 |
app, conn = setup |
|
164 |
file_id = str(uuid.uuid4()) |
|
165 | ||
166 |
http_open.return_value = file(xmlmime) |
|
167 |
mocked_get.return_value = mock.Mock(content = file(wsdl_file).read(), |
|
168 |
status_code=200) |
|
169 |
mocked_post.return_value = mock.Mock(status_code=502, |
|
170 |
content='<p>Bad Gateway</p>', reason='Bad Gateway', ok=False) |
|
171 |
url = reverse('generic-endpoint', kwargs={'slug': conn.slug, |
|
172 |
'connector': 'iparapheur', 'endpoint': 'get-file-status', |
|
173 |
'rest': file_id}) |
|
174 |
resp = app.get(url) |
|
175 | ||
176 |
assert 'x-error-code' in dict(resp.headers) |
|
177 |
assert resp.json['err_desc'] == 'Invalid Response Content, XML expected' |
|
157 |
- |