Source code for keystone.cmd.idutils

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import uuid

from oslo_log import log

from keystone.common import provider_api
from keystone.common.validation import validators
import keystone.conf
from keystone import exception
from keystone.identity.mapping_backends import mapping
from keystone import notifications
from keystone.server import backends

CONF = keystone.conf.CONF
LOG = log.getLogger(__name__)
PROVIDERS = provider_api.ProviderAPIs


[docs] class Identity(object): def __init__(self): backends.load_backends() self.user_id = None self.user_name = None self.user_password = None self.project_id = None self.project_name = None self.default_domain_id = CONF.identity.default_domain_id
[docs] def project_setup(self): try: project_id = self.project_id if project_id is None: project_id = uuid.uuid4().hex project = { 'enabled': True, 'id': project_id, 'domain_id': self.default_domain_id, 'description': 'Bootstrap project for initializing the cloud.', 'name': self.project_name } PROVIDERS.resource_api.create_project(project_id, project) LOG.info('Created project %s', self.project_name) except exception.Conflict: LOG.info('Project %s already exists, skipping creation.', self.project_name) project = PROVIDERS.resource_api.get_project_by_name( self.project_name, self.default_domain_id ) self.project_id = project['id']
def _create_user(self, user_ref, initiator=None): _self = PROVIDERS.identity_api.create_user.__self__ user = user_ref.copy() if 'password' in user: validators.validate_password(user['password']) user['name'] = user['name'].strip() user.setdefault('enabled', True) domain_id = user['domain_id'] PROVIDERS.resource_api.get_domain(domain_id) _self._assert_default_project_id_is_not_domain( user_ref.get('default_project_id')) # For creating a user, the domain is in the object itself domain_id = user_ref['domain_id'] driver = _self._select_identity_driver(domain_id) user = _self._clear_domain_id_if_domain_unaware(driver, user) # Generate a local ID - in the future this might become a function of # the underlying driver so that it could conform to rules set down by # that particular driver type. user['id'] = self.user_id ref = _self._create_user_with_federated_objects(user, driver) notifications.Audit.created(_self._USER, user['id'], initiator) return _self._set_domain_id_and_mapping( ref, domain_id, driver, mapping.EntityType.USER)
[docs] def user_setup(self): # NOTE(morganfainberg): Do not create the user if it already exists. try: user = PROVIDERS.identity_api.get_user_by_name( self.user_name, self.default_domain_id ) LOG.info('User %s already exists, skipping creation.', self.user_name) if self.user_id is not None and user['id'] != self.user_id: msg = (f'user `{self.user_name}` already exists ' f'with `{self.user_id}`') raise exception.Conflict(type='user_id', details=msg) # If the user is not enabled, re-enable them. This also helps # provide some useful logging output later. update = {} enabled = user['enabled'] if not enabled: update['enabled'] = True try: PROVIDERS.identity_api.driver.authenticate( user['id'], self.user_password ) except AssertionError: # This means that authentication failed and that we need to # update the user's password. This is going to persist a # revocation event that will make all previous tokens for the # user invalid, which is OK because it falls within the scope # of revocation. If a password changes, we shouldn't be able to # use tokens obtained with an old password. update['password'] = self.user_password # Only make a call to update the user if the password has changed # or the user was previously disabled. This allows bootstrap to act # as a recovery tool, without having to create a new user. if update: user = PROVIDERS.identity_api.update_user( user['id'], update ) LOG.info('Reset password for user %s.', self.user_name) if not enabled and user['enabled']: # Although we always try to enable the user, this log # message only makes sense if we know that the user was # previously disabled. LOG.info('Enabled user %s.', self.user_name) except exception.UserNotFound: user = self._create_user( user_ref={ 'name': self.user_name, 'enabled': True, 'domain_id': self.default_domain_id, 'password': self.user_password } ) LOG.info('Created user %s', self.user_name) self.user_id = user['id']