0001-allow-cookies-usage-in-endpoint-requests-27654.patch
passerelle/utils/__init__.py | ||
---|---|---|
214 | 214 |
if 'timeout' not in kwargs: |
215 | 215 |
kwargs['timeout'] = settings.REQUESTS_TIMEOUT |
216 | 216 | |
217 |
# don't use persistent cookies |
|
218 |
self.cookies.clear() |
|
217 |
if self.resource and hasattr(self.resource, 'cookiejar'): |
|
218 |
# use cookies that will last the whole endpoint duration |
|
219 |
self.cookies = self.resource.cookiejar |
|
219 | 220 | |
220 | 221 |
response = super(Request, self).request(method, url, **kwargs) |
221 | 222 | |
223 |
if getattr(self, 'cookies', None) and self.resource \ |
|
224 |
and hasattr(self.resource, 'cookiejar'): |
|
225 |
# make sure we get the new cookiejar; it is actually not necessary |
|
226 |
# in normal operations but httmock will replace the cookiejar |
|
227 |
# instead of filling it :/ |
|
228 |
self.resource.cookiejar = self.cookies |
|
229 | ||
222 | 230 |
if method == 'GET' and cache_duration and (response.status_code // 100 == 2): |
223 | 231 |
cache.set(cache_key, { |
224 | 232 |
'content': response.content, |
passerelle/views.py | ||
---|---|---|
22 | 22 |
from django.utils.encoding import force_text |
23 | 23 |
from django.forms.models import modelform_factory |
24 | 24 |
from django.forms.widgets import ClearableFileInput |
25 |
import requests |
|
25 | 26 | |
26 | 27 |
from dateutil import parser as date_parser |
27 | 28 | |
... | ... | |
287 | 288 |
def dispatch(self, request, *args, **kwargs): |
288 | 289 |
self.init_stuff(request, *args, **kwargs) |
289 | 290 |
connector = self.get_object() |
291 |
connector.cookiejar = requests.cookies.cookiejar_from_dict({}) |
|
290 | 292 |
self.endpoint = None |
291 | 293 |
endpoints = [] |
292 | 294 |
for name, method in inspect.getmembers(connector): |
tests/test_generic_endpoint.py | ||
---|---|---|
295 | 295 |
assert cache.get_calls == 5 |
296 | 296 |
assert cache.set_calls == 3 |
297 | 297 |
assert resp1.json_body != resp6.json_body |
298 | ||
299 | ||
300 |
def test_endpoint_cookies(app, db, monkeypatch): |
|
301 | ||
302 |
@endpoint(methods=['get']) |
|
303 |
def httpcall(obj, request): |
|
304 |
headers = {'Set-Cookie': 'somecookie=somecookievalue'} |
|
305 |
with utils.mock_url('http://some.example.org/', 'ok', headers): |
|
306 |
response = obj.requests.get('http://some.example.org/') |
|
307 |
cookie1 = response.request.headers.get('Cookie') |
|
308 |
response = obj.requests.get('http://some.example.org/') |
|
309 |
cookie2 = response.request.headers.get('Cookie') |
|
310 |
return { |
|
311 |
'cookie1': cookie1, |
|
312 |
'cookie2': cookie2 |
|
313 |
} |
|
314 | ||
315 |
monkeypatch.setattr(StubInvoicesConnector, 'httpcall', httpcall, raising=False) |
|
316 | ||
317 |
connector = StubInvoicesConnector(slug='fake') |
|
318 |
connector.save() |
|
319 | ||
320 |
json_res = app.get('/stub-invoices/fake/httpcall').json |
|
321 |
assert json_res['cookie1'] is None |
|
322 |
assert json_res['cookie2'] == 'somecookie=somecookievalue' |
|
323 |
# Do it a second time to test that no cookies are leaking from one call |
|
324 |
# to the other |
|
325 |
json_res = app.get('/stub-invoices/fake/httpcall').json |
|
326 |
assert json_res['cookie1'] is None |
|
327 |
assert json_res['cookie2'] == 'somecookie=somecookievalue' |
tests/test_requests.py | ||
---|---|---|
6 | 6 |
from httmock import urlmatch, HTTMock, response |
7 | 7 | |
8 | 8 |
from django.test import override_settings |
9 |
import requests |
|
9 | 10 | |
10 | 11 |
from passerelle.utils import Request, CaseInsensitiveDict |
11 | 12 |
from passerelle.utils.http_authenticators import HawkAuth |
... | ... | |
327 | 328 |
assert mocked_get.call_args[1]['timeout'] == 42 |
328 | 329 |
Request(logger=logger).get('http://example.net/whatever', timeout=None) |
329 | 330 |
assert mocked_get.call_args[1]['timeout'] is None |
331 | ||
332 | ||
333 |
def test_requests_cookies(caplog): |
|
334 |
resource = MockResource() |
|
335 |
resource.cookiejar = requests.cookies.cookiejar_from_dict({}) |
|
336 |
logger = logging.getLogger('requests') |
|
337 |
request = Request(resource=resource, logger=logger) |
|
338 | ||
339 |
headers = {'Set-Cookie': 'somecookie=somecookievalue'} |
|
340 |
with utils.mock_url('http://some.example.org/', 'ok', headers): |
|
341 |
response = request.get('http://some.example.org/') |
|
342 |
assert response.cookies['somecookie'] == 'somecookievalue' |
|
343 |
# cookies are stored on the resource |
|
344 |
assert resource.cookiejar == response.cookies |
|
345 | ||
346 |
with utils.mock_url('http://some.example.org/', 'ok'): |
|
347 |
# cookies are sent back |
|
348 |
response = request.get('http://some.example.org/') |
|
349 |
assert response.request.headers['Cookie'] == 'somecookie=somecookievalue' |
|
350 | ||
351 |
# cookies sent back even with a new Request obj |
|
352 |
request = Request(resource=resource, logger=logger) |
|
353 |
response = request.get('http://some.example.org/') |
|
354 |
assert response.request.headers['Cookie'] == 'somecookie=somecookievalue' |
tests/utils.py | ||
---|---|---|
30 | 30 |
return json.loads(self.content) |
31 | 31 | |
32 | 32 | |
33 |
def mock_url(url, response): |
|
33 |
def mock_url(url, response, headers=None):
|
|
34 | 34 |
parsed = urlparse.urlparse(url) |
35 | 35 |
if not isinstance(response ,str): |
36 | 36 |
response = json.dumps(response) |
37 | 37 | |
38 | 38 |
@httmock.urlmatch(netloc=parsed.netloc, path=parsed.path) |
39 | 39 |
def mocked(url, request): |
40 |
return httmock.response(200, response, request=request) |
|
40 |
return httmock.response(200, response, request=request, headers=headers)
|
|
41 | 41 |
return httmock.HTTMock(mocked) |
42 | 42 | |
43 | 43 | |
44 |
- |