Add checks for domain scoped data creep
Previously, the assertValidDomainScopedTokenResponse method only ensured specific attributes were in the token response. These checks didn't ensure that the token scope never grew. This change makes it so that the assertion will fail if extra attributes are added to the token response. This should help us be more aware of changes that have token response data creep by building the check into the tests. Change-Id: I43c86837f465f813da0985033a5af9d15d76eddc Partial-Bug: 1224273
This commit is contained in:
parent
f7eecbfa30
commit
8a5343c8c2
|
@ -122,6 +122,97 @@ class AuthTestMixin(object):
|
|||
|
||||
class RestfulTestCase(unit.SQLDriverOverrides, rest.RestfulTestCase,
|
||||
common_auth.AuthTestMixin):
|
||||
|
||||
def generate_token_schema(self, domain_scoped=False):
|
||||
"""Return a dictionary of token properties to validate against."""
|
||||
properties = {
|
||||
'audit_ids': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'string',
|
||||
},
|
||||
'minItems': 1,
|
||||
'maxItems': 2,
|
||||
},
|
||||
'bind': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'kerberos': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['kerberos'],
|
||||
'additionalProperties': False,
|
||||
},
|
||||
'expires_at': {'type': 'string'},
|
||||
'issued_at': {'type': 'string'},
|
||||
'methods': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'user': {
|
||||
'type': 'object',
|
||||
'required': ['id', 'name', 'domain'],
|
||||
'properties': {
|
||||
'id': {'type': 'string'},
|
||||
'name': {'type': 'string'},
|
||||
'domain': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'id': {'type': 'string'},
|
||||
'name': {'type': 'string'}
|
||||
},
|
||||
'required': ['id', 'name'],
|
||||
'additonalProperties': False,
|
||||
}
|
||||
},
|
||||
'additionalProperties': False,
|
||||
}
|
||||
}
|
||||
if domain_scoped:
|
||||
properties['catalog'] = {'type': 'array'}
|
||||
properties['roles'] = {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'id': {'type': 'string', },
|
||||
'name': {'type': 'string', },
|
||||
},
|
||||
'required': ['id', 'name', ],
|
||||
'additionalProperties': False,
|
||||
},
|
||||
'minItems': 1,
|
||||
}
|
||||
properties['domain'] = {
|
||||
'domain': {
|
||||
'type': 'object',
|
||||
'required': ['id', 'name'],
|
||||
'properties': {
|
||||
'id': {'type': 'string'},
|
||||
'name': {'type': 'string'}
|
||||
},
|
||||
'additionalProperties': False
|
||||
}
|
||||
}
|
||||
|
||||
schema = {
|
||||
'type': 'object',
|
||||
'properties': properties,
|
||||
'required': ['audit_ids', 'expires_at', 'issued_at', 'methods',
|
||||
'user'],
|
||||
'optional': ['bind'],
|
||||
'additionalProperties': False
|
||||
}
|
||||
|
||||
if domain_scoped:
|
||||
schema['required'].extend(['domain', 'roles'])
|
||||
schema['optional'].append('catalog')
|
||||
|
||||
return schema
|
||||
|
||||
def config_files(self):
|
||||
config_files = super(RestfulTestCase, self).config_files()
|
||||
config_files.append(unit.dirs.tests_conf('backend_sql.conf'))
|
||||
|
@ -535,62 +626,9 @@ class RestfulTestCase(unit.SQLDriverOverrides, rest.RestfulTestCase,
|
|||
|
||||
def assertValidUnscopedTokenResponse(self, r, *args, **kwargs):
|
||||
token = self.assertValidTokenResponse(r, *args, **kwargs)
|
||||
|
||||
unscoped_properties = {
|
||||
'audit_ids': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'string',
|
||||
},
|
||||
'minItems': 1,
|
||||
'maxItems': 2,
|
||||
},
|
||||
'bind': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'kerberos': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['kerberos', ],
|
||||
'additionalProperties': False,
|
||||
},
|
||||
'expires_at': {'type': 'string'},
|
||||
'issued_at': {'type': 'string'},
|
||||
'methods': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'user': {
|
||||
'type': 'object',
|
||||
'required': ['id', 'name', 'domain'],
|
||||
'properties': {
|
||||
'id': {'type': 'string'},
|
||||
'name': {'type': 'string'},
|
||||
'domain': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'id': {'type': 'string'},
|
||||
'name': {'type': 'string'}
|
||||
},
|
||||
'required': ['id', 'name'],
|
||||
'additonalProperties': False,
|
||||
}
|
||||
},
|
||||
'additionalProperties': False,
|
||||
}
|
||||
}
|
||||
unscoped_token_schema = {
|
||||
'type': 'object',
|
||||
'properties': unscoped_properties,
|
||||
'required': ['audit_ids', 'expires_at', 'issued_at', 'methods',
|
||||
'user'],
|
||||
'optional': ['bind'],
|
||||
'additionalProperties': False
|
||||
}
|
||||
validator_object = validators.SchemaValidator(unscoped_token_schema)
|
||||
validator_object = validators.SchemaValidator(
|
||||
self.generate_token_schema()
|
||||
)
|
||||
validator_object.validate(token)
|
||||
|
||||
return token
|
||||
|
@ -664,9 +702,10 @@ class RestfulTestCase(unit.SQLDriverOverrides, rest.RestfulTestCase,
|
|||
def assertValidDomainScopedTokenResponse(self, r, *args, **kwargs):
|
||||
token = self.assertValidScopedTokenResponse(r, *args, **kwargs)
|
||||
|
||||
self.assertIn('domain', token)
|
||||
self.assertIn('id', token['domain'])
|
||||
self.assertIn('name', token['domain'])
|
||||
validator_object = validators.SchemaValidator(
|
||||
self.generate_token_schema(domain_scoped=True)
|
||||
)
|
||||
validator_object.validate(token)
|
||||
|
||||
return token
|
||||
|
||||
|
|
|
@ -490,6 +490,23 @@ class TokenDataTests(object):
|
|||
r = self.get('/auth/tokens', headers=self.headers)
|
||||
self.assertValidUnscopedTokenResponse(r)
|
||||
|
||||
def test_domain_scoped_token_format(self):
|
||||
# ensure the domain scoped token response contains the appropriate data
|
||||
self.assignment_api.create_grant(
|
||||
self.role['id'],
|
||||
user_id=self.default_domain_user['id'],
|
||||
domain_id=self.domain['id'])
|
||||
|
||||
domain_scoped_token = self.get_requested_token(
|
||||
self.build_authentication_request(
|
||||
user_id=self.default_domain_user['id'],
|
||||
password=self.default_domain_user['password'],
|
||||
domain_id=self.domain['id'])
|
||||
)
|
||||
self.headers['X-Subject-Token'] = domain_scoped_token
|
||||
r = self.get('/auth/tokens', headers=self.headers)
|
||||
self.assertValidDomainScopedTokenResponse(r)
|
||||
|
||||
|
||||
class AllowRescopeScopedTokenDisabledTests(test_v3.RestfulTestCase):
|
||||
def config_overrides(self):
|
||||
|
|
Loading…
Reference in New Issue