diff -Nru py-macaroon-bakery-1.1.3/CHANGELOG.rst py-macaroon-bakery-1.2.1/CHANGELOG.rst --- py-macaroon-bakery-1.1.3/CHANGELOG.rst 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/CHANGELOG.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -.. :changelog: - -History -------- - -0.0.2 (2017-07-19) -++++++++++++++++++ - -* Fix import. - -0.0.1 (2017-06-09) -++++++++++++++++++ - -* Initial release. - diff -Nru py-macaroon-bakery-1.1.3/debian/changelog py-macaroon-bakery-1.2.1/debian/changelog --- py-macaroon-bakery-1.1.3/debian/changelog 2018-02-28 17:09:45.000000000 +0000 +++ py-macaroon-bakery-1.2.1/debian/changelog 2018-10-15 09:59:57.000000000 +0000 @@ -1,3 +1,27 @@ +py-macaroon-bakery (1.2.1-1~18.04.1) bionic; urgency=medium + + * New upstream release. + + -- Colin Watson Mon, 15 Oct 2018 10:59:57 +0100 + +py-macaroon-bakery (1.2.0-1) unstable; urgency=medium + + * debian/watch: Switch to PyPI, which upstream updates more reliably than + GitHub releases. + * New upstream release. + + -- Colin Watson Fri, 12 Oct 2018 15:29:00 +0100 + +py-macaroon-bakery (1.1.4-1) unstable; urgency=medium + + [ Ondřej Nový ] + * Convert git repository from git-dpm to gbp layout + + [ Colin Watson ] + * New upstream release. + + -- Colin Watson Mon, 20 Aug 2018 17:54:44 +0100 + py-macaroon-bakery (1.1.3-1) unstable; urgency=medium * New upstream release. diff -Nru py-macaroon-bakery-1.1.3/debian/control py-macaroon-bakery-1.2.1/debian/control --- py-macaroon-bakery-1.1.3/debian/control 2018-02-28 17:09:18.000000000 +0000 +++ py-macaroon-bakery-1.2.1/debian/control 2018-08-20 16:32:53.000000000 +0000 @@ -18,7 +18,7 @@ python3-six (>= 1.11.0), Standards-Version: 4.1.1 X-Python3-Version: >= 3.5 -Vcs-Git: https://salsa.debian.org/python-team/modules/py-macaroon-bakery +Vcs-Git: https://salsa.debian.org/python-team/modules/py-macaroon-bakery.git Vcs-Browser: https://salsa.debian.org/python-team/modules/py-macaroon-bakery Homepage: https://github.com/go-macaroon-bakery/py-macaroon-bakery Rules-Requires-Root: no diff -Nru py-macaroon-bakery-1.1.3/debian/.git-dpm py-macaroon-bakery-1.2.1/debian/.git-dpm --- py-macaroon-bakery-1.1.3/debian/.git-dpm 2018-02-28 17:09:05.000000000 +0000 +++ py-macaroon-bakery-1.2.1/debian/.git-dpm 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -# see git-dpm(1) from git-dpm package -d918563db4de954c3df719d06a31bdd3aec3a8fc -d918563db4de954c3df719d06a31bdd3aec3a8fc -4379a501141f75557e535f9c2ef3b58ef362259c -4379a501141f75557e535f9c2ef3b58ef362259c -py-macaroon-bakery_1.1.3.orig.tar.gz -0531fe0fcaa20b9554b17347b36a1b3c4cb84e06 -82450 -debianTag="debian/%e%v" -patchedTag="patched/%e%v" -upstreamTag="upstream/%e%u" diff -Nru py-macaroon-bakery-1.1.3/debian/patches/improve-unknown-interaction-mock.patch py-macaroon-bakery-1.2.1/debian/patches/improve-unknown-interaction-mock.patch --- py-macaroon-bakery-1.1.3/debian/patches/improve-unknown-interaction-mock.patch 2018-02-28 17:09:05.000000000 +0000 +++ py-macaroon-bakery-1.2.1/debian/patches/improve-unknown-interaction-mock.patch 2018-10-15 09:59:04.000000000 +0000 @@ -1,4 +1,3 @@ -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 diff -Nru py-macaroon-bakery-1.1.3/debian/patches/isolate-from-proxy.patch py-macaroon-bakery-1.2.1/debian/patches/isolate-from-proxy.patch --- py-macaroon-bakery-1.1.3/debian/patches/isolate-from-proxy.patch 2018-02-28 17:09:05.000000000 +0000 +++ py-macaroon-bakery-1.2.1/debian/patches/isolate-from-proxy.patch 2018-10-15 09:59:04.000000000 +0000 @@ -1,4 +1,3 @@ -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 @@ -41,7 +40,7 @@ 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 +index 9c57b78..fe53579 100644 --- a/macaroonbakery/tests/test_client.py +++ b/macaroonbakery/tests/test_client.py @@ -3,6 +3,7 @@ diff -Nru py-macaroon-bakery-1.1.3/debian/watch py-macaroon-bakery-1.2.1/debian/watch --- py-macaroon-bakery-1.1.3/debian/watch 2018-02-28 17:09:04.000000000 +0000 +++ py-macaroon-bakery-1.2.1/debian/watch 2018-10-12 12:08:07.000000000 +0000 @@ -1,4 +1,3 @@ version=4 -opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%py-macaroon-bakery-$1.tar.gz%" \ - https://github.com/go-macaroon-bakery/py-macaroon-bakery/releases \ - (?:.*?/)?v?(\d[\d.]*)\.tar\.gz +opts="uversionmangle=s/(rc|a|b|c)/~$1/" \ + http://pypi.debian.net/macaroonbakery/macaroonbakery@ANY_VERSION@@ARCHIVE_EXT@ diff -Nru py-macaroon-bakery-1.1.3/docs/conf.py py-macaroon-bakery-1.2.1/docs/conf.py --- py-macaroon-bakery-1.1.3/docs/conf.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/docs/conf.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,273 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Macaroon Bakery documentation build configuration file, created by -# sphinx-quickstart on Tue Jul 9 22:26:36 2013. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os - -# If extensions (or modules to document with autodoc) are in another -# directory, add these directories to sys.path here. If the directory is -# relative to the documentation root, use os.path.abspath to make it -# absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# Get the project root dir, which is the parent dir of this -cwd = os.getcwd() -project_root = os.path.dirname(cwd) - -# Insert the project root dir as the first element in the PYTHONPATH. -# This lets us ensure that the source package is imported, and that its -# version is used. -sys.path.insert(0, project_root) - -import macaroonbakery as bakery - -# -- General configuration --------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Python Macaroon Bakery' -copyright = u'2017, Juju UI Team' - -# The version info for the project you're documenting, acts as replacement -# for |version| and |release|, also used in various other places throughout -# the built documents. -# -# The short X.Y version and the full version. -version = release = '1.1.3' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to -# some non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built -# documents. -#keep_warnings = False - - -# -- Options for HTML output ------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'alabaster' - -# Theme options are theme-specific and customize the look and feel of a -# theme further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as -# html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the -# top of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon -# of the docs. This file should be a Windows icon file (.ico) being -# 16x16 or 32x32 pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) -# here, relative to this directory. They are copied after the builtin -# static files, so a file named "default.css" will overwrite the builtin -# "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page -# bottom, using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names -# to template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. -# Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. -# Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages -# will contain a tag referring to it. The value of this option -# must be the base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'bakerydoc' - - -# -- Options for LaTeX output ------------------------------------------ - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - #'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass -# [howto/manual]). -latex_documents = [ - ('index', 'bakery.tex', - u'Macaroon Bakery Documentation', - u'Juju UI Team', 'manual'), -] - -# The name of an image file (relative to this directory) to place at -# the top of the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings -# are parts, not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output ------------------------------------ - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'bakery', - u'Macaroon Bakery Documentation', - [u'Juju UI Team'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ---------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'bakery', - u'Python Macaroon Bakery Documentation', - u'Juju UI Team', - 'bakery', - 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False diff -Nru py-macaroon-bakery-1.1.3/.gitignore py-macaroon-bakery-1.2.1/.gitignore --- py-macaroon-bakery-1.1.3/.gitignore 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] - -# Distribution / packaging -.sysdeps-installed -devenv -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover - -# Sphinx documentation -docs/_build/ - -# Editor files -*.sw[op] - -# Build canaries. -.*canary diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/bakery/_checker.py py-macaroon-bakery-1.2.1/macaroonbakery/bakery/_checker.py --- py-macaroon-bakery-1.1.3/macaroonbakery/bakery/_checker.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/bakery/_checker.py 2018-10-12 13:58:52.000000000 +0000 @@ -111,21 +111,18 @@ if not self._executed: self._init_once(ctx) self._executed = True - if self._init_errors: - raise AuthInitError(self._init_errors[0]) def _init_once(self, ctx): self._auth_indexes = {} self._conditions = [None] * len(self._macaroons) for i, ms in enumerate(self._macaroons): try: - ops, conditions = self.parent._macaroon_opstore.macaroon_ops( - ms) - except VerificationError: - raise - except Exception as exc: - self._init_errors.append(exc.args[0]) + ops, conditions = self.parent._macaroon_opstore.macaroon_ops(ms) + except VerificationError as e: + self._init_errors.append(str(e)) continue + except Exception as exc: + raise AuthInitError(str(exc)) # It's a valid macaroon (in principle - we haven't checked first # party caveats). @@ -152,8 +149,7 @@ # other operations if the conditions succeed for those. declared, err = self._check_conditions(ctx, LOGIN_OP, conditions) if err is not None: - self._init_errors.append('cannot authorize login macaroon: ' + - err) + self._init_errors.append('cannot authorize login macaroon: ' + err) continue if self._identity is not None: # We've already found a login macaroon so ignore this one @@ -201,8 +197,13 @@ authorization requests. If an operation was not allowed, an exception will be raised which may - be DischargeRequiredError holding the operations that remain to - be authorized in order to allow authorization to proceed. + be: + + - DischargeRequiredError holding the operations that remain to + be authorized in order to allow authorization to proceed + - PermissionDenied when no operations can be authorized and there's + no third party to discharge macaroons for. + @param ctx AuthContext @param ops an array of Op :return: an AuthInfo object. diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/bakery/_discharge.py py-macaroon-bakery-1.2.1/macaroonbakery/bakery/_discharge.py --- py-macaroon-bakery-1.1.3/macaroonbakery/bakery/_discharge.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/bakery/_discharge.py 2018-10-12 13:15:20.000000000 +0000 @@ -33,9 +33,12 @@ It returns a list of macaroon with m as the first element, followed by all the discharge macaroons. All the discharge macaroons will be bound to the primary macaroon. + The get_discharge function is passed a context (AuthContext), - the caveat(Caveat) to be discharged and encrypted_caveat (bytes)will be + the caveat(pymacaroons.Caveat) to be discharged and encrypted_caveat (bytes) will be passed the external caveat payload found in m, if any. + It should return a bakery.Macaroon object holding the discharge + macaroon for the third party caveat. ''' primary = m.macaroon discharges = [primary] @@ -161,7 +164,7 @@ raise VerificationError(exc.args[0]) if cond == checkers.COND_NEED_DECLARED: - cav_info = cav_info._replace(condition=arg.encode('utf-8')) + cav_info = cav_info._replace(condition=arg) caveats = _check_need_declared(ctx, cav_info, checker) else: caveats = checker.check_third_party_caveat(ctx, cav_info) @@ -185,7 +188,7 @@ def _check_need_declared(ctx, cav_info, checker): - arg = cav_info.condition.decode('utf-8') + arg = cav_info.condition i = arg.find(' ') if i <= 0: raise VerificationError( @@ -197,7 +200,7 @@ raise VerificationError('need-declared caveat with empty required attribute') if len(need_declared) == 0: raise VerificationError('need-declared caveat with no required attributes') - cav_info = cav_info._replace(condition=arg[i + 1:].encode('utf-8')) + cav_info = cav_info._replace(condition=arg[i + 1:]) caveats = checker.check_third_party_caveat(ctx, cav_info) declared = {} for cav in caveats: diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/bakery/_internal/id.proto py-macaroon-bakery-1.2.1/macaroonbakery/bakery/_internal/id.proto --- py-macaroon-bakery-1.1.3/macaroonbakery/bakery/_internal/id.proto 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/bakery/_internal/id.proto 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -syntax="proto3"; - -option go_package = "macaroonpb"; - -message MacaroonId { - bytes nonce = 1; - bytes storageId = 2; - repeated Op ops = 3; -} - -message Op { - string entity = 1; - repeated string actions = 2; -} diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/bakery/_oven.py py-macaroon-bakery-1.2.1/macaroonbakery/bakery/_oven.py --- py-macaroon-bakery-1.1.3/macaroonbakery/bakery/_oven.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/bakery/_oven.py 2018-10-12 14:03:25.000000000 +0000 @@ -28,10 +28,6 @@ ) from ._internal import id_pb2 from pymacaroons import MACAROON_V2, Verifier -from pymacaroons.exceptions import ( - MacaroonInvalidSignatureException, - MacaroonUnmetCaveatException, -) class Oven: @@ -183,10 +179,20 @@ v.satisfy_general(validator) try: v.verify(macaroons[0], root_key, macaroons[1:]) - except (MacaroonUnmetCaveatException, - MacaroonInvalidSignatureException) as exc: - raise VerificationError( - 'verification failed: {}'.format(exc.args[0])) + except Exception as exc: + # Unfortunately pymacaroons doesn't control + # the set of exceptions that can be raised here. + # Possible candidates are: + # pymacaroons.exceptions.MacaroonUnmetCaveatException + # pymacaroons.exceptions.MacaroonInvalidSignatureException + # ValueError + # nacl.exceptions.CryptoError + # + # There may be others too, so just catch everything. + raise six.raise_from( + VerificationError('verification failed: {}'.format(str(exc))), + exc, + ) if (self.ops_store is not None and len(ops) == 1 diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/httpbakery/_client.py py-macaroon-bakery-1.2.1/macaroonbakery/httpbakery/_client.py --- py-macaroon-bakery-1.1.3/macaroonbakery/httpbakery/_client.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/httpbakery/_client.py 2018-08-20 10:53:31.000000000 +0000 @@ -290,12 +290,8 @@ Retry.count) ) client.handle_error(error, req.url) - # Replace the private _cookies from req as it is a copy of - # the original cookie jar passed into the requests method and we need - # to set the cookie for this request. - req._cookies = client.cookies req.headers.pop('Cookie', None) - req.prepare_cookies(req._cookies) + req.prepare_cookies(client.cookies) req.headers[BAKERY_PROTOCOL_HEADER] = \ str(bakery.LATEST_VERSION) with requests.Session() as s: diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/httpbakery/_discharge.py py-macaroon-bakery-1.2.1/macaroonbakery/httpbakery/_discharge.py --- py-macaroon-bakery-1.1.3/macaroonbakery/httpbakery/_discharge.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/httpbakery/_discharge.py 2018-09-28 15:44:07.000000000 +0000 @@ -16,10 +16,13 @@ @return The discharge macaroon {macaroonbakery.Macaroon} ''' id = content.get('id') - if id is None: + if id is not None: + id = id.encode('utf-8') + else: id = content.get('id64') if id is not None: id = utils.b64decode(id) + caveat = content.get('caveat64') if caveat is not None: caveat = utils.b64decode(caveat) diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/httpbakery/_error.py py-macaroon-bakery-1.2.1/macaroonbakery/httpbakery/_error.py --- py-macaroon-bakery-1.1.3/macaroonbakery/httpbakery/_error.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/httpbakery/_error.py 2018-10-12 14:07:27.000000000 +0000 @@ -20,7 +20,7 @@ '''This is thrown by Client when a third party has refused a discharge''' def __init__(self, msg): super(DischargeError, self).__init__( - 'third party refused discharge: {}'.format(msg)) + 'third party refused dischargex: {}'.format(msg)) class InteractionError(Exception): @@ -106,11 +106,16 @@ '''Create an error from a JSON-deserialized object @param serialized the object holding the serialized error {dict} ''' - code = serialized.get('Code') - message = serialized.get('Message') - info = ErrorInfo.from_dict(serialized.get('Info')) - return Error(code=code, message=message, info=info, - version=bakery.LATEST_VERSION) + # Some servers return lower case field names for message and code. + # The Go client is tolerant of this, so be similarly tolerant here. + def field(name): + return serialized.get(name) or serialized.get(name.lower()) + return Error( + code=field('Code'), + message=field('Message'), + info=ErrorInfo.from_dict(field('Info')), + version=bakery.LATEST_VERSION, + ) def interaction_method(self, kind, x): ''' Checks whether the error is an InteractionRequired error diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/tests/common.py py-macaroon-bakery-1.2.1/macaroonbakery/tests/common.py --- py-macaroon-bakery-1.1.3/macaroonbakery/tests/common.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/tests/common.py 2018-10-12 13:15:20.000000000 +0000 @@ -80,7 +80,7 @@ condition = cav_info.condition.decode('utf-8') if condition != self.str: raise bakery.ThirdPartyCaveatCheckFailed( - '{} doesn\'t match {}'.format(condition, self.str)) + '{} doesn\'t match {}'.format(repr(condition), repr(self.str))) return [] diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/tests/test_client.py py-macaroon-bakery-1.2.1/macaroonbakery/tests/test_client.py --- py-macaroon-bakery-1.1.3/macaroonbakery/tests/test_client.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/tests/test_client.py 2018-09-14 13:53:39.000000000 +0000 @@ -55,6 +55,133 @@ finally: httpd.shutdown() + def test_single_service_third_party(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': + 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): + 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', 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): + self.key = bakery.generate_key() + + def third_party_info(self, loc): + if loc == 'http://1.2.3.4': + return bakery.ThirdPartyInfo( + public_key=self.key.public_key, + version=bakery.VERSION_1, + ) + + d = _DischargerLocator() + b = new_bakery('loc', d, None) + + @urlmatch(path='.*/discharge') + def discharge(url, request): + 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', 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_cookie_domain_host_not_fqdn(self): + # See + # https://github.com/go-macaroon-bakery/py-macaroon-bakery/issues/53 + + b = new_bakery('loc', None, None) + + def handler(*args): + GetHandler(b, None, None, None, None, AGES, *args) + try: + httpd = HTTPServer(('', 0), handler) + thread = threading.Thread(target=httpd.serve_forever) + thread.start() + srv_macaroon = b.oven.macaroon( + version=bakery.LATEST_VERSION, expiry=AGES, + caveats=None, ops=[TEST_OP]) + self.assertEquals(srv_macaroon.macaroon.location, 'loc') + client = httpbakery.Client() + # Note: by using "localhost" instead of the presumably numeric address held + # in httpd.server_address, we're triggering the no-FQDN logic in the cookie + # code. + resp = requests.get( + url='http://localhost:' + str(httpd.server_address[1]), + cookies=client.cookies, auth=client.auth()) + resp.raise_for_status() + self.assertEquals(resp.text, 'done') + except httpbakery.BakeryException: + pass # interacion required exception is expected + finally: + httpd.shutdown() + + # the cookie has the .local domain appended + [cookie] = client.cookies + self.assertEqual(cookie.name, 'macaroon-test') + self.assertEqual(cookie.domain, 'localhost.local') + def test_single_party_with_header(self): b = new_bakery('loc', None, None) diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/tests/test_discharge.py py-macaroon-bakery-1.2.1/macaroonbakery/tests/test_discharge.py --- py-macaroon-bakery-1.1.3/macaroonbakery/tests/test_discharge.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/tests/test_discharge.py 2018-10-12 14:05:06.000000000 +0000 @@ -1,5 +1,6 @@ # Copyright 2017 Canonical Ltd. # Licensed under the LGPLv3, see LICENCE file for details. +import os import unittest import macaroonbakery.bakery as bakery @@ -153,7 +154,7 @@ bakery.LOGIN_OP ) self.fail('macaroon unmet should be raised') - except bakery.VerificationError: + except bakery.PermissionDenied: pass def test_macaroon_paper_fig6_fails_with_binding_on_tampered_sig(self): @@ -194,7 +195,7 @@ d[i + 1] = tampered_macaroon.prepare_for_request(dm) # client makes request to ts. - with self.assertRaises(bakery.VerificationError) as exc: + with self.assertRaises(bakery.PermissionDenied) as exc: ts.checker.auth([d]).allow(common.test_context, bakery.LOGIN_OP) self.assertEqual('verification failed: Signatures do not match', @@ -298,7 +299,7 @@ 'arble': 'b', }) - with self.assertRaises(bakery.AuthInitError) as exc: + with self.assertRaises(bakery.PermissionDenied) as exc: first_party.checker.auth([d]).allow(common.test_context, bakery.LOGIN_OP) self.assertEqual('cannot authorize login macaroon: caveat ' @@ -351,14 +352,14 @@ # Since no declarations are added by the discharger, class ThirdPartyCaveatCheckerF(bakery.ThirdPartyCaveatChecker): def check_third_party_caveat(self, ctx, cav_info): - if cav_info.condition == b'x': + if cav_info.condition == 'x': return [checkers.declared_caveat('foo', 'fooval1')] - if cav_info.condition == b'y': + if cav_info.condition == 'y': return [ checkers.declared_caveat('foo', 'fooval2'), checkers.declared_caveat('baz', 'bazval') ] - raise common.ThirdPartyCaveatCheckFailed('not matched') + raise bakery.ThirdPartyCaveatCheckFailed('not matched') def get_discharge(cav, payload): return bakery.discharge( @@ -377,7 +378,7 @@ 'bar': '', 'baz': 'bazval', }) - with self.assertRaises(bakery.AuthInitError) as exc: + with self.assertRaises(bakery.PermissionDenied) as exc: first_party.checker.auth([d]).allow(common.test_context, bakery.LOGIN_OP) self.assertEqual('cannot authorize login macaroon: caveat "declared ' @@ -416,7 +417,7 @@ self.assertIsNotNone(M.unbound) # Make sure it cannot be used as a normal macaroon in the third party. - with self.assertRaises(bakery.VerificationError) as exc: + with self.assertRaises(bakery.PermissionDenied) as exc: third_party.checker.auth([[M.unbound]]).allow( common.test_context, [bakery.LOGIN_OP]) self.assertEqual('no operations found in macaroon', @@ -448,7 +449,7 @@ location='as2-loc')] if self._loc == 'as2-loc': return [] - raise common.ThirdPartyCaveatCheckFailed( + raise bakery.ThirdPartyCaveatCheckFailed( 'unknown location {}'.format(self._loc)) def get_discharge(cav, payload): @@ -472,3 +473,45 @@ len(cav.caveat_id) > 3): self.fail('caveat id on caveat {} of macaroon {} ' 'is too big ({})'.format(j, i, cav.id)) + + def test_third_party_discharge_macaroon_wrong_root_key_and_third_party_caveat(self): + + root_keys = bakery.MemoryKeyStore() + ts = bakery.Bakery( + key=bakery.generate_key(), + checker=common.test_checker(), + root_key_store=root_keys, + identity_client=common.OneIdentity(), + ) + locator = bakery.ThirdPartyStore() + bs = common.new_bakery('bs-loc', locator) + + # ts creates a macaroon with a third party caveat addressed to bs. + ts_macaroon = ts.oven.macaroon(bakery.LATEST_VERSION, + common.ages, + None, [bakery.LOGIN_OP]) + ts_macaroon.add_caveat( + checkers.Caveat(location='bs-loc', condition='true'), + ts.oven.key, locator, + ) + + def get_discharge(cav, payload): + return bakery.discharge( + common.test_context, + cav.caveat_id_bytes, + payload, + bs.oven.key, + common.ThirdPartyStrcmpChecker('true'), + bs.oven.locator, + ) + + d = bakery.discharge_all(ts_macaroon, get_discharge) + + # The authorization should succeed at first. + ts.checker.auth([d]).allow(common.test_context, [bakery.LOGIN_OP]) + # Corrupt the root key and try again. + # We should get a DischargeRequiredError because the verification has failed. + root_keys._key = os.urandom(24) + with self.assertRaises(bakery.PermissionDenied) as err: + ts.checker.auth([d]).allow(common.test_context, [bakery.LOGIN_OP]) + self.assertEqual(str(err.exception), 'verification failed: Decryption failed. Ciphertext failed verification') diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/tests/test_httpbakery.py py-macaroon-bakery-1.2.1/macaroonbakery/tests/test_httpbakery.py --- py-macaroon-bakery-1.1.3/macaroonbakery/tests/test_httpbakery.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/tests/test_httpbakery.py 2018-10-15 08:01:33.000000000 +0000 @@ -1,6 +1,7 @@ from unittest import TestCase -from macaroonbakery.httpbakery import WebBrowserInteractionInfo +import macaroonbakery.httpbakery as httpbakery +import macaroonbakery.bakery as bakery class TestWebBrowserInteractionInfo(TestCase): @@ -9,8 +10,35 @@ info_dict = { 'VisitURL': 'https://example.com/visit', 'WaitTokenURL': 'https://example.com/wait'} - interaction_info = WebBrowserInteractionInfo.from_dict(info_dict) + interaction_info = httpbakery.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') + + +class TestError(TestCase): + + def test_from_dict_upper_case_fields(self): + err = httpbakery.Error.from_dict({ + 'Message': 'm', + 'Code': 'c', + }) + self.assertEqual(err, httpbakery.Error( + code='c', + message='m', + info=None, + version=bakery.LATEST_VERSION, + )) + + def test_from_dict_lower_case_fields(self): + err = httpbakery.Error.from_dict({ + 'message': 'm', + 'code': 'c', + }) + self.assertEqual(err, httpbakery.Error( + code='c', + message='m', + info=None, + version=bakery.LATEST_VERSION, + )) diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/tests/test_utils.py py-macaroon-bakery-1.2.1/macaroonbakery/tests/test_utils.py --- py-macaroon-bakery-1.1.3/macaroonbakery/tests/test_utils.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/tests/test_utils.py 2018-08-20 12:22:25.000000000 +0000 @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + # Copyright 2017 Canonical Ltd. # Licensed under the LGPLv3, see LICENCE file for details. @@ -26,6 +28,26 @@ ValueError, cookie, 'http://example.com', 'test', 'value', expires=timestamp) + def test_cookie_with_hostname_not_fqdn(self): + c = cookie('http://myhost', 'test', 'value') + self.assertEqual(c.domain, 'myhost.local') + + def test_cookie_with_hostname_ipv4(self): + c = cookie('http://1.2.3.4', 'test', 'value') + self.assertEqual(c.domain, '1.2.3.4') + + def test_cookie_with_hostname_ipv6(self): + c = cookie('http://[dead::beef]', 'test', 'value') + self.assertEqual(c.domain, 'dead::beef') + + def test_cookie_with_hostname_like_ipv4(self): + c = cookie('http://1.2.3.4.com', 'test', 'value') + self.assertEqual(c.domain, '1.2.3.4.com') + + def test_cookie_with_hostname_not_ascii(self): + c = cookie('http://κουλουράκι', 'test', 'value') + self.assertEqual(c.domain, 'κουλουράκι.local') + class TestB64Decode(TestCase): def test_decode(self): diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery/_utils/__init__.py py-macaroon-bakery-1.2.1/macaroonbakery/_utils/__init__.py --- py-macaroon-bakery-1.1.3/macaroonbakery/_utils/__init__.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery/_utils/__init__.py 2018-08-20 12:22:25.000000000 +0000 @@ -2,6 +2,7 @@ # Licensed under the LGPLv3, see LICENCE file for details. import base64 import binascii +import ipaddress import json import webbrowser from datetime import datetime @@ -134,7 +135,9 @@ it must be a naive timestamp in UTC. ''' u = urlparse(url) - domain = u.hostname or u.netloc + domain = u.hostname + if '.' not in domain and not _is_ip_addr(domain): + domain += ".local" port = str(u.port) if u.port is not None else None secure = u.scheme == 'https' if expires is not None: @@ -160,3 +163,18 @@ rest=None, rfc2109=False, ) + + +def _is_ip_addr(h): + if six.PY2: + # the python2.7 backport of ipaddr needs a bytestring passed in + try: + h = h.decode('ascii') + except UnicodeDecodeError: + # If there are non-ascii chars it's not an address anyway + return False + try: + ipaddress.ip_address(h) + except ValueError: + return False + return True diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/dependency_links.txt py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/dependency_links.txt --- py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/dependency_links.txt 1970-01-01 00:00:00.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/dependency_links.txt 2018-10-15 09:01:31.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/not-zip-safe py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/not-zip-safe --- py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/not-zip-safe 1970-01-01 00:00:00.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/not-zip-safe 2018-08-20 10:59:17.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/PKG-INFO py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/PKG-INFO --- py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/PKG-INFO 1970-01-01 00:00:00.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/PKG-INFO 2018-10-15 09:01:31.000000000 +0000 @@ -0,0 +1,55 @@ +Metadata-Version: 1.1 +Name: macaroonbakery +Version: 1.2.1 +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 + =============== + + A Python library for working with macaroons. + + + Installation + ------------ + The easiest way to install macaroonbakery is via pip:: + + $ pip install macaroonbakery + + macaroonbakery was developed around pymacaroons. On ubuntu, you + can get libsodium from a ppa:: + + $ sudo add-apt-repository ppa:yellow/ppa -y + $ apt-get install libsodium13 + + Usage + ----- + Interacting with a protected url, you can use the BakeryAuth provided to deal + with the macaroon bakery + + >>> from macaroonbakery import httpbakery + >>> jar = requests.cookies.RequestsCookieJar() + >>> resp = requests.get('some protected url', + cookies=jar, + auth=httpbakery.BakeryAuth(cookies=jar)) + >>> resp.raise_for_status() + + + You can use any cookie storage you'd like so next subsequent calls the macaroon + saved in the cookie jar will be directly used and will not require + any other authentication (for example, cookielib.FileCookieJar). + +Keywords: macaroon cookie +Platform: UNKNOWN +Classifier: Development Status :: 2 - Pre-Alpha +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3) +Classifier: Natural Language :: English +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/requires.txt py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/requires.txt --- py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/requires.txt 1970-01-01 00:00:00.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/requires.txt 2018-10-15 09:01:31.000000000 +0000 @@ -0,0 +1,7 @@ +requests<3.0,>=2.18.1 +PyNaCl<2.0,>=1.1.2 +pymacaroons<1.0,>=0.12.0 +six<2.0,>=1.11.0 +protobuf<4.0,>=3.0.0 +pyRFC3339<2.0,>=1.0 +ipaddress diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/SOURCES.txt py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/SOURCES.txt --- py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/SOURCES.txt 1970-01-01 00:00:00.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/SOURCES.txt 2018-10-15 09:01:31.000000000 +0000 @@ -0,0 +1,77 @@ +AUTHORS.rst +CONTRIBUTING.rst +LICENSE +MANIFEST.in +README.rst +setup.cfg +setup.py +docs/Makefile +docs/authors.rst +docs/contributing.rst +docs/index.rst +docs/installation.rst +docs/packaging.rst +docs/readme.rst +docs/usage.rst +macaroonbakery/__init__.py +macaroonbakery.egg-info/PKG-INFO +macaroonbakery.egg-info/SOURCES.txt +macaroonbakery.egg-info/dependency_links.txt +macaroonbakery.egg-info/not-zip-safe +macaroonbakery.egg-info/requires.txt +macaroonbakery.egg-info/top_level.txt +macaroonbakery/_utils/__init__.py +macaroonbakery/bakery/__init__.py +macaroonbakery/bakery/_authorizer.py +macaroonbakery/bakery/_bakery.py +macaroonbakery/bakery/_checker.py +macaroonbakery/bakery/_codec.py +macaroonbakery/bakery/_discharge.py +macaroonbakery/bakery/_error.py +macaroonbakery/bakery/_identity.py +macaroonbakery/bakery/_keys.py +macaroonbakery/bakery/_macaroon.py +macaroonbakery/bakery/_oven.py +macaroonbakery/bakery/_store.py +macaroonbakery/bakery/_third_party.py +macaroonbakery/bakery/_versions.py +macaroonbakery/bakery/_internal/__init__.py +macaroonbakery/bakery/_internal/id_pb2.py +macaroonbakery/checkers/__init__.py +macaroonbakery/checkers/_auth_context.py +macaroonbakery/checkers/_caveat.py +macaroonbakery/checkers/_checkers.py +macaroonbakery/checkers/_conditions.py +macaroonbakery/checkers/_declared.py +macaroonbakery/checkers/_namespace.py +macaroonbakery/checkers/_operation.py +macaroonbakery/checkers/_time.py +macaroonbakery/checkers/_utils.py +macaroonbakery/httpbakery/__init__.py +macaroonbakery/httpbakery/_browser.py +macaroonbakery/httpbakery/_client.py +macaroonbakery/httpbakery/_discharge.py +macaroonbakery/httpbakery/_error.py +macaroonbakery/httpbakery/_interactor.py +macaroonbakery/httpbakery/_keyring.py +macaroonbakery/httpbakery/agent/__init__.py +macaroonbakery/httpbakery/agent/_agent.py +macaroonbakery/tests/__init__.py +macaroonbakery/tests/common.py +macaroonbakery/tests/test_agent.py +macaroonbakery/tests/test_authorizer.py +macaroonbakery/tests/test_bakery.py +macaroonbakery/tests/test_checker.py +macaroonbakery/tests/test_checkers.py +macaroonbakery/tests/test_client.py +macaroonbakery/tests/test_codec.py +macaroonbakery/tests/test_discharge.py +macaroonbakery/tests/test_discharge_all.py +macaroonbakery/tests/test_httpbakery.py +macaroonbakery/tests/test_keyring.py +macaroonbakery/tests/test_macaroon.py +macaroonbakery/tests/test_namespace.py +macaroonbakery/tests/test_oven.py +macaroonbakery/tests/test_store.py +macaroonbakery/tests/test_time.py +macaroonbakery/tests/test_utils.py \ No newline at end of file diff -Nru py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/top_level.txt py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/top_level.txt --- py-macaroon-bakery-1.1.3/macaroonbakery.egg-info/top_level.txt 1970-01-01 00:00:00.000000000 +0000 +++ py-macaroon-bakery-1.2.1/macaroonbakery.egg-info/top_level.txt 2018-10-15 09:01:31.000000000 +0000 @@ -0,0 +1 @@ +macaroonbakery diff -Nru py-macaroon-bakery-1.1.3/Makefile py-macaroon-bakery-1.2.1/Makefile --- py-macaroon-bakery-1.1.3/Makefile 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -# Copyright 2017 Canonical Ltd. -# Licensed under the LGPLv3, see LICENCE file for details. -include sysdeps.mk - -PYTHON = python -# Since the python-tox package in Ubuntu uses Python 3, use pip to install tox -# instead. This also works on OSX where tox is not present in Homebrew. -PIP_SYSDEPS = tox - -PIP = sudo pip install $(1) - -SYSDEPS_INSTALLED = .sysdeps-installed -DEVENV = devenv -DEVENVPIP = $(DEVENV)/bin/pip - -.DEFAULT_GOAL := setup - -$(DEVENVPIP): - @tox -e devenv - -$(SYSDEPS_INSTALLED): sysdeps.mk -ifeq ($(shell command -v apt-get > /dev/null; echo $$?),0) - sudo apt-get install --yes $(APT_SYSDEPS) -else - @echo 'System dependencies can only be installed automatically on' - @echo 'systems with "apt-get". On OSX you can manually use Homebrew' - @echo 'if there are missing dependencies corresponding to the following' - @echo 'Debian packages:' - @echo '$(APT_SYSDEPS).' -endif - sudo pip2 install $(PIP_SYSDEPS) - touch $(SYSDEPS_INSTALLED) - - -.PHONY: check -check: setup lint - @tox - -.PHONY: clean -clean: - $(PYTHON) setup.py clean - # Remove the development environments. - rm -rfv $(DEVENV) .tox/ - # Remove distribution artifacts. - rm -rfv *.egg build/ dist/ macaroonbakery.egg-info MANIFEST - # Remove tests artifacts. - rm -fv .coverage - # Remove the canary file. - rm -fv $(SYSDEPS_INSTALLED) - # Remove Python compiled bytecode. - find . -name '*.pyc' -delete - find . -name '__pycache__' -type d -delete - -.PHONY: docs -docs: setup - @tox -e docs - -.PHONY: help -help: - @echo -e 'Macaroon Bakery - list of make targets:\n' - @echo 'make - Set up the development and testing environment.' - @echo 'make test - Run tests.' - @echo 'make lint - Run linter and pep8.' - @echo 'make check - Run all the tests and lint in all supported scenarios.' - @echo 'make source - Create source package.' - @echo 'make clean - Get rid of bytecode files, build and dist dirs, venvs.' - @echo 'make release - Register and upload a release on PyPI.' - @echo -e '\nAfter creating the development environment with "make", it is' - @echo 'also possible to do the following:' - @echo '- run a specific subset of the test suite, e.g. with' - @echo ' "$(DEVENV)/bin/nosetests bakery/tests/...";' - @echo '- use tox as usual on this project;' - @echo ' see https://tox.readthedocs.org/en/latest/' - - -.PHONY: lint -lint: setup - @tox -e lint - -.PHONY: release -release: check - $(PYTHON) setup.py register sdist upload - -.PHONY: setup -setup: $(SYSDEPS_INSTALLED) $(DEVENVPIP) setup.py - -.PHONY: source -source: - $(PYTHON) setup.py sdist - -.PHONY: sysdeps -sysdeps: $(SYSDEPS_INSTALLED) - -.PHONY: test -test: setup - @$(DEVENV)/bin/nosetests \ - --verbosity 2 --with-coverage --cover-erase \ - --cover-package macaroonbakery - -.PHONY: isort -isort: - isort \ - --trailing-comma \ - --recursive \ - --multi-line 3 \ - `find macaroonbakery -name '*.py' | grep -v 'internal/id_pb2\.py'` diff -Nru py-macaroon-bakery-1.1.3/PKG-INFO py-macaroon-bakery-1.2.1/PKG-INFO --- py-macaroon-bakery-1.1.3/PKG-INFO 1970-01-01 00:00:00.000000000 +0000 +++ py-macaroon-bakery-1.2.1/PKG-INFO 2018-10-15 09:01:32.000000000 +0000 @@ -0,0 +1,55 @@ +Metadata-Version: 1.1 +Name: macaroonbakery +Version: 1.2.1 +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 + =============== + + A Python library for working with macaroons. + + + Installation + ------------ + The easiest way to install macaroonbakery is via pip:: + + $ pip install macaroonbakery + + macaroonbakery was developed around pymacaroons. On ubuntu, you + can get libsodium from a ppa:: + + $ sudo add-apt-repository ppa:yellow/ppa -y + $ apt-get install libsodium13 + + Usage + ----- + Interacting with a protected url, you can use the BakeryAuth provided to deal + with the macaroon bakery + + >>> from macaroonbakery import httpbakery + >>> jar = requests.cookies.RequestsCookieJar() + >>> resp = requests.get('some protected url', + cookies=jar, + auth=httpbakery.BakeryAuth(cookies=jar)) + >>> resp.raise_for_status() + + + You can use any cookie storage you'd like so next subsequent calls the macaroon + saved in the cookie jar will be directly used and will not require + any other authentication (for example, cookielib.FileCookieJar). + +Keywords: macaroon cookie +Platform: UNKNOWN +Classifier: Development Status :: 2 - Pre-Alpha +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3) +Classifier: Natural Language :: English +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 diff -Nru py-macaroon-bakery-1.1.3/requirements.txt py-macaroon-bakery-1.2.1/requirements.txt --- py-macaroon-bakery-1.1.3/requirements.txt 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/requirements.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -# Copyright 2017 Canonical Ltd. -# Licensed under the LGPLv3, see LICENCE file for details. - -requests>=2.18.4,<3.0 -PyNaCl>=1.1.2,<2.0 -pymacaroons>=0.12.0,<1.0 -six>=1.11.0,<2.0 -protobuf>=3.4.0,<4.0 -pyRFC3339>=1.0,<2.0 diff -Nru py-macaroon-bakery-1.1.3/setup.cfg py-macaroon-bakery-1.2.1/setup.cfg --- py-macaroon-bakery-1.1.3/setup.cfg 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/setup.cfg 2018-10-15 09:01:32.000000000 +0000 @@ -1,2 +1,7 @@ [wheel] universal = 1 + +[egg_info] +tag_build = +tag_date = 0 + diff -Nru py-macaroon-bakery-1.1.3/setup.py py-macaroon-bakery-1.2.1/setup.py --- py-macaroon-bakery-1.1.3/setup.py 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/setup.py 2018-10-15 08:54:36.000000000 +0000 @@ -2,6 +2,7 @@ # Copyright 2017 Canonical Ltd. # Licensed under the LGPLv3, see LICENCE file for details. +import sys import platform from setuptools import ( @@ -12,7 +13,8 @@ PROJECT_NAME = 'macaroonbakery' -VERSION = (1, 1, 3) +# version 1.2.1 +VERSION = (1, 2, 1) def get_version(): @@ -47,6 +49,9 @@ 'ndg_httpsclient==0.3.3', ]) +if sys.version_info.major == 2: + requirements.append('ipaddress') + setup( name=PROJECT_NAME, diff -Nru py-macaroon-bakery-1.1.3/sysdeps.mk py-macaroon-bakery-1.2.1/sysdeps.mk --- py-macaroon-bakery-1.1.3/sysdeps.mk 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/sysdeps.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -APT_SYSDEPS = python-dev python-pip python-setuptools libsodium-dev python-dev libffi-dev libssl-dev diff -Nru py-macaroon-bakery-1.1.3/test-requirements.txt py-macaroon-bakery-1.2.1/test-requirements.txt --- py-macaroon-bakery-1.1.3/test-requirements.txt 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/test-requirements.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -# Copyright 2017 Canonical Ltd. -# Licensed under the LGPLv3, see LICENCE file for details. - -coverage==3.7.1 -flake8==2.4.0 -mock==1.0.1 -nose==1.3.6 -httmock==1.2.5 diff -Nru py-macaroon-bakery-1.1.3/tox.ini py-macaroon-bakery-1.2.1/tox.ini --- py-macaroon-bakery-1.1.3/tox.ini 2018-02-28 09:26:40.000000000 +0000 +++ py-macaroon-bakery-1.2.1/tox.ini 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -# Copyright 2017 Canonical Ltd. -# Licensed under the LGPLv3, see LICENCE file for details. - -[tox] -envlist = lint, py27, py35, docs -# envlist = py27 - -[testenv] -setenv = - PYTHONPATH = {toxinidir}:{toxinidir}/macaroonbakery -# drop into debugger with: nosetests --pdb -# coverage with --with-coverage --cover-inclusive --cover-html -commands = - nosetests -deps = - -r{toxinidir}/test-requirements.txt - -[testenv:devenv] -envdir = devenv -usedevelop = True -commands = - -[testenv:lint] -usedevelop = True -commands = flake8 --ignore E501 --show-source macaroonbakery --exclude macaroonbakery/bakery/_internal/id_pb2.py - -[testenv:docs] -changedir = docs -deps = sphinx -commands = sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html