def test_authorization_denied(self): locator = _DischargerLocator() ids = _IdService('ids', locator, self) auth = bakery.ClosedAuthorizer() ts = _Service('myservice', auth, ids, locator) client = _Client(locator) ctx = test_context.with_value(_DISCHARGE_USER_KEY, 'bob') with self.assertRaises(bakery.PermissionDenied): client.do(ctx, ts, [bakery.Op(entity='something', action='read')])
def test_login_only(self): locator = _DischargerLocator() ids = _IdService('ids', locator, self) auth = macaroonbakery.ClosedAuthorizer() ts = _Service('myservice', auth, ids, locator) ctx = test_context.with_value(_DISCHARGE_USER_KEY, 'bob') auth_info = _Client(locator).do(ctx, ts, [macaroonbakery.LOGIN_OP]) self.assertIsNotNone(auth_info) self.assertEqual(auth_info.identity.id(), 'bob')
def test_auth_login_op_with_identity_from_context(self): locator = _DischargerLocator() ids = _BasicAuthIdService() ts = _Service('myservice', bakery.ClosedAuthorizer(), ids, locator) # Check that we can use LoginOp # when auth isn't granted through macaroons. ctx = _context_with_basic_auth(test_context, 'sherlock', 'holmes') auth_info = _Client(locator).do(ctx, ts, [bakery.LOGIN_OP]) self.assertEqual(auth_info.identity.id(), 'sherlock') self.assertEqual(len(auth_info.macaroons), 0)
def test_duplicate_login_macaroons(self): locator = _DischargerLocator() ids = _IdService('ids', locator, self) auth = macaroonbakery.ClosedAuthorizer() ts = _Service('myservice', auth, ids, locator) # Acquire a login macaroon for bob. client1 = _Client(locator) ctx = test_context.with_value(_DISCHARGE_USER_KEY, 'bob') auth_info = client1.do(ctx, ts, [macaroonbakery.LOGIN_OP]) self.assertEqual(auth_info.identity.id(), 'bob') # Acquire a login macaroon for alice. client2 = _Client(locator) ctx = test_context.with_value(_DISCHARGE_USER_KEY, 'alice') auth_info = client2.do(ctx, ts, [macaroonbakery.LOGIN_OP]) self.assertEqual(auth_info.identity.id(), 'alice') # Combine the two login macaroons into one client. client3 = _Client(locator) client3.add_macaroon(ts, '1.bob', client1._macaroons[ts.name()]['authn']) client3.add_macaroon(ts, '2.alice', client2._macaroons[ts.name()]['authn']) # We should authenticate as bob (because macaroons are presented # ordered by "cookie" name) auth_info = client3.do(test_context, ts, [macaroonbakery.LOGIN_OP]) self.assertEqual(auth_info.identity.id(), 'bob') self.assertEqual(len(auth_info.macaroons), 1) # Try them the other way around and we should authenticate as alice. client3 = _Client(locator) client3.add_macaroon(ts, '1.alice', client2._macaroons[ts.name()]['authn']) client3.add_macaroon(ts, '2.bob', client1._macaroons[ts.name()]['authn']) auth_info = client3.do(test_context, ts, [macaroonbakery.LOGIN_OP]) self.assertEqual(auth_info.identity.id(), 'alice') self.assertEqual(len(auth_info.macaroons), 1)
def __init__(self, checker=checkers.Checker(), authorizer=macaroonbakery.ClosedAuthorizer(), identity_client=None, macaroon_opstore=None): ''' :param checker: a first party checker implementing a :param authorizer (Authorizer): used to check whether an authenticated user is allowed to perform operations. The identity parameter passed to authorizer.allow will always have been obtained from a call to identity_client.declared_identity. :param identity_client (IdentityClient) used for interactions with the external identity service used for authentication. If this is None, no authentication will be possible. :param macaroon_opstore (object with new_macaroon and macaroon_ops method): used to retrieve macaroon root keys and other associated information. ''' self._first_party_caveat_checker = checker self._authorizer = authorizer if identity_client is None: identity_client = macaroonbakery.NoIdentities() self._identity_client = identity_client self._macaroon_opstore = macaroon_opstore