def test_fallback(self):
        key = macaroonbakery.generate_key()

        @urlmatch(path='.*/discharge/info')
        def discharge_info(url, request):
            return {
                'status_code': 404,
            }

        @urlmatch(path='.*/publickey')
        def public_key(url, request):
            return {
                'status_code': 200,
                'content': {
                    'PublicKey': key.public_key.encode().decode('utf-8')
                }
            }

        expectInfo = macaroonbakery.ThirdPartyInfo(
            public_key=key.public_key, version=macaroonbakery.BAKERY_V1)
        kr = httpbakery.ThirdPartyLocator(allow_insecure=True)
        with HTTMock(discharge_info):
            with HTTMock(public_key):
                info = kr.third_party_info('http://0.1.2.3/')
        self.assertEqual(info, expectInfo)
Exemplo n.º 2
0
 def _setup_bakery(self, auth_endpoint, request):
     return bakery.Bakery(
         key=_get_macaroon_oven_key(),
         root_key_store=KeyStore(MACAROON_LIFESPAN),
         location=request.build_absolute_uri('/'),
         locator=httpbakery.ThirdPartyLocator(
             allow_insecure=not auth_endpoint.startswith('https:')),
         identity_client=IDClient(auth_endpoint),
         authorizer=bakery.ACLAuthorizer(
             get_acl=lambda ctx, op: [bakery.EVERYONE]))
Exemplo n.º 3
0
def _get_bakery(request):
    auth_endpoint = request.external_auth_info.url
    auth_domain = request.external_auth_info.domain
    return bakery.Bakery(
        key=_get_macaroon_oven_key(),
        root_key_store=KeyStore(MACAROON_LIFESPAN),
        location=request.build_absolute_uri("/"),
        locator=httpbakery.ThirdPartyLocator(
            allow_insecure=not auth_endpoint.startswith("https:")),
        identity_client=_IDClient(auth_endpoint, auth_domain=auth_domain),
        authorizer=bakery.ACLAuthorizer(
            get_acl=lambda ctx, op: [bakery.EVERYONE]),
    )
Exemplo n.º 4
0
    def is_authorized(*args, **kwargs):
        macaroon_bakery = bakery.Bakery(
            location="ubuntu.com/security",
            locator=httpbakery.ThirdPartyLocator(),
            identity_client=IdentityClient(),
            key=bakery.generate_key(),
            root_key_store=bakery.MemoryKeyStore(
                flask.current_app.config["SECRET_KEY"]),
        )
        macaroons = httpbakery.extract_macaroons(flask.request.headers)
        auth_checker = macaroon_bakery.checker.auth(macaroons)
        launchpad = Launchpad.login_anonymously("ubuntu.com/security",
                                                "production",
                                                version="devel")

        try:
            auth_info = auth_checker.allow(checkers.AuthContext(),
                                           [bakery.LOGIN_OP])
        except bakery._error.DischargeRequiredError:
            macaroon = macaroon_bakery.oven.macaroon(
                version=bakery.VERSION_2,
                expiry=datetime.utcnow() + timedelta(days=1),
                caveats=IDENTITY_CAVEATS,
                ops=[bakery.LOGIN_OP],
            )

            content, headers = httpbakery.discharge_required_response(
                macaroon, "/", "cookie-suffix")
            return content, 401, headers

        username = auth_info.identity.username()
        lp_user = launchpad.people(username)
        authorized = False

        for team in AUTHORIZED_TEAMS:
            if lp_user in launchpad.people(team).members:
                authorized = True
                break

        if not authorized:
            return (
                f"{username} is not in any of the authorized teams: "
                f"{str(AUTHORIZED_TEAMS)}",
                401,
            )

        # Validate authentication token
        return func(*args, **kwargs)
Exemplo n.º 5
0
    def __init__(self, locator=None):
        locator = httpbakery.ThirdPartyLocator()

        # generate a new keypair for encrypting third party caveats
        # it's safe to use a new keypair every time the server starts
        # as it's used only for encrypting the third party caveats
        # for sending them to be discharged. The private key doesn't need
        # to survive across restarts.
        key = bakery.generate_key()

        location = 'localhost:8000'
        root_key = 'private-key'

        self._bakery = bakery.Bakery(
            location=location, locator=locator,
            identity_client=IdentityClient(), key=key,
            root_key_store=bakery.MemoryKeyStore(root_key))
Exemplo n.º 6
0
    def test_cache_fetch_no_version(self):
        key = bakery.generate_key()

        @urlmatch(path='.*/discharge/info')
        def discharge_info(url, request):
            return {
                'status_code': 200,
                'content': {
                    'PublicKey': str(key.public_key),
                }
            }

        expectInfo = bakery.ThirdPartyInfo(public_key=key.public_key,
                                           version=bakery.VERSION_1)
        kr = httpbakery.ThirdPartyLocator(allow_insecure=True)
        with HTTMock(discharge_info):
            info = kr.third_party_info('http://0.1.2.3/')
        self.assertEqual(info, expectInfo)
 def test_allow_insecure(self):
     kr = httpbakery.ThirdPartyLocator()
     with self.assertRaises(macaroonbakery.error.ThirdPartyInfoNotFound):
         kr.third_party_info('http://0.1.2.3/')