Made project_id required for ec2 credential

ec2 tokens cannot be created without the user and project
associated with the credentials. The project_id must be
required when creating ec2 credentials.

Updating json schema to check:
- if ec2 type, project_id is required
- else, project_id is optional

 Closes-Bug: #1268977

Change-Id: Id7118e028d8c3ff607ac24cd9ecba90a905ce91f
This commit is contained in:
lin-hua-cheng 2015-02-14 01:19:36 -08:00
parent 6716bd360f
commit a9f257dc05
3 changed files with 83 additions and 8 deletions

View File

@ -29,8 +29,29 @@ _credential_properties = {
credential_create = { credential_create = {
'type': 'object', 'type': 'object',
'properties': _credential_properties, 'properties': _credential_properties,
'required': ['blob', 'type', 'user_id'], 'additionalProperties': True,
'additionalProperties': True 'oneOf': [
{
'title': 'ec2 credential requires project_id',
'required': ['blob', 'type', 'user_id', 'project_id'],
'properties': {
'type': {
'enum': ['ec2']
}
}
},
{
'title': 'non-ec2 credential does not require project_id',
'required': ['blob', 'type', 'user_id'],
'properties': {
'type': {
'not': {
'enum': ['ec2']
}
}
}
}
]
} }
credential_update = { credential_update = {

View File

@ -132,7 +132,8 @@ class CredentialTestCase(CredentialBaseTestCase):
def test_create_ec2_credential(self): def test_create_ec2_credential(self):
"""Call ``POST /credentials`` for creating ec2 credential.""" """Call ``POST /credentials`` for creating ec2 credential."""
ref = self.new_credential_ref(user_id=self.user['id']) ref = self.new_credential_ref(user_id=self.user['id'],
project_id=self.project_id)
blob = {"access": uuid.uuid4().hex, blob = {"access": uuid.uuid4().hex,
"secret": uuid.uuid4().hex} "secret": uuid.uuid4().hex}
ref['blob'] = json.dumps(blob) ref['blob'] = json.dumps(blob)
@ -187,11 +188,26 @@ class CredentialTestCase(CredentialBaseTestCase):
self.assertNotEqual(r.result['credential']['id'], self.assertNotEqual(r.result['credential']['id'],
hashlib.sha256(blob['access']).hexdigest()) hashlib.sha256(blob['access']).hexdigest())
def test_create_ec2_credential_with_missing_project_id(self):
"""Call ``POST /credentials`` for creating ec2
credential with missing project_id.
"""
ref = self.new_credential_ref(user_id=self.user['id'])
blob = {"access": uuid.uuid4().hex,
"secret": uuid.uuid4().hex}
ref['blob'] = json.dumps(blob)
ref['type'] = 'ec2'
# Assert 400 status for bad request with missing project_id
self.post(
'/credentials',
body={'credential': ref}, expected_status=400)
def test_create_ec2_credential_with_invalid_blob(self): def test_create_ec2_credential_with_invalid_blob(self):
"""Call ``POST /credentials`` for creating ec2 """Call ``POST /credentials`` for creating ec2
credential with invalid blob. credential with invalid blob.
""" """
ref = self.new_credential_ref(user_id=self.user['id']) ref = self.new_credential_ref(user_id=self.user['id'],
project_id=self.project_id)
ref['blob'] = '{"abc":"def"d}' ref['blob'] = '{"abc":"def"d}'
ref['type'] = 'ec2' ref['type'] = 'ec2'
# Assert 400 status for bad request containing invalid # Assert 400 status for bad request containing invalid
@ -251,7 +267,8 @@ class TestCredentialTrustScoped(test_v3.RestfulTestCase):
token_id = r.headers.get('X-Subject-Token') token_id = r.headers.get('X-Subject-Token')
# Create the credential with the trust scoped token # Create the credential with the trust scoped token
ref = self.new_credential_ref(user_id=self.user['id']) ref = self.new_credential_ref(user_id=self.user['id'],
project_id=self.project_id)
blob = {"access": uuid.uuid4().hex, blob = {"access": uuid.uuid4().hex,
"secret": uuid.uuid4().hex} "secret": uuid.uuid4().hex}
ref['blob'] = json.dumps(blob) ref['blob'] = json.dumps(blob)

View File

@ -695,9 +695,46 @@ class CredentialValidationTestCase(testtools.TestCase):
self.create_credential_validator.validate, self.create_credential_validator.validate,
request_to_validate) request_to_validate)
def test_validate_credential_with_types_succeeds(self): def test_validate_credential_ec2_without_project_id_fails(self):
"""Test that credential type works for ec2 and cert.""" """Validate `project_id` is required for ec2.
cred_types = ['ec2', 'cert', uuid.uuid4().hex]
Test that an exception is raised when type is ec2 and no `project_id`
is provided in create request.
"""
request_to_validate = {'blob': 'some credential blob',
'type': 'ec2',
'user_id': uuid.uuid4().hex}
self.assertRaises(exception.SchemaValidationError,
self.create_credential_validator.validate,
request_to_validate)
def test_validate_credential_ec2_with_project_id_succeeds(self):
"""Test that credential request works for ec2."""
request_to_validate = {'blob': 'some credential blob',
'project_id': uuid.uuid4().hex,
'type': 'ec2',
'user_id': uuid.uuid4().hex}
self.create_credential_validator.validate(request_to_validate)
def test_validate_credential_non_ec2_with_project_id_succeeds(self):
"""Test that credential request works for non-ec2."""
cred_types = ['cert', uuid.uuid4().hex]
for c_type in cred_types:
request_to_validate = {'blob': 'some blob',
'project_id': uuid.uuid4().hex,
'type': c_type,
'user_id': uuid.uuid4().hex}
# Make sure an exception isn't raised
self.create_credential_validator.validate(request_to_validate)
def test_validate_credential_non_ec2_without_project_id_succeeds(self):
"""Validate `project_id` is not required for non-ec2.
Test that create request without `project_id` succeeds for any
non-ec2 credential.
"""
cred_types = ['cert', uuid.uuid4().hex]
for c_type in cred_types: for c_type in cred_types:
request_to_validate = {'blob': 'some blob', request_to_validate = {'blob': 'some blob',