Esempio n. 1
0
    def handle_error(self, error, url):
        '''Try to resolve the given error, which should be a response
        to the given URL, by discharging any macaroon contained in
        it. That is, if error.code is ERR_DISCHARGE_REQUIRED
        then it will try to discharge err.info.macaroon. If the discharge
        succeeds, the discharged macaroon will be saved to the client's cookie
        jar, otherwise an exception will be raised.
        '''
        if error.info is None or error.info.macaroon is None:
            raise BakeryException('unable to read info in discharge error '
                                  'response')

        discharges = bakery.discharge_all(
            error.info.macaroon,
            self.acquire_discharge,
            self.key,
        )
        macaroons = '[' + ','.join(
            map(utils.macaroon_to_json_string, discharges)) + ']'
        all_macaroons = base64.urlsafe_b64encode(utils.to_bytes(macaroons))

        full_path = relative_url(url, error.info.macaroon_path)
        if error.info.cookie_name_suffix is not None:
            name = 'macaroon-' + error.info.cookie_name_suffix
        else:
            name = 'macaroon-auth'
        expires = checkers.macaroons_expiry_time(checkers.Namespace(),
                                                 discharges)
        self.cookies.set_cookie(
            utils.cookie(
                name=name,
                value=all_macaroons.decode('ascii'),
                url=full_path,
                expires=expires,
            ))
    def handle_error(self, error, url):
        '''Try to resolve the given error, which should be a response
        to the given URL, by discharging any macaroon contained in
        it. That is, if error.code is ERR_DISCHARGE_REQUIRED
        then it will try to discharge err.info.macaroon. If the discharge
        succeeds, the discharged macaroon will be saved to the client's cookie
        jar, otherwise an exception will be raised.
        '''
        if error.info is None or error.info.macaroon is None:
            raise BakeryException('unable to read info in discharge error '
                                  'response')

        discharges = bakery.discharge_all(
            error.info.macaroon,
            self.acquire_discharge,
            self.key,
        )
        macaroons = '[' + ','.join(map(utils.macaroon_to_json_string,
                                       discharges)) + ']'
        all_macaroons = base64.urlsafe_b64encode(utils.to_bytes(macaroons))

        full_path = urljoin(url, error.info.macaroon_path)
        if error.info.cookie_name_suffix is not None:
            name = 'macaroon-' + error.info.cookie_name_suffix
        else:
            name = 'macaroon-auth'
        expires = checkers.macaroons_expiry_time(checkers.Namespace(), discharges)
        self.cookies.set_cookie(utils.cookie(
            name=name,
            value=all_macaroons.decode('ascii'),
            url=full_path,
            expires=expires,
        ))
Esempio n. 3
0
 def test_macaroons_expire_time(self):
     ExpireTest = namedtuple('ExpireTest', 'about macaroons expectTime')
     tests = [
         ExpireTest(
             about='no macaroons',
             macaroons=[newMacaroon()],
             expectTime=None,
         ),
         ExpireTest(
             about='single macaroon without caveats',
             macaroons=[newMacaroon()],
             expectTime=None,
         ),
         ExpireTest(
             about='multiple macaroon without caveats',
             macaroons=[newMacaroon()],
             expectTime=None,
         ),
         ExpireTest(
             about='single macaroon with time-before caveat',
             macaroons=[
                 newMacaroon([checkers.time_before_caveat(t1).condition]),
             ],
             expectTime=t1,
         ),
         ExpireTest(
             about='single macaroon with multiple time-before caveats',
             macaroons=[
                 newMacaroon([
                     checkers.time_before_caveat(t2).condition,
                     checkers.time_before_caveat(t1).condition,
                 ]),
             ],
             expectTime=t1,
         ),
         ExpireTest(
             about='multiple macaroons with multiple time-before caveats',
             macaroons=[
                 newMacaroon([
                     checkers.time_before_caveat(t3).condition,
                     checkers.time_before_caveat(t1).condition,
                 ]),
                 newMacaroon([
                     checkers.time_before_caveat(t3).condition,
                     checkers.time_before_caveat(t1).condition,
                 ]),
             ],
             expectTime=t1,
         ),
     ]
     for test in tests:
         print('test ', test.about)
         t = checkers.macaroons_expiry_time(checkers.Namespace(),
                                            test.macaroons)
         self.assertEqual(t, test.expectTime)
 def test_macaroons_expire_time(self):
     ExpireTest = namedtuple('ExpireTest', 'about macaroons expectTime')
     tests = [
         ExpireTest(
             about='no macaroons',
             macaroons=[newMacaroon()],
             expectTime=None,
         ),
         ExpireTest(
             about='single macaroon without caveats',
             macaroons=[newMacaroon()],
             expectTime=None,
         ),
         ExpireTest(
             about='multiple macaroon without caveats',
             macaroons=[newMacaroon()],
             expectTime=None,
         ),
         ExpireTest(
             about='single macaroon with time-before caveat',
             macaroons=[
                 newMacaroon([checkers.time_before_caveat(t1).condition]),
             ],
             expectTime=t1,
         ),
         ExpireTest(
             about='single macaroon with multiple time-before caveats',
             macaroons=[
                 newMacaroon([
                     checkers.time_before_caveat(t2).condition,
                     checkers.time_before_caveat(t1).condition,
                 ]),
             ],
             expectTime=t1,
         ),
         ExpireTest(
             about='multiple macaroons with multiple time-before caveats',
             macaroons=[
                 newMacaroon([
                     checkers.time_before_caveat(t3).condition,
                     checkers.time_before_caveat(t1).condition,
                 ]),
                 newMacaroon([
                     checkers.time_before_caveat(t3).condition,
                     checkers.time_before_caveat(t1).condition,
                 ]),
             ],
             expectTime=t1,
         ),
     ]
     for test in tests:
         print('test ', test.about)
         t = checkers.macaroons_expiry_time(checkers.Namespace(),
                                            test.macaroons)
         self.assertEqual(t, test.expectTime)
