mirror of
https://invent.kde.org/system/dolphin
synced 2024-10-05 16:19:10 +00:00
Guide users to using kio-admin instead of sudo
This commit adds a guided setup that leads users from a situation in which they try to "sudo dolphin" towards them successfully setting up and using kio-admin. 1. When users enter "sudo dolphin", they are told to start Dolphin by typing "dolphin --sudo" or "dolphin --admin" instead. 2. When Dolphin is started with "--sudo" or "--admin" it checks whether an "admin" protocol is installed. If not, a guided setup leads users towards installing it. 3. After that, Dolphin starts with an installed "admin" protocoll like kio-admin. Now a non-modal information dialog appears that explains how to activate and use kio-admin.
This commit is contained in:
parent
887f3a6e83
commit
92b178b740
|
@ -103,7 +103,7 @@ find_package(Phonon4Qt6 CONFIG REQUIRED)
|
||||||
find_package(PackageKitQt6)
|
find_package(PackageKitQt6)
|
||||||
set_package_properties(PackageKitQt6
|
set_package_properties(PackageKitQt6
|
||||||
PROPERTIES DESCRIPTION "Software Manager integration"
|
PROPERTIES DESCRIPTION "Software Manager integration"
|
||||||
TYPE OPTIONAL
|
TYPE RECOMMENDED
|
||||||
PURPOSE "Used in the service menu installer"
|
PURPOSE "Used in the service menu installer"
|
||||||
)
|
)
|
||||||
if(PackageKitQt6_FOUND)
|
if(PackageKitQt6_FOUND)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
include(ECMAddAppIcon)
|
include(ECMAddAppIcon)
|
||||||
|
|
||||||
|
set(ADMIN_WORKER_PACKAGE_NAME "kio-admin")
|
||||||
configure_file(config-dolphin.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-dolphin.h)
|
configure_file(config-dolphin.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-dolphin.h)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
|
@ -274,6 +275,7 @@ target_sources(dolphinstatic PRIVATE
|
||||||
dolphincontextmenu.cpp
|
dolphincontextmenu.cpp
|
||||||
dolphinnavigatorswidgetaction.cpp
|
dolphinnavigatorswidgetaction.cpp
|
||||||
dolphintabbar.cpp
|
dolphintabbar.cpp
|
||||||
|
dolphinpackageinstaller.cpp
|
||||||
dolphinplacesmodelsingleton.cpp
|
dolphinplacesmodelsingleton.cpp
|
||||||
dolphinrecenttabsmenu.cpp
|
dolphinrecenttabsmenu.cpp
|
||||||
dolphintabpage.cpp
|
dolphintabpage.cpp
|
||||||
|
@ -334,6 +336,7 @@ target_sources(dolphinstatic PRIVATE
|
||||||
dolphincontextmenu.h
|
dolphincontextmenu.h
|
||||||
dolphinnavigatorswidgetaction.h
|
dolphinnavigatorswidgetaction.h
|
||||||
dolphintabbar.h
|
dolphintabbar.h
|
||||||
|
dolphinpackageinstaller.h
|
||||||
dolphinplacesmodelsingleton.h
|
dolphinplacesmodelsingleton.h
|
||||||
dolphinrecenttabsmenu.h
|
dolphinrecenttabsmenu.h
|
||||||
dolphintabpage.h
|
dolphintabpage.h
|
||||||
|
@ -459,6 +462,13 @@ if (HAVE_PLASMA_ACTIVITIES)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(HAVE_PACKAGEKIT)
|
||||||
|
target_link_libraries(
|
||||||
|
dolphinstatic
|
||||||
|
PK::packagekitqt6
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (HAVE_KUSERFEEDBACK)
|
if (HAVE_KUSERFEEDBACK)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
dolphinstatic
|
dolphinstatic
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
|
|
||||||
#include "workerintegration.h"
|
#include "workerintegration.h"
|
||||||
|
|
||||||
|
#include "config-dolphin.h"
|
||||||
#include "dolphinmainwindow.h"
|
#include "dolphinmainwindow.h"
|
||||||
|
#include "dolphinpackageinstaller.h"
|
||||||
#include "dolphinviewcontainer.h"
|
#include "dolphinviewcontainer.h"
|
||||||
|
|
||||||
#include <KActionCollection>
|
#include <KActionCollection>
|
||||||
|
@ -18,8 +20,77 @@
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
using namespace Admin;
|
using namespace Admin;
|
||||||
|
|
||||||
|
/** Free file-local functions */
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
/** @returns the translated name of the actAsAdminAction. */
|
||||||
|
QString actionName()
|
||||||
|
{
|
||||||
|
return i18nc("@action:inmenu", "Act as Administrator");
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @returns the default keyboard shortcut of the actAsAdminAction. */
|
||||||
|
QKeySequence actionDefaultShortcut()
|
||||||
|
{
|
||||||
|
return Qt::CTRL | Qt::SHIFT | Qt::ALT | Qt::Key_A;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @returns whether any worker for the protocol "admin" is available. */
|
||||||
|
bool isWorkerInstalled()
|
||||||
|
{
|
||||||
|
return KProtocolInfo::isKnownProtocol(QStringLiteral("admin"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Admin::guideUserTowardsInstallingAdminWorker()
|
||||||
|
{
|
||||||
|
if (!isWorkerInstalled()) {
|
||||||
|
std::cout << qPrintable(
|
||||||
|
xi18nc("@info:shell",
|
||||||
|
"<application>Dolphin</application> requires <application>%1</application> to manage system-controlled files, but it is not installed.<nl/>"
|
||||||
|
"Press %2 to install <application>%1</application> or %3 to cancel.",
|
||||||
|
ADMIN_WORKER_PACKAGE_NAME,
|
||||||
|
QKeySequence{Qt::Key_Enter}.toString(QKeySequence::NativeText),
|
||||||
|
QKeySequence{Qt::CTRL | Qt::Key_C}.toString(QKeySequence::NativeText)));
|
||||||
|
std::cin.ignore();
|
||||||
|
|
||||||
|
/// Installing admin worker
|
||||||
|
DolphinPackageInstaller adminWorkerInstaller{ADMIN_WORKER_PACKAGE_NAME, QUrl(QStringLiteral("appstream://org.kde.kio.admin")), isWorkerInstalled};
|
||||||
|
QObject::connect(&adminWorkerInstaller, &KJob::result, [](KJob *job) {
|
||||||
|
if (job->error()) {
|
||||||
|
std::cout << qPrintable(job->errorString()) << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
adminWorkerInstaller.exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Admin::guideUserTowardsUsingAdminWorker()
|
||||||
|
{
|
||||||
|
KuitSetup *kuitSetup = &Kuit::setupForDomain("dolphin");
|
||||||
|
kuitSetup->setTagPattern(QStringLiteral("numberedlist"), QStringList{}, Kuit::RichText, ki18nc("tag-format-pattern <numberedlist> rich", "<ol>%1</ol>"));
|
||||||
|
kuitSetup->setTagPattern(QStringLiteral("numbereditem"), QStringList{}, Kuit::RichText, ki18nc("tag-format-pattern <numbereditem> rich", "<li>%1</li>"));
|
||||||
|
|
||||||
|
KMessageBox::information(
|
||||||
|
nullptr,
|
||||||
|
xi18nc("@info",
|
||||||
|
"<para>Make use of your administrator rights in Dolphin:<numberedlist>"
|
||||||
|
"<numbereditem>Navigate to the file or folder you want to change.</numbereditem>"
|
||||||
|
"<numbereditem>Activate the \"%1\" action either under <interface>Open Menu|More|View</interface> or <interface>Menu Bar|View</interface>.<nl/>"
|
||||||
|
"Default shortcut: <shortcut>%2</shortcut></numbereditem>"
|
||||||
|
"<numbereditem>After authorization you can manage files as an administrator.</numbereditem></numberedlist></para>",
|
||||||
|
actionName(),
|
||||||
|
actionDefaultShortcut().toString(QKeySequence::NativeText)),
|
||||||
|
i18nc("@title:window", "How to Administrate"),
|
||||||
|
"",
|
||||||
|
KMessageBox::WindowModal);
|
||||||
|
}
|
||||||
|
|
||||||
QString Admin::warningMessage()
|
QString Admin::warningMessage()
|
||||||
{
|
{
|
||||||
return xi18nc(
|
return xi18nc(
|
||||||
|
@ -52,12 +123,12 @@ WorkerIntegration::WorkerIntegration(DolphinMainWindow *parent, QAction *actAsAd
|
||||||
void WorkerIntegration::createActAsAdminAction(KActionCollection *actionCollection, DolphinMainWindow *dolphinMainWindow)
|
void WorkerIntegration::createActAsAdminAction(KActionCollection *actionCollection, DolphinMainWindow *dolphinMainWindow)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!instance);
|
Q_ASSERT(!instance);
|
||||||
if (KProtocolInfo::isKnownProtocol(QStringLiteral("admin"))) {
|
if (isWorkerInstalled()) {
|
||||||
QAction *actAsAdminAction = actionCollection->addAction(QStringLiteral("act_as_admin"));
|
QAction *actAsAdminAction = actionCollection->addAction(QStringLiteral("act_as_admin"));
|
||||||
actAsAdminAction->setText(i18nc("@action:inmenu", "Act as Administrator"));
|
actAsAdminAction->setText(actionName());
|
||||||
actAsAdminAction->setIcon(QIcon::fromTheme(QStringLiteral("system-switch-user")));
|
actAsAdminAction->setIcon(QIcon::fromTheme(QStringLiteral("system-switch-user")));
|
||||||
actAsAdminAction->setCheckable(true);
|
actAsAdminAction->setCheckable(true);
|
||||||
actionCollection->setDefaultShortcut(actAsAdminAction, Qt::CTRL | Qt::SHIFT | Qt::ALT | Qt::Key_A);
|
actionCollection->setDefaultShortcut(actAsAdminAction, actionDefaultShortcut());
|
||||||
|
|
||||||
instance = new WorkerIntegration(dolphinMainWindow, actAsAdminAction);
|
instance = new WorkerIntegration(dolphinMainWindow, actAsAdminAction);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,15 @@ class QUrl;
|
||||||
*/
|
*/
|
||||||
namespace Admin
|
namespace Admin
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* When a user starts Dolphin with arguments that imply that they want to use administrative rights, this method is called.
|
||||||
|
* This function acts like a command line program that guides users towards installing kio-admin. It will not return until this is accomplished.
|
||||||
|
* This function will do nothing if kio-admin is already installed.
|
||||||
|
*/
|
||||||
|
void guideUserTowardsInstallingAdminWorker();
|
||||||
|
|
||||||
|
void guideUserTowardsUsingAdminWorker();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used with the KMessageBox API so users can disable the warning.
|
* Used with the KMessageBox API so users can disable the warning.
|
||||||
* @see KMessageBox::saveDontShowAgainContinue()
|
* @see KMessageBox::saveDontShowAgainContinue()
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
/** Set whether to build Dolphin with support for these technologies or not. */
|
||||||
#cmakedefine01 HAVE_BALOO
|
#cmakedefine01 HAVE_BALOO
|
||||||
#cmakedefine01 HAVE_PLASMA_ACTIVITIES
|
#cmakedefine01 HAVE_PLASMA_ACTIVITIES
|
||||||
#cmakedefine01 HAVE_KUSERFEEDBACK
|
#cmakedefine01 HAVE_KUSERFEEDBACK
|
||||||
#cmakedefine01 HAVE_PACKAGEKIT
|
#cmakedefine01 HAVE_PACKAGEKIT
|
||||||
#cmakedefine01 HAVE_TERMINAL
|
#cmakedefine01 HAVE_TERMINAL
|
||||||
#cmakedefine01 HAVE_X11
|
#cmakedefine01 HAVE_X11
|
||||||
|
|
||||||
|
/** The name of the package that needs to be installed so URLs starting with "admin:" can be opened in Dolphin. */
|
||||||
|
#cmakedefine ADMIN_WORKER_PACKAGE_NAME "@ADMIN_WORKER_PACKAGE_NAME@"
|
||||||
|
|
115
src/dolphinpackageinstaller.cpp
Normal file
115
src/dolphinpackageinstaller.cpp
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
This file is part of the KDE project
|
||||||
|
SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dolphinpackageinstaller.h"
|
||||||
|
|
||||||
|
#include <KLocalizedString>
|
||||||
|
|
||||||
|
#if HAVE_PACKAGEKIT
|
||||||
|
#include <PackageKit/Daemon>
|
||||||
|
#else
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QtAssert>
|
||||||
|
|
||||||
|
DolphinPackageInstaller::DolphinPackageInstaller(const QString &packageName,
|
||||||
|
const QUrl &fallBackInstallationPageUrl,
|
||||||
|
std::function<bool()> isPackageInstalledCheck,
|
||||||
|
QObject *parent)
|
||||||
|
: KJob(parent)
|
||||||
|
, m_packageName{packageName}
|
||||||
|
, m_fallBackInstallationPageUrl{fallBackInstallationPageUrl}
|
||||||
|
, m_isPackageInstalledCheck{isPackageInstalledCheck}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DolphinPackageInstaller::start()
|
||||||
|
{
|
||||||
|
if (m_isPackageInstalledCheck()) {
|
||||||
|
emitResult();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_PACKAGEKIT
|
||||||
|
PackageKit::Daemon::setHints(PackageKit::Daemon::hints() + QStringList{QStringLiteral("interactive=true")});
|
||||||
|
const PackageKit::Transaction *resolveTransaction = PackageKit::Daemon::resolve(m_packageName);
|
||||||
|
|
||||||
|
connect(resolveTransaction, &PackageKit::Transaction::errorCode, this, &DolphinPackageInstaller::slotInstallationFailed);
|
||||||
|
connect(resolveTransaction, &PackageKit::Transaction::finished, this, [this]() { // Will be disconnected if we find a package.
|
||||||
|
slotInstallationFailed(PackageKit::Transaction::ErrorPackageNotFound,
|
||||||
|
i18nc("@info:shell about system packages", "Could not find package %1.", m_packageName));
|
||||||
|
});
|
||||||
|
connect(resolveTransaction,
|
||||||
|
&PackageKit::Transaction::package,
|
||||||
|
this,
|
||||||
|
[this, resolveTransaction](PackageKit::Transaction::Info /* info */, const QString &packageId) {
|
||||||
|
disconnect(resolveTransaction, nullptr, this, nullptr); // We only care about the first package.
|
||||||
|
install(packageId);
|
||||||
|
});
|
||||||
|
#else
|
||||||
|
QDesktopServices::openUrl(m_fallBackInstallationPageUrl);
|
||||||
|
auto waitForSuccess = new QTimer(this);
|
||||||
|
connect(waitForSuccess, &QTimer::timeout, this, [this]() {
|
||||||
|
if (m_isPackageInstalledCheck()) {
|
||||||
|
emitResult();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
waitForSuccess->start(3000);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_PACKAGEKIT
|
||||||
|
void DolphinPackageInstaller::install(const QString &packageId)
|
||||||
|
{
|
||||||
|
const PackageKit::Transaction *installTransaction = PackageKit::Daemon::installPackage(packageId);
|
||||||
|
connectTransactionToJobProgress(*installTransaction);
|
||||||
|
connect(installTransaction,
|
||||||
|
&PackageKit::Transaction::errorCode,
|
||||||
|
this,
|
||||||
|
[installTransaction, this](PackageKit::Transaction::Error error, const QString &details) {
|
||||||
|
disconnect(installTransaction, nullptr, this, nullptr); // We only want to emit a result once.
|
||||||
|
slotInstallationFailed(error, details);
|
||||||
|
});
|
||||||
|
connect(installTransaction,
|
||||||
|
&PackageKit::Transaction::finished,
|
||||||
|
this,
|
||||||
|
[installTransaction, this](const PackageKit::Transaction::Exit status, uint /* runtime */) {
|
||||||
|
disconnect(installTransaction, nullptr, this, nullptr); // We only want to emit a result once.
|
||||||
|
if (status == PackageKit::Transaction::ExitSuccess) {
|
||||||
|
emitResult();
|
||||||
|
} else {
|
||||||
|
slotInstallationFailed(PackageKit::Transaction::ErrorUnknown,
|
||||||
|
i18nc("@info %1 is error code",
|
||||||
|
"Installation exited without reporting success. (%1)",
|
||||||
|
QMetaEnum::fromType<PackageKit::Transaction::Exit>().valueToKey(status)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void DolphinPackageInstaller::connectTransactionToJobProgress(const PackageKit::Transaction &transaction)
|
||||||
|
{
|
||||||
|
connect(&transaction, &PackageKit::Transaction::speedChanged, this, [this, &transaction]() {
|
||||||
|
emitSpeed(transaction.speed());
|
||||||
|
});
|
||||||
|
connect(&transaction, &PackageKit::Transaction::percentageChanged, this, [this, &transaction]() {
|
||||||
|
setPercent(transaction.percentage());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void DolphinPackageInstaller::slotInstallationFailed(PackageKit::Transaction::Error error, const QString &details)
|
||||||
|
{
|
||||||
|
setErrorString(xi18nc("@info:shell %1 is package name, %2 is error message, %3 is error e.g. 'ErrorNoNetwork'",
|
||||||
|
"Installing <application>%1</application> failed: %2 (%3)<nl/>Please try installing <application>%1</application> manually instead.",
|
||||||
|
m_packageName,
|
||||||
|
details,
|
||||||
|
QMetaEnum::fromType<PackageKit::Transaction::Error>().valueToKey(error)));
|
||||||
|
setError(error);
|
||||||
|
emitResult();
|
||||||
|
}
|
||||||
|
#endif
|
92
src/dolphinpackageinstaller.h
Normal file
92
src/dolphinpackageinstaller.h
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
This file is part of the KDE project
|
||||||
|
SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef dolphinpackageinstaller_H
|
||||||
|
#define dolphinpackageinstaller_H
|
||||||
|
|
||||||
|
#include "config-dolphin.h"
|
||||||
|
|
||||||
|
#if HAVE_PACKAGEKIT
|
||||||
|
#include <PackageKit/Transaction>
|
||||||
|
#endif
|
||||||
|
#include <KJob>
|
||||||
|
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A KJob providing simple means to install a package.
|
||||||
|
*/
|
||||||
|
class DolphinPackageInstaller : public KJob
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Installs a system package.
|
||||||
|
*
|
||||||
|
* @param packageName A name that can be resolved to a package.
|
||||||
|
* @param fallBackInstallationPageUrl This url will be opened if Dolphin was installed without the PackageKit library. A good choice for this parameter
|
||||||
|
* is an appstream url that will be opened in a software store like Discover
|
||||||
|
* e.g. "appstream://org.kde.filelight.desktop". The user is then expected to install the package themselves and
|
||||||
|
* KJob::result() will be emitted when it is detected that the installation finished successfully.
|
||||||
|
* @param isPackageInstalledCheck A function that can be regularly checked to determine if the installation was already successful.
|
||||||
|
*/
|
||||||
|
explicit DolphinPackageInstaller(const QString &packageName,
|
||||||
|
const QUrl &fallBackInstallationPageUrl,
|
||||||
|
std::function<bool()> isPackageInstalledCheck,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see KJob::start().
|
||||||
|
* Make sure to connect to the KJob::result() signal and show the KJob::errorString() to users there before calling this.
|
||||||
|
*/
|
||||||
|
void start() override;
|
||||||
|
|
||||||
|
/** @see KJob::errorString(). */
|
||||||
|
inline QString errorString() const override
|
||||||
|
{
|
||||||
|
return m_errorString;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** @see KJob::errorString(). */
|
||||||
|
inline void setErrorString(const QString &errorString)
|
||||||
|
{
|
||||||
|
m_errorString = errorString;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if HAVE_PACKAGEKIT
|
||||||
|
/**
|
||||||
|
* Asynchronously installs a package uniquely identified by its @param packageId using PackageKit.
|
||||||
|
* For progress reporting this method will use DolphinPackageInstaller::connectTransactionToJobProgress().
|
||||||
|
* This method will call KJob::emitResult() once it failed or succeeded.
|
||||||
|
*/
|
||||||
|
void install(const QString &packageId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes sure progress signals of @p transaction are forwarded to KJob's progress signals.
|
||||||
|
*/
|
||||||
|
void connectTransactionToJobProgress(const PackageKit::Transaction &transaction);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
/** Creates a nice user-facing error message from its parameters and then finishes this job with an @p error. */
|
||||||
|
void slotInstallationFailed(PackageKit::Transaction::Error error, const QString &details);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** The name of the package that is supposed to be installed. */
|
||||||
|
const QString m_packageName;
|
||||||
|
|
||||||
|
/** @see DolphinPackageInstaller::DolphinPackageInstaller(). */
|
||||||
|
const QUrl m_fallBackInstallationPageUrl;
|
||||||
|
|
||||||
|
/** @see DolphinPackageInstaller::DolphinPackageInstaller(). */
|
||||||
|
const std::function<bool()> m_isPackageInstalledCheck;
|
||||||
|
|
||||||
|
/** @see KJob::errorString(). */
|
||||||
|
QString m_errorString;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // dolphinpackageinstaller_H
|
42
src/main.cpp
42
src/main.cpp
|
@ -6,6 +6,7 @@
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "admin/workerintegration.h"
|
||||||
#include "config-dolphin.h"
|
#include "config-dolphin.h"
|
||||||
#include "dbusinterface.h"
|
#include "dbusinterface.h"
|
||||||
#include "dolphin_generalsettings.h"
|
#include "dolphin_generalsettings.h"
|
||||||
|
@ -54,24 +55,22 @@
|
||||||
#endif
|
#endif
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
constexpr auto dolphinTranslationDomain{"dolphin"};
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
// Prohibit using sudo or kdesu (but allow using the root user directly)
|
// Prohibit using sudo or kdesu (but allow using the root user directly)
|
||||||
if (getuid() == 0) {
|
if (getuid() == 0 && (!qEnvironmentVariableIsEmpty("SUDO_USER") || !qEnvironmentVariableIsEmpty("KDESU_USER"))) {
|
||||||
if (!qEnvironmentVariableIsEmpty("SUDO_USER")) {
|
QCoreApplication app(argc, argv); // Needed for the xi18ndc() call below.
|
||||||
std::cout << "Running Dolphin with sudo is not supported as it can cause bugs and expose you to security vulnerabilities. Instead, install the "
|
std::cout << qPrintable(
|
||||||
"`kio-admin` package from your distro and use it to manage root-owned locations by right-clicking on them and selecting \"Open as "
|
xi18ndc(dolphinTranslationDomain,
|
||||||
"Administrator\"."
|
"@info:shell %1 is a terminal command",
|
||||||
<< std::endl;
|
"Running <application>Dolphin</application> with <command>sudo</command> is discouraged. Please run <icode>%1</icode> instead.",
|
||||||
return EXIT_FAILURE;
|
QStringLiteral("dolphin --sudo")))
|
||||||
} else if (!qEnvironmentVariableIsEmpty("KDESU_USER")) {
|
<< std::endl;
|
||||||
std::cout << "Running Dolphin with kdesu is not supported as it can cause bugs and expose you to security vulnerabilities. Instead, install the "
|
// We could perform a privilege de-escalation here and continue as normal. It is a bit safer though to simply let the user restart without sudo.
|
||||||
"`kio-admin` package from your distro and use it to manage root-owned locations by right-clicking on them and selecting \"Open as "
|
return EXIT_FAILURE;
|
||||||
"Administrator\"."
|
|
||||||
<< std::endl;
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -116,7 +115,7 @@ int main(int argc, char **argv)
|
||||||
migrate.migrate();
|
migrate.migrate();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
KLocalizedString::setApplicationDomain("dolphin");
|
KLocalizedString::setApplicationDomain(dolphinTranslationDomain);
|
||||||
|
|
||||||
KAboutData aboutData(QStringLiteral("dolphin"),
|
KAboutData aboutData(QStringLiteral("dolphin"),
|
||||||
i18n("Dolphin"),
|
i18n("Dolphin"),
|
||||||
|
@ -164,6 +163,8 @@ int main(int argc, char **argv)
|
||||||
"will be selected.")));
|
"will be selected.")));
|
||||||
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("split"), i18nc("@info:shell", "Dolphin will get started with a split view.")));
|
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("split"), i18nc("@info:shell", "Dolphin will get started with a split view.")));
|
||||||
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("new-window"), i18nc("@info:shell", "Dolphin will explicitly open in a new window.")));
|
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("new-window"), i18nc("@info:shell", "Dolphin will explicitly open in a new window.")));
|
||||||
|
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("sudo") << QStringLiteral("admin"),
|
||||||
|
i18nc("@info:shell", "Set up Dolphin for administrative tasks.")));
|
||||||
parser.addOption(
|
parser.addOption(
|
||||||
QCommandLineOption(QStringList() << QStringLiteral("daemon"), i18nc("@info:shell", "Start Dolphin Daemon (only required for DBus Interface).")));
|
QCommandLineOption(QStringList() << QStringLiteral("daemon"), i18nc("@info:shell", "Start Dolphin Daemon (only required for DBus Interface).")));
|
||||||
parser.addPositionalArgument(QStringLiteral("+[Url]"), i18nc("@info:shell", "Document to open"));
|
parser.addPositionalArgument(QStringLiteral("+[Url]"), i18nc("@info:shell", "Document to open"));
|
||||||
|
@ -173,11 +174,18 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
const bool splitView = parser.isSet(QStringLiteral("split")) || GeneralSettings::splitView();
|
const bool splitView = parser.isSet(QStringLiteral("split")) || GeneralSettings::splitView();
|
||||||
const bool openFiles = parser.isSet(QStringLiteral("select"));
|
const bool openFiles = parser.isSet(QStringLiteral("select"));
|
||||||
|
const bool adminWorkerInfoWanted = parser.isSet(QStringLiteral("sudo")) || parser.isSet(QStringLiteral("admin"));
|
||||||
const QStringList args = parser.positionalArguments();
|
const QStringList args = parser.positionalArguments();
|
||||||
QList<QUrl> urls = Dolphin::validateUris(args);
|
QList<QUrl> urls = Dolphin::validateUris(args);
|
||||||
// We later mutate urls, so we need to store if it was empty originally
|
// We later mutate urls, so we need to store if it was empty originally
|
||||||
const bool startedWithURLs = !urls.isEmpty();
|
const bool startedWithURLs = !urls.isEmpty();
|
||||||
|
|
||||||
|
if (adminWorkerInfoWanted || std::any_of(urls.cbegin(), urls.cend(), [](const QUrl &url) {
|
||||||
|
return url.scheme() == QStringLiteral("admin");
|
||||||
|
})) {
|
||||||
|
Admin::guideUserTowardsInstallingAdminWorker();
|
||||||
|
}
|
||||||
|
|
||||||
if (parser.isSet(QStringLiteral("daemon"))) {
|
if (parser.isSet(QStringLiteral("daemon"))) {
|
||||||
// Disable session management for the daemonized version
|
// Disable session management for the daemonized version
|
||||||
// See https://bugs.kde.org/show_bug.cgi?id=417219
|
// See https://bugs.kde.org/show_bug.cgi?id=417219
|
||||||
|
@ -275,6 +283,10 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
mainWindow->setSessionAutoSaveEnabled(GeneralSettings::rememberOpenedTabs());
|
mainWindow->setSessionAutoSaveEnabled(GeneralSettings::rememberOpenedTabs());
|
||||||
|
|
||||||
|
if (adminWorkerInfoWanted) {
|
||||||
|
Admin::guideUserTowardsUsingAdminWorker();
|
||||||
|
}
|
||||||
|
|
||||||
#if HAVE_KUSERFEEDBACK
|
#if HAVE_KUSERFEEDBACK
|
||||||
auto feedbackProvider = DolphinFeedbackProvider::instance();
|
auto feedbackProvider = DolphinFeedbackProvider::instance();
|
||||||
Q_UNUSED(feedbackProvider)
|
Q_UNUSED(feedbackProvider)
|
||||||
|
|
Loading…
Reference in a new issue