Beispiel #1
0
    def get(self, request, user_id):
        """
        Get user info based on the user id.

        Will only find users in your project.
        """
        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)

        class_conf = settings.TASK_SETTINGS.get(self.task_type,
                                                settings.DEFAULT_TASK_SETTINGS)
        role_blacklist = class_conf.get('role_blacklist', [])
        project_id = request.keystone_user['project_id']
        project = id_manager.get_project(project_id)

        roles = [role.name for role in id_manager.get_roles(user, project)]
        roles_blacklisted = set(role_blacklist) & set(roles)

        if not roles or roles_blacklisted:
            return Response(no_user, status=404)
        return Response({
            'id': user.id,
            "username": user.name,
            "email": getattr(user, 'email', ''),
            'roles': roles
        })
Beispiel #2
0
 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)
Beispiel #3
0
    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_role_names = {role.name for role in current_roles}

        # NOTE(adriant): Only allow someone to edit roles if all roles from
        # the target user can be managed by editor.
        can_manage_roles = user_store.get_managable_roles(
            self.action.task.keystone_user['roles'])
        if not set(can_manage_roles).issuperset(current_role_names):
            self.add_note('Not all target user roles are manageable.')
            return False

        if self.remove:
            remaining = set(current_role_names) & set(self.roles)
            if not remaining:
                self.action.state = "complete"
                self.add_note("User doesn't have roles to remove.")
            else:
                self.roles = list(remaining)
                self.add_note('User has roles to remove.')
        else:
            missing = set(self.roles) - set(current_role_names)
            if not missing:
                self.action.state = "complete"
                self.add_note('User already has roles.')
            else:
                self.roles = list(missing)
                self.add_note('User user missing roles.')
        # All paths are valid here
        # We've just set state and roles that need to be changed.
        return True
Beispiel #4
0
    def _submit(self, token_data):
        """
        The submit action is performed when a token is submitted.
        This is done to set a user password only, and so should now only
        change the user password. The project and user themselves are created
        on post_approve.
        """

        self._validate_user_submit()

        if not self.valid:
            return

        project_id = self.get_cache('project_id')
        self.action.task.cache['project_id'] = project_id
        user_id = self.get_cache('user_id')
        self.action.task.cache['user_id'] = user_id
        id_manager = user_store.IdentityManager()

        if self.action.state in ["default", "disabled"]:
            user = id_manager.get_user(user_id)
            try:
                id_manager.update_user_password(user, token_data['password'])
            except Exception as e:
                self.add_note(
                    "Error: '%s' while changing password for user: %s" %
                    (e, self.username))
                raise
            self.add_note('User %s password has been changed.' % self.username)

        elif self.action.state == "existing":
            # do nothing, everything is already done.
            self.add_note("Existing user '%s' already attached to project %s" %
                          (user_id, project_id))
Beispiel #5
0
    def _submit(self, token_data):
        self._validate()

        if not self.valid:
            return

        id_manager = user_store.IdentityManager()
        user = id_manager.find_user(self.username, None)
        roles = id_manager.get_roles(user, self.project_id)
        role_names = {role.name for role in roles}
        missing = set(self.roles) - role_names

        self.add_note("Accepted by %s" %
                      self.action.task.keystone_user['username'])

        if not missing:
            self.add_note(
                'Existing user %s already had roles %s in project %s.' %
                (self.username, self.roles, self.project_id))
        else:
            self.roles = list(missing)
            self.grant_roles(user, self.roles, self.project_id)
            self.add_note(
                'Existing user %s has been given roles %s in project %s.' %
                (self.username, self.roles, self.project_id))
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
    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
Beispiel #9
0
    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
Beispiel #10
0
 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
Beispiel #11
0
 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
Beispiel #12
0
 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)
     project_id = request.keystone_user['project_id']
     project = id_manager.get_project(project_id)
     roles = []
     for role in id_manager.get_roles(user, project):
         roles.append(role.to_dict())
     return Response({"roles": roles})
Beispiel #13
0
    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
Beispiel #14
0
 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
Beispiel #15
0
 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.project_name)
             return False
     return True
Beispiel #16
0
    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
Beispiel #17
0
    def _validate_email_not_in_use(self):
        if settings.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
Beispiel #18
0
    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)
Beispiel #19
0
    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
Beispiel #20
0
    def _validate_project_exists(self):
        if not self.project_id:
            self.add_note('No project_id set, previous action should have '
                          'set it.')
            return False

        id_manager = user_store.IdentityManager()
        project = id_manager.get_project(self.project_id)
        if not project:
            self.add_note('Project with id %s does not exist.' %
                          self.project_id)
            return False
        self.add_note('Project with id %s exists.' % self.project_id)
        return True
Beispiel #21
0
 def create_user(self, password):
     id_manager = user_store.IdentityManager()
     try:
         user = id_manager.create_user(
             name=self.username, password=password,
             email=self.email, domain=self.domain_id,
             created_on=str(timezone.now()))
     except Exception as e:
         # TODO: Narrow the Exceptions caught to a relevant set.
         self.add_note(
             "Error: '%s' while creating user: %s with roles: %s" %
             (e, self.username, self.roles))
         raise
     return user
Beispiel #22
0
 def _create_project(self):
     id_manager = user_store.IdentityManager()
     try:
         project = id_manager.create_project(
             self.project_name, created_on=str(timezone.now()),
             parent=self.parent_id, domain=self.domain_id)
     except Exception as e:
         self.add_note(
             "Error: '%s' while creating project: %s" %
             (e, self.project_name))
         raise
     # put project_id into action cache:
     self.action.task.cache['project_id'] = project.id
     self.set_cache('project_id', project.id)
     self.add_note("New project '%s' created." % project.name)
