Convert OS-INHERIT API to flask native dispatching
Convert OS-INHERIT API to flask native dispatching. NOTE: A minor test change was needed, the test was mis-constructing the URI with multiple slashes. The test now properly constructs the URI using an lstrip when combining the direct_url bits. Change-Id: I0907eb00cdfb9849342220f9b528f94175e71545 Partial-Bug: #1776504
This commit is contained in:
		@@ -17,6 +17,7 @@ from keystone.api import groups
 | 
			
		||||
from keystone.api import limits
 | 
			
		||||
from keystone.api import os_ep_filter
 | 
			
		||||
from keystone.api import os_federation
 | 
			
		||||
from keystone.api import os_inherit
 | 
			
		||||
from keystone.api import os_oauth1
 | 
			
		||||
from keystone.api import os_revoke
 | 
			
		||||
from keystone.api import os_simple_cert
 | 
			
		||||
@@ -38,6 +39,7 @@ __all__ = (
 | 
			
		||||
    'limits',
 | 
			
		||||
    'os_ep_filter',
 | 
			
		||||
    'os_federation',
 | 
			
		||||
    'os_inherit',
 | 
			
		||||
    'os_oauth1',
 | 
			
		||||
    'os_revoke',
 | 
			
		||||
    'os_simple_cert',
 | 
			
		||||
@@ -60,6 +62,7 @@ __apis__ = (
 | 
			
		||||
    limits,
 | 
			
		||||
    os_ep_filter,
 | 
			
		||||
    os_federation,
 | 
			
		||||
    os_inherit,
 | 
			
		||||
    os_oauth1,
 | 
			
		||||
    os_revoke,
 | 
			
		||||
    os_simple_cert,
 | 
			
		||||
 
 | 
			
		||||
@@ -65,3 +65,8 @@ os_federation_resource_rel_func = functools.partial(
 | 
			
		||||
os_federation_parameter_rel_func = functools.partial(
 | 
			
		||||
    json_home.build_v3_extension_parameter_relation,
 | 
			
		||||
    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')
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										399
									
								
								keystone/api/os_inherit.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										399
									
								
								keystone/api/os_inherit.py
									
									
									
									
									
										Normal file
									
								
							@@ -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."""
 | 
			
		||||
 | 
			
		||||
import functools
 | 
			
		||||
 | 
			
		||||
from keystone.assignment import controllers
 | 
			
		||||
from keystone.common import json_home
 | 
			
		||||
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):
 | 
			
		||||
    def add_routes(self, mapper):
 | 
			
		||||
        tenant_controller = controllers.TenantAssignment()
 | 
			
		||||
@@ -38,7 +31,7 @@ class Public(wsgi.ComposableRouter):
 | 
			
		||||
 | 
			
		||||
class Routers(wsgi.RoutersBase):
 | 
			
		||||
 | 
			
		||||
    _path_prefixes = ('users', 'projects', 'domains', 'OS-INHERIT')
 | 
			
		||||
    _path_prefixes = ('users', 'projects', 'domains')
 | 
			
		||||
 | 
			
		||||
    def append_v3_routers(self, mapper, routers):
 | 
			
		||||
 | 
			
		||||
@@ -137,81 +130,3 @@ class Routers(wsgi.RoutersBase):
 | 
			
		||||
                '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/'
 | 
			
		||||
            '{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',
 | 
			
		||||
     'endpoints',
 | 
			
		||||
     'groups',
 | 
			
		||||
     'OS-OAUTH1',
 | 
			
		||||
     'OS-EP-FILTER',
 | 
			
		||||
     'OS-FEDERATION',
 | 
			
		||||
     'OS-INHERIT',
 | 
			
		||||
     'OS-OAUTH1',
 | 
			
		||||
     'OS-REVOKE',
 | 
			
		||||
     'OS-SIMPLE-CERT',
 | 
			
		||||
     'OS-TRUST',
 | 
			
		||||
 
 | 
			
		||||
@@ -1693,7 +1693,8 @@ class AssignmentInheritanceTestCase(test_v3.RestfulTestCase,
 | 
			
		||||
            # Define URLs
 | 
			
		||||
            direct_url = '%s/users/%s/roles/%s' % (
 | 
			
		||||
                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
 | 
			
		||||
            self.put(direct_url)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user