def _user_roles_edit(self, user, roles, project_id, remove=False, inherited=False): id_manager = user_store.IdentityManager() if not remove: action_fn = id_manager.add_user_role action_string = "granting" else: action_fn = id_manager.remove_user_role action_string = "removing" ks_roles = [] try: for role in roles: ks_role = id_manager.find_role(role) if ks_role: ks_roles.append(ks_role) else: raise TypeError("Keystone missing role: %s" % role) for role in ks_roles: action_fn(user, role, project_id, inherited=inherited) except Exception as e: self.add_note( "Error: '%s' while %s the roles: %s on user: %s " % (e, action_string, roles, user)) raise
def get(self, request, user_id): """ Get role info based on the user id. """ id_manager = user_store.IdentityManager() user = id_manager.get_user(user_id) no_user = {'errors': ['No user with this id.']} if not user: return Response(no_user, status=404) project_id = request.keystone_user['project_id'] project = id_manager.get_project(project_id) class_conf = settings.TASK_SETTINGS.get(self.task_type, settings.DEFAULT_TASK_SETTINGS) role_blacklist = class_conf.get('role_blacklist', []) roles = [role.name for role in id_manager.get_roles(user, project)] roles_blacklisted = set(role_blacklist) & set(roles) inherited_roles = [ role.name for role in id_manager.get_roles(user, project, True) ] inherited_roles_blacklisted = (set(role_blacklist) & set(inherited_roles)) if not roles or roles_blacklisted or inherited_roles_blacklisted: return Response(no_user, status=404) return Response({'roles': roles, 'inherited_roles': inherited_roles})
def delete(self, request, user_id): """ Remove this user from the project. This may cancel a pending user invite, or simply revoke roles. """ id_manager = user_store.IdentityManager() user = id_manager.get_user(user_id) project_id = request.keystone_user['project_id'] # NOTE(dale): For now, we only support cancelling pending invites. if user: return Response( { 'errors': [ 'Revoking keystone users not implemented. ' 'Try removing all roles instead.' ] }, status=501) project_tasks = models.Task.objects.filter(project_id=project_id, task_type="invite_user", completed=0, cancelled=0) for task in project_tasks: if task.uuid == user_id: task.add_action_note(self.__class__.__name__, 'Cancelled.') task.cancelled = True task.save() return Response('Cancelled pending invite task!', status=200) return Response('Not found.', status=404)
def delete(self, request, user_id): """ Remove this user from the project. This may cancel a pending user invite, or simply revoke roles. """ id_manager = user_store.IdentityManager() user = id_manager.get_user(user_id) project_id = request.keystone_user["project_id"] # NOTE(dale): For now, we only support cancelling pending invites. if user: return Response( { "errors": [ "Revoking keystone users not implemented. " "Try removing all roles instead." ] }, status=501, ) project_tasks = models.Task.objects.filter( project_id=project_id, task_type="invite_user_to_project", completed=0, cancelled=0, ) for task in project_tasks: if task.uuid == user_id: self.task_manager.cancel(task) return Response("Cancelled pending invite task!", status=200) return Response("Not found.", status=404)
def get(self, request, user_id): """ Get role info based on the user id. """ id_manager = user_store.IdentityManager() user = id_manager.get_user(user_id) no_user = {"errors": ["No user with this id."]} if not user: return Response(no_user, status=404) project_id = request.keystone_user["project_id"] project = id_manager.get_project(project_id) class_conf = self.config blacklisted_roles = class_conf.blacklisted_roles roles = [role.name for role in id_manager.get_roles(user, project)] roles_blacklisted = set(blacklisted_roles) & set(roles) inherited_roles = [ role.name for role in id_manager.get_roles(user, project, True) ] inherited_roles_blacklisted = set(blacklisted_roles) & set(inherited_roles) if not roles or roles_blacklisted or inherited_roles_blacklisted: return Response(no_user, status=404) return Response({"roles": roles, "inherited_roles": inherited_roles})
def check_region_exists(self, region): # Check that the region actually exists id_manager = user_store.IdentityManager() v_region = id_manager.get_region(region) if not v_region: return False return True
def _validate_role_permissions(self): id_manager = user_store.IdentityManager() current_user_roles = id_manager.get_roles( project=self.project_id, user=self.user_id ) current_user_roles = [role.name for role in current_user_roles] current_roles_manageable = self.are_roles_manageable( self.action.task.keystone_user["roles"], current_user_roles ) all_roles = set() all_roles.update(self.roles) all_roles.update(self.inherited_roles) new_roles_manageable = self.are_roles_manageable( self.action.task.keystone_user["roles"], all_roles ) if new_roles_manageable and current_roles_manageable: self.add_note("All user roles are manageable.") return True self.add_note("Not all user roles are manageable.") return False
def _validate_user_roles(self): id_manager = user_store.IdentityManager() user = self._get_target_user() project = id_manager.get_project(self.project_id) # user roles current_roles = id_manager.get_roles(user, project) current_inherited_roles = id_manager.get_roles(user, project, inherited=True) current_roles = {role.name for role in current_roles} current_inherited_roles = {role.name for role in current_inherited_roles} if self.remove: remaining = set(current_roles) & set(self.roles) remaining_inherited = set(current_inherited_roles) & set( self.inherited_roles ) if not remaining and not remaining_inherited: self.action.state = "complete" self.add_note("User doesn't have roles to remove.") else: self.roles = list(remaining) self.inherited_roles = list(remaining_inherited) self.add_note("User has roles to remove.") else: missing = set(self.roles) - set(current_roles) missing_inherited = set(self.inherited_roles) - set(current_inherited_roles) if not missing and not missing_inherited: self.action.state = "complete" self.add_note("User already has roles.") else: self.roles = list(missing) self.inherited_roles = list(missing_inherited) self.add_note("User missing roles.") # All paths are valid here # We've just set state and roles that need to be changed. return True
def delete(self, request, user_id): # FIXME(knikolla): This function is a copy from base class with # task name updated. id_manager = user_store.IdentityManager() user = id_manager.get_user(user_id) project_id = request.keystone_user["project_id"] # NOTE(dale): For now, we only support cancelling pending invites. if user: return Response( { "errors": [ "Revoking keystone users not implemented. " "Try removing all roles instead." ] }, status=501, ) project_tasks = models.Task.objects.filter( project_id=project_id, task_type="moc_invite_user", completed=0, cancelled=0, ) for task in project_tasks: if task.uuid == user_id: self.task_manager.cancel(task) return Response("Cancelled pending invite task!", status=200) return Response("Not found.", status=404)
def get(self, request): user_id = request.keystone_user['user_id'] id_manager = user_store.IdentityManager() user = id_manager.get_user(user_id) has_mfa = bool(id_manager.list_credentials(user_id, 'totp')) return Response({'username': user.name, 'has_mfa': has_mfa})
def _validate_username_exists(self): id_manager = user_store.IdentityManager() self.user = id_manager.find_user(self.username, self.domain.id) if not self.user: self.add_note('No user present with username') return False return True
def _validate_domain_id(self): id_manager = user_store.IdentityManager() domain = id_manager.get_domain(self.domain_id) if not domain: self.add_note('Domain does not exist.') return False return True
def is_root_project(project_id): id_manager = user_store.IdentityManager() project = id_manager.get_project(project_id) if project.parent_id: parent = id_manager.get_project(project.parent_id) if not parent.is_domain: return False return True
def _get_target_user(self): """ Gets the target user by id """ id_manager = user_store.IdentityManager() user = id_manager.get_user(self.user_id) return user
def setUp(self) -> None: super().setUp() for key in ['kaizen', 'massopen', '.cloud', '.com']: if key in CONF.identity.auth.auth_url: self.skipTest('Detected possible run on production systems.') self.identity = user_store.IdentityManager() self.ks_client = self.identity.ks_client
def _get_target_user(self): """ Gets the target user by their username """ id_manager = user_store.IdentityManager() user = id_manager.find_user(self.username, self.domain_id) return user
def _validate_project_absent(self): id_manager = user_store.IdentityManager() project = id_manager.find_project(self.project_name, self.domain_id) if project: self.add_note("Existing project with name '%s'." % self.project_name) return False self.add_note("No existing project with name '%s'." % self.project_name) return True
def _validate_domain_name(self): id_manager = user_store.IdentityManager() self.domain = id_manager.find_domain(self.domain_name) if not self.domain: self.add_note('Domain does not exist.') return False # also store the domain_id separately for later use self.domain_id = self.domain.id return True
def _validate_parent_project(self): id_manager = user_store.IdentityManager() # NOTE(adriant): If parent id is None, Keystone defaults to the domain. # So we only care to validate if parent_id is not None. if self.parent_id: parent = id_manager.get_project(self.parent_id) if not parent: self.add_note("Parent id: '%s' does not exist." % self.parent_id) return False return True
def _validate_region_exists(self, region): # Check that the region actually exists id_manager = user_store.IdentityManager() v_region = id_manager.get_region(region) if not v_region: self.add_note('ERROR: Region: %s does not exist.' % region) return False self.add_note('Region: %s exists.' % region) return True
def _validate_email_not_in_use(self): if CONF.identity.username_is_email: self.domain_id = self.action.task.keystone_user["project_domain_id"] id_manager = user_store.IdentityManager() if id_manager.find_user(self.new_email, self.domain_id): self.add_note("User with same username already exists") return False self.add_note("No user with same username") return True
def update_user_name(self, username, user=None): id_manager = user_store.IdentityManager() try: if not user: user = self.find_user() id_manager.update_user_name(user, username) except Exception as e: self.add_note( "Error: '%s' while changing username for user: %s" % (e, self.username)) raise
def enable_user(self, user=None): id_manager = user_store.IdentityManager() try: if not user: user = self.find_user() id_manager.enable_user(user) except Exception as e: self.add_note( "Error: '%s' while re-enabling user: %s with roles: %s" % (e, self.username, self.roles)) raise
def _validate_users(self): id_manager = user_store.IdentityManager() all_found = True for user in self.users: ks_user = id_manager.find_user(user, self.domain_id) if ks_user: self.add_note('User: %s exists.' % user) else: self.add_note('ERROR: User: %s does not exist.' % user) all_found = False return all_found
def set_email(self, conf): self.emails = set() if conf.get("email_current_user"): self.add_note("Adding the current user's email address") if CONF.identity.username_is_email: self.emails.add(self.action.task.keystone_user["username"]) else: try: id_manager = user_store.IdentityManager() email = id_manager.get_user( self.action.task.keystone_user["user_id"]).email self.emails.add(email) except AttributeError: self.add_note("Could not add current user email address") if conf.get("email_roles"): roles = set(conf.get("email_roles")) project_id = self.action.task.keystone_user["project_id"] self.add_note("Adding email addresses for roles %s in project %s" % (roles, project_id)) id_manager = user_store.IdentityManager() users = id_manager.list_users(project_id) for user in users: user_roles = [role.name for role in user.roles] if roles.intersection(user_roles): if CONF.identity.username_is_email: self.emails.add(user.name) else: self.emails.add(user.email) if conf.get("email_task_cache"): task_emails = self.action.task.cache.get("additional_emails", []) if isinstance(task_emails, six.string_types): task_emails = [task_emails] for email in task_emails: self.emails.add(email) for email in conf.get("email_additional_addresses"): self.emails.add(email)
def set_email(self, conf): self.emails = set() if conf.get('email_current_user'): self.add_note("Adding the current user's email address") if settings.USERNAME_IS_EMAIL: self.emails.add(self.action.task.keystone_user['username']) else: try: id_manager = user_store.IdentityManager() email = id_manager.get_user( self.action.task.keystone_user['user_id']).email self.emails.add(email) except AttributeError: self.add_note("Could not add current user email address") if conf.get('email_roles'): roles = set(conf.get('email_roles')) project_id = self.action.task.keystone_user['project_id'] self.add_note('Adding email addresses for roles %s in project %s' % (roles, project_id)) id_manager = user_store.IdentityManager() users = id_manager.list_users(project_id) for user in users: user_roles = [role.name for role in user.roles] if roles.intersection(user_roles): if settings.USERNAME_IS_EMAIL: self.emails.add(user.name) else: self.emails.add(user.email) if conf.get('email_task_cache'): task_emails = self.action.task.cache.get('additional_emails', []) if isinstance(task_emails, six.string_types): task_emails = [task_emails] for email in task_emails: self.emails.add(email) for email in conf.get('email_additional_addresses', []): self.emails.add(email)
def _validate_region(self): if not self.region: self.add_note('ERROR: No region given.') return False id_manager = user_store.IdentityManager() region = id_manager.get_region(self.region) if not region: self.add_note('ERROR: Region does not exist.') return False self.add_note('Region: %s exists.' % self.region) return True
def _get_email(self): if settings.USERNAME_IS_EMAIL: return self.action.task.keystone_user['username'] else: id_manager = user_store.IdentityManager() user = id_manager.users.get(self.keystone_user['user_id']) email = user.email if email: return email self.add_note("User email address not set.") return None
def _get_email(self): if CONF.identity.username_is_email: return self.action.task.keystone_user["username"] else: id_manager = user_store.IdentityManager() user = id_manager.users.get(self.keystone_user["user_id"]) email = user.email if email: return email self.add_note("User email address not set.") return None
def post(self, request): request.data['project_id'] = request.keystone_user['project_id'] self.project_id = request.keystone_user['project_id'] regions = request.data.get('regions', None) if not regions: id_manager = user_store.IdentityManager() regions = [region.id for region in id_manager.list_regions()] request.data['regions'] = regions self.logger.info("(%s) - New UpdateProjectQuotas request." % timezone.now()) processed, status = self.process_actions(request) # check the status errors = processed.get('errors', None) if errors: self.logger.info("(%s) - Validation errors with task." % timezone.now()) return Response({'errors': errors}, status=status) if processed.get('auto_approved', False): response_dict = {'notes': processed['notes']} return Response(response_dict, status=status) task = processed['task'] action_models = task.actions valid = all([act.valid for act in action_models]) if not valid: return Response( { 'errors': [ 'Actions invalid. You may have usage ' 'above the new quota level.' ] }, 400) # Action needs to be manually approved notes = {'notes': ['New task for UpdateProjectQuotas.']} create_notification(processed['task'], notes) self.logger.info("(%s) - Task processed. Awaiting Aprroval" % timezone.now()) response_dict = {'notes': ['Task processed. Awaiting Aprroval.']} return Response(response_dict, status=202)