def test_get_all_role_assignments(self):
        role_assignment_dbs = rbac_service.get_all_role_assignments(
            include_remote=True)
        self.assertEqual(len(role_assignment_dbs), 5)

        role_assignment_dbs = rbac_service.get_all_role_assignments(
            include_remote=False)
        self.assertEqual(len(role_assignment_dbs), 4)

        for role_assignment_db in role_assignment_dbs:
            self.assertFalse(role_assignment_db.is_remote)
Esempio n. 2
0
    def sync_users_role_assignments(self, role_assignment_apis):
        """
        Synchronize role assignments for all the users in the database.

        :param role_assignment_apis: Role assignments API objects for the assignments loaded
                                      from the files.
        :type role_assignment_apis: ``list`` of :class:`UserRoleAssignmentFileFormatAPI`

        :return: Dictionary with created and removed role assignments for each user.
        :rtype: ``dict``
        """
        assert isinstance(role_assignment_apis, (list, tuple))

        LOG.info('Synchronizing users role assignments...')

        # Note: We exclude remote assignments because sync tool is not supposed to manipulate
        # remote assignments
        role_assignment_dbs = rbac_service.get_all_role_assignments(include_remote=False)

        user_dbs = User.get_all()

        username_to_user_db_map = dict([(user_db.name, user_db) for user_db in user_dbs])
        username_to_role_assignment_apis_map = defaultdict(list)
        username_to_role_assignment_dbs_map = defaultdict(list)

        for role_assignment_api in role_assignment_apis:
            username = role_assignment_api.username
            username_to_role_assignment_apis_map[username].append(role_assignment_api)

        for role_assignment_db in role_assignment_dbs:
            username = role_assignment_db.user
            username_to_role_assignment_dbs_map[username].append(role_assignment_db)

        # Note: We process assignments for all the users (ones specified in the assignment files
        # and ones which are in the database). We want to make sure assignments are correctly
        # deleted from the database for users which existing in the database, but have no
        # assignment file on disk and for assignments for users which don't exist in the database.
        all_usernames = (list(username_to_user_db_map.keys()) +
                         list(username_to_role_assignment_apis_map.keys()) +
                         list(username_to_role_assignment_dbs_map.keys()))
        all_usernames = list(set(all_usernames))

        results = {}
        for username in all_usernames:
            user_db = username_to_user_db_map.get(username, None)

            if not user_db:
                # Note: We allow assignments to be created for the users which don't exist in the
                # DB yet because user creation in StackStorm is lazy (we only create UserDB) object
                # when user first logs in.
                user_db = UserDB(name=username)
                LOG.debug(('User "%s" doesn\'t exist in the DB, creating assignment anyway' %
                          (username)))

            role_assignment_apis = username_to_role_assignment_apis_map.get(username, [])
            role_assignment_dbs = username_to_role_assignment_dbs_map.get(username, [])

            # Additional safety assert to ensure we don't accidentally manipulate remote
            # assignments
            for role_assignment_db in role_assignment_dbs:
                assert role_assignment_db.is_remote is False

            result = self._sync_user_role_assignments(
                user_db=user_db, role_assignment_dbs=role_assignment_dbs,
                role_assignment_apis=role_assignment_apis)

            results[username] = result

        LOG.info('User role assignments synchronized')
        return results