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)  

users.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/users
14 
15 import base64
16 import os
17 import uuid
18 
19 import flask
20 import http.client
21 from oslo_serialization import jsonutils
22 from werkzeug import exceptions
23 
24 from keystone.api._shared import json_home_relations
25 from keystone.application_credential import schema as app_cred_schema
26 from keystone.common import json_home
27 from keystone.common import provider_api
28 from keystone.common import rbac_enforcer
29 from keystone.common import utils
30 from keystone.common import validation
31 import keystone.conf
32 from keystone import exception as ks_exception
33 from keystone.i18n import _
34 from keystone.identity import schema
35 from keystone import notifications
36 from keystone.server import flask as ks_flask
37 
38 
39 CRED_TYPE_EC2 = 'ec2'
40 CONF = keystone.conf.CONF
41 ENFORCER = rbac_enforcer.RBACEnforcer
42 PROVIDERS = provider_api.ProviderAPIs
43 
44 ACCESS_TOKEN_ID_PARAMETER_RELATION = (
45  json_home_relations.os_oauth1_parameter_rel_func(
46  parameter_name='access_token_id')
47 )
48 
49 
51  # Prior to bug #1259584 fix, blob was stored unserialized
52  # but it should be stored as a json string for compatibility
53  # with the v3 credentials API. Fall back to the old behavior
54  # for backwards compatibility with existing DB contents
55  try:
56  blob = jsonutils.loads(credential['blob'])
57  except TypeError:
58  blob = credential['blob']
59  return {'user_id': credential.get('user_id'),
60  'tenant_id': credential.get('project_id'),
61  'access': blob.get('access'),
62  'secret': blob.get('secret'),
63  'trust_id': blob.get('trust_id')}
64 
65 
67 
68  formatted_entity = entity.copy()
69  access_token_id = formatted_entity['id']
70  user_id = formatted_entity.get('authorizing_user_id', '')
71  if 'role_ids' in entity:
72  formatted_entity.pop('role_ids')
73  if 'access_secret' in entity:
74  formatted_entity.pop('access_secret')
75 
76  url = ('/users/%(user_id)s/OS-OAUTH1/access_tokens/%(access_token_id)s'
77  '/roles' % {'user_id': user_id,
78  'access_token_id': access_token_id})
79 
80  formatted_entity.setdefault('links', {})
81  formatted_entity['links']['roles'] = (ks_flask.base_url(url))
82 
83  return formatted_entity
84 
85 
87  if 'application_credential' in token.methods:
88  if not token.application_credential['unrestricted']:
89  action = _("Using method 'application_credential' is not "
90  "allowed for managing additional application "
91  "credentials.")
92  raise ks_exception.ForbiddenAction(action=action)
93 
94 
96  target = {}
97  try:
98  target['user'] = PROVIDERS.identity_api.get_user(
99  flask.request.view_args.get('user_id')
100  )
101  if flask.request.view_args.get('group_id'):
102  target['group'] = PROVIDERS.identity_api.get_group(
103  flask.request.view_args.get('group_id')
104  )
105  except ks_exception.NotFound: # nosec
106  # Defer existence in the event the user doesn't exist, we'll
107  # check this later anyway.
108  pass
109 
110  return target
111 
112 
114  ref = {}
115  if flask.request.view_args:
116  credential_id = flask.request.view_args.get('credential_id')
117  if credential_id is not None:
118  hashed_id = utils.hash_access_key(credential_id)
119  ref['credential'] = PROVIDERS.credential_api.get_credential(
120  hashed_id)
121  return ref
122 
123 
124 def _format_role_entity(role_id):
125  role = PROVIDERS.role_api.get_role(role_id)
126  formatted_entity = role.copy()
127  if 'description' in role:
128  formatted_entity.pop('description')
129  if 'enabled' in role:
130  formatted_entity.pop('enabled')
131  return formatted_entity
132 
133 
134 class UserResource(ks_flask.ResourceBase):
135  collection_key = 'users'
136  member_key = 'user'
137  get_member_from_driver = PROVIDERS.deferred_provider_lookup(
138  api='identity_api', method='get_user')
139 
140  def get(self, user_id=None):
141  """Get a user resource or list users.
142 
143  GET/HEAD /v3/users
144  GET/HEAD /v3/users/{user_id}
145  """
146  if user_id is not None:
147  return self._get_user(user_id)
148  return self._list_users()
149 
150  def _get_user(self, user_id):
151  """Get a user resource.
152 
153  GET/HEAD /v3/users/{user_id}
154  """
155  ENFORCER.enforce_call(
156  action='identity:get_user',
157  build_target=_build_user_target_enforcement
158  )
159  ref = PROVIDERS.identity_api.get_user(user_id)
160  return self.wrap_member(ref)
161 
162  def _list_users(self):
163  """List users.
164 
165  GET/HEAD /v3/users
166  """
167  filters = ('domain_id', 'enabled', 'idp_id', 'name', 'protocol_id',
168  'unique_id', 'password_expires_at')
169  target = None
170  if self.oslo_context.domain_id:
171  target = {'domain_id': self.oslo_context.domain_id}
172  hints = self.build_driver_hints(filters)
173  ENFORCER.enforce_call(
174  action='identity:list_users', filters=filters, target_attr=target
175  )
176  domain = self._get_domain_id_for_list_request()
177  if domain is None and self.oslo_context.domain_id:
178  domain = self.oslo_context.domain_id
179  refs = PROVIDERS.identity_api.list_users(
180  domain_scope=domain, hints=hints)
181 
182  # If the user making the request used a domain-scoped token, let's make
183  # sure we filter out users that are not in that domain. Otherwise, we'd
184  # be exposing users in other domains. This if statement is needed in
185  # case _get_domain_id_for_list_request() short-circuits due to
186  # configuration and protects against information from other domains
187  # leaking to people who shouldn't see it.
188  if self.oslo_context.domain_id:
189  domain_id = self.oslo_context.domain_id
190  users = [user for user in refs if user['domain_id'] == domain_id]
191  else:
192  users = refs
193 
194  return self.wrap_collection(users, hints=hints)
195 
196  def post(self):
197  """Create a user.
198 
199  POST /v3/users
200  """
201  user_data = self.request_body_json.get('user', {})
202  target = {'user': user_data}
203  ENFORCER.enforce_call(
204  action='identity:create_user', target_attr=target
205  )
206  validation.lazy_validate(schema.user_create, user_data)
207  user_data = self._normalize_dict(user_data)
208  user_data = self._normalize_domain_id(user_data)
209  ref = PROVIDERS.identity_api.create_user(
210  user_data,
211  initiator=self.audit_initiator)
212  return self.wrap_member(ref), http.client.CREATED
213 
214  def patch(self, user_id):
215  """Update a user.
216 
217  PATCH /v3/users/{user_id}
218  """
219  ENFORCER.enforce_call(
220  action='identity:update_user',
221  build_target=_build_user_target_enforcement
222  )
223  PROVIDERS.identity_api.get_user(user_id)
224  user_data = self.request_body_json.get('user', {})
225  validation.lazy_validate(schema.user_update, user_data)
226  self._require_matching_id(user_data)
227  ref = PROVIDERS.identity_api.update_user(
228  user_id, user_data, initiator=self.audit_initiator)
229  return self.wrap_member(ref)
230 
231  def delete(self, user_id):
232  """Delete a user.
233 
234  DELETE /v3/users/{user_id}
235  """
236  ENFORCER.enforce_call(
237  action='identity:delete_user',
238  build_target=_build_user_target_enforcement
239  )
240  PROVIDERS.identity_api.delete_user(user_id)
241  return None, http.client.NO_CONTENT
242 
243 
244 class UserChangePasswordResource(ks_flask.ResourceBase):
245  @ks_flask.unenforced_api
246  def get(self, user_id):
247  # Special case, GET is not allowed.
248  raise exceptions.MethodNotAllowed(valid_methods=['POST'])
249 
250  @ks_flask.unenforced_api
251  def post(self, user_id):
252  user_data = self.request_body_json.get('user', {})
253  validation.lazy_validate(schema.password_change, user_data)
254 
255  try:
256  PROVIDERS.identity_api.change_password(
257  user_id=user_id,
258  original_password=user_data['original_password'],
259  new_password=user_data['password'],
260  initiator=self.audit_initiator)
261  except AssertionError as e:
262  raise ks_exception.Unauthorized(
263  _('Error when changing user password: %s') % e
264  )
265  return None, http.client.NO_CONTENT
266 
267 
268 class UserProjectsResource(ks_flask.ResourceBase):
269  collection_key = 'projects'
270  member_key = 'project'
271  get_member_from_driver = PROVIDERS.deferred_provider_lookup(
272  api='resource_api', method='get_project')
273 
274  def get(self, user_id):
275  filters = ('domain_id', 'enabled', 'name')
276  ENFORCER.enforce_call(action='identity:list_user_projects',
277  filters=filters,
278  build_target=_build_user_target_enforcement)
279  hints = self.build_driver_hints(filters)
280  refs = PROVIDERS.assignment_api.list_projects_for_user(user_id)
281  return self.wrap_collection(refs, hints=hints)
282 
283 
284 class UserGroupsResource(ks_flask.ResourceBase):
285  collection_key = 'groups'
286  member_key = 'group'
287  get_member_from_driver = PROVIDERS.deferred_provider_lookup(
288  api='identity_api', method='get_group')
289 
290  def get(self, user_id):
291  """Get groups for a user.
292 
293  GET/HEAD /v3/users/{user_id}/groups
294  """
295  filters = ('name',)
296  hints = self.build_driver_hints(filters)
297  ENFORCER.enforce_call(action='identity:list_groups_for_user',
298  build_target=_build_user_target_enforcement,
299  filters=filters)
300  refs = PROVIDERS.identity_api.list_groups_for_user(user_id=user_id,
301  hints=hints)
302  if (self.oslo_context.domain_id):
303  filtered_refs = []
304  for ref in refs:
305  if ref['domain_id'] == self.oslo_context.domain_id:
306  filtered_refs.append(ref)
307  refs = filtered_refs
308  return self.wrap_collection(refs, hints=hints)
309 
310 
311 class _UserOSEC2CredBaseResource(ks_flask.ResourceBase):
312  collection_key = 'credentials'
313  member_key = 'credential'
314 
315  @classmethod
316  def _add_self_referential_link(cls, ref, collection_name=None):
317  # NOTE(morgan): This should be refactored to have an EC2 Cred API with
318  # a sane prefix instead of overloading the "_add_self_referential_link"
319  # method. This was chosen as it more closely mirrors the pre-flask
320  # code (for transition).
321  path = '/users/%(user_id)s/credentials/OS-EC2/%(credential_id)s'
322 
323  url = ks_flask.base_url(path) % {
324  'user_id': ref['user_id'],
325  'credential_id': ref['access']}
326  ref.setdefault('links', {})
327  ref['links']['self'] = url
328 
329 
331  def get(self, user_id):
332  """List EC2 Credentials for user.
333 
334  GET/HEAD /v3/users/{user_id}/credentials/OS-EC2
335  """
336  ENFORCER.enforce_call(action='identity:ec2_list_credentials')
337  PROVIDERS.identity_api.get_user(user_id)
338  credential_refs = PROVIDERS.credential_api.list_credentials_for_user(
339  user_id, type=CRED_TYPE_EC2)
340  collection_refs = [
342  for cred in credential_refs
343  ]
344  return self.wrap_collection(collection_refs)
345 
346  def post(self, user_id):
347  """Create EC2 Credential for user.
348 
349  POST /v3/users/{user_id}/credentials/OS-EC2
350  """
351  target = {}
352  target['credential'] = {'user_id': user_id}
353  ENFORCER.enforce_call(action='identity:ec2_create_credential',
354  target_attr=target)
355  PROVIDERS.identity_api.get_user(user_id)
356  tenant_id = self.request_body_json.get('tenant_id')
357  PROVIDERS.resource_api.get_project(tenant_id)
358  blob = dict(
359  access=uuid.uuid4().hex,
360  secret=uuid.uuid4().hex,
361  trust_id=self.oslo_context.trust_id
362  )
363  credential_id = utils.hash_access_key(blob['access'])
364  cred_data = dict(
365  user_id=user_id,
366  project_id=tenant_id,
367  blob=jsonutils.dumps(blob),
368  id=credential_id,
369  type=CRED_TYPE_EC2
370  )
371  PROVIDERS.credential_api.create_credential(credential_id, cred_data)
372  ref = _convert_v3_to_ec2_credential(cred_data)
373  return self.wrap_member(ref), http.client.CREATED
374 
375 
377  @staticmethod
378  def _get_cred_data(credential_id):
379  cred = PROVIDERS.credential_api.get_credential(credential_id)
380  if not cred or cred['type'] != CRED_TYPE_EC2:
381  raise ks_exception.Unauthorized(
382  message=_('EC2 access key not found.'))
383  return _convert_v3_to_ec2_credential(cred)
384 
385  def get(self, user_id, credential_id):
386  """Get a specific EC2 credential.
387 
388  GET/HEAD /users/{user_id}/credentials/OS-EC2/{credential_id}
389  """
390  func = _build_enforcer_target_data_owner_and_user_id_match
391  ENFORCER.enforce_call(
392  action='identity:ec2_get_credential',
393  build_target=func)
394  PROVIDERS.identity_api.get_user(user_id)
395  ec2_cred_id = utils.hash_access_key(credential_id)
396  cred_data = self._get_cred_data(ec2_cred_id)
397  return self.wrap_member(cred_data)
398 
399  def delete(self, user_id, credential_id):
400  """Delete a specific EC2 credential.
401 
402  DELETE /users/{user_id}/credentials/OS-EC2/{credential_id}
403  """
404  func = _build_enforcer_target_data_owner_and_user_id_match
405  ENFORCER.enforce_call(action='identity:ec2_delete_credential',
406  build_target=func)
407  PROVIDERS.identity_api.get_user(user_id)
408  ec2_cred_id = utils.hash_access_key(credential_id)
409  self._get_cred_data(ec2_cred_id)
410  PROVIDERS.credential_api.delete_credential(ec2_cred_id)
411  return None, http.client.NO_CONTENT
412 
413 
414 class _OAuth1ResourceBase(ks_flask.ResourceBase):
415  collection_key = 'access_tokens'
416  member_key = 'access_token'
417 
418  @classmethod
419  def _add_self_referential_link(cls, ref, collection_name=None):
420  # NOTE(morgan): This should be refactored to have an OAuth1 API with
421  # a sane prefix instead of overloading the "_add_self_referential_link"
422  # method. This was chosen as it more closely mirrors the pre-flask
423  # code (for transition).
424  ref.setdefault('links', {})
425  path = '/users/%(user_id)s/OS-OAUTH1/access_tokens' % {
426  'user_id': ref.get('authorizing_user_id', '')
427  }
428  ref['links']['self'] = ks_flask.base_url(path) + '/' + ref['id']
429 
430 
432  def get(self, user_id):
433  """List OAuth1 Access Tokens for user.
434 
435  GET /v3/users/{user_id}/OS-OAUTH1/access_tokens
436  """
437  ENFORCER.enforce_call(action='identity:list_access_tokens')
438  if self.oslo_context.is_delegated_auth:
439  raise ks_exception.Forbidden(
440  _('Cannot list request tokens with a token '
441  'issued via delegation.'))
442  refs = PROVIDERS.oauth_api.list_access_tokens(user_id)
443  formatted_refs = ([_format_token_entity(x) for x in refs])
444  return self.wrap_collection(formatted_refs)
445 
446 
448  def get(self, user_id, access_token_id):
449  """Get specific access token.
450 
451  GET/HEAD /v3/users/{user_id}/OS-OAUTH1/access_tokens/{access_token_id}
452  """
453  ENFORCER.enforce_call(action='identity:get_access_token')
454  access_token = PROVIDERS.oauth_api.get_access_token(access_token_id)
455  if access_token['authorizing_user_id'] != user_id:
456  raise ks_exception.NotFound()
457  access_token = _format_token_entity(access_token)
458  return self.wrap_member(access_token)
459 
460  def delete(self, user_id, access_token_id):
461  """Delete specific access token.
462 
463  DELETE /v3/users/{user_id}/OS-OAUTH1/access_tokens/{access_token_id}
464  """
465  ENFORCER.enforce_call(
466  action='identity:ec2_delete_credential',
467  build_target=_build_enforcer_target_data_owner_and_user_id_match)
468  access_token = PROVIDERS.oauth_api.get_access_token(access_token_id)
469  reason = (
470  'Invalidating the token cache because an access token for '
471  'consumer %(consumer_id)s has been deleted. Authorization for '
472  'users with OAuth tokens will be recalculated and enforced '
473  'accordingly the next time they authenticate or validate a '
474  'token.' % {'consumer_id': access_token['consumer_id']}
475  )
476  notifications.invalidate_token_cache_notification(reason)
477  PROVIDERS.oauth_api.delete_access_token(
478  user_id, access_token_id, initiator=self.audit_initiator)
479  return None, http.client.NO_CONTENT
480 
481 
482 class OAuth1AccessTokenRoleListResource(ks_flask.ResourceBase):
483  collection_key = 'roles'
484  member_key = 'role'
485 
486  def get(self, user_id, access_token_id):
487  """List roles for a user access token.
488 
489  GET/HEAD /v3/users/{user_id}/OS-OAUTH1/access_tokens/
490  {access_token_id}/roles
491  """
492  ENFORCER.enforce_call(action='identity:list_access_token_roles')
493  access_token = PROVIDERS.oauth_api.get_access_token(access_token_id)
494  if access_token['authorizing_user_id'] != user_id:
495  raise ks_exception.NotFound()
496  authed_role_ids = access_token['role_ids']
497  authed_role_ids = jsonutils.loads(authed_role_ids)
498  refs = ([_format_role_entity(x) for x in authed_role_ids])
499  return self.wrap_collection(refs)
500 
501 
502 class OAuth1AccessTokenRoleResource(ks_flask.ResourceBase):
503  collection_key = 'roles'
504  member_key = 'role'
505 
506  def get(self, user_id, access_token_id, role_id):
507  """Get role for access token.
508 
509  GET/HEAD /v3/users/{user_id}/OS-OAUTH1/access_tokens/
510  {access_token_id}/roles/{role_id}
511  """
512  ENFORCER.enforce_call(action='identity:get_access_token_role')
513  access_token = PROVIDERS.oauth_api.get_access_token(access_token_id)
514  if access_token['authorizing_user_id'] != user_id:
515  raise ks_exception.Unauthorized(_('User IDs do not match'))
516  authed_role_ids = access_token['role_ids']
517  authed_role_ids = jsonutils.loads(authed_role_ids)
518  for authed_role_id in authed_role_ids:
519  if authed_role_id == role_id:
520  role = _format_role_entity(role_id)
521  return self.wrap_member(role)
522  raise ks_exception.RoleNotFound(role_id=role_id)
523 
524 
525 class UserAppCredListCreateResource(ks_flask.ResourceBase):
526  collection_key = 'application_credentials'
527  member_key = 'application_credential'
528  _public_parameters = frozenset([
529  'id',
530  'name',
531  'description',
532  'expires_at',
533  'project_id',
534  'roles',
535  # secret is only exposed after create, it is not stored
536  'secret',
537  'links',
538  'unrestricted',
539  'access_rules'
540  ])
541 
542  @staticmethod
544  length = 64
545  secret = os.urandom(length)
546  secret = base64.urlsafe_b64encode(secret)
547  secret = secret.rstrip(b'=')
548  secret = secret.decode('utf-8')
549  return secret
550 
551  @staticmethod
552  def _normalize_role_list(app_cred_roles):
553  roles = []
554  for role in app_cred_roles:
555  if role.get('id'):
556  roles.append(role)
557  else:
558  roles.append(PROVIDERS.role_api.get_unique_role_by_name(
559  role['name']))
560  return roles
561 
562  def _get_roles(self, app_cred_data, token):
563  if app_cred_data.get('roles'):
564  roles = self._normalize_role_list(app_cred_data['roles'])
565  # NOTE(cmurphy): The user is not allowed to add a role that is not
566  # in their token. This is to prevent trustees or application
567  # credential users from escallating their privileges to include
568  # additional roles that the trustor or application credential
569  # creator has assigned on the project.
570  token_roles = [r['id'] for r in token.roles]
571  for role in roles:
572  if role['id'] not in token_roles:
573  detail = _('Cannot create an application credential with '
574  'unassigned role')
575  raise ks_exception.ApplicationCredentialValidationError(
576  detail=detail)
577  else:
578  roles = token.roles
579  return roles
580 
581  def get(self, user_id):
582  """List application credentials for user.
583 
584  GET/HEAD /v3/users/{user_id}/application_credentials
585  """
586  filters = ('name',)
587  ENFORCER.enforce_call(action='identity:list_application_credentials',
588  filters=filters)
589  app_cred_api = PROVIDERS.application_credential_api
590  hints = self.build_driver_hints(filters)
591  refs = app_cred_api.list_application_credentials(user_id, hints=hints)
592  return self.wrap_collection(refs, hints=hints)
593 
594  def post(self, user_id):
595  """Create application credential.
596 
597  POST /v3/users/{user_id}/application_credentials
598  """
599  ENFORCER.enforce_call(action='identity:create_application_credential')
600  app_cred_data = self.request_body_json.get(
601  'application_credential', {})
602  validation.lazy_validate(app_cred_schema.application_credential_create,
603  app_cred_data)
604  token = self.auth_context['token']
606  if self.oslo_context.user_id != user_id:
607  action = _('Cannot create an application credential for another '
608  'user.')
609  raise ks_exception.ForbiddenAction(action=action)
610  project_id = self.oslo_context.project_id
611  app_cred_data = self._assign_unique_id(app_cred_data)
612  if not app_cred_data.get('secret'):
613  app_cred_data['secret'] = self._generate_secret()
614  app_cred_data['user_id'] = user_id
615  app_cred_data['project_id'] = project_id
616  app_cred_data['roles'] = self._get_roles(app_cred_data, token)
617  if app_cred_data.get('expires_at'):
618  app_cred_data['expires_at'] = utils.parse_expiration_date(
619  app_cred_data['expires_at'])
620  if app_cred_data.get('access_rules'):
621  for access_rule in app_cred_data['access_rules']:
622  # If user provides an access rule by ID, it will be looked up
623  # by ID. If user provides an access rule that is identical to
624  # an existing one, the ID generated here will be ignored and
625  # the pre-existing access rule will be used.
626  if 'id' not in access_rule:
627  # Generate directly, rather than using _assign_unique_id,
628  # so that there is no deep copy made
629  access_rule['id'] = uuid.uuid4().hex
630  app_cred_data = self._normalize_dict(app_cred_data)
631  app_cred_api = PROVIDERS.application_credential_api
632 
633  try:
634  ref = app_cred_api.create_application_credential(
635  app_cred_data, initiator=self.audit_initiator)
636  except ks_exception.RoleAssignmentNotFound as e:
637  # Raise a Bad Request, not a Not Found, in accordance with the
638  # API-SIG recommendations:
639  # https://specs.openstack.org/openstack/api-wg/guidelines/http.html#failure-code-clarifications
640  raise ks_exception.ApplicationCredentialValidationError(
641  detail=str(e))
642  return self.wrap_member(ref), http.client.CREATED
643 
644 
645 class UserAppCredGetDeleteResource(ks_flask.ResourceBase):
646  collection_key = 'application_credentials'
647  member_key = 'application_credential'
648 
649  def get(self, user_id, application_credential_id):
650  """Get application credential resource.
651 
652  GET/HEAD /v3/users/{user_id}/application_credentials/
653  {application_credential_id}
654  """
655  ENFORCER.enforce_call(action='identity:get_application_credential')
656  ref = PROVIDERS.application_credential_api.get_application_credential(
657  application_credential_id)
658  return self.wrap_member(ref)
659 
660  def delete(self, user_id, application_credential_id):
661  """Delete application credential resource.
662 
663  DELETE /v3/users/{user_id}/application_credentials/
664  {application_credential_id}
665  """
666  ENFORCER.enforce_call(action='identity:delete_application_credential')
667  token = self.auth_context['token']
669  PROVIDERS.application_credential_api.delete_application_credential(
670  application_credential_id, initiator=self.audit_initiator)
671  return None, http.client.NO_CONTENT
672 
673 
674 class UserAccessRuleListResource(ks_flask.ResourceBase):
675  collection_key = 'access_rules'
676  member_key = 'access_rule'
677 
678  def get(self, user_id):
679  """List access rules for user.
680 
681  GET/HEAD /v3/users/{user_id}/access_rules
682  """
683  filters = ('service', 'path', 'method',)
684  ENFORCER.enforce_call(action='identity:list_access_rules',
685  filters=filters,
686  build_target=_build_user_target_enforcement)
687  app_cred_api = PROVIDERS.application_credential_api
688  hints = self.build_driver_hints(filters)
689  refs = app_cred_api.list_access_rules_for_user(user_id, hints=hints)
690  hints = self.build_driver_hints(filters)
691  return self.wrap_collection(refs, hints=hints)
692 
693 
694 class UserAccessRuleGetDeleteResource(ks_flask.ResourceBase):
695  collection_key = 'access_rules'
696  member_key = 'access_rule'
697 
698  def get(self, user_id, access_rule_id):
699  """Get access rule resource.
700 
701  GET/HEAD /v3/users/{user_id}/access_rules/{access_rule_id}
702  """
703  ENFORCER.enforce_call(
704  action='identity:get_access_rule',
705  build_target=_build_user_target_enforcement
706  )
707  ref = PROVIDERS.application_credential_api.get_access_rule(
708  access_rule_id)
709  return self.wrap_member(ref)
710 
711  def delete(self, user_id, access_rule_id):
712  """Delete access rule resource.
713 
714  DELETE /v3/users/{user_id}/access_rules/{access_rule_id}
715  """
716  ENFORCER.enforce_call(
717  action='identity:delete_access_rule',
718  build_target=_build_user_target_enforcement
719  )
720  PROVIDERS.application_credential_api.delete_access_rule(
721  access_rule_id, initiator=self.audit_initiator)
722  return None, http.client.NO_CONTENT
723 
724 
725 class UserAPI(ks_flask.APIBase):
726  _name = 'users'
727  _import_name = __name__
728  resources = [UserResource]
729  resource_mapping = [
730  ks_flask.construct_resource_map(
731  resource=UserChangePasswordResource,
732  url='/users/<string:user_id>/password',
733  resource_kwargs={},
734  rel='user_change_password',
735  path_vars={'user_id': json_home.Parameters.USER_ID}
736  ),
737  ks_flask.construct_resource_map(
738  resource=UserGroupsResource,
739  url='/users/<string:user_id>/groups',
740  resource_kwargs={},
741  rel='user_groups',
742  path_vars={'user_id': json_home.Parameters.USER_ID}
743  ),
744  ks_flask.construct_resource_map(
745  resource=UserProjectsResource,
746  url='/users/<string:user_id>/projects',
747  resource_kwargs={},
748  rel='user_projects',
749  path_vars={'user_id': json_home.Parameters.USER_ID}
750  ),
751  ks_flask.construct_resource_map(
752  resource=UserOSEC2CredentialsResourceListCreate,
753  url='/users/<string:user_id>/credentials/OS-EC2',
754  resource_kwargs={},
755  rel='user_credentials',
756  resource_relation_func=(
757  json_home_relations.os_ec2_resource_rel_func),
758  path_vars={'user_id': json_home.Parameters.USER_ID}
759  ),
760  ks_flask.construct_resource_map(
761  resource=UserOSEC2CredentialsResourceGetDelete,
762  url=('/users/<string:user_id>/credentials/OS-EC2/'
763  '<string:credential_id>'),
764  resource_kwargs={},
765  rel='user_credential',
766  resource_relation_func=(
767  json_home_relations.os_ec2_resource_rel_func),
768  path_vars={
769  'credential_id': json_home.build_v3_parameter_relation(
770  'credential_id'),
771  'user_id': json_home.Parameters.USER_ID}
772  ),
773  ks_flask.construct_resource_map(
774  resource=OAuth1ListAccessTokensResource,
775  url='/users/<string:user_id>/OS-OAUTH1/access_tokens',
776  resource_kwargs={},
777  rel='user_access_tokens',
778  resource_relation_func=(
779  json_home_relations.os_oauth1_resource_rel_func),
780  path_vars={'user_id': json_home.Parameters.USER_ID}
781  ),
782  ks_flask.construct_resource_map(
783  resource=OAuth1AccessTokenCRUDResource,
784  url=('/users/<string:user_id>/OS-OAUTH1/'
785  'access_tokens/<string:access_token_id>'),
786  resource_kwargs={},
787  rel='user_access_token',
788  resource_relation_func=(
789  json_home_relations.os_oauth1_resource_rel_func),
790  path_vars={
791  'access_token_id': ACCESS_TOKEN_ID_PARAMETER_RELATION,
792  'user_id': json_home.Parameters.USER_ID}
793  ),
794  ks_flask.construct_resource_map(
795  resource=OAuth1AccessTokenRoleListResource,
796  url=('/users/<string:user_id>/OS-OAUTH1/access_tokens/'
797  '<string:access_token_id>/roles'),
798  resource_kwargs={},
799  rel='user_access_token_roles',
800  resource_relation_func=(
801  json_home_relations.os_oauth1_resource_rel_func),
802  path_vars={'access_token_id': ACCESS_TOKEN_ID_PARAMETER_RELATION,
803  'user_id': json_home.Parameters.USER_ID}
804  ),
805  ks_flask.construct_resource_map(
806  resource=OAuth1AccessTokenRoleResource,
807  url=('/users/<string:user_id>/OS-OAUTH1/access_tokens/'
808  '<string:access_token_id>/roles/<string:role_id>'),
809  resource_kwargs={},
810  rel='user_access_token_role',
811  resource_relation_func=(
812  json_home_relations.os_oauth1_resource_rel_func),
813  path_vars={'access_token_id': ACCESS_TOKEN_ID_PARAMETER_RELATION,
814  'role_id': json_home.Parameters.ROLE_ID,
815  'user_id': json_home.Parameters.USER_ID}
816  ),
817  ks_flask.construct_resource_map(
818  resource=UserAppCredListCreateResource,
819  url='/users/<string:user_id>/application_credentials',
820  resource_kwargs={},
821  rel='application_credentials',
822  path_vars={'user_id': json_home.Parameters.USER_ID}
823  ),
824  ks_flask.construct_resource_map(
825  resource=UserAppCredGetDeleteResource,
826  url=('/users/<string:user_id>/application_credentials/'
827  '<string:application_credential_id>'),
828  resource_kwargs={},
829  rel='application_credential',
830  path_vars={
831  'user_id': json_home.Parameters.USER_ID,
832  'application_credential_id':
833  json_home.Parameters.APPLICATION_CRED_ID}
834  ),
835  ks_flask.construct_resource_map(
836  resource=UserAccessRuleListResource,
837  url='/users/<string:user_id>/access_rules',
838  resource_kwargs={},
839  rel='access_rules',
840  path_vars={'user_id': json_home.Parameters.USER_ID}
841  ),
842  ks_flask.construct_resource_map(
843  resource=UserAccessRuleGetDeleteResource,
844  url=('/users/<string:user_id>/access_rules/'
845  '<string:access_rule_id>'),
846  resource_kwargs={},
847  rel='access_rule',
848  path_vars={
849  'user_id': json_home.Parameters.USER_ID,
850  'access_rule_id':
851  json_home.Parameters.ACCESS_RULE_ID}
852  )
853  ]
854 
855 
856 APIs = (UserAPI,)
keystone.api.users.OAuth1AccessTokenRoleResource.get
def get(self, user_id, access_token_id, role_id)
Definition: users.py:506
keystone.api.users.OAuth1AccessTokenRoleResource
Definition: users.py:502
keystone.api.users.OAuth1AccessTokenRoleListResource
Definition: users.py:482
keystone.api.users.UserAppCredGetDeleteResource.get
def get(self, user_id, application_credential_id)
Definition: users.py:649
keystone.api.users.OAuth1AccessTokenCRUDResource.get
def get(self, user_id, access_token_id)
Definition: users.py:448
keystone.api.users.UserProjectsResource.get
def get(self, user_id)
Definition: users.py:274
keystone.api.users.UserResource.delete
def delete(self, user_id)
Definition: users.py:231
keystone.application_credential
Definition: __init__.py:1
keystone.api.users.UserOSEC2CredentialsResourceListCreate.get
def get(self, user_id)
Definition: users.py:331
keystone.api.users.OAuth1AccessTokenCRUDResource
Definition: users.py:447
keystone.api.users._UserOSEC2CredBaseResource._add_self_referential_link
def _add_self_referential_link(cls, ref, collection_name=None)
Definition: users.py:316
keystone.api.users.UserAccessRuleListResource.get
def get(self, user_id)
Definition: users.py:678
keystone.api.users.UserGroupsResource
Definition: users.py:284
keystone.api.users.UserAppCredListCreateResource
Definition: users.py:525
keystone.api.users.UserAppCredListCreateResource._get_roles
def _get_roles(self, app_cred_data, token)
Definition: users.py:562
keystone.api.users._convert_v3_to_ec2_credential
def _convert_v3_to_ec2_credential(credential)
Definition: users.py:50
keystone.api.users.UserGroupsResource.get
def get(self, user_id)
Definition: users.py:290
keystone.api.users.OAuth1AccessTokenRoleListResource.get
def get(self, user_id, access_token_id)
Definition: users.py:486
keystone.api.users.UserChangePasswordResource
Definition: users.py:244
keystone.api.users.UserResource.get
def get(self, user_id=None)
Definition: users.py:140
keystone.api.users.UserOSEC2CredentialsResourceListCreate
Definition: users.py:330
keystone.api.users.UserChangePasswordResource.get
def get(self, user_id)
Definition: users.py:246
keystone.api.users.UserResource
Definition: users.py:134
keystone.api.users._OAuth1ResourceBase
Definition: users.py:414
keystone.api.users.UserOSEC2CredentialsResourceGetDelete
Definition: users.py:376
keystone.api.users.UserResource.post
def post(self)
Definition: users.py:196
keystone.api.users._format_role_entity
def _format_role_entity(role_id)
Definition: users.py:124
keystone.api.users._build_user_target_enforcement
def _build_user_target_enforcement()
Definition: users.py:95
keystone.api.users._check_unrestricted_application_credential
def _check_unrestricted_application_credential(token)
Definition: users.py:86
keystone.api.users.UserOSEC2CredentialsResourceGetDelete.delete
def delete(self, user_id, credential_id)
Definition: users.py:399
keystone.api.users.UserOSEC2CredentialsResourceListCreate.post
def post(self, user_id)
Definition: users.py:346
keystone.api.users.UserChangePasswordResource.post
def post(self, user_id)
Definition: users.py:251
keystone.api.users.UserResource.patch
def patch(self, user_id)
Definition: users.py:214
keystone.api.users.UserAccessRuleGetDeleteResource.delete
def delete(self, user_id, access_rule_id)
Definition: users.py:711
keystone.api.users.UserAppCredGetDeleteResource
Definition: users.py:645
keystone.api.users.UserAppCredGetDeleteResource.delete
def delete(self, user_id, application_credential_id)
Definition: users.py:660
keystone.api.users.UserAppCredListCreateResource.post
def post(self, user_id)
Definition: users.py:594
keystone.api.users.UserOSEC2CredentialsResourceGetDelete._get_cred_data
def _get_cred_data(credential_id)
Definition: users.py:378
keystone.api.users._format_token_entity
def _format_token_entity(entity)
Definition: users.py:66
keystone.api.users.OAuth1AccessTokenCRUDResource.delete
def delete(self, user_id, access_token_id)
Definition: users.py:460
keystone.api.users.UserAppCredListCreateResource._normalize_role_list
def _normalize_role_list(app_cred_roles)
Definition: users.py:552
keystone.api.users.UserOSEC2CredentialsResourceGetDelete.get
def get(self, user_id, credential_id)
Definition: users.py:385
keystone.api.users._UserOSEC2CredBaseResource
Definition: users.py:311
keystone.api.users._OAuth1ResourceBase._add_self_referential_link
def _add_self_referential_link(cls, ref, collection_name=None)
Definition: users.py:419
keystone.server
Definition: __init__.py:1
keystone.conf
Definition: __init__.py:1
keystone.api.users.UserAppCredListCreateResource._generate_secret
def _generate_secret()
Definition: users.py:543
keystone.api.users.UserAPI
Definition: users.py:725
keystone.api.users.UserAccessRuleGetDeleteResource
Definition: users.py:694
keystone.api.users.UserResource._get_user
def _get_user(self, user_id)
Definition: users.py:150
keystone.api.users.UserAccessRuleGetDeleteResource.get
def get(self, user_id, access_rule_id)
Definition: users.py:698
keystone.i18n._
_
Definition: i18n.py:29
keystone.identity
Definition: __init__.py:1
keystone.api.users.UserResource._list_users
def _list_users(self)
Definition: users.py:162
keystone.api.users.UserProjectsResource
Definition: users.py:268
keystone.common
Definition: __init__.py:1
keystone.i18n
Definition: i18n.py:1
keystone.api._shared
Definition: __init__.py:1
keystone.api.users.OAuth1ListAccessTokensResource.get
def get(self, user_id)
Definition: users.py:432
keystone.api.users.UserAccessRuleListResource
Definition: users.py:674
keystone.api.users.UserAppCredListCreateResource.get
def get(self, user_id)
Definition: users.py:581
keystone.api.users._build_enforcer_target_data_owner_and_user_id_match
def _build_enforcer_target_data_owner_and_user_id_match()
Definition: users.py:113
keystone.api.users.OAuth1ListAccessTokensResource
Definition: users.py:431