"Fossies" - the Fresh Open Source Software Archive

Member "keystone-17.0.0/keystone/api/os_inherit.py" (13 May 2020, 19007 Bytes) of package /linux/misc/openstack/keystone-17.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "os_inherit.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 16.0.1_vs_17.0.0.

    1 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
    2 #    not use this file except in compliance with the License. You may obtain
    3 #    a copy of the License at
    4 #
    5 #         http://www.apache.org/licenses/LICENSE-2.0
    6 #
    7 #    Unless required by applicable law or agreed to in writing, software
    8 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    9 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   10 #    License for the specific language governing permissions and limitations
   11 #    under the License.
   12 
   13 # This file handles all flask-restful resources for /v3/OS-INHERIT
   14 
   15 import flask_restful
   16 import functools
   17 import http.client
   18 from oslo_log import log
   19 
   20 from keystone.api._shared import json_home_relations
   21 from keystone.common import json_home
   22 from keystone.common import provider_api
   23 from keystone.common import rbac_enforcer
   24 from keystone import exception
   25 from keystone.server import flask as ks_flask
   26 
   27 
   28 ENFORCER = rbac_enforcer.RBACEnforcer
   29 PROVIDERS = provider_api.ProviderAPIs
   30 LOG = log.getLogger(__name__)
   31 
   32 _build_resource_relation = json_home_relations.os_inherit_resource_rel_func
   33 
   34 
   35 def _build_enforcement_target_attr(role_id=None, user_id=None, group_id=None,
   36                                    project_id=None, domain_id=None,
   37                                    allow_non_existing=False):
   38     """Check protection for role grant APIs.
   39 
   40     The policy rule might want to inspect attributes of any of the entities
   41     involved in the grant.  So we get these and pass them to the
   42     check_protection() handler in the controller.
   43 
   44     """
   45     # !!!!!!!!!! WARNING: Security Concern !!!!!!!!!!
   46     #
   47     # NOTE(morgan): This function must handle all expected exceptions,
   48     # including NOT FOUNDs otherwise the exception will be raised up to the
   49     # end user before enforcement, resulting in the exception being returned
   50     # instead of an appropriate 403. In each case, it is logged that a value
   51     # was not found and the target is explicitly set to empty. This allows for
   52     # the enforcement rule to decide what to do (most of the time raise an
   53     # appropriate 403).
   54     #
   55     # ###############################################
   56 
   57     target = {}
   58     if role_id:
   59         try:
   60             target['role'] = PROVIDERS.role_api.get_role(role_id)
   61         except exception.RoleNotFound:
   62             LOG.info('Role (%(role_id)s) not found, Enforcement target of '
   63                      '`role` remaind empty', {'role_id': role_id})
   64             target['role'] = {}
   65     if user_id:
   66         try:
   67             target['user'] = PROVIDERS.identity_api.get_user(user_id)
   68         except exception.UserNotFound:
   69             if not allow_non_existing:
   70                 LOG.info('User (%(user_id)s) was not found. Enforcement target'
   71                          ' of `user` remains empty.', {'user_id': user_id})
   72                 target['user'] = {}
   73     else:
   74         try:
   75             target['group'] = PROVIDERS.identity_api.get_group(group_id)
   76         except exception.GroupNotFound:
   77             if not allow_non_existing:
   78                 LOG.info('Group (%(group_id)s) was not found. Enforcement '
   79                          'target of `group` remains empty.',
   80                          {'group_id': group_id})
   81                 target['group'] = {}
   82 
   83     # NOTE(lbragstad): This if/else check will need to be expanded in the
   84     # future to handle system hierarchies if that is implemented.
   85     if domain_id:
   86         try:
   87             target['domain'] = PROVIDERS.resource_api.get_domain(domain_id)
   88         except exception.DomainNotFound:
   89             LOG.info('Domain (%(domain_id)s) was not found. Enforcement '
   90                      'target of `domain` remains empty.',
   91                      {'domain_id': domain_id})
   92             target['domain'] = {}
   93     elif project_id:
   94         try:
   95             target['project'] = PROVIDERS.resource_api.get_project(project_id)
   96         except exception.ProjectNotFound:
   97             LOG.info('Project (%(project_id)s) was not found. Enforcement '
   98                      'target of `project` remains empty.',
   99                      {'project_id': project_id})
  100             target['project'] = {}
  101 
  102     return target
  103 
  104 
  105 class OSInheritDomainGroupRolesResource(flask_restful.Resource):
  106     def get(self, domain_id, group_id, role_id):
  107         """Check for an inherited grant for a group on a domain.
  108 
  109         GET/HEAD /OS-INHERIT/domains/{domain_id}/groups/{group_id}
  110                  /roles/{role_id}/inherited_to_projects
  111         """
  112         ENFORCER.enforce_call(
  113             action='identity:check_grant',
  114             build_target=functools.partial(_build_enforcement_target_attr,
  115                                            domain_id=domain_id,
  116                                            group_id=group_id,
  117                                            role_id=role_id))
  118         PROVIDERS.assignment_api.get_grant(
  119             domain_id=domain_id, group_id=group_id, role_id=role_id,
  120             inherited_to_projects=True)
  121         return None, http.client.NO_CONTENT
  122 
  123     def put(self, domain_id, group_id, role_id):
  124         """Create an inherited grant for a group on a domain.
  125 
  126         PUT /OS-INHERIT/domains/{domain_id}/groups/{group_id}
  127             /roles/{role_id}/inherited_to_projects
  128         """
  129         ENFORCER.enforce_call(
  130             action='identity:create_grant',
  131             build_target=functools.partial(_build_enforcement_target_attr,
  132                                            domain_id=domain_id,
  133                                            group_id=group_id,
  134                                            role_id=role_id))
  135         PROVIDERS.assignment_api.create_grant(
  136             domain_id=domain_id, group_id=group_id, role_id=role_id,
  137             inherited_to_projects=True)
  138         return None, http.client.NO_CONTENT
  139 
  140     def delete(self, domain_id, group_id, role_id):
  141         """Revoke an inherited grant for a group on a domain.
  142 
  143         DELETE /OS-INHERIT/domains/{domain_id}/groups/{group_id}
  144                /roles/{role_id}/inherited_to_projects
  145         """
  146         ENFORCER.enforce_call(
  147             action='identity:revoke_grant',
  148             build_target=functools.partial(_build_enforcement_target_attr,
  149                                            domain_id=domain_id,
  150                                            group_id=group_id,
  151                                            role_id=role_id))
  152         PROVIDERS.assignment_api.delete_grant(
  153             domain_id=domain_id, group_id=group_id, role_id=role_id,
  154             inherited_to_projects=True)
  155         return None, http.client.NO_CONTENT
  156 
  157 
  158 class OSInheritDomainGroupRolesListResource(flask_restful.Resource):
  159     def get(self, domain_id, group_id):
  160         """List roles (inherited) for a group on a domain.
  161 
  162         GET/HEAD /OS-INHERIT/domains/{domain_id}/groups/{group_id}
  163                  /roles/inherited_to_projects
  164         """
  165         ENFORCER.enforce_call(
  166             action='identity:list_grants',
  167             build_target=functools.partial(_build_enforcement_target_attr,
  168                                            domain_id=domain_id,
  169                                            group_id=group_id))
  170         refs = PROVIDERS.assignment_api.list_grants(
  171             domain_id=domain_id, group_id=group_id, inherited_to_projects=True)
  172         return ks_flask.ResourceBase.wrap_collection(
  173             refs, collection_name='roles')
  174 
  175 
  176 class OSInheritDomainUserRolesResource(flask_restful.Resource):
  177     def get(self, domain_id, user_id, role_id):
  178         """Check for an inherited grant for a user on a domain.
  179 
  180         GET/HEAD /OS-INHERIT/domains/{domain_id}/users/{user_id}/roles
  181                  /{role_id}/inherited_to_projects
  182         """
  183         ENFORCER.enforce_call(
  184             action='identity:check_grant',
  185             build_target=functools.partial(_build_enforcement_target_attr,
  186                                            domain_id=domain_id,
  187                                            user_id=user_id,
  188                                            role_id=role_id))
  189         PROVIDERS.assignment_api.get_grant(
  190             domain_id=domain_id, user_id=user_id, role_id=role_id,
  191             inherited_to_projects=True)
  192         return None, http.client.NO_CONTENT
  193 
  194     def put(self, domain_id, user_id, role_id):
  195         """Create an inherited grant for a user on a domain.
  196 
  197         PUT /OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}
  198             /inherited_to_projects
  199         """
  200         ENFORCER.enforce_call(
  201             action='identity:create_grant',
  202             build_target=functools.partial(_build_enforcement_target_attr,
  203                                            domain_id=domain_id,
  204                                            user_id=user_id,
  205                                            role_id=role_id))
  206         PROVIDERS.assignment_api.create_grant(
  207             domain_id=domain_id, user_id=user_id, role_id=role_id,
  208             inherited_to_projects=True)
  209         return None, http.client.NO_CONTENT
  210 
  211     def delete(self, domain_id, user_id, role_id):
  212         """Revoke a grant from a user on a domain.
  213 
  214         DELETE /OS-INHERIT/domains/{domain_id}/users/{user_id}/roles
  215                /{role_id}/inherited_to_projects
  216         """
  217         ENFORCER.enforce_call(
  218             action='identity:revoke_grant',
  219             build_target=functools.partial(_build_enforcement_target_attr,
  220                                            domain_id=domain_id,
  221                                            user_id=user_id,
  222                                            role_id=role_id))
  223         PROVIDERS.assignment_api.delete_grant(
  224             domain_id=domain_id, user_id=user_id, role_id=role_id,
  225             inherited_to_projects=True)
  226         return None, http.client.NO_CONTENT
  227 
  228 
  229 class OSInheritDomainUserRolesListResource(flask_restful.Resource):
  230     def get(self, domain_id, user_id):
  231         """List roles (inherited) for a user on a domain.
  232 
  233         GET/HEAD /OS-INHERIT/domains/{domain_id}/users/{user_id}
  234                  /roles/inherited_to_projects
  235         """
  236         ENFORCER.enforce_call(
  237             action='identity:list_grants',
  238             build_target=functools.partial(_build_enforcement_target_attr,
  239                                            domain_id=domain_id,
  240                                            user_id=user_id))
  241         refs = PROVIDERS.assignment_api.list_grants(
  242             domain_id=domain_id, user_id=user_id, inherited_to_projects=True)
  243         return ks_flask.ResourceBase.wrap_collection(
  244             refs, collection_name='roles')
  245 
  246 
  247 class OSInheritProjectUserResource(flask_restful.Resource):
  248     def get(self, project_id, user_id, role_id):
  249         """Check for an inherited grant for a user on a project.
  250 
  251         GET/HEAD /OS-INHERIT/projects/{project_id}/users/{user_id}
  252                  /roles/{role_id}/inherited_to_projects
  253         """
  254         ENFORCER.enforce_call(
  255             action='identity:check_grant',
  256             build_target=functools.partial(_build_enforcement_target_attr,
  257                                            project_id=project_id,
  258                                            user_id=user_id,
  259                                            role_id=role_id))
  260         PROVIDERS.assignment_api.get_grant(
  261             project_id=project_id, user_id=user_id, role_id=role_id,
  262             inherited_to_projects=True)
  263         return None, http.client.NO_CONTENT
  264 
  265     def put(self, project_id, user_id, role_id):
  266         """Create an inherited grant for a user on a project.
  267 
  268         PUT /OS-INHERIT/projects/{project_id}/users/{user_id}
  269             /roles/{role_id}/inherited_to_projects
  270         """
  271         ENFORCER.enforce_call(
  272             action='identity:create_grant',
  273             build_target=functools.partial(_build_enforcement_target_attr,
  274                                            project_id=project_id,
  275                                            user_id=user_id,
  276                                            role_id=role_id))
  277         PROVIDERS.assignment_api.create_grant(
  278             project_id=project_id, user_id=user_id, role_id=role_id,
  279             inherited_to_projects=True)
  280         return None, http.client.NO_CONTENT
  281 
  282     def delete(self, project_id, user_id, role_id):
  283         """Revoke an inherited grant for a user on a project.
  284 
  285         DELETE /OS-INHERIT/projects/{project_id}/users/{user_id}
  286                /roles/{role_id}/inherited_to_projects
  287         """
  288         ENFORCER.enforce_call(
  289             action='identity:revoke_grant',
  290             build_target=functools.partial(_build_enforcement_target_attr,
  291                                            project_id=project_id,
  292                                            user_id=user_id,
  293                                            role_id=role_id))
  294         PROVIDERS.assignment_api.delete_grant(
  295             project_id=project_id, user_id=user_id, role_id=role_id,
  296             inherited_to_projects=True)
  297         return None, http.client.NO_CONTENT
  298 
  299 
  300 class OSInheritProjectGroupResource(flask_restful.Resource):
  301     def get(self, project_id, group_id, role_id):
  302         """Check for an inherited grant for a group on a project.
  303 
  304         GET/HEAD /OS-INHERIT/projects/{project_id}/groups/{group_id}
  305                  /roles/{role_id}/inherited_to_projects
  306         """
  307         ENFORCER.enforce_call(
  308             action='identity:check_grant',
  309             build_target=functools.partial(_build_enforcement_target_attr,
  310                                            project_id=project_id,
  311                                            group_id=group_id,
  312                                            role_id=role_id))
  313         PROVIDERS.assignment_api.get_grant(
  314             project_id=project_id, group_id=group_id, role_id=role_id,
  315             inherited_to_projects=True)
  316         return None, http.client.NO_CONTENT
  317 
  318     def put(self, project_id, group_id, role_id):
  319         """Create an inherited grant for a group on a project.
  320 
  321         PUT /OS-INHERIT/projects/{project_id}/groups/{group_id}
  322             /roles/{role_id}/inherited_to_projects
  323         """
  324         ENFORCER.enforce_call(
  325             action='identity:create_grant',
  326             build_target=functools.partial(_build_enforcement_target_attr,
  327                                            project_id=project_id,
  328                                            group_id=group_id,
  329                                            role_id=role_id))
  330         PROVIDERS.assignment_api.create_grant(
  331             project_id=project_id, group_id=group_id, role_id=role_id,
  332             inherited_to_projects=True)
  333         return None, http.client.NO_CONTENT
  334 
  335     def delete(self, project_id, group_id, role_id):
  336         """Revoke an inherited grant for a group on a project.
  337 
  338         DELETE /OS-INHERIT/projects/{project_id}/groups/{group_id}
  339                /roles/{role_id}/inherited_to_projects
  340         """
  341         ENFORCER.enforce_call(
  342             action='identity:revoke_grant',
  343             build_target=functools.partial(_build_enforcement_target_attr,
  344                                            project_id=project_id,
  345                                            group_id=group_id,
  346                                            role_id=role_id))
  347         PROVIDERS.assignment_api.delete_grant(
  348             project_id=project_id, group_id=group_id, role_id=role_id,
  349             inherited_to_projects=True)
  350         return None, http.client.NO_CONTENT
  351 
  352 
  353 class OSInheritAPI(ks_flask.APIBase):
  354     _name = "OS-INHERIT"
  355     _import_name = __name__
  356     _api_url_prefix = '/OS-INHERIT'
  357     resources = []
  358     resource_mapping = [
  359         ks_flask.construct_resource_map(
  360             resource=OSInheritDomainGroupRolesResource,
  361             url=('/domains/<string:domain_id>/groups/<string:group_id>/roles'
  362                  '/<string:role_id>/inherited_to_projects'),
  363             resource_kwargs={},
  364             rel='domain_group_role_inherited_to_projects',
  365             resource_relation_func=_build_resource_relation,
  366             path_vars={
  367                 'domain_id': json_home.Parameters.DOMAIN_ID,
  368                 'group_id': json_home.Parameters.GROUP_ID,
  369                 'role_id': json_home.Parameters.ROLE_ID}),
  370         ks_flask.construct_resource_map(
  371             resource=OSInheritDomainGroupRolesListResource,
  372             url=('/domains/<string:domain_id>/groups/<string:group_id>/roles'
  373                  '/inherited_to_projects'),
  374             resource_kwargs={},
  375             rel='domain_group_roles_inherited_to_projects',
  376             resource_relation_func=_build_resource_relation,
  377             path_vars={
  378                 'domain_id': json_home.Parameters.DOMAIN_ID,
  379                 'group_id': json_home.Parameters.GROUP_ID}),
  380         ks_flask.construct_resource_map(
  381             resource=OSInheritDomainUserRolesResource,
  382             url=('/domains/<string:domain_id>/users/<string:user_id>/roles'
  383                  '/<string:role_id>/inherited_to_projects'),
  384             resource_kwargs={},
  385             rel='domain_user_role_inherited_to_projects',
  386             resource_relation_func=_build_resource_relation,
  387             path_vars={
  388                 'domain_id': json_home.Parameters.DOMAIN_ID,
  389                 'user_id': json_home.Parameters.USER_ID,
  390                 'role_id': json_home.Parameters.ROLE_ID}),
  391         ks_flask.construct_resource_map(
  392             resource=OSInheritDomainUserRolesListResource,
  393             url=('/domains/<string:domain_id>/users/<string:user_id>/roles'
  394                  '/inherited_to_projects'),
  395             resource_kwargs={},
  396             rel='domain_user_roles_inherited_to_projects',
  397             resource_relation_func=_build_resource_relation,
  398             path_vars={
  399                 'domain_id': json_home.Parameters.DOMAIN_ID,
  400                 'user_id': json_home.Parameters.USER_ID}),
  401         ks_flask.construct_resource_map(
  402             resource=OSInheritProjectUserResource,
  403             url=('projects/<string:project_id>/users/<string:user_id>/roles'
  404                  '/<string:role_id>/inherited_to_projects'),
  405             resource_kwargs={},
  406             rel='project_user_role_inherited_to_projects',
  407             resource_relation_func=_build_resource_relation,
  408             path_vars={
  409                 'project_id': json_home.Parameters.PROJECT_ID,
  410                 'user_id': json_home.Parameters.USER_ID,
  411                 'role_id': json_home.Parameters.ROLE_ID}),
  412         ks_flask.construct_resource_map(
  413             resource=OSInheritProjectGroupResource,
  414             url=('projects/<string:project_id>/groups/<string:group_id>/roles'
  415                  '/<string:role_id>/inherited_to_projects'),
  416             resource_kwargs={},
  417             rel='project_group_role_inherited_to_projects',
  418             resource_relation_func=_build_resource_relation,
  419             path_vars={
  420                 'project_id': json_home.Parameters.PROJECT_ID,
  421                 'group_id': json_home.Parameters.GROUP_ID,
  422                 'role_id': json_home.Parameters.ROLE_ID})
  423     ]
  424 
  425 
  426 APIs = (OSInheritAPI,)