From 4379a501141f75557e535f9c2ef3b58ef362259c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 28 Feb 2018 17:08:16 +0000 Subject: Import py-macaroon-bakery_1.1.3.orig.tar.gz --- docs/conf.py | 2 +- macaroonbakery/checkers/_checkers.py | 9 ++++++--- macaroonbakery/httpbakery/_browser.py | 5 +++-- macaroonbakery/httpbakery/_client.py | 7 +++++-- macaroonbakery/tests/common.py | 4 +--- macaroonbakery/tests/test_checkers.py | 3 +-- macaroonbakery/tests/test_client.py | 5 +++++ macaroonbakery/tests/test_httpbakery.py | 16 ++++++++++++++++ macaroonbakery/tests/test_utils.py | 4 ++-- requirements.txt | 1 - setup.py | 3 +-- 11 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 macaroonbakery/tests/test_httpbakery.py diff --git a/docs/conf.py b/docs/conf.py index 7985e17..3e35fbd 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -63,7 +63,7 @@ copyright = u'2017, Juju UI Team' # the built documents. # # The short X.Y version and the full version. -version = release = '1.1.2' +version = release = '1.1.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/macaroonbakery/checkers/_checkers.py b/macaroonbakery/checkers/_checkers.py index 71cb56f..11a41b9 100644 --- a/macaroonbakery/checkers/_checkers.py +++ b/macaroonbakery/checkers/_checkers.py @@ -5,7 +5,6 @@ from collections import namedtuple from datetime import datetime import pyrfc3339 -import pytz from ._caveat import parse_caveat from ._conditions import ( COND_ALLOW, @@ -166,12 +165,16 @@ class CheckerInfo(namedtuple('CheckInfo', 'prefix name ns check')): def _check_time_before(ctx, cond, arg): clock = ctx.get(TIME_KEY) if clock is None: - now = pytz.UTC.localize(datetime.utcnow()) + now = datetime.utcnow() else: now = clock.utcnow() try: - if pyrfc3339.parse(arg) <= now: + # Note: pyrfc3339 returns a datetime with a timezone, which + # we need to remove before we can compare it with the naive + # datetime object returned by datetime.utcnow. + expiry = pyrfc3339.parse(arg, utc=True).replace(tzinfo=None) + if now >= expiry: return 'macaroon has expired' except ValueError: return 'cannot parse "{}" as RFC 3339'.format(arg) diff --git a/macaroonbakery/httpbakery/_browser.py b/macaroonbakery/httpbakery/_browser.py index a1ccbb0..c8a5586 100644 --- a/macaroonbakery/httpbakery/_browser.py +++ b/macaroonbakery/httpbakery/_browser.py @@ -85,5 +85,6 @@ class WebBrowserInteractionInfo(namedtuple('WebBrowserInteractionInfo', @param info_dict The deserialized JSON object @return a new WebBrowserInteractionInfo object. ''' - return WebBrowserInteractionInfo(visit_url=info_dict.get('VisitURL'), - wait_token_url=info_dict('WaitURL')) + return WebBrowserInteractionInfo( + visit_url=info_dict.get('VisitURL'), + wait_token_url=info_dict.get('WaitTokenURL')) diff --git a/macaroonbakery/httpbakery/_client.py b/macaroonbakery/httpbakery/_client.py index d877140..4fe0ab1 100644 --- a/macaroonbakery/httpbakery/_client.py +++ b/macaroonbakery/httpbakery/_client.py @@ -320,8 +320,11 @@ def extract_macaroons(headers_or_request): mss = [] def add_macaroon(data): - data = utils.b64decode(data) - data_as_objs = json.loads(data.decode('utf-8')) + try: + data = utils.b64decode(data) + data_as_objs = json.loads(data.decode('utf-8')) + except ValueError: + return ms = [utils.macaroon_from_dict(x) for x in data_as_objs] mss.append(ms) diff --git a/macaroonbakery/tests/common.py b/macaroonbakery/tests/common.py index cfbfc52..972b3ad 100644 --- a/macaroonbakery/tests/common.py +++ b/macaroonbakery/tests/common.py @@ -4,7 +4,6 @@ from datetime import datetime, timedelta import macaroonbakery.bakery as bakery import macaroonbakery.checkers as checkers -import pytz class _StoppedClock(object): @@ -15,8 +14,7 @@ class _StoppedClock(object): return self.t -epoch = pytz.utc.localize( - datetime(year=1900, month=11, day=17, hour=19, minute=00, second=13)) +epoch = datetime(year=1900, month=11, day=17, hour=19, minute=00, second=13) ages = epoch + timedelta(days=1) test_context = checkers.context_with_clock(checkers.AuthContext(), diff --git a/macaroonbakery/tests/test_checkers.py b/macaroonbakery/tests/test_checkers.py index 28da06e..2628153 100644 --- a/macaroonbakery/tests/test_checkers.py +++ b/macaroonbakery/tests/test_checkers.py @@ -4,7 +4,6 @@ from datetime import datetime, timedelta from unittest import TestCase import macaroonbakery.checkers as checkers -import pytz import six from pymacaroons import MACAROON_V2, Macaroon @@ -15,7 +14,7 @@ NOW = datetime( class TestClock(): def utcnow(self): - return pytz.UTC.localize(NOW) + return NOW class TestCheckers(TestCase): diff --git a/macaroonbakery/tests/test_client.py b/macaroonbakery/tests/test_client.py index ab20c3b..bfc7807 100644 --- a/macaroonbakery/tests/test_client.py +++ b/macaroonbakery/tests/test_client.py @@ -346,6 +346,11 @@ class TestClient(TestCase): value=encode_macaroon(m2), url='http://example.com', )) + jar.set_cookie(utils.cookie( + name='macaroon-empty', + value='', + url='http://example.com', + )) jar.add_cookie_header(req) macaroons = httpbakery.extract_macaroons(req) diff --git a/macaroonbakery/tests/test_httpbakery.py b/macaroonbakery/tests/test_httpbakery.py new file mode 100644 index 0000000..4aac850 --- /dev/null +++ b/macaroonbakery/tests/test_httpbakery.py @@ -0,0 +1,16 @@ +from unittest import TestCase + +from macaroonbakery.httpbakery import WebBrowserInteractionInfo + + +class TestWebBrowserInteractionInfo(TestCase): + + def test_from_dict(self): + info_dict = { + 'VisitURL': 'https://example.com/visit', + 'WaitTokenURL': 'https://example.com/wait'} + interaction_info = WebBrowserInteractionInfo.from_dict(info_dict) + self.assertEqual( + interaction_info.visit_url, 'https://example.com/visit') + self.assertEqual( + interaction_info.wait_token_url, 'https://example.com/wait') diff --git a/macaroonbakery/tests/test_utils.py b/macaroonbakery/tests/test_utils.py index fcc8839..65edeb4 100644 --- a/macaroonbakery/tests/test_utils.py +++ b/macaroonbakery/tests/test_utils.py @@ -7,7 +7,6 @@ from unittest import TestCase import macaroonbakery.bakery as bakery import pymacaroons -import pytz from macaroonbakery._utils import cookie from pymacaroons.serializers import json_serializer @@ -21,7 +20,8 @@ class CookieTest(TestCase): c.expires, int((timestamp - datetime(1970, 1, 1)).total_seconds())) def test_cookie_expires_with_timezone(self): - timestamp = datetime.now(pytz.UTC) + from datetime import tzinfo + timestamp = datetime.utcnow().replace(tzinfo=tzinfo()) self.assertRaises( ValueError, cookie, 'http://example.com', 'test', 'value', expires=timestamp) diff --git a/requirements.txt b/requirements.txt index 06cc66e..889c512 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,3 @@ pymacaroons>=0.12.0,<1.0 six>=1.11.0,<2.0 protobuf>=3.4.0,<4.0 pyRFC3339>=1.0,<2.0 -pytz>=2017.2,<2018.0 diff --git a/setup.py b/setup.py index 265b5f8..8beaad3 100755 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ from setuptools import ( PROJECT_NAME = 'macaroonbakery' -VERSION = (1, 1, 2) +VERSION = (1, 1, 3) def get_version(): @@ -30,7 +30,6 @@ requirements = [ 'six>=1.11.0,<2.0', 'protobuf>=3.0.0,<4.0', 'pyRFC3339>=1.0,<2.0', - 'pytz>=2017.2,<2018.0' ] test_requirements = [ -- cgit v1.2.1 From 920e53a9172a6a76d6f1abcef56be2edf4301596 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 6 Nov 2017 10:27:10 +0000 Subject: Isolate client tests from any HTTP proxy Debian's Python packaging tools set http_proxy to a non-existent proxy to help flush out packages that try to talk to the network during build, but these tests could previously fail in more normal development environments too. Forwarded: https://github.com/go-macaroon-bakery/py-macaroon-bakery/pull/28 Last-Update: 2018-02-05 Patch-Name: isolate-from-proxy.patch --- macaroonbakery/tests/test_bakery.py | 6 ++++++ macaroonbakery/tests/test_client.py | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/macaroonbakery/tests/test_bakery.py b/macaroonbakery/tests/test_bakery.py index a6c3e58..72a6928 100644 --- a/macaroonbakery/tests/test_bakery.py +++ b/macaroonbakery/tests/test_bakery.py @@ -1,5 +1,6 @@ # Copyright 2017 Canonical Ltd. # Licensed under the LGPLv3, see LICENCE file for details. +import os from unittest import TestCase import macaroonbakery.httpbakery as httpbakery @@ -171,6 +172,11 @@ def wait_on_error(url, request): class TestBakery(TestCase): + def setUp(self): + super(TestBakery, self).setUp() + # http_proxy would cause requests to talk to the proxy, which is + # unlikely to know how to talk to the test server. + os.environ.pop('http_proxy', None) def assert_cookie_security(self, cookies, name, secure): for cookie in cookies: diff --git a/macaroonbakery/tests/test_client.py b/macaroonbakery/tests/test_client.py index bfc7807..baafeed 100644 --- a/macaroonbakery/tests/test_client.py +++ b/macaroonbakery/tests/test_client.py @@ -3,6 +3,7 @@ import base64 import datetime import json +import os import threading from unittest import TestCase @@ -27,6 +28,12 @@ TEST_OP = bakery.Op(entity='test', action='test') class TestClient(TestCase): + def setUp(self): + super(TestClient, self).setUp() + # http_proxy would cause requests to talk to the proxy, which is + # unlikely to know how to talk to the test server. + os.environ.pop('http_proxy', None) + def test_single_service_first_party(self): b = new_bakery('loc', None, None) -- cgit v1.2.1 From d918563db4de954c3df719d06a31bdd3aec3a8fc Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 9 Feb 2018 21:54:21 +0000 Subject: Improve mock setup for 407-then-unknown test `test_407_then_unknown_interaction_methods` causes the client to fetch the possible methods supported by the discharger (because it's told that it only supports a non-window method). This is currently unmocked, which causes the client to actually contact `http://example.com/visit`. This fails in Launchpad builds because they run with a restrictive network setup that doesn't even expose DNS lookups for non-permitted hosts. There isn't really a good way to simulate this without setting up a similar stunt DNS server (though perhaps installing an `httmock.all_requests` fallback mock that raises an exception would be a good idea?), but this seems to be the only failure at the moment. Forwarded: https://github.com/go-macaroon-bakery/py-macaroon-bakery/pull/45 Last-Update: 2018-02-09 Patch-Name: improve-unknown-interaction-mock.patch --- macaroonbakery/tests/test_bakery.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/macaroonbakery/tests/test_bakery.py b/macaroonbakery/tests/test_bakery.py index 72a6928..1883987 100644 --- a/macaroonbakery/tests/test_bakery.py +++ b/macaroonbakery/tests/test_bakery.py @@ -146,6 +146,16 @@ def discharge_401(url, request): } +@urlmatch(path='.*/visit') +def visit_200(url, request): + return { + 'status_code': 200, + 'content': { + 'interactive': '/visit' + } + } + + @urlmatch(path='.*/wait') def wait_after_401(url, request): if request.url != 'http://example.com/wait': @@ -245,7 +255,8 @@ class TestBakery(TestCase): def kind(self): return 'unknown' client = httpbakery.Client(interaction_methods=[UnknownInteractor()]) - with HTTMock(first_407_then_200), HTTMock(discharge_401): + with HTTMock(first_407_then_200), HTTMock(discharge_401),\ + HTTMock(visit_200): with self.assertRaises(httpbakery.InteractionError) as exc: requests.get( ID_PATH, -- cgit v1.2.1