"Fossies" - the Fresh Open Source Software Archive

Member "keystone-17.0.0/keystone/api/groups.py" (13 May 2020, 8791 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 "groups.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/groups
   14 
   15 import flask
   16 import flask_restful
   17 import functools
   18 import http.client
   19 
   20 from keystone.common import json_home
   21 from keystone.common import provider_api
   22 from keystone.common import rbac_enforcer
   23 from keystone.common import validation
   24 import keystone.conf
   25 from keystone import exception
   26 from keystone.identity import schema
   27 from keystone import notifications
   28 from keystone.server import flask as ks_flask
   29 
   30 
   31 CONF = keystone.conf.CONF
   32 ENFORCER = rbac_enforcer.RBACEnforcer
   33 PROVIDERS = provider_api.ProviderAPIs
   34 
   35 
   36 def _build_group_target_enforcement():
   37     target = {}
   38     try:
   39         target['group'] = PROVIDERS.identity_api.get_group(
   40             flask.request.view_args.get('group_id')
   41         )
   42     except exception.NotFound:  # nosec
   43         # Defer existance in the event the group doesn't exist, we'll
   44         # check this later anyway.
   45         pass
   46 
   47     return target
   48 
   49 
   50 class GroupsResource(ks_flask.ResourceBase):
   51     collection_key = 'groups'
   52     member_key = 'group'
   53     get_member_from_driver = PROVIDERS.deferred_provider_lookup(
   54         api='identity_api', method='get_group')
   55 
   56     def get(self, group_id=None):
   57         if group_id is not None:
   58             return self._get_group(group_id)
   59         return self._list_groups()
   60 
   61     def _get_group(self, group_id):
   62         """Get a group reference.
   63 
   64         GET/HEAD /groups/{group_id}
   65         """
   66         ENFORCER.enforce_call(
   67             action='identity:get_group',
   68             build_target=_build_group_target_enforcement
   69         )
   70         return self.wrap_member(PROVIDERS.identity_api.get_group(group_id))
   71 
   72     def _list_groups(self):
   73         """List groups.
   74 
   75         GET/HEAD /groups
   76         """
   77         filters = ['domain_id', 'name']
   78         target = None
   79         if self.oslo_context.domain_id:
   80             target = {'group': {'domain_id': self.oslo_context.domain_id}}
   81         ENFORCER.enforce_call(action='identity:list_groups', filters=filters,
   82                               target_attr=target)
   83         hints = self.build_driver_hints(filters)
   84         domain = self._get_domain_id_for_list_request()
   85         refs = PROVIDERS.identity_api.list_groups(domain_scope=domain,
   86                                                   hints=hints)
   87         if self.oslo_context.domain_id:
   88             filtered_refs = []
   89             for ref in refs:
   90                 if ref['domain_id'] == target['group']['domain_id']:
   91                     filtered_refs.append(ref)
   92             refs = filtered_refs
   93         return self.wrap_collection(refs, hints=hints)
   94 
   95     def post(self):
   96         """Create group.
   97 
   98         POST /groups
   99         """
  100         group = self.request_body_json.get('group', {})
  101         target = {'group': group}
  102         ENFORCER.enforce_call(
  103             action='identity:create_group', target_attr=target
  104         )
  105         validation.lazy_validate(schema.group_create, group)
  106         group = self._normalize_dict(group)
  107         group = self._normalize_domain_id(group)
  108         ref = PROVIDERS.identity_api.create_group(
  109             group, initiator=self.audit_initiator)
  110         return self.wrap_member(ref), http.client.CREATED
  111 
  112     def patch(self, group_id):
  113         """Update group.
  114 
  115         PATCH /groups/{group_id}
  116         """
  117         ENFORCER.enforce_call(
  118             action='identity:update_group',
  119             build_target=_build_group_target_enforcement
  120         )
  121         group = self.request_body_json.get('group', {})
  122         validation.lazy_validate(schema.group_update, group)
  123         self._require_matching_id(group)
  124         ref = PROVIDERS.identity_api.update_group(
  125             group_id, group, initiator=self.audit_initiator)
  126         return self.wrap_member(ref)
  127 
  128     def delete(self, group_id):
  129         """Delete group.
  130 
  131         DELETE /groups/{group_id}
  132         """
  133         ENFORCER.enforce_call(action='identity:delete_group')
  134         PROVIDERS.identity_api.delete_group(
  135             group_id, initiator=self.audit_initiator)
  136         return None, http.client.NO_CONTENT
  137 
  138 
  139 class GroupUsersResource(ks_flask.ResourceBase):
  140     def get(self, group_id):
  141         """Get list of users in group.
  142 
  143         GET/HEAD /groups/{group_id}/users
  144         """
  145         filters = ['domain_id', 'enabled', 'name', 'password_expires_at']
  146         target = None
  147         try:
  148             target = {'group': PROVIDERS.identity_api.get_group(group_id)}
  149         except exception.GroupNotFound:
  150             # NOTE(morgan): If we have an issue populating the group
  151             # data, leage target empty. This is the safest route and does not
  152             # leak data before enforcement happens.
  153             pass
  154         ENFORCER.enforce_call(action='identity:list_users_in_group',
  155                               target_attr=target, filters=filters)
  156         hints = ks_flask.ResourceBase.build_driver_hints(filters)
  157         refs = PROVIDERS.identity_api.list_users_in_group(
  158             group_id, hints=hints)
  159         if (self.oslo_context.domain_id):
  160             filtered_refs = []
  161             for ref in refs:
  162                 if ref['domain_id'] == self.oslo_context.domain_id:
  163                     filtered_refs.append(ref)
  164             refs = filtered_refs
  165         return ks_flask.ResourceBase.wrap_collection(
  166             refs, hints=hints, collection_name='users')
  167 
  168 
  169 class UserGroupCRUDResource(flask_restful.Resource):
  170     @staticmethod
  171     def _build_enforcement_target_attr(user_id, group_id):
  172         target = {}
  173         try:
  174             target['group'] = PROVIDERS.identity_api.get_group(group_id)
  175         except exception.GroupNotFound:
  176             # Don't populate group data if group is not found.
  177             pass
  178 
  179         try:
  180             target['user'] = PROVIDERS.identity_api.get_user(user_id)
  181         except exception.UserNotFound:
  182             # Don't populate user data if user is not found
  183             pass
  184 
  185         return target
  186 
  187     def get(self, group_id, user_id):
  188         """Check if a user is in a group.
  189 
  190         GET/HEAD /groups/{group_id}/users/{user_id}
  191         """
  192         ENFORCER.enforce_call(
  193             action='identity:check_user_in_group',
  194             build_target=functools.partial(self._build_enforcement_target_attr,
  195                                            user_id, group_id))
  196         PROVIDERS.identity_api.check_user_in_group(user_id, group_id)
  197         return None, http.client.NO_CONTENT
  198 
  199     def put(self, group_id, user_id):
  200         """Add user to group.
  201 
  202         PUT /groups/{group_id}/users/{user_id}
  203         """
  204         ENFORCER.enforce_call(
  205             action='identity:add_user_to_group',
  206             build_target=functools.partial(self._build_enforcement_target_attr,
  207                                            user_id, group_id))
  208         PROVIDERS.identity_api.add_user_to_group(
  209             user_id, group_id, initiator=notifications.build_audit_initiator())
  210         return None, http.client.NO_CONTENT
  211 
  212     def delete(self, group_id, user_id):
  213         """Remove user from group.
  214 
  215         DELETE /groups/{group_id}/users/{user_id}
  216         """
  217         ENFORCER.enforce_call(
  218             action='identity:remove_user_from_group',
  219             build_target=functools.partial(self._build_enforcement_target_attr,
  220                                            user_id, group_id))
  221         PROVIDERS.identity_api.remove_user_from_group(
  222             user_id, group_id, initiator=notifications.build_audit_initiator())
  223         return None, http.client.NO_CONTENT
  224 
  225 
  226 class GroupAPI(ks_flask.APIBase):
  227     _name = 'groups'
  228     _import_name = __name__
  229     resources = [GroupsResource]
  230     resource_mapping = [
  231         ks_flask.construct_resource_map(
  232             resource=GroupUsersResource,
  233             url='/groups/<string:group_id>/users',
  234             resource_kwargs={},
  235             rel='group_users',
  236             path_vars={'group_id': json_home.Parameters.GROUP_ID}),
  237         ks_flask.construct_resource_map(
  238             resource=UserGroupCRUDResource,
  239             url='/groups/<string:group_id>/users/<string:user_id>',
  240             resource_kwargs={},
  241             rel='group_user',
  242             path_vars={
  243                 'group_id': json_home.Parameters.GROUP_ID,
  244                 'user_id': json_home.Parameters.USER_ID})
  245     ]
  246 
  247 
  248 APIs = (GroupAPI,)