keystone  18.0.0
About: OpenStack Keystone (Core Service: Identity) provides an authentication and authorization service for other OpenStack services. Provides a catalog of endpoints for all OpenStack services.
The "Victoria" series (maintained release).
  Fossies Dox: keystone-18.0.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

groups.py
Go to the documentation of this file.
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 
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)}
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)
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,)
keystone.api.groups.GroupsResource
Definition: groups.py:50
keystone.api.groups.GroupsResource._list_groups
def _list_groups(self)
Definition: groups.py:72
keystone.api.groups.GroupsResource._get_group
def _get_group(self, group_id)
Definition: groups.py:61
keystone.exception.UserNotFound
Definition: exception.py:469
keystone.api.groups.GroupsResource.post
def post(self)
Definition: groups.py:95
keystone.exception.NotFound
Definition: exception.py:395
keystone.api.groups.GroupsResource.get
def get(self, group_id=None)
Definition: groups.py:56
keystone.api.groups.GroupUsersResource.get
def get(self, group_id)
Definition: groups.py:140
keystone.api.groups.GroupAPI
Definition: groups.py:226
keystone.exception.GroupNotFound
Definition: exception.py:473
keystone.api.groups.GroupsResource.delete
def delete(self, group_id)
Definition: groups.py:128
keystone.api.groups.UserGroupCRUDResource._build_enforcement_target_attr
def _build_enforcement_target_attr(user_id, group_id)
Definition: groups.py:171
keystone.server
Definition: __init__.py:1
keystone.conf
Definition: __init__.py:1
keystone.api.groups.GroupsResource.patch
def patch(self, group_id)
Definition: groups.py:112
keystone.identity
Definition: __init__.py:1
keystone.api.groups.UserGroupCRUDResource
Definition: groups.py:169
keystone.common
Definition: __init__.py:1
keystone.api.groups.UserGroupCRUDResource.get
def get(self, group_id, user_id)
Definition: groups.py:187
keystone.api.groups._build_group_target_enforcement
def _build_group_target_enforcement()
Definition: groups.py:36
keystone.api.groups.GroupUsersResource
Definition: groups.py:139
keystone.api.groups.UserGroupCRUDResource.put
def put(self, group_id, user_id)
Definition: groups.py:199
keystone.api.groups.UserGroupCRUDResource.delete
def delete(self, group_id, user_id)
Definition: groups.py:212