Example #1
0
    def test_add_third_party_caveat(self):
        locator = bakery.ThirdPartyStore()
        bs = common.new_bakery('bs-loc', locator)

        lbv = six.int2byte(bakery.LATEST_VERSION)
        tests = [
            ('no existing id', b'', [], lbv + six.int2byte(0)),
            ('several existing ids', b'', [
                lbv + six.int2byte(0),
                lbv + six.int2byte(1),
                lbv + six.int2byte(2)
            ], lbv + six.int2byte(3)),
            ('with base id', lbv + six.int2byte(0), [lbv + six.int2byte(0)],
             lbv + six.int2byte(0) + six.int2byte(0)),
            ('with base id and existing id', lbv + six.int2byte(0), [
                lbv + six.int2byte(0) + six.int2byte(0)
            ], lbv + six.int2byte(0) + six.int2byte(1))
        ]

        for test in tests:
            print('test ', test[0])
            m = bakery.Macaroon(
                root_key=b'root key', id=b'id',
                location='location',
                version=bakery.LATEST_VERSION)
            for id in test[2]:
                m.macaroon.add_third_party_caveat(key=None, key_id=id,
                                                  location='')
                m._caveat_id_prefix = test[1]
            m.add_caveat(checkers.Caveat(location='bs-loc',
                                         condition='something'),
                         bs.oven.key, locator)
            self.assertEqual(m.macaroon.caveats[len(test[2])].caveat_id,
                             test[3])
Example #2
0
    def test_marshal_json_latest_version(self):
        locator = bakery.ThirdPartyStore()
        bs = common.new_bakery('bs-loc', locator)
        ns = checkers.Namespace({
            'testns': 'x',
            'otherns': 'y',
        })
        m = bakery.Macaroon(
            root_key=b'root key', id=b'id',
            location='location',
            version=bakery.LATEST_VERSION,
            namespace=ns)
        m.add_caveat(checkers.Caveat(location='bs-loc', condition='something'),
                     bs.oven.key, locator)
        data = m.serialize_json()
        m1 = bakery.Macaroon.deserialize_json(data)
        # Just check the signature and version - we're not interested in fully
        # checking the macaroon marshaling here.
        self.assertEqual(m1.macaroon.signature, m.macaroon.signature)
        self.assertEqual(m1.macaroon.version, m.macaroon.version)
        self.assertEqual(len(m1.macaroon.caveats), 1)
        self.assertEqual(m1.namespace, m.namespace)
        self.assertEqual(m1._caveat_data, m._caveat_data)

        # test with the encoder, decoder
        data = json.dumps(m, cls=bakery.MacaroonJSONEncoder)
        m1 = json.loads(data, cls=bakery.MacaroonJSONDecoder)
        self.assertEqual(m1.macaroon.signature, m.macaroon.signature)
        self.assertEqual(m1.macaroon.version, m.macaroon.version)
        self.assertEqual(len(m1.macaroon.caveats), 1)
        self.assertEqual(m1.namespace, m.namespace)
        self.assertEqual(m1._caveat_data, m._caveat_data)
Example #3
0
 def test_add_first_party_caveat(self):
     m = bakery.Macaroon('rootkey', 'some id', 'here',
                         bakery.LATEST_VERSION)
     m.add_caveat(checkers.Caveat('test_condition'))
     caveats = m.first_party_caveats()
     self.assertEquals(len(caveats), 1)
     self.assertEquals(caveats[0].caveat_id, b'test_condition')