Esempio n. 5
0
    def test_expiry_cookie_is_set(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()
                }
            }

        ages = datetime.datetime.utcnow() + datetime.timedelta(days=1)

        def handler(*args):
            GetHandler(b, 'http://1.2.3.4', None, None, None, ages, *args)
        try:
            httpd = HTTPServer(('', 0), handler)
            thread = threading.Thread(target=httpd.serve_forever)
            thread.start()
            client = httpbakery.Client()
            with HTTMock(discharge):
                resp = requests.get(
                    url='http://' + httpd.server_address[0] + ':' +
                        str(httpd.server_address[1]),
                    cookies=client.cookies,
                    auth=client.auth())
            resp.raise_for_status()
            m = bakery.Macaroon.from_dict(json.loads(
                base64.b64decode(client.cookies.get('macaroon-test')).decode('utf-8'))[0])
            t = checkers.macaroons_expiry_time(
                checkers.Namespace(), [m.macaroon])
            self.assertEquals(ages, t)
            self.assertEquals(resp.text, 'done')
        finally:
            httpd.shutdown()
    def test_expiry_cookie_is_set(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()
                }
            }

        ages = datetime.datetime.utcnow() + datetime.timedelta(days=1)

        def handler(*args):
            GetHandler(b, 'http://1.2.3.4', None, None, None, ages, *args)
        try:
            httpd = HTTPServer(('', 0), handler)
            thread = threading.Thread(target=httpd.serve_forever)
            thread.start()
            client = httpbakery.Client()
            with HTTMock(discharge):
                resp = requests.get(
                    url='http://' + httpd.server_address[0] + ':' +
                        str(httpd.server_address[1]),
                    cookies=client.cookies,
                    auth=client.auth())
            resp.raise_for_status()
            m = bakery.Macaroon.from_dict(json.loads(
                base64.b64decode(client.cookies.get('macaroon-test')).decode('utf-8'))[0])
            t = checkers.macaroons_expiry_time(
                checkers.Namespace(), [m.macaroon])
            self.assertEquals(ages, t)
            self.assertEquals(resp.text, 'done')
        finally:
            httpd.shutdown()
Esempio n. 7
0
 def test_macaroons_expire_time_skips_third_party(self):
     m1 = newMacaroon([checkers.time_before_caveat(t1).condition])
     m2 = newMacaroon()
     m2.add_third_party_caveat('https://example.com', 'a-key', '123')
     t = checkers.macaroons_expiry_time(checkers.Namespace(), [m1, m2])
     self.assertEqual(t1, t)
 def test_macaroons_expire_time_skips_third_party(self):
     m1 = newMacaroon([checkers.time_before_caveat(t1).condition])
     m2 = newMacaroon()
     m2.add_third_party_caveat('https://example.com', 'a-key', '123')
     t = checkers.macaroons_expiry_time(checkers.Namespace(), [m1, m2])
     self.assertEqual(t1, t)