Merge "Convert OS-INHERIT API to flask native dispatching"
This commit is contained in:
commit
95f11874dd
|
@ -17,6 +17,7 @@ from keystone.api import groups
|
||||||
from keystone.api import limits
|
from keystone.api import limits
|
||||||
from keystone.api import os_ep_filter
|
from keystone.api import os_ep_filter
|
||||||
from keystone.api import os_federation
|
from keystone.api import os_federation
|
||||||
|
from keystone.api import os_inherit
|
||||||
from keystone.api import os_oauth1
|
from keystone.api import os_oauth1
|
||||||
from keystone.api import os_revoke
|
from keystone.api import os_revoke
|
||||||
from keystone.api import os_simple_cert
|
from keystone.api import os_simple_cert
|
||||||
|
@ -38,6 +39,7 @@ __all__ = (
|
||||||
'limits',
|
'limits',
|
||||||
'os_ep_filter',
|
'os_ep_filter',
|
||||||
'os_federation',
|
'os_federation',
|
||||||
|
'os_inherit',
|
||||||
'os_oauth1',
|
'os_oauth1',
|
||||||
'os_revoke',
|
'os_revoke',
|
||||||
'os_simple_cert',
|
'os_simple_cert',
|
||||||
|
@ -60,6 +62,7 @@ __apis__ = (
|
||||||
limits,
|
limits,
|
||||||
os_ep_filter,
|
os_ep_filter,
|
||||||
os_federation,
|
os_federation,
|
||||||
|
os_inherit,
|
||||||
os_oauth1,
|
os_oauth1,
|
||||||
os_revoke,
|
os_revoke,
|
||||||
os_simple_cert,
|
os_simple_cert,
|
||||||
|
|
|
@ -65,3 +65,8 @@ os_federation_resource_rel_func = functools.partial(
|
||||||
os_federation_parameter_rel_func = functools.partial(
|
os_federation_parameter_rel_func = functools.partial(
|
||||||
json_home.build_v3_extension_parameter_relation,
|
json_home.build_v3_extension_parameter_relation,
|
||||||
extension_name='OS-FEDERATION', extension_version='1.0')
|
extension_name='OS-FEDERATION', extension_version='1.0')
|
||||||
|
|
||||||
|
# OS-INHERIT "extension"
|
||||||
|
os_inherit_resource_rel_func = functools.partial(
|
||||||
|
json_home.build_v3_extension_resource_relation,
|
||||||
|
extension_name='OS-INHERIT', extension_version='1.0')
|
||||||
|
|
|
@ -0,0 +1,399 @@
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
# This file handles all flask-restful resources for /v3/OS-INHERIT
|
||||||
|
|
||||||
|
import flask_restful
|
||||||
|
from oslo_log import log
|
||||||
|
from six.moves import http_client
|
||||||
|
|
||||||
|
from keystone.api._shared import json_home_relations
|
||||||
|
from keystone.common import json_home
|
||||||
|
from keystone.common import provider_api
|
||||||
|
from keystone.common import rbac_enforcer
|
||||||
|
from keystone import exception
|
||||||
|
from keystone.server import flask as ks_flask
|
||||||
|
|
||||||
|
|
||||||
|
ENFORCER = rbac_enforcer.RBACEnforcer
|
||||||
|
PROVIDERS = provider_api.ProviderAPIs
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
_build_resource_relation = json_home_relations.os_inherit_resource_rel_func
|
||||||
|
|
||||||
|
|
||||||
|
def _build_enforcement_target_attr(role_id=None, user_id=None, group_id=None,
|
||||||
|
project_id=None, domain_id=None,
|
||||||
|
allow_non_existing=False):
|
||||||
|
"""Check protection for role grant APIs.
|
||||||
|
|
||||||
|
The policy rule might want to inspect attributes of any of the entities
|
||||||
|
involved in the grant. So we get these and pass them to the
|
||||||
|
check_protection() handler in the controller.
|
||||||
|
|
||||||
|
"""
|
||||||
|
# !!!!!!!!!! WARNING: Security Concern !!!!!!!!!!
|
||||||
|
#
|
||||||
|
# NOTE(morgan): This function must handle all expected exceptions,
|
||||||
|
# including NOT FOUNDs otherwise the exception will be raised up to the
|
||||||
|
# end user before enforcement, resulting in the exception being returned
|
||||||
|
# instead of an appropriate 403. In each case, it is logged that a value
|
||||||
|
# was not found and the target is explicitly set to empty. This allows for
|
||||||
|
# the enforcement rule to decide what to do (most of the time raise an
|
||||||
|
# appropriate 403).
|
||||||
|
#
|
||||||
|
# ###############################################
|
||||||
|
|
||||||
|
target = {}
|
||||||
|
if role_id:
|
||||||
|
try:
|
||||||
|
target['role'] = PROVIDERS.role_api.get_role(role_id)
|
||||||
|
except exception.RoleNotFound:
|
||||||
|
LOG.info('Role (%(role_id)s) not found, Enforcement target of '
|
||||||
|
'`role` remaind empty', {'role_id': role_id})
|
||||||
|
target['role'] = {}
|
||||||
|
if user_id:
|
||||||
|
try:
|
||||||
|
target['user'] = PROVIDERS.identity_api.get_user(user_id)
|
||||||
|
except exception.UserNotFound:
|
||||||
|
if not allow_non_existing:
|
||||||
|
LOG.info('User (%(user_id)s) was not found. Enforcement target'
|
||||||
|
' of `user` remains empty.', {'user_id': user_id})
|
||||||
|
target['user'] = {}
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
target['group'] = PROVIDERS.identity_api.get_group(group_id)
|
||||||
|
except exception.GroupNotFound:
|
||||||
|
if not allow_non_existing:
|
||||||
|
LOG.info('Group (%(group_id)s) was not found. Enforcement '
|
||||||
|
'target of `group` remains empty.',
|
||||||
|
{'group_id': group_id})
|
||||||
|
target['group'] = {}
|
||||||
|
|
||||||
|
# NOTE(lbragstad): This if/else check will need to be expanded in the
|
||||||
|
# future to handle system hierarchies if that is implemented.
|
||||||
|
if domain_id:
|
||||||
|
try:
|
||||||
|
target['domain'] = PROVIDERS.resource_api.get_domain(domain_id)
|
||||||
|
except exception.DomainNotFound:
|
||||||
|
LOG.info('Domain (%(domain_id)s) was not found. Enforcement '
|
||||||
|
'target of `domain` remains empty.',
|
||||||
|
{'domain_id': domain_id})
|
||||||
|
target['domain'] = {}
|
||||||
|
elif project_id:
|
||||||
|
try:
|
||||||
|
target['project'] = PROVIDERS.resource_api.get_project(project_id)
|
||||||
|
except exception.ProjectNotFound:
|
||||||
|
LOG.info('Project (%(project_id)s) was not found. Enforcement '
|
||||||
|
'target of `project` remains empty.',
|
||||||
|
{'project_id': project_id})
|
||||||
|
target['project'] = {}
|
||||||
|
|
||||||
|
return target
|
||||||
|
|
||||||
|
|
||||||
|
class OSInheritDomainGroupRolesResource(flask_restful.Resource):
|
||||||
|
def get(self, domain_id, group_id, role_id):
|
||||||
|
"""Check for an inherited grant for a group on a domain.
|
||||||
|
|
||||||
|
GET/HEAD /OS-INHERIT/domains/{domain_id}/groups/{group_id}
|
||||||
|
/roles/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:check_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
domain_id=domain_id, group_id=group_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.get_grant(
|
||||||
|
domain_id=domain_id, group_id=group_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def put(self, domain_id, group_id, role_id):
|
||||||
|
"""Create an inherited grant for a group on a domain.
|
||||||
|
|
||||||
|
PUT /OS-INHERIT/domains/{domain_id}/groups/{group_id}
|
||||||
|
/roles/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:create_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
domain_id=domain_id, group_id=group_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.create_grant(
|
||||||
|
domain_id=domain_id, group_id=group_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def delete(self, domain_id, group_id, role_id):
|
||||||
|
"""Revoke an inherited grant for a group on a domain.
|
||||||
|
|
||||||
|
DELETE /OS-INHERIT/domains/{domain_id}/groups/{group_id}
|
||||||
|
/roles/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:revoke_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
domain_id=domain_id, group_id=group_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.delete_grant(
|
||||||
|
domain_id=domain_id, group_id=group_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class OSInheritDomainGroupRolesListResource(flask_restful.Resource):
|
||||||
|
def get(self, domain_id, group_id):
|
||||||
|
"""List roles (inherited) for a group on a domain.
|
||||||
|
|
||||||
|
GET/HEAD /OS-INHERIT/domains/{domain_id}/groups/{group_id}
|
||||||
|
/roles/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:list_grants',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
domain_id=domain_id, group_id=group_id))
|
||||||
|
refs = PROVIDERS.assignment_api.list_grants(
|
||||||
|
domain_id=domain_id, group_id=group_id, inherited_to_projects=True)
|
||||||
|
return ks_flask.ResourceBase.wrap_collection(
|
||||||
|
refs, collection_name='roles')
|
||||||
|
|
||||||
|
|
||||||
|
class OSInheritDomainUserRolesResource(flask_restful.Resource):
|
||||||
|
def get(self, domain_id, user_id, role_id):
|
||||||
|
"""Check for an inherited grant for a user on a domain.
|
||||||
|
|
||||||
|
GET/HEAD /OS-INHERIT/domains/{domain_id}/users/{user_id}/roles
|
||||||
|
/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:check_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
domain_id=domain_id, user_id=user_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.get_grant(
|
||||||
|
domain_id=domain_id, user_id=user_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def put(self, domain_id, user_id, role_id):
|
||||||
|
"""Create an inherited grant for a user on a domain.
|
||||||
|
|
||||||
|
PUT /OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}
|
||||||
|
/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:create_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
domain_id=domain_id, user_id=user_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.create_grant(
|
||||||
|
domain_id=domain_id, user_id=user_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def delete(self, domain_id, user_id, role_id):
|
||||||
|
"""Revoke a grant from a user on a domain.
|
||||||
|
|
||||||
|
DELETE /OS-INHERIT/domains/{domain_id}/users/{user_id}/roles
|
||||||
|
/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:revoke_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
domain_id=domain_id, user_id=user_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.delete_grant(
|
||||||
|
domain_id=domain_id, user_id=user_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class OSInheritDomainUserRolesListResource(flask_restful.Resource):
|
||||||
|
def get(self, domain_id, user_id):
|
||||||
|
"""List roles (inherited) for a user on a domain.
|
||||||
|
|
||||||
|
GET/HEAD /OS-INHERIT/domains/{domain_id}/users/{user_id}
|
||||||
|
/roles/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:list_grants',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
domain_id=domain_id, user_id=user_id))
|
||||||
|
refs = PROVIDERS.assignment_api.list_grants(
|
||||||
|
domain_id=domain_id, user_id=user_id, inherited_to_projects=True)
|
||||||
|
return ks_flask.ResourceBase.wrap_collection(
|
||||||
|
refs, collection_name='roles')
|
||||||
|
|
||||||
|
|
||||||
|
class OSInheritProjectUserResource(flask_restful.Resource):
|
||||||
|
def get(self, project_id, user_id, role_id):
|
||||||
|
"""Check for an inherited grant for a user on a project.
|
||||||
|
|
||||||
|
GET/HEAD /OS-INHERIT/projects/{project_id}/users/{user_id}
|
||||||
|
/roles/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:check_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
project_id=project_id, user_id=user_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.get_grant(
|
||||||
|
project_id=project_id, user_id=user_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def put(self, project_id, user_id, role_id):
|
||||||
|
"""Create an inherited grant for a user on a project.
|
||||||
|
|
||||||
|
PUT /OS-INHERIT/projects/{project_id}/users/{user_id}
|
||||||
|
/roles/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:create_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
project_id=project_id, user_id=user_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.create_grant(
|
||||||
|
project_id=project_id, user_id=user_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def delete(self, project_id, user_id, role_id):
|
||||||
|
"""Revoke an inherited grant for a user on a project.
|
||||||
|
|
||||||
|
DELETE /OS-INHERIT/projects/{project_id}/users/{user_id}
|
||||||
|
/roles/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:revoke_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
project_id=project_id, user_id=user_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.delete_grant(
|
||||||
|
project_id=project_id, user_id=user_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class OSInheritProjectGroupResource(flask_restful.Resource):
|
||||||
|
def get(self, project_id, group_id, role_id):
|
||||||
|
"""Check for an inherited grant for a group on a project.
|
||||||
|
|
||||||
|
GET/HEAD /OS-INHERIT/projects/{project_id}/groups/{group_id}
|
||||||
|
/roles/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:check_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
project_id=project_id, group_id=group_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.get_grant(
|
||||||
|
project_id=project_id, group_id=group_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def put(self, project_id, group_id, role_id):
|
||||||
|
"""Create an inherited grant for a group on a project.
|
||||||
|
|
||||||
|
PUT /OS-INHERIT/projects/{project_id}/groups/{group_id}
|
||||||
|
/roles/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:create_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
project_id=project_id, group_id=group_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.create_grant(
|
||||||
|
project_id=project_id, group_id=group_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
def delete(self, project_id, group_id, role_id):
|
||||||
|
"""Revoke an inherited grant for a group on a project.
|
||||||
|
|
||||||
|
DELETE /OS-INHERIT/projects/{project_id}/groups/{group_id}
|
||||||
|
/roles/{role_id}/inherited_to_projects
|
||||||
|
"""
|
||||||
|
ENFORCER.enforce_call(
|
||||||
|
action='identity:revoke_grant',
|
||||||
|
target_attr=_build_enforcement_target_attr(
|
||||||
|
project_id=project_id, group_id=group_id, role_id=role_id))
|
||||||
|
PROVIDERS.assignment_api.delete_grant(
|
||||||
|
project_id=project_id, group_id=group_id, role_id=role_id,
|
||||||
|
inherited_to_projects=True)
|
||||||
|
return None, http_client.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class OSInheritAPI(ks_flask.APIBase):
|
||||||
|
_name = "OS-INHERIT"
|
||||||
|
_import_name = __name__
|
||||||
|
_api_url_prefix = '/OS-INHERIT'
|
||||||
|
resources = []
|
||||||
|
resource_mapping = [
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=OSInheritDomainGroupRolesResource,
|
||||||
|
url=('/domains/<string:domain_id>/groups/<string:group_id>/roles'
|
||||||
|
'/<string:role_id>/inherited_to_projects'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_group_role_inherited_to_projects',
|
||||||
|
resource_relation_func=_build_resource_relation,
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
|
'group_id': json_home.Parameters.GROUP_ID,
|
||||||
|
'role_id': json_home.Parameters.ROLE_ID}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=OSInheritDomainGroupRolesListResource,
|
||||||
|
url=('/domains/<string:domain_id>/groups/<string:group_id>/roles'
|
||||||
|
'/inherited_to_projects'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_group_roles_inherited_to_projects',
|
||||||
|
resource_relation_func=_build_resource_relation,
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
|
'group_id': json_home.Parameters.GROUP_ID}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=OSInheritDomainUserRolesResource,
|
||||||
|
url=('/domains/<string:domain_id>/users/<string:user_id>/roles'
|
||||||
|
'/<string:role_id>/inherited_to_projects'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_user_role_inherited_to_projects',
|
||||||
|
resource_relation_func=_build_resource_relation,
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
|
'user_id': json_home.Parameters.USER_ID,
|
||||||
|
'role_id': json_home.Parameters.ROLE_ID}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=OSInheritDomainUserRolesListResource,
|
||||||
|
url=('/domains/<string:domain_id>/users/<string:user_id>/roles'
|
||||||
|
'/inherited_to_projects'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='domain_user_roles_inherited_to_projects',
|
||||||
|
resource_relation_func=_build_resource_relation,
|
||||||
|
path_vars={
|
||||||
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
|
'user_id': json_home.Parameters.USER_ID}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=OSInheritProjectUserResource,
|
||||||
|
url=('projects/<string:project_id>/users/<string:user_id>/roles'
|
||||||
|
'/<string:role_id>/inherited_to_projects'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='project_user_role_inherited_to_projects',
|
||||||
|
resource_relation_func=_build_resource_relation,
|
||||||
|
path_vars={
|
||||||
|
'project_id': json_home.Parameters.PROJECT_ID,
|
||||||
|
'user_id': json_home.Parameters.USER_ID,
|
||||||
|
'role_id': json_home.Parameters.ROLE_ID}),
|
||||||
|
ks_flask.construct_resource_map(
|
||||||
|
resource=OSInheritProjectGroupResource,
|
||||||
|
url=('projects/<string:project_id>/groups/<string:group_id>/roles'
|
||||||
|
'/<string:role_id>/inherited_to_projects'),
|
||||||
|
resource_kwargs={},
|
||||||
|
rel='project_group_role_inherited_to_projects',
|
||||||
|
resource_relation_func=_build_resource_relation,
|
||||||
|
path_vars={
|
||||||
|
'project_id': json_home.Parameters.PROJECT_ID,
|
||||||
|
'group_id': json_home.Parameters.GROUP_ID,
|
||||||
|
'role_id': json_home.Parameters.ROLE_ID})
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
APIs = (OSInheritAPI,)
|
|
@ -15,18 +15,11 @@
|
||||||
|
|
||||||
"""WSGI Routers for the Assignment service."""
|
"""WSGI Routers for the Assignment service."""
|
||||||
|
|
||||||
import functools
|
|
||||||
|
|
||||||
from keystone.assignment import controllers
|
from keystone.assignment import controllers
|
||||||
from keystone.common import json_home
|
from keystone.common import json_home
|
||||||
from keystone.common import wsgi
|
from keystone.common import wsgi
|
||||||
|
|
||||||
|
|
||||||
build_os_inherit_relation = functools.partial(
|
|
||||||
json_home.build_v3_extension_resource_relation,
|
|
||||||
extension_name='OS-INHERIT', extension_version='1.0')
|
|
||||||
|
|
||||||
|
|
||||||
class Public(wsgi.ComposableRouter):
|
class Public(wsgi.ComposableRouter):
|
||||||
def add_routes(self, mapper):
|
def add_routes(self, mapper):
|
||||||
tenant_controller = controllers.TenantAssignment()
|
tenant_controller = controllers.TenantAssignment()
|
||||||
|
@ -38,7 +31,7 @@ class Public(wsgi.ComposableRouter):
|
||||||
|
|
||||||
class Routers(wsgi.RoutersBase):
|
class Routers(wsgi.RoutersBase):
|
||||||
|
|
||||||
_path_prefixes = ('users', 'projects', 'domains', 'OS-INHERIT')
|
_path_prefixes = ('users', 'projects', 'domains')
|
||||||
|
|
||||||
def append_v3_routers(self, mapper, routers):
|
def append_v3_routers(self, mapper, routers):
|
||||||
|
|
||||||
|
@ -137,81 +130,3 @@ class Routers(wsgi.RoutersBase):
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
'domain_id': json_home.Parameters.DOMAIN_ID,
|
||||||
'group_id': json_home.Parameters.GROUP_ID,
|
'group_id': json_home.Parameters.GROUP_ID,
|
||||||
})
|
})
|
||||||
self._add_resource(
|
|
||||||
mapper, grant_controller,
|
|
||||||
path='/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/'
|
|
||||||
'{role_id}/inherited_to_projects',
|
|
||||||
get_head_action='check_grant',
|
|
||||||
put_action='create_grant',
|
|
||||||
delete_action='revoke_grant',
|
|
||||||
rel=build_os_inherit_relation(
|
|
||||||
resource_name='domain_user_role_inherited_to_projects'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
|
||||||
'role_id': json_home.Parameters.ROLE_ID,
|
|
||||||
'user_id': json_home.Parameters.USER_ID,
|
|
||||||
})
|
|
||||||
self._add_resource(
|
|
||||||
mapper, grant_controller,
|
|
||||||
path='/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/'
|
|
||||||
'{role_id}/inherited_to_projects',
|
|
||||||
get_head_action='check_grant',
|
|
||||||
put_action='create_grant',
|
|
||||||
delete_action='revoke_grant',
|
|
||||||
rel=build_os_inherit_relation(
|
|
||||||
resource_name='domain_group_role_inherited_to_projects'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
|
||||||
'group_id': json_home.Parameters.GROUP_ID,
|
|
||||||
'role_id': json_home.Parameters.ROLE_ID,
|
|
||||||
})
|
|
||||||
self._add_resource(
|
|
||||||
mapper, grant_controller,
|
|
||||||
path='/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/'
|
|
||||||
'inherited_to_projects',
|
|
||||||
get_head_action='list_grants',
|
|
||||||
rel=build_os_inherit_relation(
|
|
||||||
resource_name='domain_group_roles_inherited_to_projects'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
|
||||||
'group_id': json_home.Parameters.GROUP_ID,
|
|
||||||
})
|
|
||||||
self._add_resource(
|
|
||||||
mapper, grant_controller,
|
|
||||||
path='/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/'
|
|
||||||
'inherited_to_projects',
|
|
||||||
get_head_action='list_grants',
|
|
||||||
rel=build_os_inherit_relation(
|
|
||||||
resource_name='domain_user_roles_inherited_to_projects'),
|
|
||||||
path_vars={
|
|
||||||
'domain_id': json_home.Parameters.DOMAIN_ID,
|
|
||||||
'user_id': json_home.Parameters.USER_ID,
|
|
||||||
})
|
|
||||||
self._add_resource(
|
|
||||||
mapper, grant_controller,
|
|
||||||
path='/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/'
|
|
||||||
'{role_id}/inherited_to_projects',
|
|
||||||
get_head_action='check_grant',
|
|
||||||
put_action='create_grant',
|
|
||||||
delete_action='revoke_grant',
|
|
||||||
rel=build_os_inherit_relation(
|
|
||||||
resource_name='project_user_role_inherited_to_projects'),
|
|
||||||
path_vars={
|
|
||||||
'project_id': json_home.Parameters.PROJECT_ID,
|
|
||||||
'user_id': json_home.Parameters.USER_ID,
|
|
||||||
'role_id': json_home.Parameters.ROLE_ID,
|
|
||||||
})
|
|
||||||
self._add_resource(
|
|
||||||
mapper, grant_controller,
|
|
||||||
path='/OS-INHERIT/projects/{project_id}/groups/{group_id}/'
|
|
||||||
'roles/{role_id}/inherited_to_projects',
|
|
||||||
get_head_action='check_grant',
|
|
||||||
put_action='create_grant',
|
|
||||||
delete_action='revoke_grant',
|
|
||||||
rel=build_os_inherit_relation(
|
|
||||||
resource_name='project_group_role_inherited_to_projects'),
|
|
||||||
path_vars={
|
|
||||||
'project_id': json_home.Parameters.PROJECT_ID,
|
|
||||||
'group_id': json_home.Parameters.GROUP_ID,
|
|
||||||
'role_id': json_home.Parameters.ROLE_ID,
|
|
||||||
})
|
|
||||||
|
|
|
@ -41,9 +41,10 @@ _MOVED_API_PREFIXES = frozenset(
|
||||||
['credentials',
|
['credentials',
|
||||||
'endpoints',
|
'endpoints',
|
||||||
'groups',
|
'groups',
|
||||||
'OS-OAUTH1',
|
|
||||||
'OS-EP-FILTER',
|
'OS-EP-FILTER',
|
||||||
'OS-FEDERATION',
|
'OS-FEDERATION',
|
||||||
|
'OS-INHERIT',
|
||||||
|
'OS-OAUTH1',
|
||||||
'OS-REVOKE',
|
'OS-REVOKE',
|
||||||
'OS-SIMPLE-CERT',
|
'OS-SIMPLE-CERT',
|
||||||
'OS-TRUST',
|
'OS-TRUST',
|
||||||
|
|
|
@ -1693,7 +1693,8 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
|
||||||
# Define URLs
|
# Define URLs
|
||||||
direct_url = '%s/users/%s/roles/%s' % (
|
direct_url = '%s/users/%s/roles/%s' % (
|
||||||
target_url, self.user_id, role['id'])
|
target_url, self.user_id, role['id'])
|
||||||
inherited_url = '/OS-INHERIT/%s/inherited_to_projects' % direct_url
|
inherited_url = ('/OS-INHERIT/%s/inherited_to_projects' %
|
||||||
|
direct_url.lstrip('/'))
|
||||||
|
|
||||||
# Create the direct assignment
|
# Create the direct assignment
|
||||||
self.put(direct_url)
|
self.put(direct_url)
|
||||||
|
|
Loading…
Reference in New Issue