def setUp(self): self.cinder_client_exception = cinder_exceptions.ClientException(404) self.glance_client_exception = glance_exceptions.ClientException() self.keystone_client_exception = keystone_exceptions.ClientException() self.neutron_client_exception = neutron_exceptions.NeutronClientException( ) self.nova_client_exception = nova_exceptions.ClientException(404)
def user_update(request, user, **data): manager = keystoneclient(request, admin=True).users error = None if not keystone_can_edit_user(): raise keystone_exceptions.ClientException( 405, _("Identity service does not allow editing user data.")) # The v2 API updates user model, password and default project separately if VERSIONS.active < 3: password = data.pop('password') project = data.pop('project') # Update user details try: user = manager.update(user, **data) except Exception: error = exceptions.handle(request, ignore=True) # Update default tenant try: user_update_tenant(request, user, project) user.tenantId = project except Exception: error = exceptions.handle(request, ignore=True) # Check for existing roles # Show a warning if no role exists for the project user_roles = roles_for_user(request, user, project) if not user_roles: messages.warning( request, _('User %s has no role defined for ' 'that project.') % data.get('name', None)) # If present, update password # FIXME(gabriel): password change should be its own form + view if password: try: user_update_password(request, user, password) if user.id == request.user.id: return utils.logout_with_message( request, _("Password changed. Please log in again to continue.") ) except Exception: error = exceptions.handle(request, ignore=True) if error is not None: raise error # v3 API is so much simpler... else: if not data['password']: data.pop('password') user = manager.update(user, **data) if data.get('password') and user.id == request.user.id: return utils.logout_with_message( request, _("Password changed. Please log in again to continue."))
def test_exception(self): user = self.data.user form_data = {'region': settings.OPENSTACK_KEYSTONE_URL, 'domain': DEFAULT_DOMAIN, 'password': user.password, 'username': user.name} self.mox.StubOutWithMock(self.ks_client_module, "Client") exc = keystone_exceptions.ClientException(500) self.ks_client_module.Client(auth_url=settings.OPENSTACK_KEYSTONE_URL, password=user.password, username=user.name, user_domain_name=DEFAULT_DOMAIN, insecure=False, debug=False).AndRaise(exc) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertTemplateUsed(response, 'auth/login.html') self.assertContains(response, ("An error occurred authenticating. Please try " "again later."))
def _reload_connection(self): '''Called before any operation, it check if credentials has changed Throw keystoneclient.apiclient.exceptions.AuthorizationFailure ''' #TODO control the timing and possible token timeout, but it seams that python client does this task for us :-) if self.reload_client: #test valid params if len(self.n_creds) < 4: raise ksExceptions.ClientException( "Not enough parameters to connect to openstack") self.nova = nClient.Client(2, **self.n_creds) self.keystone = ksClient.Client(**self.k_creds) self.glance_endpoint = self.keystone.service_catalog.url_for( service_type='image', endpoint_type='publicURL') self.glance = glClient.Client( self.glance_endpoint, token=self.keystone.auth_token, **self.k_creds) #TODO check k_creds vs n_creds self.ne_endpoint = self.keystone.service_catalog.url_for( service_type='network', endpoint_type='publicURL') self.neutron = neClient.Client('2.0', endpoint_url=self.ne_endpoint, token=self.keystone.auth_token, **self.k_creds) self.reload_client = False
def test_launch_keypairlist_error(self): IMAGE_ID = '2' self.mox.StubOutWithMock(api, 'image_get_meta') api.image_get_meta(IsA(http.HttpRequest), IMAGE_ID).AndReturn(self.visibleImage) self.mox.StubOutWithMock(api, 'tenant_quota_get') api.tenant_quota_get(IsA(http.HttpRequest), self.TEST_TENANT).AndReturn(FakeQuota) self.mox.StubOutWithMock(api, 'flavor_list') api.flavor_list(IsA(http.HttpRequest)).AndReturn(self.flavors) exception = keystone_exceptions.ClientException('Failed.') self.mox.StubOutWithMock(api, 'keypair_list') api.keypair_list(IsA(http.HttpRequest)).AndRaise(exception) self.mox.StubOutWithMock(api, 'security_group_list') api.security_group_list(IsA(http.HttpRequest)).AndReturn( self.security_groups) self.mox.ReplayAll() res = self.client.get( reverse('horizon:nova:images_and_snapshots:images:launch', args=[IMAGE_ID])) self.assertTemplateUsed(res, 'nova/images_and_snapshots/images/launch.html') form = res.context['form'] form_keyfield = form.fields['keypair'] self.assertEqual(len(form_keyfield.choices), 0)
def user_update_password(request, user, password, admin=True): if not keystone_can_edit_user(): raise keystone_exceptions.ClientException( 405, _("Identity service does not allow editing user password.")) manager = keystoneclient(request, admin=admin).users manager.update(user, password=password)
def test_find_desktop_with_name_not_unique(self, mocked_get, mock_list): desktops = self.app.client_manager.workspace.desktops mocked_get.side_effect = exceptions.ClientException(0) mock_list.return_value = self.get_fake_desktop_list(count=2) # self.assertRaises(execs.NotUniqueMatch, desktops.find, "chen01") result = desktops.find("chen010") expected = self.get_fake_desktop(instance=self.instances[0]) self.assertEquals(expected, result)
def request(self, url, method, **kwargs): """Send an http request with the specified characteristics. Wrapper around requests.request to handle tasks such as setting headers, JSON encoding/decoding, and error handling. """ # Copy the kwargs so we can reuse the original in case of redirects request_kwargs = copy.copy(kwargs) request_kwargs.setdefault('headers', kwargs.get('headers', {})) request_kwargs['headers']['User-Agent'] = self.USER_AGENT if self.original_ip: request_kwargs['headers']['Forwarded'] = "for=%s;by=%s" % ( self.original_ip, self.USER_AGENT) if 'body' in kwargs: request_kwargs['headers']['Content-Type'] = 'application/json' request_kwargs['data'] = self.serialize(kwargs['body']) del request_kwargs['body'] if self.cert: request_kwargs['cert'] = self.cert if self.timeout is not None: request_kwargs.setdefault('timeout', self.timeout) self.http_log_req(( url, method, ), request_kwargs) try: resp = requests.request(method, url, verify=self.verify_cert, **request_kwargs) except requests.ConnectionError: msg = 'Unable to establish connection to %s' % url raise exceptions.ClientException(msg) self.http_log_resp(resp) if resp.text: try: body = json.loads(resp.text) except (ValueError, TypeError): body = None _logger.debug("Could not decode JSON from body: %s" % resp.text) else: _logger.debug("No body was returned.") body = None if resp.status_code >= 400: _logger.debug("Request returned failure status: %s", resp.status_code) raise exceptions.from_response(resp, body or resp.text) elif resp.status_code in (301, 302, 305): # Redirected. Reissue the request to the new location. return self.request(resp.headers['location'], method, **kwargs) return resp, body
class ShellTestWithKeystoneV3Auth(ShellTest): # auth environment to use auth_env = FAKE_V3_ENV.copy() token_url = DEFAULT_V3_AUTH_URL + '/auth/tokens' def _assert_auth_plugin_args(self): self.assertFalse(self.v2_auth.called) self.assertEqual(1, self.v3_auth.call_count) body = json.loads(self.v3_auth.last_request.body) user = body['auth']['identity']['password']['user'] self.assertEqual(self.auth_env['OS_USERNAME'], user['name']) self.assertEqual(self.auth_env['OS_PASSWORD'], user['password']) self.assertEqual(self.auth_env['OS_USER_DOMAIN_NAME'], user['domain']['name']) self.assertEqual(self.auth_env['OS_PROJECT_ID'], body['auth']['scope']['project']['id']) @mock.patch('glanceclient.v1.client.Client') def test_auth_plugin_invocation_with_v1(self, v1_client): args = 'image-list' glance_shell = openstack_shell.OpenStackImagesShell() glance_shell.main(args.split()) self._assert_auth_plugin_args() @mock.patch('glanceclient.v2.client.Client') @mock.patch.object(openstack_shell.OpenStackImagesShell, '_cache_schemas') def test_auth_plugin_invocation_with_v2(self, v2_client, cache_schemas): args = '--os-image-api-version 2 image-list' glance_shell = openstack_shell.OpenStackImagesShell() glance_shell.main(args.split()) self._assert_auth_plugin_args() @mock.patch('keystoneclient.discover.Discover', side_effect=ks_exc.ClientException()) def test_api_discovery_failed_with_unversioned_auth_url(self, discover): args = '--os-auth-url %s image-list' % DEFAULT_UNVERSIONED_AUTH_URL glance_shell = openstack_shell.OpenStackImagesShell() self.assertRaises(exc.CommandError, glance_shell.main, args.split()) def test_bash_completion(self): stdout, stderr = self.shell('bash_completion') # just check we have some output required = [ '--status', 'image-create', 'help', '--size'] for r in required: self.assertIn(r, stdout.split()) avoided = [ 'bash_completion', 'bash-completion'] for r in avoided: self.assertNotIn(r, stdout.split())
def _update(self, url, body, response_key=None, method="PUT"): methods = {"PUT": self.api.put, "POST": self.api.post} try: resp, body = methods[method](url, body=body) except KeyError: raise exceptions.ClientException("Invalid update method: %s" % method) # PUT requests may not return a body if body: return self.resource_class(self, body[response_key])
def delete(self, request, obj_id): domain = self.table.get_object_by_id(obj_id) if domain.enabled: msg = _('Domain "%s" must be disabled before it can be deleted.') \ % domain.name messages.error(request, msg) raise exceptions.ClientException(409, msg) else: LOG.info('Deleting domain "%s".' % obj_id) api.keystone.domain_delete(request, obj_id)
def user_update(request, user, **data): manager = keystoneclient(request, admin=True).users if not keystone_can_edit_user(): raise keystone_exceptions.ClientException( 405, _("Identity service does not allow editing user data.")) try: user = manager.update(user, **data) except keystone_exceptions.Conflict: raise exceptions.Conflict()
def test_find_desktop_with_name(self, mocked_get, mock_list): desktops = self.app.client_manager.workspace.desktops mocked_get.side_effect = exceptions.ClientException(0) d = self.get_fake_desktop(instance=self.instances[1]) mock_list.return_value = base_resource.ListWithMeta([d], None) find = desktops.find("chen01") mock_list.assert_called_once_with("/desktops/detail", params=dict(computer_name="chen01"), key="desktops") self.assertEquals(d, find)
def test_find_config_with_name(self, mocked_get, mock_list): configs = self.app.client_manager.auto_scaling.configs mocked_get.side_effect = exceptions.ClientException(0) _list = [resource.AutoScalingConfig(None, c) for c in self._configs] mock_list.return_value = br.ListWithMeta(_list, None) find = configs.find("config_name_1") params = dict(scaling_configuration_name="config_name_1") mock_list.assert_called_once_with("/scaling_configuration", key="scaling_configurations", params=params) self.assertEquals(_list[0], find)
def test_launch_form_keystone_exception(self): FLAVOR_ID = self.flavors[0].id IMAGE_ID = '1' keypair = self.keypairs[0].name SERVER_NAME = 'serverName' USER_DATA = 'userData' self.mox.StubOutWithMock(api, 'image_get_meta') self.mox.StubOutWithMock(api, 'flavor_list') self.mox.StubOutWithMock(api, 'keypair_list') self.mox.StubOutWithMock(api, 'security_group_list') self.mox.StubOutWithMock(api, 'server_create') self.mox.StubOutWithMock(api, 'volume_list') form_data = {'method': 'LaunchForm', 'flavor': FLAVOR_ID, 'image_id': IMAGE_ID, 'keypair': keypair, 'name': SERVER_NAME, 'tenant_id': self.TEST_TENANT, 'user_data': USER_DATA, 'count': int(1), 'security_groups': 'default'} api.flavor_list(IgnoreArg()).AndReturn(self.flavors) api.keypair_list(IgnoreArg()).AndReturn(self.keypairs) api.security_group_list(IsA(http.HttpRequest)).AndReturn( self.security_groups) api.image_get_meta(IgnoreArg(), IMAGE_ID).AndReturn(self.visibleImage) api.volume_list(IgnoreArg()).AndReturn(self.volumes) exception = keystone_exceptions.ClientException('Failed') api.server_create(IsA(http.HttpRequest), SERVER_NAME, IMAGE_ID, str(FLAVOR_ID), keypair, USER_DATA, [group.name for group in self.security_groups], None, instance_count=IsA(int)).AndRaise(exception) self.mox.StubOutWithMock(messages, 'error') messages.error(IsA(http.HttpRequest), IsA(basestring)) self.mox.ReplayAll() url = reverse('horizon:nova:images_and_snapshots:images:launch', args=[IMAGE_ID]) res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, IMAGES_INDEX_URL)
class ShellTestWithKeystoneV3Auth(ShellTest): # auth environment to use auth_env = FAKE_V3_ENV.copy() # expected auth plugin to invoke auth_plugin = 'keystoneclient.auth.identity.v3.Password' def _assert_auth_plugin_args(self, mock_auth_plugin): mock_auth_plugin.assert_called_once_with( keystone_client_fixtures.V3_URL, user_id='', username=self.auth_env['OS_USERNAME'], password=self.auth_env['OS_PASSWORD'], user_domain_id='', user_domain_name=self.auth_env['OS_USER_DOMAIN_NAME'], project_id=self.auth_env['OS_PROJECT_ID'], project_name='', project_domain_id='', project_domain_name='') @mock.patch('afloclient.v1.client.Client') @mock.patch('keystoneclient.session.Session') @mock.patch.object(keystoneclient.discover.Discover, 'url_for', side_effect=[None, keystone_client_fixtures.V3_URL]) def test_auth_plugin_invocation_with_v1(self, v1_client, ks_session, url_for): with mock.patch(self.auth_plugin) as mock_auth_plugin: args = 'ticket-list' aflo_shell = openstack_shell.OpenStackClientShell() aflo_shell.main(args.split()) self._assert_auth_plugin_args(mock_auth_plugin) @mock.patch('keystoneclient.session.Session') @mock.patch('keystoneclient.discover.Discover', side_effect=ks_exc.ClientException()) def test_api_discovery_failed_with_unversioned_auth_url( self, ks_session, discover): args = '--os-auth-url %s ticket-list' % ( keystone_client_fixtures.BASE_URL) aflo_shell = openstack_shell.OpenStackClientShell() self.assertRaises(exc.CommandError, aflo_shell.main, args.split()) def test_bash_completion(self): stdout, stderr = self.shell('bash_completion') # just check we have some output required = ['ticket-create', 'help'] for r in required: self.assertIn(r, stdout.split()) avoided = ['bash_completion', 'bash-completion'] for r in avoided: self.assertNotIn(r, stdout.split())
def _update(self, url, body=None, response_key=None, method="PUT", **kwargs): methods = {"PUT": self.client.put, "POST": self.client.post, "PATCH": self.client.patch} try: resp, body = methods[method](url, body=body, **kwargs) except KeyError: raise exceptions.ClientException(_("Invalid update method: %s") % method) # PUT requests may not return a body if body: return self.resource_class(self, body[response_key])
def data(TEST): TEST.exceptions = TestDataContainer() msg = "Expected failure." keystone_exception = keystone_exceptions.ClientException(500, message=msg) keystone_exception.silence_logging = True TEST.exceptions.keystone = keystone_exception nova_exception = nova_exceptions.ClientException(500, message=msg) nova_exception.silence_logging = True TEST.exceptions.nova = nova_exception glance_exception = glance_exceptions.ClientException(500, message=msg) glance_exception.silence_logging = True TEST.exceptions.glance = glance_exception
def test_enable_disable_user_exception(self): OTHER_USER_ID = '5' formData = {'action': 'users__enable__%s' % OTHER_USER_ID} self.mox.StubOutWithMock(api.keystone, 'user_update_enabled') api_exception = keystone_exceptions.ClientException( 'apiException', message='apiException') api.keystone.user_update_enabled(IgnoreArg(), OTHER_USER_ID, True) \ .AndRaise(api_exception) self.mox.ReplayAll() res = self.client.post(USERS_INDEX_URL, formData) self.assertRedirects(res, USERS_INDEX_URL)
def user_update(request, user, **data): manager = keystoneclient(request, admin=True).users error = None if not keystone_can_edit_user(): raise keystone_exceptions.ClientException( 405, _("Identity service does not allow editing user data.")) # The v2 API updates user model and default project separately if VERSIONS.active < 3: project = data.pop('project') # Update user details try: user = manager.update(user, **data) print "%%%%%%%%%%%%%%%%%%%%%%%%%%" print user except keystone_exceptions.Conflict: raise exceptions.Conflict() except Exception: error = exceptions.handle(request, ignore=True) print error # Update default tenant try: user_update_tenant(request, user, project) user.tenantId = project except Exception: error = exceptions.handle(request, ignore=True) # Check for existing roles # Show a warning if no role exists for the project user_roles = roles_for_user(request, user, project) if not user_roles: messages.warning( request, _('User %s has no role defined for ' 'that project.') % data.get('name', None)) if error is not None: raise error # v3 API is so much simpler... else: try: user = manager.update(user, **data) except keystone_exceptions.Conflict: raise exceptions.Conflict()
def test_launch_form_keystone_exception(self): flavor = self.flavors.first() image = self.images.first() keypair = self.keypairs.first() server = self.servers.first() sec_group = self.security_groups.first() USER_DATA = 'userData' self.mox.StubOutWithMock(api, 'image_get_meta') self.mox.StubOutWithMock(api, 'flavor_list') self.mox.StubOutWithMock(api, 'keypair_list') self.mox.StubOutWithMock(api, 'security_group_list') self.mox.StubOutWithMock(api, 'server_create') self.mox.StubOutWithMock(api, 'volume_list') api.flavor_list(IgnoreArg()).AndReturn(self.flavors.list()) api.keypair_list(IgnoreArg()).AndReturn(self.keypairs.list()) api.security_group_list(IsA(http.HttpRequest)) \ .AndReturn(self.security_groups.list()) api.image_get_meta(IgnoreArg(), image.id).AndReturn(image) api.volume_list(IgnoreArg()).AndReturn(self.volumes.list()) exc = keystone_exceptions.ClientException('Failed') api.server_create(IsA(http.HttpRequest), server.name, image.id, flavor.id, keypair.name, USER_DATA, [sec_group.name], None, instance_count=IsA(int)).AndRaise(exc) self.mox.ReplayAll() form_data = { 'method': 'LaunchForm', 'flavor': flavor.id, 'image_id': image.id, 'keypair': keypair.name, 'name': server.name, 'tenant_id': self.tenant.id, 'user_data': USER_DATA, 'count': 1, 'security_groups': sec_group.name } url = reverse('horizon:nova:images_and_snapshots:images:launch', args=[image.id]) res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, IMAGES_INDEX_URL)
def _update(self, url, body=None, response_key=None, method="PUT", management=True): methods = {"PUT": self.api.put, "POST": self.api.post, "PATCH": self.api.patch} try: if body is not None: resp, body = methods[method](url, body=body, management=management) else: resp, body = methods[method](url, management=management) except KeyError: raise exceptions.ClientException("Invalid update method: %s" % method) # PUT requests may not return a body if body: return self.resource_class(self, body[response_key])
def test_exception(self): user = self.data.user form_data = self.get_form_data(user) exc = keystone_exceptions.ClientException(500) self._mock_client_password_auth_failure(user.name, user.password, exc) self.mox.ReplayAll() url = reverse('login') # GET the page to set the test cookie. response = self.client.get(url, form_data) self.assertEqual(response.status_code, 200) # POST to the page to log in. response = self.client.post(url, form_data) self.assertTemplateUsed(response, 'auth/login.html') self.assertContains(response, ("An error occurred authenticating. Please try " "again later."))
def test_launch_flavorlist_error(self): image = self.images.first() self.mox.StubOutWithMock(api, 'image_get_meta') self.mox.StubOutWithMock(api, 'tenant_quota_usages') self.mox.StubOutWithMock(api, 'flavor_list') self.mox.StubOutWithMock(api, 'keypair_list') self.mox.StubOutWithMock(api, 'security_group_list') api.image_get_meta(IsA(http.HttpRequest), image.id).AndReturn(image) api.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn( self.quota_usages.first()) exc = keystone_exceptions.ClientException('Failed.') api.flavor_list(IsA(http.HttpRequest)).AndRaise(exc) api.keypair_list(IsA(http.HttpRequest)).AndReturn(self.keypairs.list()) api.security_group_list(IsA(http.HttpRequest)) \ .AndReturn(self.security_groups.list()) self.mox.ReplayAll() url = reverse('horizon:nova:images_and_snapshots:images:launch', args=[image.id]) res = self.client.get(url) self.assertTemplateUsed( res, 'nova/images_and_snapshots/images/launch.html')
def _test_discover_auth_versions_exception(self, mock_discover, mock_url_parse, client_exception=None, expected_auth="fake auth"): auths = {"/v2": None, "/v3": None} if client_exception is None: mock_url_for = mock.Mock() mock_url_for.url_for.side_effect = tuple(auths) mock_discover.return_value = mock_url_for result = client._discover_auth_versions(mock.sentinel, mock.sentinel) self.assertEqual(result, tuple(auths.values())) else: auth_url = mock.sentinel mock_discover.side_effect = ks_exc.ClientException() mock_path = mock.Mock() mock_path.path = expected_auth mock_url_parse.return_value = mock_path if expected_auth in auths.keys(): result = client._discover_auth_versions( mock.sentinel, auth_url) auths[expected_auth] = auth_url self.assertEqual(sorted(result), sorted(tuple(auths.values()))) else: msg = ('Unable to determine the Keystone version ' 'to authenticate with using the given ' 'auth_url. Identity service may not support API ' 'version discovery. Please provide a versioned ' 'auth_url instead.') exp = exc.CommandError(msg) with self.assertRaises(exc.CommandError) as ex: client._discover_auth_versions(mock.sentinel, mock.sentinel) self.assertEqual(ex.exception.message, exp.message)
def test_find_desktop_with_name_no_match(self, mocked_get, mock_list): desktops = self.app.client_manager.workspace.desktops mocked_get.side_effect = exceptions.ClientException(0) mock_list.return_value = base_resource.ListWithMeta([], None) self.assertRaises(exceptions.NotFound, desktops.find, "chen01")
def test_find_policy_with_name_no_match(self, mocked_get): policies = self.app.client_manager.auto_scaling.policies mocked_get.side_effect = exceptions.ClientException(0) self.assertRaises(exceptions.NotFound, policies.find, "policy_name_1")
def test_find_config_with_name_no_match(self, mocked_get, mock_list): configs = self.app.client_manager.auto_scaling.configs mocked_get.side_effect = exceptions.ClientException(0) mock_list.return_value = br.ListWithMeta([], None) self.assertRaises(exceptions.NotFound, configs.find, "config_name_1")
def request(url, method='GET', headers=None, original_ip=None, debug=False, logger=None, **kwargs): """Perform a http request with standard settings. A wrapper around requests.request that adds standard headers like User-Agent and provides optional debug logging of the request. Arguments that are not handled are passed through to the requests library. :param string url: The url to make the request of. :param string method: The http method to use. (eg. 'GET', 'POST') :param dict headers: Headers to be included in the request. (optional) :param string original_ip: Mark this request as forwarded for this ip. (optional) :param bool debug: Enable debug logging. (Defaults to False) :param logging.Logger logger: A logger to output to. (optional) :raises exceptions.ClientException: For connection failure, or to indicate an error response code. :returns: The response to the request. """ if not headers: headers = dict() if not logger: logger = _logger headers.setdefault('User-Agent', USER_AGENT) if original_ip: headers['Forwarded'] = "for=%s;by=%s" % (original_ip, USER_AGENT) if debug: string_parts = ['curl -i'] if method: string_parts.append(' -X %s' % method) string_parts.append(' %s' % url) if headers: for header in headers.iteritems(): string_parts.append(' -H "%s: %s"' % header) logger.debug("REQ: %s" % "".join(string_parts)) data = kwargs.get('data') if data: logger.debug("REQ BODY: %s\n" % data) try: resp = requests.request(method, url, headers=headers, **kwargs) except requests.ConnectionError: msg = 'Unable to establish connection to %s' % url raise exceptions.ClientException(msg) if debug: logger.debug("RESP: [%s] %s\nRESP BODY: %s\n", resp.status_code, resp.headers, resp.text) if resp.status_code >= 400: logger.debug("Request returned failure status: %s", resp.status_code) raise exceptions.from_response(resp, method, url) return resp
def user_update(request, user, **data): manager = keystoneclient(request, admin=True).users error = None if not keystone_can_edit_user(): raise keystone_exceptions.ClientException( 405, _("Identity service does not allow editing user data.")) # The v2 API updates user model and default project separately if VERSIONS.active < 3: # Update user details try: user = manager.update(user, **data) except keystone_exceptions.Conflict: raise exceptions.Conflict() except Exception: error = exceptions.handle(request, ignore=True) if "project" in data: project = data.pop('project') password = data.pop('password') # Update default tenant try: user_update_tenant(request, user, project) user.tenantId = project except Exception: error = exceptions.handle(request, ignore=True) # Check for existing roles # Show a warning if no role exists for the project user_roles = roles_for_user(request, user, project) if not user_roles: messages.warning( request, _('User %s has no role defined for ' 'that project.') % data.get('name', None)) if password: email = data.pop('email') LOG.info("v2 password:%s email:%s" % (password, email)) try: user_update_password(request, user, password) if user.id == request.user.id: return utils.logout_with_message( request, _("Password changed. Please log in again to continue." )) if email: LOG.info("v2 send email") send_mail(request, email, password) except Exception: error = exceptions.handle(request, ignore=True) if error is not None: raise error # v3 API is so much simpler... else: try: user = manager.update(user, **data) password = data.pop('password') if password: email = data.pop('email') LOG.info("v3 password:%s email:%s" % (password, email)) try: user_update_password(request, user, password) if user.id == request.user.id: return utils.logout_with_message( request, _("Password changed. Please log in again to continue." )) if email: LOG.info("v3 send email") send_mail(request, email, password) except Exception: error = exceptions.handle(request, ignore=True) if error is not None: raise error except keystone_exceptions.Conflict: raise exceptions.Conflict()