def test_verify_third_party_caveats(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier)

        discharge = Macaroon(
            location='http://auth.mybank/',
            key=caveat_key,
            identifier=identifier
        )
        discharge.add_first_party_caveat('time < 2015-01-01T00:00')
        protected = m.prepare_for_request(discharge)

        v = Verifier()
        v.satisfy_exact('account = 3735928559')
        v.satisfy_exact('time < 2015-01-01T00:00')
        verified = v.verify(
            m,
            'this is a different super-secret key; \
never use the same secret twice',
            discharge_macaroons=[protected]
        )
        assert_true(verified)
    def test_prepare_for_request(self, rand_nonce):
        # use a fixed nonce to ensure the same signature
        rand_nonce.return_value = truncate_or_pad(
            b'\0',
            size=crypto_box_NONCEBYTES
        )
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat(
            'http://auth.mybank/',
            caveat_key,
            identifier
        )

        discharge = Macaroon(
            location='http://auth.mybank/',
            key=caveat_key,
            identifier=identifier
        )
        discharge.add_first_party_caveat('time < 2015-01-01T00:00')
        protected = m.prepare_for_request(discharge)
        assert_equal(
            protected.signature,
            '2eb01d0dd2b4475330739140188648cf25dda0425ea9f661f1574ca0a9eac54e'
        )
示例#3
0
    def test_verify_third_party_caveats_multi_level(self):
        # See https://github.com/ecordell/pymacaroons/issues/37
        root = Macaroon(location="", identifier="root-id", key="root-key")
        root.add_third_party_caveat("bob", "bob-caveat-root-key",
                                    "bob-is-great")

        # Create a discharge macaroon that requires a secondary discharge.
        discharge1 = Macaroon(location="bob",
                              identifier="bob-is-great",
                              key="bob-caveat-root-key")
        discharge1.add_third_party_caveat("barbara", "barbara-caveat-root-key",
                                          "barbara-is-great")

        # Create the secondary discharge macaroon.
        discharge2 = Macaroon(location="barbara",
                              identifier="barbara-is-great",
                              key="barbara-caveat-root-key")

        # Prepare the discharge macaroons for request.
        discharge1 = root.prepare_for_request(discharge1)
        discharge2 = root.prepare_for_request(discharge2)

        verified = Verifier(
            discharge_macaroons=[discharge1, discharge2]).verify(
                root, "root-key")
        assert_true(verified)
示例#4
0
    def test_verify_third_party_caveats(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier)

        discharge = Macaroon(
            location='http://auth.mybank/',
            key=caveat_key,
            identifier=identifier
        )
        discharge.add_first_party_caveat('time < 2015-01-01T00:00')
        protected = m.prepare_for_request(discharge)

        v = Verifier()
        v.satisfy_exact('account = 3735928559')
        v.satisfy_exact('time < 2015-01-01T00:00')
        verified = v.verify(
            m,
            'this is a different super-secret key; \
never use the same secret twice',
            discharge_macaroons=[protected]
        )
        assert_true(verified)
示例#5
0
 def test_mutual_discharge(self):
     m1 = Macaroon(location="", identifier="root-id", key="root-key")
     m1.add_third_party_caveat("bob", "bob-caveat-root-key", "bob-is-great")
     m2 = Macaroon(location="bob", identifier="bob-is-great", key="bob-caveat-root-key")
     m2.add_third_party_caveat("charlie", "bob-caveat-root-key", "bob-is-great")
     m2 = m1.prepare_for_request(m2)
     Verifier(discharge_macaroons=[m2]).verify(m1, "root-key")
示例#6
0
    def test_prepare_for_request(self, rand_nonce):
        # use a fixed nonce to ensure the same signature
        rand_nonce.return_value = truncate_or_pad(
            b'\0',
            size=crypto_box_NONCEBYTES
        )
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat(
            'http://auth.mybank/',
            caveat_key,
            identifier
        )

        discharge = Macaroon(
            location='http://auth.mybank/',
            key=caveat_key,
            identifier=identifier
        )
        discharge.add_first_party_caveat('time < 2015-01-01T00:00')
        protected = m.prepare_for_request(discharge)
        assert_equal(
            protected.signature,
            '2eb01d0dd2b4475330739140188648cf25dda0425ea9f661f1574ca0a9eac54e'
        )
    def generate_macaroon(self, nonce):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat(
            'http://auth.mybank/',
            caveat_key,
            identifier,
            nonce=nonce,
        )

        discharge = Macaroon(
            location='http://auth.mybank/',
            key=caveat_key,
            identifier=identifier
        )
        discharge.add_first_party_caveat('time < 2015-01-01T00:00')
        protected = m.prepare_for_request(discharge)
        return protected.signature
