def test_switch_user_from_root(self, osmock):
        """Test switch user from root, let it as root"""
        osmock.getenv.return_value = 0
        osmock.geteuid.return_value = 0
        tools.switch_to_current_user()

        osmock.setegid.assert_called_once_with(0)
        osmock.seteuid.assert_called_once_with(0)
    def test_switch_user_from_sudo(self, osmock):
        """Test switch user account from root to previous user under SUDO"""
        osmock.getenv.return_value = 1234
        osmock.geteuid.return_value = 0
        tools.switch_to_current_user()

        osmock.setegid.assert_called_once_with(1234)
        osmock.seteuid.assert_called_once_with(1234)
    def test_switch_user_from_non_sudo(self, osmock):
        """Test switch user from a non sudo command (non root), dosen't call anything"""
        osmock.getenv.return_value = 1234
        osmock.geteuid.return_value = 1234
        tools.switch_to_current_user()

        self.assertFalse(osmock.setegid.called)
        self.assertFalse(osmock.seteuid.called)
        self.assertFalse(osmock.getenv.called)
    def setup(self):
        """Method call to setup the Framework"""
        if not self.is_installable:
            logger.error("You can't install that framework on that machine")
            UI.return_main_screen()
            return

        if self.need_root_access and os.geteuid() != 0:
            logger.debug("Requesting root access")
            cmd = ["sudo", "-E", "env", "PATH={}".format(os.getenv("PATH"))]
            cmd.extend(sys.argv)
            MainLoop().quit(subprocess.call(cmd))

        # be a normal, kind user as we don't want normal files to be written as root
        switch_to_current_user()
    def _really_install_bucket(self, current_bucket):
        """Really install current bucket and bind signals"""
        bucket = current_bucket["bucket"]
        logger.debug("Starting {} installation".format(bucket))

        # exchange file output for apt and dpkg after the fork() call (open it empty)
        self.apt_fd = tempfile.NamedTemporaryFile(delete=False)
        self.apt_fd.close()

        if self.is_bucket_uptodate(bucket):
            return True

        for pkg_name in bucket:
            if ":" in pkg_name:
                arch = pkg_name.split(":", -1)[-1]
                # try to add the arch
                if arch not in get_foreign_archs() and arch != get_current_arch():
                    logger.info("Adding foreign arch: {}".format(arch))
                    with open(os.devnull, "w") as f:
                        try:
                            os.seteuid(0)
                            os.setegid(0)
                            if subprocess.call(["dpkg", "--add-architecture", arch], stdout=f) != 0:
                                msg = "Can't add foreign foreign architecture {}".format(arch)
                                raise BaseException(msg)
                            self.cache.update()
                        finally:
                            switch_to_current_user()
                        self._force_reload_apt_cache()

        # mark for install and so on
        for pkg_name in bucket:
            # /!\ danger: if current arch == ':appended_arch', on a non multiarch system, dpkg doesn't understand that
            # strip :arch then
            if ":" in pkg_name:
                (pkg_without_arch_name, arch) = pkg_name.split(":", -1)
                if arch == get_current_arch():
                    pkg_name = pkg_without_arch_name
            try:
                pkg = self.cache[pkg_name]
                if pkg.is_installed and pkg.is_upgradable:
                    logger.debug("Marking {} for upgrade".format(pkg_name))
                    pkg.mark_upgrade()
                else:
                    logger.debug("Marking {} for install".format(pkg_name))
                    pkg.mark_install(auto_fix=False)
            except Exception as msg:
                message = "Can't mark for install {}: {}".format(pkg_name, msg)
                raise BaseException(message)

        # this can raise on installedArchives() exception if the commit() fails
        try:
            os.seteuid(0)
            os.setegid(0)
            self.cache.commit(fetch_progress=self._FetchProgress(current_bucket,
                                                                 self.STATUS_DOWNLOADING,
                                                                 current_bucket["progress_callback"]),
                              install_progress=self._InstallProgress(current_bucket,
                                                                     self.STATUS_INSTALLING,
                                                                     current_bucket["progress_callback"],
                                                                     self._force_reload_apt_cache,
                                                                     self.apt_fd.name))
        finally:
            switch_to_current_user()

        return True