Example #4
0
    def _test_json_with_version(self, version):
        locator = bakery.ThirdPartyStore()
        bs = common.new_bakery('bs-loc', locator)

        ns = checkers.Namespace({
            'testns': 'x',
        })

        m = bakery.Macaroon(
            root_key=b'root key', id=b'id',
            location='location', version=version,
            namespace=ns)
        m.add_caveat(checkers.Caveat(location='bs-loc', condition='something'),
                     bs.oven.key, locator)

        # Sanity check that no external caveat data has been added.
        self.assertEqual(len(m._caveat_data), 0)

        data = json.dumps(m, cls=bakery.MacaroonJSONEncoder)
        m1 = json.loads(data, cls=bakery.MacaroonJSONDecoder)

        # Just check the signature and version - we're not interested in fully
        # checking the macaroon marshaling here.
        self.assertEqual(m1.macaroon.signature, m.macaroon.signature)
        self.assertEqual(m1.macaroon.version,
                         bakery.macaroon_version(version))
        self.assertEqual(len(m1.macaroon.caveats), 1)

        # Namespace information has been thrown away.
        self.assertEqual(m1.namespace, bakery.legacy_namespace())

        self.assertEqual(len(m1._caveat_data), 0)
        def get_discharge(cav, payload):
            self.assertEqual(payload, None)
            m = bakery.Macaroon(
                root_key='root key {}'.format(
                    cav.caveat_id.decode('utf-8')).encode('utf-8'),
                id=cav.caveat_id, location='',
                version=bakery.LATEST_VERSION)

            add_caveats(m)
            return m
Example #6
0
 def test_new_macaroon(self):
     m = bakery.Macaroon(
         b'rootkey',
         b'some id',
         'here',
         bakery.LATEST_VERSION)
     self.assertIsNotNone(m)
     self.assertEquals(m._macaroon.identifier, b'some id')
     self.assertEquals(m._macaroon.location, 'here')
     self.assertEquals(m.version, bakery.LATEST_VERSION)
 def discharge(url, request):
     wrong_macaroon = bakery.Macaroon(root_key=b'some key',
                                      id=b'xxx',
                                      location='some other location',
                                      version=bakery.VERSION_0)
     return {
         'status_code': 200,
         'content': {
             'Macaroon': wrong_macaroon.to_dict()
         }
     }
Example #8
0
 def new_macaroon(self, caveats, namespace, ops):
     root_key, id = self._root_key_store.root_key()
     m_id = {'id': base64.urlsafe_b64encode(id).decode('utf-8'), 'ops': ops}
     data = json.dumps(m_id)
     m = bakery.Macaroon(root_key=root_key,
                         id=data,
                         location='',
                         version=bakery.LATEST_VERSION,
                         namespace=namespace)
     m.add_caveats(caveats, self._key, self._locator)
     return m
 def test_discharge_all_no_discharges(self):
     root_key = b'root key'
     m = bakery.Macaroon(
         root_key=root_key, id=b'id0', location='loc0',
         version=bakery.LATEST_VERSION,
         namespace=common.test_checker().namespace())
     ms = bakery.discharge_all(m, no_discharge(self))
     self.assertEqual(len(ms), 1)
     self.assertEqual(ms[0], m.macaroon)
     v = Verifier()
     v.satisfy_general(always_ok)
     v.verify(m.macaroon, root_key, None)
Example #10
0
 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/")
Example #11
0
    def test_json_deserialize_from_go(self):
        ns = checkers.Namespace()
        ns.register("someuri", "x")
        m = bakery.Macaroon(
            root_key=b'rootkey', id=b'some id', location='here',
            version=bakery.LATEST_VERSION, namespace=ns)
        m.add_caveat(checkers.Caveat(condition='something',
                                     namespace='someuri'))
        data = '{"m":{"c":[{"i":"x:something"}],"l":"here","i":"some id",' \
               '"s64":"c8edRIupArSrY-WZfa62pgZFD8VjDgqho9U2PlADe-E"},"v":3,' \
               '"ns":"someuri:x"}'
        m_go = bakery.Macaroon.deserialize_json(data)

        self.assertEqual(m.macaroon.signature_bytes,
                         m_go.macaroon.signature_bytes)
        self.assertEqual(m.macaroon.version, m_go.macaroon.version)
        self.assertEqual(len(m_go.macaroon.caveats), 1)
        self.assertEqual(m.namespace, m_go.namespace)
    def test_discharge_all_many_discharges(self):
        root_key = b'root key'
        m0 = bakery.Macaroon(
            root_key=root_key, id=b'id0', location='loc0',
            version=bakery.LATEST_VERSION)

        class State(object):
            total_required = 40
            id = 1

        def add_caveats(m):
            for i in range(0, 1):
                if State.total_required == 0:
                    break
                cid = 'id{}'.format(State.id)
                m.macaroon.add_third_party_caveat(
                    location='somewhere',
                    key='root key {}'.format(cid).encode('utf-8'),
                    key_id=cid.encode('utf-8'))
                State.id += 1
                State.total_required -= 1

        add_caveats(m0)

        def get_discharge(cav, payload):
            self.assertEqual(payload, None)
            m = bakery.Macaroon(
                root_key='root key {}'.format(
                    cav.caveat_id.decode('utf-8')).encode('utf-8'),
                id=cav.caveat_id, location='',
                version=bakery.LATEST_VERSION)

            add_caveats(m)
            return m

        ms = bakery.discharge_all(m0, get_discharge)

        self.assertEqual(len(ms), 41)

        v = Verifier()
        v.satisfy_general(always_ok)
        v.verify(ms[0], root_key, ms[1:])
