summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PKG-INFO3
-rw-r--r--macaroonbakery.egg-info/PKG-INFO3
-rw-r--r--macaroonbakery/httpbakery/_client.py29
-rw-r--r--macaroonbakery/tests/test_client.py68
-rwxr-xr-xsetup.py4
5 files changed, 84 insertions, 23 deletions
diff --git a/PKG-INFO b/PKG-INFO
index 571fa8a..c0150fc 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,11 @@
Metadata-Version: 1.1
Name: macaroonbakery
-Version: 1.2.1
+Version: 1.2.3
Summary: A Python library port for bakery, higher level operation to work with macaroons
Home-page: https://github.com/go-macaroon-bakery/py-macaroon-bakery
Author: Juju UI Team
Author-email: juju-gui@lists.ubuntu.com
License: LGPL3
-Description-Content-Type: UNKNOWN
Description: ===============
Macaroon Bakery
===============
diff --git a/macaroonbakery.egg-info/PKG-INFO b/macaroonbakery.egg-info/PKG-INFO
index 571fa8a..c0150fc 100644
--- a/macaroonbakery.egg-info/PKG-INFO
+++ b/macaroonbakery.egg-info/PKG-INFO
@@ -1,12 +1,11 @@
Metadata-Version: 1.1
Name: macaroonbakery
-Version: 1.2.1
+Version: 1.2.3
Summary: A Python library port for bakery, higher level operation to work with macaroons
Home-page: https://github.com/go-macaroon-bakery/py-macaroon-bakery
Author: Juju UI Team
Author-email: juju-gui@lists.ubuntu.com
License: LGPL3
-Description-Content-Type: UNKNOWN
Description: ===============
Macaroon Bakery
===============
diff --git a/macaroonbakery/httpbakery/_client.py b/macaroonbakery/httpbakery/_client.py
index 2510f73..326c33d 100644
--- a/macaroonbakery/httpbakery/_client.py
+++ b/macaroonbakery/httpbakery/_client.py
@@ -107,7 +107,7 @@ class Client:
discharges)) + ']'
all_macaroons = base64.urlsafe_b64encode(utils.to_bytes(macaroons))
- full_path = relative_url(url, error.info.macaroon_path)
+ full_path = urljoin(url, error.info.macaroon_path)
if error.info.cookie_name_suffix is not None:
name = 'macaroon-' + error.info.cookie_name_suffix
else:
@@ -164,7 +164,10 @@ class Client:
if payload is not None:
req['caveat64'] = base64.urlsafe_b64encode(payload).rstrip(
b'=').decode('utf-8')
- target = relative_url(cav.location, 'discharge')
+ loc = cav.location
+ if not loc.endswith('/'):
+ loc += '/'
+ target = urljoin(loc, 'discharge')
headers = {
BAKERY_PROTOCOL_HEADER: str(bakery.LATEST_VERSION)
}
@@ -200,8 +203,8 @@ class Client:
raise InteractionError('no supported interaction method')
def _legacy_interact(self, location, error_info):
- visit_url = relative_url(location, error_info.info.visit_url)
- wait_url = relative_url(location, error_info.info.wait_url)
+ visit_url = urljoin(location, error_info.info.visit_url)
+ wait_url = urljoin(location, error_info.info.wait_url)
method_urls = {
"interactive": visit_url
}
@@ -226,7 +229,7 @@ class Client:
if visit_url is None:
continue
- visit_url = relative_url(location, visit_url)
+ visit_url = urljoin(location, visit_url)
interactor.legacy_interact(self, location, visit_url)
return _wait_for_macaroon(wait_url)
@@ -295,7 +298,9 @@ def _prepare_discharge_hook(req, client):
req.headers[BAKERY_PROTOCOL_HEADER] = \
str(bakery.LATEST_VERSION)
with requests.Session() as s:
- return s.send(req)
+ settings = s.merge_environment_settings(
+ req.url, {}, None, None, None)
+ return s.send(req, **settings)
return hook
@@ -371,16 +376,6 @@ def _wait_for_macaroon(wait_url):
return bakery.Macaroon.from_dict(resp.json().get('Macaroon'))
-def relative_url(base, new):
- ''' Returns new path relative to an original URL.
- '''
- if new == '':
- return base
- if not base.endswith('/'):
- base += '/'
- return urljoin(base, new)
-
-
def _legacy_get_interaction_methods(u):
''' Queries a URL as found in an ErrInteractionRequired VisitURL field to
find available interaction methods.
@@ -397,7 +392,7 @@ def _legacy_get_interaction_methods(u):
if resp.status_code == 200:
json_resp = resp.json()
for m in json_resp:
- method_urls[m] = relative_url(u, json_resp[m])
+ method_urls[m] = urljoin(u, json_resp[m])
if method_urls.get('interactive') is None:
# There's no "interactive" method returned, but we know
diff --git a/macaroonbakery/tests/test_client.py b/macaroonbakery/tests/test_client.py
index 9c57b78..b03bafa 100644
--- a/macaroonbakery/tests/test_client.py
+++ b/macaroonbakery/tests/test_client.py
@@ -72,6 +72,7 @@ class TestClient(TestCase):
@urlmatch(path='.*/discharge')
def discharge(url, request):
+ self.assertEqual(url.path, '/discharge')
qs = parse_qs(request.body)
content = {q: qs[q][0] for q in qs}
m = httpbakery.discharge(checkers.AuthContext(), content, d.key, d,
@@ -101,6 +102,53 @@ class TestClient(TestCase):
finally:
httpd.shutdown()
+ def test_single_service_third_party_with_path(self):
+ class _DischargerLocator(bakery.ThirdPartyLocator):
+ def __init__(self):
+ self.key = bakery.generate_key()
+
+ def third_party_info(self, loc):
+ if loc == 'http://1.2.3.4/some/path':
+ return bakery.ThirdPartyInfo(
+ public_key=self.key.public_key,
+ version=bakery.LATEST_VERSION,
+ )
+
+ d = _DischargerLocator()
+ b = new_bakery('loc', d, None)
+
+ @urlmatch(path='.*/discharge')
+ def discharge(url, request):
+ self.assertEqual(url.path, '/some/path/discharge')
+ qs = parse_qs(request.body)
+ content = {q: qs[q][0] for q in qs}
+ m = httpbakery.discharge(checkers.AuthContext(), content, d.key, d,
+ alwaysOK3rd)
+ return {
+ 'status_code': 200,
+ 'content': {
+ 'Macaroon': m.to_dict()
+ }
+ }
+
+ def handler(*args):
+ GetHandler(b, 'http://1.2.3.4/some/path', None, None, None, AGES, *args)
+ try:
+ httpd = HTTPServer(('', 0), handler)
+ server_url = 'http://' + httpd.server_address[0] + ':' + str(httpd.server_address[1])
+ thread = threading.Thread(target=httpd.serve_forever)
+ thread.start()
+ client = httpbakery.Client()
+ with HTTMock(discharge):
+ resp = requests.get(
+ url=server_url,
+ cookies=client.cookies,
+ auth=client.auth())
+ resp.raise_for_status()
+ self.assertEquals(resp.text, 'done')
+ finally:
+ httpd.shutdown()
+
def test_single_service_third_party_version_1_caveat(self):
class _DischargerLocator(bakery.ThirdPartyLocator):
def __init__(self):
@@ -486,6 +534,26 @@ class TestClient(TestCase):
self.assertEquals(macaroons[0][0].identifier, m1.identifier)
self.assertEquals(macaroons[1][0].identifier, m2.identifier)
+ def test_handle_error_cookie_path(self):
+ macaroon = bakery.Macaroon(
+ root_key=b'some key', id=b'xxx',
+ location='some location',
+ version=bakery.VERSION_0)
+ info = {
+ 'Macaroon': macaroon.to_dict(),
+ 'MacaroonPath': '.',
+ 'CookieNameSuffix': 'test'
+ }
+ error = httpbakery.Error(
+ code=407,
+ message='error',
+ version=bakery.LATEST_VERSION,
+ info=httpbakery.ErrorInfo.from_dict(info))
+ client = httpbakery.Client()
+ client.handle_error(error, 'http://example.com/some/path')
+ [cookie] = client.cookies
+ self.assertEqual(cookie.path, "/some/")
+
class GetHandler(BaseHTTPRequestHandler):
'''A mock HTTP server that serves a GET request'''
diff --git a/setup.py b/setup.py
index fefbee9..f098e76 100755
--- a/setup.py
+++ b/setup.py
@@ -13,8 +13,8 @@ from setuptools import (
PROJECT_NAME = 'macaroonbakery'
-# version 1.2.1
-VERSION = (1, 2, 1)
+# version 1.2.3
+VERSION = (1, 2, 3)
def get_version():