def test_delegation_token(self): peer_ident = model.Identity.from_bytes('user:[email protected]') class Handler(handler.AuthenticatingHandler): @classmethod def get_auth_methods(cls, conf): return [lambda _request: peer_ident] @api.public def get(self): self.response.write( json.dumps({ 'peer_id': api.get_peer_identity().to_bytes(), 'cur_id': api.get_current_identity().to_bytes(), })) app = self.make_test_app('/request', Handler) def call(headers=None): return json.loads(app.get('/request', headers=headers).body) # No delegation. self.assertEqual( { u'cur_id': u'user:[email protected]', u'peer_id': u'user:[email protected]' }, call()) # TODO(vadimsh): Mint token via some high-level function call. subtoken = delegation_pb2.Subtoken( delegated_identity='user:[email protected]', audience=['*'], services=['*'], creation_time=int(utils.time_time()), validity_duration=3600) tok = delegation.serialize_token(delegation.seal_token(subtoken)) # With valid delegation token. self.assertEqual( { u'cur_id': u'user:[email protected]', u'peer_id': u'user:[email protected]' }, call({'X-Delegation-Token-V1': tok})) # With invalid delegation token. r = app.get('/request', headers={'X-Delegation-Token-V1': tok + 'blah'}, expect_errors=True) self.assertEqual(403, r.status_int) # Transient error. def mocked_check(*_args): raise delegation.TransientError('Blah') self.mock(delegation, 'check_bearer_delegation_token', mocked_check) r = app.get('/request', headers={'X-Delegation-Token-V1': tok}, expect_errors=True) self.assertEqual(500, r.status_int)
def test_delegation_token(self): peer_ident = model.Identity.from_bytes('user:[email protected]') class Handler(handler.AuthenticatingHandler): @classmethod def get_auth_methods(cls, conf): return [lambda _request: peer_ident] @api.public def get(self): self.response.write(json.dumps({ 'peer_id': api.get_peer_identity().to_bytes(), 'cur_id': api.get_current_identity().to_bytes(), })) app = self.make_test_app('/request', Handler) def call(headers=None): return json.loads(app.get('/request', headers=headers).body) # No delegation. self.assertEqual( {u'cur_id': u'user:[email protected]', u'peer_id': u'user:[email protected]'}, call()) # TODO(vadimsh): Mint token via some high-level function call. subtokens = delegation_pb2.SubtokenList(subtokens=[ delegation_pb2.Subtoken( issuer_id='user:[email protected]', creation_time=int(utils.time_time()), validity_duration=3600), ]) tok = delegation.serialize_token(delegation.seal_token(subtokens)) # With valid delegation token. self.assertEqual( {u'cur_id': u'user:[email protected]', u'peer_id': u'user:[email protected]'}, call({'X-Delegation-Token-V1': tok})) # With invalid delegation token. r = app.get( '/request', headers={'X-Delegation-Token-V1': tok + 'blah'}, expect_errors=True) self.assertEqual(403, r.status_int) # Transient error. def mocked_check(*_args): raise delegation.TransientError('Blah') self.mock(delegation, 'check_delegation_token', mocked_check) r = app.get( '/request', headers={'X-Delegation-Token-V1': tok}, expect_errors=True) self.assertEqual(500, r.status_int)
def test_works(self): api.reset_local_state() # to clear request-cached AuthDB # Subtoken proto. tok = fake_subtoken_proto('user:[email protected]', audience=['user:[email protected]']) # Sign, serialize. blob = delegation.serialize_token(delegation.seal_token(tok)) # Deserialize, check sig, validate. make_id = model.Identity.from_bytes ident = delegation.check_bearer_delegation_token( blob, make_id('user:[email protected]')) self.assertEqual(make_id('user:[email protected]'), ident)
def post(self): # Forbid usage of delegation tokens for this particular call. Using # delegation when creating delegation tokens is too deep. Redelegation will # be done as separate explicit API call that accept existing delegation # token via request body, not via headers. if auth.get_current_identity() != auth.get_peer_identity(): raise auth.AuthorizationError( 'This API call must not be used with active delegation token') # Convert request body to proto (with validation). Verify IP format. try: body = self.parse_body() subtoken = subtoken_from_jsonish(body) intent = body.get('intent') or '' if not isinstance(intent, basestring): raise TypeError('"intent" must be string') except (TypeError, ValueError) as exc: self.abort_with_error(400, text=str(exc)) # Fill in defaults. assert not subtoken.requestor_identity user_id = auth.get_current_identity().to_bytes() subtoken.requestor_identity = user_id if not subtoken.delegated_identity: subtoken.delegated_identity = user_id subtoken.creation_time = int(utils.time_time()) if not subtoken.validity_duration: subtoken.validity_duration = DEF_VALIDITY_DURATION_SEC if '*' in subtoken.services: subtoken.services[:] = get_default_allowed_services(user_id) # Check ACL (raises auth.AuthorizationError on errors). rule = check_can_create_token(user_id, subtoken) # Register the token in the datastore, generate its ID. subtoken.subtoken_id = register_subtoken(subtoken, rule, intent, auth.get_peer_ip()) # Create and sign the token. try: token = delegation.serialize_token(delegation.seal_token(subtoken)) except delegation.BadTokenError as exc: # This happens if resulting token is too large. self.abort_with_error(400, text=str(exc)) self.send_response(response={ 'delegation_token': token, 'subtoken_id': str(subtoken.subtoken_id), 'validity_duration': subtoken.validity_duration, }, http_code=201)
def test_works(self): # Subtoken list proto. toks = delegation_pb2.SubtokenList(subtokens=[ fake_subtoken_proto( 'user:[email protected]', audience=['user:[email protected]']), fake_subtoken_proto( 'user:[email protected]', audience=['user:[email protected]']), ]) # Sign, serialize. blob = delegation.serialize_token(delegation.seal_token(toks)) # Deserialize, check sig, validate. make_id = model.Identity.from_bytes ident = delegation.check_delegation_token(blob, make_id('user:[email protected]')) self.assertEqual(make_id('user:[email protected]'), ident)
def test_works(self): # Subtoken list proto. toks = delegation_pb2.SubtokenList(subtokens=[ fake_subtoken_proto('user:[email protected]', audience=['user:[email protected]']), fake_subtoken_proto('user:[email protected]', audience=['user:[email protected]']), ]) # Sign, serialize. blob = delegation.serialize_token(delegation.seal_token(toks)) # Deserialize, check sig, validate. make_id = model.Identity.from_bytes ident = delegation.check_delegation_token(blob, make_id('user:[email protected]')) self.assertEqual(make_id('user:[email protected]'), ident)
def post(self): # Forbid usage of delegation tokens for this particular call. Using # delegation when creating delegation tokens is too deep. Redelegation will # be done as separate explicit API call that accept existing delegation # token via request body, not via headers. if auth.get_current_identity() != auth.get_peer_identity(): raise auth.AuthorizationError( 'This API call must not be used with active delegation token') # Convert request body to proto (with validation). try: subtoken = subtoken_from_jsonish(self.parse_body()) except (TypeError, ValueError) as exc: self.abort_with_error(400, text=str(exc)) # Fill in defaults. assert not subtoken.impersonator_id user_id = auth.get_current_identity().to_bytes() if not subtoken.issuer_id: subtoken.issuer_id = user_id if subtoken.issuer_id != user_id: subtoken.impersonator_id = user_id subtoken.creation_time = int(utils.time_time()) if not subtoken.validity_duration: subtoken.validity_duration = DEF_VALIDITY_DURATION_SEC if not subtoken.services or '*' in subtoken.services: subtoken.services[:] = get_default_allowed_services(user_id) # Check ACL (raises auth.AuthorizationError on errors). check_can_create_token(user_id, subtoken) # Create and sign the token. try: token = delegation.serialize_token( delegation.seal_token( delegation_pb2.SubtokenList(subtokens=[subtoken]))) except delegation.BadTokenError as exc: # This happens if resulting token is too large. self.abort_with_error(400, text=str(exc)) self.send_response( response={ 'delegation_token': token, 'validity_duration': subtoken.validity_duration, }, http_code=201)
def post(self): # Forbid usage of delegation tokens for this particular call. Using # delegation when creating delegation tokens is too deep. Redelegation will # be done as separate explicit API call that accept existing delegation # token via request body, not via headers. if auth.get_current_identity() != auth.get_peer_identity(): raise auth.AuthorizationError( 'This API call must not be used with active delegation token') # Convert request body to proto (with validation). try: subtoken = subtoken_from_jsonish(self.parse_body()) except (TypeError, ValueError) as exc: self.abort_with_error(400, text=str(exc)) # Fill in defaults. assert not subtoken.impersonator_id user_id = auth.get_current_identity().to_bytes() if not subtoken.issuer_id: subtoken.issuer_id = user_id if subtoken.issuer_id != user_id: subtoken.impersonator_id = user_id subtoken.creation_time = int(utils.time_time()) if not subtoken.validity_duration: subtoken.validity_duration = DEF_VALIDITY_DURATION_SEC if not subtoken.services or '*' in subtoken.services: subtoken.services[:] = get_default_allowed_services(user_id) # Check ACL (raises auth.AuthorizationError on errors). check_can_create_token(user_id, subtoken) # Create and sign the token. try: token = delegation.serialize_token( delegation.seal_token( delegation_pb2.SubtokenList(subtokens=[subtoken]))) except delegation.BadTokenError as exc: # This happens if resulting token is too large. self.abort_with_error(400, text=str(exc)) self.send_response(response={ 'delegation_token': token, 'validity_duration': subtoken.validity_duration, }, http_code=201)
def test_delegation_token(self): def call(tok=None): headers = {'X-Delegation-Token-V1': tok} if tok else None self.call('127.0.0.1', '*****@*****.**', headers) return { 'cur_id': api.get_current_identity().to_bytes(), 'peer_id': api.get_current_identity().to_bytes(), } # No delegation. self.assertEqual( { 'cur_id': 'user:[email protected]', 'peer_id': 'user:[email protected]' }, call()) # TODO(vadimsh): Mint token via some high-level function call. subtokens = delegation_pb2.SubtokenList(subtokens=[ delegation_pb2.Subtoken(issuer_id='user:[email protected]', creation_time=int(utils.time_time()), validity_duration=3600), ]) tok = delegation.serialize_token(delegation.seal_token(subtokens)) # Valid delegation token. self.assertEqual( { 'cur_id': 'user:[email protected]', 'peer_id': 'user:[email protected]' }, call(tok)) # Invalid delegation token. with self.assertRaises(api.AuthorizationError): call(tok + 'blah') # Transient error. def mocked_check(*_args): raise delegation.TransientError('Blah') self.mock(delegation, 'check_delegation_token', mocked_check) with self.assertRaises(endpoints.InternalServerErrorException): call(tok)
def test_delegation_token(self): def call(tok=None): headers = {'X-Delegation-Token-V1': tok} if tok else None self.call('127.0.0.1', '*****@*****.**', headers) return { 'cur_id': api.get_current_identity().to_bytes(), 'peer_id': api.get_current_identity().to_bytes(), } # No delegation. self.assertEqual( {'cur_id': 'user:[email protected]', 'peer_id': 'user:[email protected]'}, call()) # TODO(vadimsh): Mint token via some high-level function call. subtokens = delegation_pb2.SubtokenList(subtokens=[ delegation_pb2.Subtoken( issuer_id='user:[email protected]', creation_time=int(utils.time_time()), validity_duration=3600), ]) tok = delegation.serialize_token(delegation.seal_token(subtokens)) # Valid delegation token. self.assertEqual( {'cur_id': 'user:[email protected]', 'peer_id': 'user:[email protected]'}, call(tok)) # Invalid delegation token. with self.assertRaises(api.AuthorizationError): call(tok + 'blah') # Transient error. def mocked_check(*_args): raise delegation.TransientError('Blah') self.mock(delegation, 'check_delegation_token', mocked_check) with self.assertRaises(endpoints.InternalServerErrorException): call(tok)
def test_deserialize_not_base64(self): msg = fake_token_proto() tok = delegation.serialize_token(msg) tok += 'not base 64' with self.assertRaises(delegation.BadTokenError): delegation.deserialize_token(tok)
def test_serialize_huge(self): msg = fake_token_proto() msg.serialized_subtoken_list = 'huge' * 10000 with self.assertRaises(delegation.BadTokenError): delegation.serialize_token(msg)
def test_serialization_works(self): msg = fake_token_proto() tok = delegation.serialize_token(msg) self.assertEqual(msg, delegation.deserialize_token(tok))
def test_serialize_huge(self): msg = fake_token_proto() msg.serialized_subtoken = 'huge' * 10000 with self.assertRaises(delegation.BadTokenError): delegation.serialize_token(msg)