Projet

Général

Profil

0001-arpege_ecp-do-not-log-requests-errors-35358.patch

Benjamin Dauvergne, 12 août 2019 12:26

Télécharger (8,98 ko)

Voir les différences:

Subject: [PATCH] arpege_ecp: do not log requests errors (#35358)

Add proper conversion of all HTTP errors to APIError.
 passerelle/apps/arpege_ecp/models.py | 31 ++++++++++-----
 tests/test_arpege_ecp.py             | 57 ++++++++++++++--------------
 tests/utils.py                       | 17 ++++++---
 3 files changed, 61 insertions(+), 44 deletions(-)
passerelle/apps/arpege_ecp/models.py
17 17
import json
18 18
import urlparse
19 19

  
20
from requests import RequestException
21

  
20 22
from django.db import models
21 23
from django.utils.translation import ugettext_lazy as _
22 24
from django.utils.dateparse import parse_date, parse_time
......
29 31

  
30 32

  
31 33
class ArpegeECP(BaseResource):
34
    log_requests_errors = False
35

  
32 36
    category = _('Business Process Connectors')
33 37
    webservice_base_url = models.URLField(_('Webservice Base URL'))
34 38
    hawk_auth_id = models.CharField(_('Hawk Authentication id'), max_length=64)
......
39 43

  
40 44
    def check_status(self):
41 45
        url = urlparse.urljoin(self.webservice_base_url, 'Hello')
42
        response = self.requests.get(url, auth=HawkAuth(self.hawk_auth_id, self.hawk_auth_key))
43
        response.raise_for_status()
46
        try:
47
            response = self.requests.get(url, auth=HawkAuth(self.hawk_auth_id, self.hawk_auth_key))
48
            response.raise_for_status()
49
        except RequestException as e:
50
            raise Exception('Arpege server is down: %s' % e)
44 51
        if not response.json().get('Data'):
45 52
            raise Exception('Invalid credentials')
46 53
        return {'data': response.json()['Data']}
47 54

  
48 55
    def get_access_token(self, NameID):
49 56
        url = urlparse.urljoin(self.webservice_base_url, 'LoginParSubOIDC')
50
        response = self.requests.post(url, auth=HawkAuth(self.hawk_auth_id, self.hawk_auth_key),
51
                                      json={'subOIDC': NameID})
52
        if response.status_code // 100 != 2:
53
            raise APIError(u'HTTP error: %s' % response.status_code)
57
        try:
58
            response = self.requests.post(url, auth=HawkAuth(self.hawk_auth_id, self.hawk_auth_key),
59
                                          json={'subOIDC': NameID})
60
            response.raise_for_status()
61
        except RequestException as e:
62
            raise APIError(u'Arpege server is down: %s' % e)
54 63
        try:
55 64
            result = response.json()
56 65
        except ValueError:
57
            raise APIError(u'No JSON content returned: %r' % response.content[:1000])
66
            raise APIError(u'Arpege server is down: no JSON content returned, %r' % response.content[:1000])
58 67
        if result.get('Data'):
59 68
            if 'AccessToken' not in result['Data']:
60 69
                raise APIError(u'Error on LoginParSubOIDC: missing Data/AccessToken')
......
69 78
        url = urlparse.urljoin(self.webservice_base_url, 'DemandesUsager')
70 79
        params = {'scope': 'data_administratives'}
71 80
        auth = HawkAuth(self.hawk_auth_id, self.hawk_auth_key, ext=access_token)
72
        response = self.requests.get(url, params=params, auth=auth)
81
        try:
82
            response = self.requests.get(url, params=params, auth=auth)
83
            response.raise_for_status()
84
        except RequestException as e:
85
            raise APIError(u'Arpege server is down: %s' % e)
73 86
        data = []
74
        if response.status_code // 100 != 2:
75
            raise APIError(u'HTTP error: %s' % response.status_code)
76 87
        try:
77 88
            result = response.json()
78 89
        except ValueError:
tests/test_arpege_ecp.py
82 82
        resp = connector.check_status()
83 83
    assert str(error.value) == 'Invalid credentials'
84 84

  
85
@mock.patch('passerelle.utils.Request.post')
86
def test_get_access_token(mocked_post, connector):
87
    mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
88
    token = connector.get_access_token('nameid')
89
    assert token == '0f86353f2d87b8b78aaaacc2ecc763e287ded44f773289a5e336546a251718b3'
90 85

  
91
    mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=404)
92
    with pytest.raises(APIError) as error:
86
def test_get_access_token(connector):
87
    with utils.mock_url(response=FAKE_LOGIN_OIDC_RESPONSE):