Example #13
0
 def test_clone(self):
     locator = bakery.ThirdPartyStore()
     bs = common.new_bakery("bs-loc", locator)
     ns = checkers.Namespace({
         "testns": "x",
     })
     m = bakery.Macaroon(
         root_key=b'root key', id=b'id',
         location='location',
         version=bakery.LATEST_VERSION,
         namespace=ns)
     m.add_caveat(checkers.Caveat(location='bs-loc', condition='something'),
                  bs.oven.key, locator)
     m1 = m.copy()
     self.assertEqual(len(m.macaroon.caveats), 1)
     self.assertEqual(len(m1.macaroon.caveats), 1)
     self.assertEqual(m._caveat_data, m1._caveat_data)
     m.add_caveat(checkers.Caveat(location='bs-loc', condition='something'),
                  bs.oven.key, locator)
     self.assertEqual(len(m.macaroon.caveats), 2)
     self.assertEqual(len(m1.macaroon.caveats), 1)
     self.assertNotEqual(m._caveat_data, m1._caveat_data)
    def test_discharge_all_many_discharges_with_real_third_party_caveats(self):
        # This is the same flow as TestDischargeAllManyDischarges except that
        # we're using actual third party caveats as added by
        # Macaroon.add_caveat and we use a larger number of caveats
        # so that caveat ids will need to get larger.
        locator = bakery.ThirdPartyStore()
        bakeries = {}
        total_discharges_required = 40

        class M:
            bakery_id = 0
            still_required = total_discharges_required

        def add_bakery():
            M.bakery_id += 1
            loc = 'loc{}'.format(M.bakery_id)
            bakeries[loc] = common.new_bakery(loc, locator)
            return loc

        ts = common.new_bakery('ts-loc', locator)

        def checker(_, ci):
            caveats = []
            if ci.condition != 'something':
                self.fail('unexpected condition')
            for i in range(0, 2):
                if M.still_required <= 0:
                    break
                caveats.append(checkers.Caveat(location=add_bakery(),
                                               condition='something'))
                M.still_required -= 1
            return caveats

        root_key = b'root key'
        m0 = bakery.Macaroon(
            root_key=root_key, id=b'id0', location='ts-loc',
            version=bakery.LATEST_VERSION)

        m0.add_caveat(checkers. Caveat(location=add_bakery(),
                                       condition='something'),
                      ts.oven.key, locator)

        # We've added a caveat (the first) so one less caveat is required.
        M.still_required -= 1

        class ThirdPartyCaveatCheckerF(bakery.ThirdPartyCaveatChecker):
            def check_third_party_caveat(self, ctx, info):
                return checker(ctx, info)

        def get_discharge(cav, payload):
            return bakery.discharge(
                common.test_context, cav.caveat_id, payload,
                bakeries[cav.location].oven.key,
                ThirdPartyCaveatCheckerF(), locator)

        ms = bakery.discharge_all(m0, get_discharge)

        self.assertEqual(len(ms), total_discharges_required + 1)

        v = Verifier()
        v.satisfy_general(always_ok)
        v.verify(ms[0], root_key, ms[1:])