示例#8
0
 def test_logging(self):
     r = Request()
     root_key = hashlib.sha256("root").hexdigest()
     root_macaroon = Macaroon(key=root_key)
     discharge_key = hashlib.sha256("discharge").hexdigest()
     discharge_caveat_id = '{"secret": "thing"}'
     root_macaroon.add_third_party_caveat(
         "sso.example", discharge_key, discharge_caveat_id)
     root_macaroon.add_first_party_caveat(
         "store.example|package_id|{}".format(
             json.dumps(["example-package"])))
     unbound_discharge_macaroon = Macaroon(
         location="sso.example", key=discharge_key,
         identifier=discharge_caveat_id)
     unbound_discharge_macaroon.add_first_party_caveat(
         "sso.example|account|{}".format(
             base64.b64encode(json.dumps({
                 "openid": "1234567",
                 "email": "*****@*****.**",
                 }))))
     logger = BufferLogger()
     MacaroonAuth(
         root_macaroon.serialize(),
         unbound_discharge_macaroon.serialize(), logger=logger)(r)
     self.assertEqual(
         ['DEBUG root macaroon: snap-ids: ["example-package"]',
          'DEBUG discharge macaroon: OpenID identifier: 1234567'],
         logger.getLogBuffer().splitlines())
示例#9
0
 def test_mutual_discharge(self):
     m1 = Macaroon(location="", identifier="root-id", key="root-key")
     m1.add_third_party_caveat("bob", "bob-caveat-root-key", "bob-is-great")
     m2 = Macaroon(location="bob",
                   identifier="bob-is-great",
                   key="bob-caveat-root-key")
     m2.add_third_party_caveat("charlie", "bob-caveat-root-key",
                               "bob-is-great")
     m2 = m1.prepare_for_request(m2)
     Verifier(discharge_macaroons=[m2]).verify(m1, "root-key")
示例#10
0
    def test_serializing_macaroon_with_first_and_third_caveats(self):
        m = Macaroon(location='http://mybank/',
                     identifier='we used our other secret key',
                     key='this is a different super-secret key; \
never use the same secret twice')
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier)

        n = Macaroon.deserialize(m.serialize())

        assert_equal(m.signature, n.signature)
示例#11
0
    def test_third_party_caveat(self, rand_nonce):
        # use a fixed nonce to ensure the same signature
        rand_nonce.return_value = truncate_or_pad(b'\0',
                                                  size=crypto_box_NONCEBYTES)
        m = Macaroon(location='http://mybank/',
                     identifier='we used our other secret key',
                     key='this is a different super-secret key; \
never use the same secret twice')
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier)
        assert_equal(
            m.signature,
            'd27db2fd1f22760e4c3dae8137e2d8fc1df6c0741c18aed4b97256bf78d1f55c')
示例#12
0
    def test_third_party_caveat(self):
        m = Macaroon(location='http://mybank/',
                     identifier='we used our other secret key',
                     key='this is a different super-secret key; \
never use the same secret twice')
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat('http://auth.mybank/',
                                 caveat_key,
                                 identifier,
                                 nonce=ZERO_NONCE)
        assert_equal(
            m.signature,
            'd27db2fd1f22760e4c3dae8137e2d8fc1df6c0741c18aed4b97256bf78d1f55c')
示例#13
0
 def _make_store_secrets(self):
     self.root_key = hashlib.sha256(
         self.factory.getUniqueString()).hexdigest()
     root_macaroon = Macaroon(key=self.root_key)
     self.discharge_key = hashlib.sha256(
         self.factory.getUniqueString()).hexdigest()
     self.discharge_caveat_id = self.factory.getUniqueString()
     root_macaroon.add_third_party_caveat(
         "sso.example", self.discharge_key, self.discharge_caveat_id)
     unbound_discharge_macaroon = Macaroon(
         location="sso.example", key=self.discharge_key,
         identifier=self.discharge_caveat_id)
     return {
         "root": root_macaroon.serialize(),
         "discharge": unbound_discharge_macaroon.serialize(),
         }
