Do not consume trust uses when create token fails

Currently, remaining trust uses are consumed even when create token
fails. We should only consume trust uses when successfully creating
a token.

Change-Id: I55a726250312fa81ed9556dfd530e96f72548930
Closes-Bug: #1335037
This commit is contained in:
wanghong 2014-06-30 10:54:53 +08:00
parent c4c8d0b99a
commit f6a266972d
4 changed files with 57 additions and 4 deletions

View File

@ -380,9 +380,6 @@ class Auth(controller.V3Controller):
self._check_and_set_default_scoping(auth_info, auth_context)
(domain_id, project_id, trust) = auth_info.get_scope()
if trust:
self.trust_api.consume_use(trust['id'])
method_names = auth_info.get_method_names()
method_names += auth_context.get('method_names', [])
# make sure the list is unique
@ -396,6 +393,11 @@ class Auth(controller.V3Controller):
auth_context['user_id'], method_names, expires_at, project_id,
domain_id, auth_context, trust, metadata_ref, include_catalog)
# NOTE(wanghong): We consume a trust use only when we are using
# trusts and have successfully issued a token.
if trust:
self.trust_api.consume_use(trust['id'])
return render_token_data_response(token_id, token_data,
created=True)
except exception.TrustNotFound as e:

View File

@ -960,6 +960,26 @@ class AuthWithTrust(AuthTest):
exception.Forbidden,
self.controller.authenticate, {}, request_body)
def test_do_not_consume_remaining_uses_when_get_token_fails(self):
trust_data = copy.deepcopy(self.sample_data)
trust_data['remaining_uses'] = 3
new_trust = self.create_trust(trust_data, self.trustor['name'])
for assigned_role in self.assigned_roles:
self.assignment_api.remove_role_from_user_and_project(
self.trustor['id'], self.tenant_bar['id'], assigned_role)
request_body = self.build_v2_token_request('TWO', 'two2', new_trust)
self.assertRaises(exception.Forbidden,
self.controller.authenticate, {}, request_body)
unscoped_token = self.get_unscoped_token(self.trustor['name'])
context = self._create_auth_context(
unscoped_token['access']['token']['id'])
trust = self.trust_controller.get_trust(context,
new_trust['id'])['trust']
self.assertEqual(3, trust['remaining_uses'])
class TokenExpirationTest(AuthTest):

View File

@ -3092,6 +3092,32 @@ class TestTrustAuth(test_v3.RestfulTestCase):
expected_status=200)
self.assertValidRoleResponse(r, self.role)
def test_do_not_consume_remaining_uses_when_get_token_fails(self):
ref = self.new_trust_ref(
trustor_user_id=self.user_id,
trustee_user_id=self.trustee_user_id,
project_id=self.project_id,
impersonation=False,
expires=dict(minutes=1),
role_ids=[self.role_id],
remaining_uses=3)
del ref['id']
r = self.post('/OS-TRUST/trusts', body={'trust': ref})
new_trust = r.result.get('trust')
trust_id = new_trust.get('id')
# Pass in another user's ID as the trustee, the result being a failed
# token authenticate and the remaining_uses of the trust should not be
# decremented.
auth_data = self.build_authentication_request(
user_id=self.default_domain_user['id'],
password=self.default_domain_user['password'],
trust_id=trust_id)
self.v3_authenticate_token(auth_data, expected_status=403)
r = self.get('/OS-TRUST/trusts/%s' % trust_id)
self.assertEqual(3, r.result.get('trust').get('remaining_uses'))
class TestAPIProtectionWithoutAuthContextMiddleware(test_v3.RestfulTestCase):
def test_api_protection_with_no_auth_context_in_env(self):

View File

@ -141,6 +141,12 @@ class Auth(controller.V2Controller):
(token_id, token_data) = self.token_provider_api.issue_v2_token(
auth_token_data, roles_ref=roles_ref, catalog_ref=catalog_ref)
# NOTE(wanghong): We consume a trust use only when we are using trusts
# and have successfully issued a token.
if CONF.trust.enabled and 'trust_id' in auth:
self.trust_api.consume_use(auth['trust_id'])
return token_data
def _authenticate_token(self, context, auth):
@ -202,7 +208,6 @@ class Auth(controller.V2Controller):
trust_ref['trustee_user_id'])
if not trustee_user_ref['enabled']:
raise exception.Forbidden()()
self.trust_api.consume_use(auth['trust_id'])
if trust_ref['impersonation'] is True:
current_user_ref = trustor_user_ref