Beispiel #23
0
    def _validate_project_id(self):
        # Handle an edge_case where some actions set their
        # own project_id value.
        if not self.project_id:
            self.add_note('No project_id given.')
            return False

        # Now actually check the project exists.
        id_manager = user_store.IdentityManager()
        project = id_manager.get_project(self.project_id)
        if not project:
            self.add_note('Project with id %s does not exist.' %
                          self.project_id)
            return False
        self.add_note('Project with id %s exists.' % self.project_id)
        return True
Beispiel #24
0
    def _validate_target_user(self):
        id_manager = user_store.IdentityManager()

        # check if user exists and is valid
        # this may mean we need a token.
        user = self._get_target_user()
        if not user:
            self.action.need_token = True
            # add to cache to use in template
            self.action.task.cache['user_state'] = "default"
            self.set_token_fields(["password"])
            self.add_note(
                'No user present with username. Need to create new user.')
            return True
        if user.email != self.email:
            self.add_note('Found matching username, but email did not match.' +
                          'Reporting as invalid.')
            return False

        if not user.enabled:
            self.action.need_token = True
            self.action.state = "disabled"
            # add to cache to use in template
            self.action.task.cache['user_state'] = "disabled"
            # as they are disabled we'll reset their password
            self.set_token_fields(["password"])
            self.add_note('Existing disabled user with matching email.')
            return True

        # role_validation
        roles = id_manager.get_roles(user, self.project_id)
        role_names = {role.name for role in roles}
        missing = set(self.roles) - role_names
        if not missing:
            self.action.need_token = False
            self.action.state = "complete"
            self.add_note('Existing user already has roles.')
        else:
            self.roles = list(missing)
            self.action.need_token = True
            self.set_token_fields(["confirm"])
            self.action.state = "existing"
            # add to cache to use in template
            self.action.task.cache['user_state'] = "existing"
            self.add_note('Existing user with matching email missing roles.')

        return True
Beispiel #25
0
    def _validate_user_submit(self):
        user_id = self.get_cache('user_id')
        project_id = self.get_cache('project_id')

        id_manager = user_store.IdentityManager()

        user = id_manager.get_user(user_id)
        project = id_manager.get_project(project_id)

        if user and project:
            self.action.valid = True
        else:
            self.action.valid = False

        self.action.task.cache['user_state'] = self.action.state

        self.action.save()
Beispiel #26
0
    def get(self, request):
        """Returns a list of roles that may be managed for this project"""

        # get roles for this user on the project
        user_roles = request.keystone_user['roles']
        managable_role_names = user_store.get_managable_roles(user_roles)

        id_manager = user_store.IdentityManager()

        # look up role names and form output dict of valid roles
        managable_roles = []
        for role_name in managable_role_names:
            role = id_manager.find_role(role_name)
            if role:
                managable_roles.append(role.to_dict())

        return Response({'roles': managable_roles})
Beispiel #27
0
    def _post_approve(self):
        id_manager = user_store.IdentityManager()
        self.project_id = self.action.task.cache.get('project_id', None)
        self._validate()

        if self.valid and not self.action.state == "completed":
            try:
                for user in self.users:
                    ks_user = id_manager.find_user(user, self.domain_id)

                    self.grant_roles(ks_user, self.roles, self.project_id)
                    self.add_note(
                        'User: "******" given roles: %s on project: %s.' %
                        (ks_user.name, self.roles, self.project_id))
            except Exception as e:
                self.add_note("Error: '%s' while adding users to project: %s" %
                              (e, self.project_id))
                raise
            self.action.state = "completed"
            self.action.save()
            self.add_note("All users added.")
Beispiel #28
0
    def _post_approve(self):
        project_id = self.get_cache('project_id')
        if project_id:
            self.action.task.cache['project_id'] = project_id
            self.add_note("Project already created.")
        else:
            self._validate()

            if not self.valid:
                return

            self._create_project()

        user_id = self.get_cache('user_id')
        if user_id:
            self.action.task.cache['user_id'] = user_id
            self.add_note("User already given roles.")
        else:
            default_roles = self.settings.get("default_roles", {})

            project_id = self.get_cache('project_id')
            keystone_user = self.action.task.keystone_user

            try:
                id_manager = user_store.IdentityManager()
                user = id_manager.get_user(keystone_user['user_id'])

                self.grant_roles(user, default_roles, project_id)
            except Exception as e:
                self.add_note(("Error: '%s' while adding roles %s "
                               "to user '%s' on project '%s'") %
                              (e, default_roles, user.name, project_id))
                raise

            # put user_id into action cache:
            self.action.task.cache['user_id'] = user.id
            self.set_cache('user_id', user.id)
            self.add_note(
                ("Existing user '%s' attached to project %s" +
                 " with roles: %s") % (user.name, project_id, default_roles))
Beispiel #29
0
    def _validate_user_roles(self):
        id_manager = user_store.IdentityManager()

        self.user = id_manager.find_user(self.username, self.domain.id)
        roles = id_manager.get_all_roles(self.user)

        user_roles = []
        for roles in roles.itervalues():
            user_roles.extend(role.name for role in roles)

        if set(self.blacklist) & set(user_roles):
            self.add_note('Cannot reset users with blacklisted roles.')
            return False

        if self.user.email == self.email:
            self.action.need_token = True
            self.set_token_fields(["password"])
            self.add_note('Existing user with matching email.')
            return True
        else:
            self.add_note('Existing user with non-matching email.')
            return False
Beispiel #30
0
    def _user_roles_edit(self, user, roles, project_id, remove=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)
        except Exception as e:
            self.add_note("Error: '%s' while %s the roles: %s on user: %s " %
                          (e, action_string, roles, user))
            raise