示例#14
0
    def test_verify_third_party_caveats_multi_level(self):
      # See https://github.com/ecordell/pymacaroons/issues/37
      root = Macaroon(location="", identifier="root-id", key="root-key")
      root.add_third_party_caveat("bob", "bob-caveat-root-key", "bob-is-great")

      # Create a discharge macaroon that requires a secondary discharge.
      discharge1 = Macaroon(location="bob", identifier="bob-is-great", key="bob-caveat-root-key")
      discharge1.add_third_party_caveat("barbara", "barbara-caveat-root-key", "barbara-is-great")

      # Create the secondary discharge macaroon.
      discharge2 = Macaroon(location="barbara", identifier="barbara-is-great", key="barbara-caveat-root-key")

      # Prepare the discharge macaroons for request.
      discharge1 = root.prepare_for_request(discharge1)
      discharge2 = root.prepare_for_request(discharge2)

      verified = Verifier(discharge_macaroons=[discharge1, discharge2]).verify(root, "root-key")
      assert_true(verified)
示例#15
0
    def test_login_handler_redirect(self):
        m = Macaroon()
        m.add_third_party_caveat("login.ubuntu.com", "key", "id")

        serialized_macaroon = m.serialize()

        responses.add(
            responses.Response(
                method="POST",
                url=self.api_url,
                json={"macaroon": serialized_macaroon},
                status=200,
            ))

        response = self.client.get(self.endpoint_url)

        assert len(responses.calls) == 1
        assert response.status_code == 302
示例#16
0
    def test_serializing_macaroon_with_first_and_third_caveats(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier)

        n = Macaroon.deserialize(m.serialize())

        assert_equal(
            m.signature,
            n.signature
        )
示例#17
0
 def test_good(self):
     r = Request()
     root_key = hashlib.sha256("root").hexdigest()
     root_macaroon = Macaroon(key=root_key)
     discharge_key = hashlib.sha256("discharge").hexdigest()
     discharge_caveat_id = '{"secret": "thing"}'
     root_macaroon.add_third_party_caveat(
         "sso.example", discharge_key, discharge_caveat_id)
     unbound_discharge_macaroon = Macaroon(
         location="sso.example", key=discharge_key,
         identifier=discharge_caveat_id)
     MacaroonAuth(
         root_macaroon.serialize(),
         unbound_discharge_macaroon.serialize())(r)
     auth_value = r.headers["Authorization"]
     self.assertThat(auth_value, StartsWith("Macaroon "))
     self.assertThat(
         parse_dict_header(auth_value[len("Macaroon "):]),
         MacaroonsVerify(root_key))
def alice_server_get_macaroon():
    m = Macaroon(location='alices-server.example.com',
                 identifier='key-for-bob',
                 key=alice_server_keys['key-for-bob'])
    # should be random
    caveat_key = 'randomKey'
    predicate = 'Bob'
    identifier = auth_server_get_identifier(caveat_key, predicate)
    # location is unused
    m.add_third_party_caveat('http://auth-server.example.com/', caveat_key,
                             identifier)
    serialized = m.serialize()
    resp = make_response(
        render_template("auth_demo.html",
                        macaroon=m.inspect().replace("\n", "<br/>"),
                        caveat_key=caveat_key,
                        identifier=identifier))
    resp.set_cookie('macaroonCookie', serialized)
    return resp
    def test_login_handler_redirect(self):
        m = Macaroon()
        m.add_third_party_caveat("login.ubuntu.com", "key", "id")

        serialized_macaroon = m.serialize()

        responses.add(
            responses.Response(
                method="POST",
                url=self.api_url,
                json={"macaroon": serialized_macaroon},
                status=200,
            )
        )

        response = self.client.get(self.endpoint_url)

        assert len(responses.calls) == 1
        assert response.status_code == 302
示例#20
0
    def test_third_party_caveat(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat(
            'http://auth.mybank/',
            caveat_key,
            identifier,
            nonce=ZERO_NONCE)
        assert_equal(
            m.signature,
            'd27db2fd1f22760e4c3dae8137e2d8fc1df6c0741c18aed4b97256bf78d1f55c'
        )
    def test_third_party_caveat(self, rand_nonce):
        # use a fixed nonce to ensure the same signature
        rand_nonce.return_value = truncate_or_pad(
            b'\0',
            size=crypto_box_NONCEBYTES
        )
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier)
        assert_equal(
            m.signature,
            'd27db2fd1f22760e4c3dae8137e2d8fc1df6c0741c18aed4b97256bf78d1f55c'
        )
