summaryrefslogtreecommitdiff
path: root/macaroonbakery/macaroon.py
diff options
context:
space:
mode:
Diffstat (limited to 'macaroonbakery/macaroon.py')
-rw-r--r--macaroonbakery/macaroon.py81
1 files changed, 47 insertions, 34 deletions
diff --git a/macaroonbakery/macaroon.py b/macaroonbakery/macaroon.py
index 6f6039e..b745282 100644
--- a/macaroonbakery/macaroon.py
+++ b/macaroonbakery/macaroon.py
@@ -9,7 +9,7 @@ import os
import pymacaroons
from pymacaroons.serializers import json_serializer
-import macaroonbakery
+import macaroonbakery as bakery
import macaroonbakery.checkers as checkers
from macaroonbakery import utils
@@ -24,7 +24,7 @@ class Macaroon(object):
'''
def __init__(self, root_key, id, location=None,
- version=macaroonbakery.LATEST_BAKERY_VERSION, namespace=None):
+ version=bakery.LATEST_VERSION, namespace=None):
'''Creates a new macaroon with the given root key, id and location.
If the version is more than the latest known version,
@@ -36,11 +36,11 @@ class Macaroon(object):
@param version the bakery version.
@param namespace is that of the service creating it
'''
- if version > macaroonbakery.LATEST_BAKERY_VERSION:
+ if version > bakery.LATEST_VERSION:
log.info('use last known version:{} instead of: {}'.format(
- macaroonbakery.LATEST_BAKERY_VERSION, version
+ bakery.LATEST_VERSION, version
))
- version = macaroonbakery.LATEST_BAKERY_VERSION
+ version = bakery.LATEST_VERSION
# m holds the underlying macaroon.
self._macaroon = pymacaroons.Macaroon(
location=location, key=root_key, identifier=id,
@@ -115,12 +115,14 @@ class Macaroon(object):
# Use the least supported version to encode the caveat.
if self._version < info.version:
- info = macaroonbakery.ThirdPartyInfo(version=self._version,
- public_key=info.public_key)
+ info = bakery.ThirdPartyInfo(
+ version=self._version,
+ public_key=info.public_key,
+ )
- caveat_info = macaroonbakery.encode_caveat(
+ caveat_info = bakery.encode_caveat(
cav.condition, root_key, info, key, self._namespace)
- if info.version < macaroonbakery.BAKERY_V3:
+ if info.version < bakery.VERSION_3:
# We're encoding for an earlier client or third party which does
# not understand bundled caveat info, so use the encoded
# caveat information as the caveat id.
@@ -155,7 +157,7 @@ class Macaroon(object):
'''Return a dict representation of the macaroon data in JSON format.
@return a dict
'''
- if self.version < macaroonbakery.BAKERY_V3:
+ if self.version < bakery.VERSION_3:
if len(self._caveat_data) > 0:
raise ValueError('cannot serialize pre-version3 macaroon with '
'external caveat data')
@@ -178,37 +180,40 @@ class Macaroon(object):
return serialized
@classmethod
- def deserialize_json(cls, serialized_json):
- serialized = json.loads(serialized_json)
- json_macaroon = serialized.get('m')
+ def from_dict(cls, json_dict):
+ '''Return a macaroon obtained from the given dictionary as
+ deserialized from JSON.
+ @param json_dict The deserialized JSON object.
+ '''
+ json_macaroon = json_dict.get('m')
if json_macaroon is None:
- # Try the v1 format if we don't have a macaroon filed
+ # Try the v1 format if we don't have a macaroon field.
m = pymacaroons.Macaroon.deserialize(
- serialized_json, json_serializer.JsonSerializer())
+ json.dumps(json_dict), json_serializer.JsonSerializer())
macaroon = Macaroon(root_key=None, id=None,
- namespace=macaroonbakery.legacy_namespace(),
+ namespace=bakery.legacy_namespace(),
version=_bakery_version(m.version))
macaroon._macaroon = m
return macaroon
- version = serialized.get('v', None)
+ version = json_dict.get('v', None)
if version is None:
raise ValueError('no version specified')
- if (version < macaroonbakery.BAKERY_V3 or
- version > macaroonbakery.LATEST_BAKERY_VERSION):
- raise ValueError('unknow bakery version {}'.format(version))
+ if (version < bakery.VERSION_3 or
+ version > bakery.LATEST_VERSION):
+ raise ValueError('unknown bakery version {}'.format(version))
m = pymacaroons.Macaroon.deserialize(json.dumps(json_macaroon),
json_serializer.JsonSerializer())
if m.version != macaroon_version(version):
raise ValueError(
'underlying macaroon has inconsistent version; '
'got {} want {}'.format(m.version, macaroon_version(version)))
- namespace = checkers.deserialize_namespace(serialized.get('ns'))
- cdata = serialized.get('cdata', {})
+ namespace = checkers.deserialize_namespace(json_dict.get('ns'))
+ cdata = json_dict.get('cdata', {})
caveat_data = {}
for id64 in cdata:
- id = utils.raw_b64decode(id64)
- data = utils.raw_b64decode(cdata[id64])
+ id = utils.b64decode(id64)
+ data = utils.b64decode(cdata[id64])
caveat_data[id] = data
macaroon = Macaroon(root_key=None, id=None,
namespace=namespace,
@@ -217,6 +222,15 @@ class Macaroon(object):
macaroon._macaroon = m
return macaroon
+ @classmethod
+ def deserialize_json(cls, serialized_json):
+ '''Return a macaroon deserialized from a string
+ @param serialized_json The string to decode {str}
+ @return {Macaroon}
+ '''
+ serialized = json.loads(serialized_json)
+ return Macaroon.from_dict(serialized)
+
def _new_caveat_id(self, base):
'''Return a third party caveat id
@@ -237,7 +251,7 @@ class Macaroon(object):
# payload, having this version gives a strong indication
# that the payload has been omitted so we can produce
# a better error for the user.
- id.append(macaroonbakery.BAKERY_V3)
+ id.append(bakery.VERSION_3)
# Iterate through integers looking for one that isn't already used,
# starting from n so that if everyone is using this same algorithm,
@@ -251,7 +265,7 @@ class Macaroon(object):
# end up with a duplicate third party caveat id and thus create
# a macaroon that cannot be discharged.
temp = id[:]
- macaroonbakery.encode_uvarint(i, temp)
+ bakery.encode_uvarint(i, temp)
found = False
for cav in caveats:
if (cav.verification_key_id is not None
@@ -296,7 +310,7 @@ def macaroon_version(bakery_version):
@param bakery_version the bakery version
@return macaroon_version the derived macaroon version
'''
- if bakery_version in [macaroonbakery.BAKERY_V0, macaroonbakery.BAKERY_V1]:
+ if bakery_version in [bakery.VERSION_0, bakery.VERSION_1]:
return pymacaroons.MACAROON_V1
return pymacaroons.MACAROON_V2
@@ -326,7 +340,7 @@ class ThirdPartyStore(ThirdPartyLocator):
def third_party_info(self, loc):
info = self._store.get(loc.rstrip('/'))
if info is None:
- raise macaroonbakery.ThirdPartyInfoNotFound(
+ raise bakery.ThirdPartyInfoNotFound(
'cannot retrieve the info for location {}'.format(loc))
return info
@@ -355,7 +369,7 @@ def _parse_local_location(loc):
'''
if not (loc.startswith('local ')):
return None
- v = macaroonbakery.BAKERY_V1
+ v = bakery.VERSION_1
fields = loc.split()
fields = fields[1:] # Skip 'local'
if len(fields) == 2:
@@ -365,9 +379,8 @@ def _parse_local_location(loc):
return None
fields = fields[1:]
if len(fields) == 1:
- key = macaroonbakery.PublicKey.deserialize(fields[0])
- return macaroonbakery.ThirdPartyInfo(public_key=key,
- version=v)
+ key = bakery.PublicKey.deserialize(fields[0])
+ return bakery.ThirdPartyInfo(public_key=key, version=v)
return None
@@ -381,11 +394,11 @@ def _bakery_version(v):
if v == pymacaroons.MACAROON_V1:
# Use version 1 because we don't know of any existing
# version 0 clients.
- return macaroonbakery.BAKERY_V1
+ return bakery.VERSION_1
elif v == pymacaroons.MACAROON_V2:
# Note that this could also correspond to Version 3, but
# this logic is explicitly for legacy versions.
- return macaroonbakery.BAKERY_V2
+ return bakery.VERSION_2
else:
raise ValueError('unknown macaroon version when deserializing legacy '
'bakery macaroon; got {}'.format(v))