93 88
        token = connector.get_access_token('nameid')
89
    assert token == '0f86353f2d87b8b78aaaacc2ecc763e287ded44f773289a5e336546a251718b3'
94 90

  
95
    assert str(error.value) == 'HTTP error: 404'
91
    with utils.mock_url(response=FAKE_LOGIN_OIDC_RESPONSE, status_code=404):
92
        with pytest.raises(APIError) as error:
93
            token = connector.get_access_token('nameid')
96 94

  
97
    mocked_post.return_value = utils.FakedResponse(content="content", status_code=200)
98
    with pytest.raises(APIError) as error:
99
        token = connector.get_access_token('nameid')
100
    assert str(error.value) == 'No JSON content returned: \'content\''
95
    assert ' 404 ' in str(error.value)
101 96

  
102
    mocked_post.return_value = utils.FakedResponse(content="content", status_code=200)
103
    with pytest.raises(APIError) as error:
104
        token = connector.get_access_token('nameid')
105
    assert str(error.value) == 'No JSON content returned: \'content\''
97
    with utils.mock_url(response="content", status_code=200):
98
        with pytest.raises(APIError) as error:
99
            token = connector.get_access_token('nameid')
100
    assert 'no JSON content' in str(error.value)
106 101

  
107
    mocked_post.return_value = utils.FakedResponse(content='{"IsSuccess": false, "CodErreur": "Fail", "LibErreur": "Auth FAIL"}',
108
                                                   status_code=200)
109
    with pytest.raises(APIError) as error:
110
        token = connector.get_access_token('nameid')
102
    with utils.mock_url(response="content", status_code=200):
103
        with pytest.raises(APIError) as error:
104
            token = connector.get_access_token('nameid')
105
    assert 'no JSON content' in str(error.value)
106

  
107
    with utils.mock_url(response='{"IsSuccess": false, "CodErreur": "Fail", "LibErreur": "Auth FAIL"}',
108
                        status_code=200):
109
        with pytest.raises(APIError) as error:
110
            token = connector.get_access_token('nameid')
111 111
    assert str(error.value) == 'Auth FAIL (Fail)'
112 112

  
113 113

  
......
149 149
    assert result['err_desc'] == 'Failed to get demands (Fail)'
150 150

  
151 151

  
152
@mock.patch('passerelle.utils.Request.get')
153
@mock.patch('passerelle.utils.Request.post')
154
def test_get_user_forms_failure_404(mocked_post, mocked_get, app, connector):
152
def test_get_user_forms_failure_404(app, connector):
155 153
    endpoint = reverse('generic-endpoint', kwargs={
156 154
        'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms'})
157 155

  
158
    mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
159
    mocked_get.return_value = utils.FakedResponse(content=FAKE_USER_DEMANDS_RESPONSE, status_code=404)
160
    resp = app.get(endpoint)
161
    result = resp.json
162
    assert result['err'] == 1
163
    assert result['err_desc'] == 'HTTP error: 404'
156
    with utils.mock_url(url='/LoginParSubOIDC', response=FAKE_LOGIN_OIDC_RESPONSE):
157
        with utils.mock_url(url='/DemandesUsager', status_code=404):
158
            resp = app.get(endpoint)
159
            result = resp.json
160
            assert result['err'] == 1
161
            assert 'Arpege server is down' in result['err_desc']
162
            assert ' 404 ' in result['err_desc']
164 163

  
165 164

  
166 165
@mock.patch('passerelle.utils.Request.get')
tests/utils.py
30 30
        return json.loads(self.content)
31 31

  
32 32

  
33
def mock_url(url, response):
34
    parsed = urlparse.urlparse(url)
35
    if not isinstance(response ,str):
33
def mock_url(url=None, response='', status_code=200):
34
    urlmatch_kwargs = {}
35
    if url:
36
        parsed = urlparse.urlparse(url)
37
        if parsed.netloc:
38
            urlmatch_kwargs['netloc'] = parsed.netloc
39
        if parsed.path:
40
            urlmatch_kwargs['path'] = parsed.path
41

  
42
    if not isinstance(response, str):
36 43
        response = json.dumps(response)
37 44

  
38
    @httmock.urlmatch(netloc=parsed.netloc, path=parsed.path)
45
    @httmock.urlmatch(**urlmatch_kwargs)
39 46
    def mocked(url, request):
40
        return httmock.response(200, response, request=request)
47
        return httmock.response(status_code, response, request=request)
41 48
    return httmock.HTTMock(mocked)
42 49

  
43 50

  
44
-