示例#22
0
 def test_inspect(self):
     m = Macaroon(
         location='http://mybank/',
         identifier='we used our secret key',
         key='this is our super secret key; only we should know it')
     m.add_first_party_caveat('test = caveat')
     caveat_key = '4; guaranteed random by a fair toss of the dice'
     identifier = 'this was how we remind auth of key/pred'
     m.add_third_party_caveat('http://auth.mybank/',
                              caveat_key,
                              identifier,
                              nonce=ZERO_NONCE)
     assert_equal(m.inspect(), (
         'location http://mybank/\n'
         'identifier we used our secret key\n'
         'cid test = caveat\n'
         'cid this was how we remind auth of key/pred\n'
         'vid AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA68NYajhiFuHnKGSNcVhkAwgbs0VZ0yK2o+q0Aq9+bONkXw7ky7HAuhCLO9hhaMMc\n'
         'cl http://auth.mybank/\n'
         'signature 7a9289bfbb92d725f748bbcb4f3e04e56b7021513ebeed8411bfba10a16a662e'
     ))
示例#23
0
    def generate_macaroon(self, nonce):
        m = Macaroon(location='http://mybank/',
                     identifier='we used our other secret key',
                     key='this is a different super-secret key; \
never use the same secret twice')
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat(
            'http://auth.mybank/',
            caveat_key,
            identifier,
            nonce=nonce,
        )

        discharge = Macaroon(location='http://auth.mybank/',
                             key=caveat_key,
                             identifier=identifier)
        discharge.add_first_party_caveat('time < 2015-01-01T00:00')
        protected = m.prepare_for_request(discharge)
        return protected.signature
示例#24
0
 def test_inspect(self):
     m = Macaroon(
         location='http://mybank/',
         identifier='we used our secret key',
         key='this is our super secret key; only we should know it'
     )
     m.add_first_party_caveat('test = caveat')
     caveat_key = '4; guaranteed random by a fair toss of the dice'
     identifier = 'this was how we remind auth of key/pred'
     m.add_third_party_caveat(
         'http://auth.mybank/',
         caveat_key,
         identifier,
         nonce=ZERO_NONCE
     )
     assert_equal(m.inspect(), (
         'location http://mybank/\n'
         'identifier we used our secret key\n'
         'cid test = caveat\n'
         'cid this was how we remind auth of key/pred\n'
         'vid AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA68NYajhiFuHnKGSNcVhkAwgbs0VZ0yK2o+q0Aq9+bONkXw7ky7HAuhCLO9hhaMMc\n'
         'cl http://auth.mybank/\n'
         'signature 7a9289bfbb92d725f748bbcb4f3e04e56b7021513ebeed8411bfba10a16a662e'))
 def test_infer_declared(self):
     tests = [
         ('no macaroons', [], {}, None),
         ('single macaroon with one declaration', [
             [checkers.Caveat(condition='declared foo bar')]
         ], {'foo': 'bar'}, None),
         ('only one argument to declared', [
             [checkers.Caveat(condition='declared foo')]
         ], {}, None),
         ('spaces in value', [
             [checkers.Caveat(condition='declared foo bar bloggs')]
         ], {'foo': 'bar bloggs'}, None),
         ('attribute with declared prefix', [
             [checkers.Caveat(condition='declaredccf foo')]
         ], {}, None),
         ('several macaroons with different declares', [
             [
                 checkers.declared_caveat('a', 'aval'),
                 checkers.declared_caveat('b', 'bval')
             ], [
                 checkers.declared_caveat('c', 'cval'),
                 checkers.declared_caveat('d', 'dval')
             ]
         ], {'a': 'aval', 'b': 'bval', 'c': 'cval', 'd': 'dval'}, None),
         ('duplicate values', [
             [
                 checkers.declared_caveat('a', 'aval'),
                 checkers.declared_caveat('a', 'aval'),
                 checkers.declared_caveat('b', 'bval')
             ], [
                 checkers.declared_caveat('a', 'aval'),
                 checkers.declared_caveat('b', 'bval'),
                 checkers.declared_caveat('c', 'cval'),
                 checkers.declared_caveat('d', 'dval')
             ]
         ], {'a': 'aval', 'b': 'bval', 'c': 'cval', 'd': 'dval'}, None),
         ('conflicting values', [
             [
                 checkers.declared_caveat('a', 'aval'),
                 checkers.declared_caveat('a', 'conflict'),
                 checkers.declared_caveat('b', 'bval')
             ], [
                 checkers.declared_caveat('a', 'conflict'),
                 checkers.declared_caveat('b', 'another conflict'),
                 checkers.declared_caveat('c', 'cval'),
                 checkers.declared_caveat('d', 'dval')
             ]
         ], {'c': 'cval', 'd': 'dval'}, None),
         ('third party caveats ignored', [
             [checkers.Caveat(condition='declared a no conflict',
                              location='location')],
             [checkers.declared_caveat('a', 'aval')]
         ], {'a': 'aval'}, None),
         ('unparseable caveats ignored', [
             [checkers.Caveat(condition=' bad')],
             [checkers.declared_caveat('a', 'aval')]
         ], {'a': 'aval'}, None),
         ('infer with namespace', [
             [
                 checkers.declared_caveat('a', 'aval'),
                 caveat_with_ns(checkers.declared_caveat('a', 'aval'),
                                'testns'),
             ]
         ], {'a': 'aval'}, None),
     ]
     for test in tests:
         uri_to_prefix = test[3]
         if uri_to_prefix is None:
             uri_to_prefix = {checkers.STD_NAMESPACE: ''}
         ns = checkers.Namespace(uri_to_prefix)
         print(test[0])
         ms = []
         for i, caveats in enumerate(test[1]):
             m = Macaroon(key=None, identifier=six.int2byte(i), location='',
                          version=MACAROON_V2)
             for cav in caveats:
                 cav = ns.resolve_caveat(cav)
                 if cav.location == '':
                     m.add_first_party_caveat(cav.condition)
                 else:
                     m.add_third_party_caveat(cav.location, None,
                                              cav.condition)
             ms.append(m)
         self.assertEqual(checkers.infer_declared(ms), test[2])
