Add API changes for app cred access rules
bp whitelist-extension-for-app-creds Change-Id: Ie022e379d03d0309ec320b6947b987758d87fe5d
This commit is contained in:
parent
ee7315971c
commit
14c4b177ef
|
@ -545,7 +545,8 @@ class UserAppCredListCreateResource(ks_flask.ResourceBase):
|
|||
# secret is only exposed after create, it is not stored
|
||||
'secret',
|
||||
'links',
|
||||
'unrestricted'
|
||||
'unrestricted',
|
||||
'access_rules'
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
|
@ -608,6 +609,16 @@ class UserAppCredListCreateResource(ks_flask.ResourceBase):
|
|||
if app_cred_data.get('expires_at'):
|
||||
app_cred_data['expires_at'] = utils.parse_expiration_date(
|
||||
app_cred_data['expires_at'])
|
||||
if app_cred_data.get('access_rules'):
|
||||
for access_rule in app_cred_data['access_rules']:
|
||||
# If user provides an access rule by ID, it will be looked up
|
||||
# by ID. If user provides an access rule that is identical to
|
||||
# an existing one, the ID generated here will be ignored and
|
||||
# the pre-existing access rule will be used.
|
||||
if 'id' not in access_rule:
|
||||
# Generate directly, rather than using _assign_unique_id,
|
||||
# so that there is no deep copy made
|
||||
access_rule['id'] = uuid.uuid4().hex
|
||||
app_cred_data = self._normalize_dict(app_cred_data)
|
||||
app_cred_api = PROVIDERS.application_credential_api
|
||||
|
||||
|
|
|
@ -29,6 +29,28 @@ _role_properties = {
|
|||
}
|
||||
}
|
||||
|
||||
_access_rules_properties = {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'path': {
|
||||
'type': 'string',
|
||||
'minLength': 0,
|
||||
'maxLength': 225,
|
||||
'pattern': '^\/.*'
|
||||
},
|
||||
'method': {
|
||||
'type': 'string',
|
||||
'pattern': '^(POST|GET|HEAD|PATCH|PUT|DELETE)$'
|
||||
},
|
||||
'service': parameter_types.id_string,
|
||||
'id': parameter_types.id_string,
|
||||
},
|
||||
'additionalProperties': False
|
||||
}
|
||||
}
|
||||
|
||||
_application_credential_properties = {
|
||||
'name': parameter_types.name,
|
||||
'description': validation.nullable(parameter_types.description),
|
||||
|
@ -39,7 +61,8 @@ _application_credential_properties = {
|
|||
'type': ['null', 'string']
|
||||
},
|
||||
'roles': _role_properties,
|
||||
'unrestricted': parameter_types.boolean
|
||||
'unrestricted': parameter_types.boolean,
|
||||
'access_rules': _access_rules_properties
|
||||
}
|
||||
|
||||
application_credential_create = {
|
||||
|
|
|
@ -35,7 +35,8 @@ class ApplicationCredentialTestCase(test_v3.RestfulTestCase):
|
|||
self.config_fixture.config(group='auth',
|
||||
methods='password,application_credential')
|
||||
|
||||
def _app_cred_body(self, roles=None, name=None, expires=None, secret=None):
|
||||
def _app_cred_body(self, roles=None, name=None, expires=None, secret=None,
|
||||
access_rules=None):
|
||||
name = name or uuid.uuid4().hex
|
||||
description = 'Credential for backups'
|
||||
app_cred_data = {
|
||||
|
@ -48,6 +49,8 @@ class ApplicationCredentialTestCase(test_v3.RestfulTestCase):
|
|||
app_cred_data['expires_at'] = expires
|
||||
if secret:
|
||||
app_cred_data['secret'] = secret
|
||||
if access_rules is not None:
|
||||
app_cred_data['access_rules'] = access_rules
|
||||
return {'application_credential': app_cred_data}
|
||||
|
||||
def test_create_application_credential(self):
|
||||
|
@ -187,6 +190,96 @@ class ApplicationCredentialTestCase(test_v3.RestfulTestCase):
|
|||
expected_status_code=http_client.CREATED,
|
||||
headers={'x-Auth-Token': token_data.headers['x-subject-token']})
|
||||
|
||||
def test_create_application_credential_with_access_rules(self):
|
||||
roles = [{'id': self.role_id}]
|
||||
access_rules = [
|
||||
{
|
||||
'path': '/v3/projects',
|
||||
'method': 'POST',
|
||||
'service': 'identity',
|
||||
}
|
||||
]
|
||||
app_cred_body = self._app_cred_body(roles=roles,
|
||||
access_rules=access_rules)
|
||||
with self.test_client() as c:
|
||||
token = self.get_scoped_token()
|
||||
resp = c.post('/v3/users/%s/application_credentials' % self.user_id,
|
||||
headers={'X-Auth-Token': token},
|
||||
json=app_cred_body,
|
||||
expected_status_code=http_client.CREATED)
|
||||
resp_access_rules = resp.json['application_credential']['access_rules']
|
||||
self.assertIn('id', resp_access_rules[0])
|
||||
resp_access_rules[0].pop('id')
|
||||
self.assertEqual(access_rules[0], resp_access_rules[0])
|
||||
|
||||
def test_create_application_credential_with_duplicate_access_rule(self):
|
||||
roles = [{'id': self.role_id}]
|
||||
access_rules = [
|
||||
{
|
||||
'path': '/v3/projects',
|
||||
'method': 'POST',
|
||||
'service': 'identity',
|
||||
}
|
||||
]
|
||||
app_cred_body_1 = self._app_cred_body(roles=roles,
|
||||
access_rules=access_rules)
|
||||
with self.test_client() as c:
|
||||
token = self.get_scoped_token()
|
||||
resp = c.post('/v3/users/%s/application_credentials' % self.user_id,
|
||||
headers={'X-Auth-Token': token},
|
||||
json=app_cred_body_1,
|
||||
expected_status_code=http_client.CREATED)
|
||||
resp_access_rules = resp.json['application_credential']['access_rules']
|
||||
self.assertIn('id', resp_access_rules[0])
|
||||
access_rule_id = resp_access_rules[0].pop('id')
|
||||
self.assertEqual(access_rules[0], resp_access_rules[0])
|
||||
|
||||
app_cred_body_2 = self._app_cred_body(roles=roles,
|
||||
access_rules=access_rules)
|
||||
with self.test_client() as c:
|
||||
token = self.get_scoped_token()
|
||||
resp = c.post('/v3/users/%s/application_credentials' % self.user_id,
|
||||
headers={'X-Auth-Token': token},
|
||||
json=app_cred_body_2,
|
||||
expected_status_code=http_client.CREATED)
|
||||
resp_access_rules = resp.json['application_credential']['access_rules']
|
||||
self.assertEqual(access_rule_id, resp_access_rules[0]['id'])
|
||||
|
||||
def test_create_application_credential_with_access_rule_by_id(self):
|
||||
roles = [{'id': self.role_id}]
|
||||
access_rules = [
|
||||
{
|
||||
'path': '/v3/projects',
|
||||
'method': 'POST',
|
||||
'service': 'identity',
|
||||
}
|
||||
]
|
||||
app_cred_body_1 = self._app_cred_body(roles=roles,
|
||||
access_rules=access_rules)
|
||||
with self.test_client() as c:
|
||||
token = self.get_scoped_token()
|
||||
resp = c.post('/v3/users/%s/application_credentials' % self.user_id,
|
||||
headers={'X-Auth-Token': token},
|
||||
json=app_cred_body_1,
|
||||
expected_status_code=http_client.CREATED)
|
||||
resp_access_rules = resp.json['application_credential']['access_rules']
|
||||
access_rule_id = resp_access_rules
|
||||
self.assertIn('id', resp_access_rules[0])
|
||||
access_rule_id = resp_access_rules[0].pop('id')
|
||||
self.assertEqual(access_rules[0], resp_access_rules[0])
|
||||
|
||||
access_rules = [{'id': access_rule_id}]
|
||||
app_cred_body_2 = self._app_cred_body(roles=roles,
|
||||
access_rules=access_rules)
|
||||
with self.test_client() as c:
|
||||
token = self.get_scoped_token()
|
||||
resp = c.post('/v3/users/%s/application_credentials' % self.user_id,
|
||||
headers={'X-Auth-Token': token},
|
||||
json=app_cred_body_2,
|
||||
expected_status_code=http_client.CREATED)
|
||||
resp_access_rules = resp.json['application_credential']['access_rules']
|
||||
self.assertEqual(access_rule_id, resp_access_rules[0]['id'])
|
||||
|
||||
def test_list_application_credentials(self):
|
||||
with self.test_client() as c:
|
||||
token = self.get_scoped_token()
|
||||
|
|
Loading…
Reference in New Issue