Projet

Général

Profil

0001-iparapheur-add-handling-of-invalid-response-content.patch

Josué Kouka, 09 septembre 2016 16:35

Télécharger (6,61 ko)

Voir les différences:

Subject: [PATCH 1/3] iparapheur: add handling of invalid response content

 passerelle/contrib/iparapheur/models.py | 36 ++++++++++++++++++++-------------
 passerelle/contrib/iparapheur/soap.py   | 12 +++++++++--
 tests/test_iparapheur.py                | 21 +++++++++++++++++++
 3 files changed, 53 insertions(+), 16 deletions(-)
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
-