示例#26
0
 def test_infer_declared(self):
     tests = [
         ('no macaroons', [], {}, None),
         ('single macaroon with one declaration',
          [[checkers.Caveat(condition='declared foo bar')]], {
              'foo': 'bar'
          }, None),
         ('only one argument to declared',
          [[checkers.Caveat(condition='declared foo')]], {}, None),
         ('spaces in value',
          [[checkers.Caveat(condition='declared foo bar bloggs')]], {
              'foo': 'bar bloggs'
          }, None),
         ('attribute with declared prefix',
          [[checkers.Caveat(condition='declaredccf foo')]], {}, None),
         ('several macaroons with different declares',
          [[
              checkers.declared_caveat('a', 'aval'),
              checkers.declared_caveat('b', 'bval')
          ],
           [
               checkers.declared_caveat('c', 'cval'),
               checkers.declared_caveat('d', 'dval')
           ]], {
               'a': 'aval',
               'b': 'bval',
               'c': 'cval',
               'd': 'dval'
           }, None),
         ('duplicate values', [[
             checkers.declared_caveat('a', 'aval'),
             checkers.declared_caveat('a', 'aval'),
             checkers.declared_caveat('b', 'bval')
         ],
                               [
                                   checkers.declared_caveat('a', 'aval'),
                                   checkers.declared_caveat('b', 'bval'),
                                   checkers.declared_caveat('c', 'cval'),
                                   checkers.declared_caveat('d', 'dval')
                               ]], {
                                   'a': 'aval',
                                   'b': 'bval',
                                   'c': 'cval',
                                   'd': 'dval'
                               }, None),
         ('conflicting values',
          [[
              checkers.declared_caveat('a', 'aval'),
              checkers.declared_caveat('a', 'conflict'),
              checkers.declared_caveat('b', 'bval')
          ],
           [
               checkers.declared_caveat('a', 'conflict'),
               checkers.declared_caveat('b', 'another conflict'),
               checkers.declared_caveat('c', 'cval'),
               checkers.declared_caveat('d', 'dval')
           ]], {
               'c': 'cval',
               'd': 'dval'
           }, None),
         ('third party caveats ignored', [[
             checkers.Caveat(condition='declared a no conflict',
                             location='location')
         ], [checkers.declared_caveat('a', 'aval')]], {
             'a': 'aval'
         }, None),
         ('unparseable caveats ignored',
          [[checkers.Caveat(condition=' bad')],
           [checkers.declared_caveat('a', 'aval')]], {
               'a': 'aval'
           }, None),
         ('infer with namespace', [[
             checkers.declared_caveat('a', 'aval'),
             caveat_with_ns(checkers.declared_caveat('a', 'aval'),
                            'testns'),
         ]], {
             'a': 'aval'
         }, None),
     ]
     for test in tests:
         uri_to_prefix = test[3]
         if uri_to_prefix is None:
             uri_to_prefix = {checkers.STD_NAMESPACE: ''}
         ns = checkers.Namespace(uri_to_prefix)
         print(test[0])
         ms = []
         for i, caveats in enumerate(test[1]):
             m = Macaroon(key=None,
                          identifier=six.int2byte(i),
                          location='',
                          version=MACAROON_V2)
             for cav in caveats:
                 cav = ns.resolve_caveat(cav)
                 if cav.location == '':
                     m.add_first_party_caveat(cav.condition)
                 else:
                     m.add_third_party_caveat(cav.location, None,
                                              cav.condition)
             ms.append(m)
         self.assertEqual(checkers.infer_declared(ms), test[2])