diff options
| author | Felix Ernst <[email protected]> | 2024-05-11 17:16:35 +0000 |
|---|---|---|
| committer | Felix Ernst <[email protected]> | 2024-05-11 17:16:35 +0000 |
| commit | 6c60655ce246a91758f4b9035edf318cb1197a2c (patch) | |
| tree | f7b6ac7d13cbdc76a67af70765373f735ca56a27 /src/admin/workerintegration.cpp | |
| parent | 742566eb69e6bf46e7abb74e9ce9293c4b3ed7e8 (diff) | |
Add "Act as Administrator" toggle action
This commit adds an "Act as Administrator" toggle action to the
View menu if kio-admin is installed. The action allows switching
between acting as an admin with root-access or not.
This was already possible in Dolphin when kio-admin is installed by
editing the location bar directly. However this is somewhat
unintuitive and there are no warnings at all about the dangers of
acting as an administrator.
This commit adds a warning dialog when triggering the action. It is
somewhat explicit about the risks because this is in fact very
dangerous.
Furthermore, while acting on a view with administrative privileges,
a bar above the view shows up that contains a warning. The bar can
be closed to stop acting with elevated privileges.
The warning dialog can be disabled and re-enabled from the Dolphin
settings but only if the action is even available.
There is a lot more to be done to further improve this feature both
security-wise as well as when it comes to usability. But
considering that we are already encouraging users to use this
feature without any warnings at all, I feel like now is a good time
to merge this.
This work is part of a project funded through the NGI0 Entrust
Fund, a fund established by NLnet with financial support from the
European Commission's Next Generation Internet programme, under the
aegis of DG Communications Networks, Content and Technology. As
such, please contact me if you plan on doing related work so what
you are doing doesn't collide with work I am being funded to do.
Diffstat (limited to 'src/admin/workerintegration.cpp')
| -rw-r--r-- | src/admin/workerintegration.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/admin/workerintegration.cpp b/src/admin/workerintegration.cpp new file mode 100644 index 000000000..f9b587391 --- /dev/null +++ b/src/admin/workerintegration.cpp @@ -0,0 +1,120 @@ +/* + This file is part of the KDE project + SPDX-FileCopyrightText: 2022 Felix Ernst <[email protected]> + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "workerintegration.h" + +#include "dolphinmainwindow.h" +#include "dolphinviewcontainer.h" + +#include <KActionCollection> +#include <KLocalizedString> +#include <KMessageBox> +#include <KMessageDialog> +#include <KProtocolInfo> + +#include <QAction> + +using namespace Admin; + +QString Admin::warningMessage() +{ + return xi18nc( + "@info", + "<para>You are about to use administrator privileges. While acting as an administrator you can change or replace any file or folder on this system. " + "This includes items which are critical for this system to function.</para><para>You are able to <emphasis>delete every users' data</emphasis> on this " + "computer and to <emphasis>break this installation beyond repair.</emphasis> Adding just one letter in a folder or file name or its contents can " + "render a system <emphasis>unbootable.</emphasis></para><para>There is probably not going to be another warning even if you are about to break this " + "system.</para><para>You might want to <emphasis>backup files and folders</emphasis> before proceeding.</para>"); +} + +namespace +{ +/** The only WorkerIntegration object that is ever constructed. It is only ever accessed directly from within this file. */ +WorkerIntegration *instance = nullptr; +} + +WorkerIntegration::WorkerIntegration(DolphinMainWindow *parent, QAction *actAsAdminAction) + : QObject{parent} + , m_actAsAdminAction{actAsAdminAction} +{ + Q_CHECK_PTR(parent); + Q_CHECK_PTR(actAsAdminAction); + + connect(parent, &DolphinMainWindow::urlChanged, this, &WorkerIntegration::updateActAsAdminAction); + + connect(actAsAdminAction, &QAction::triggered, this, &WorkerIntegration::toggleActAsAdmin); +} + +void WorkerIntegration::createActAsAdminAction(KActionCollection *actionCollection, DolphinMainWindow *dolphinMainWindow) +{ + Q_ASSERT(!instance); + if (KProtocolInfo::isKnownProtocol(QStringLiteral("admin"))) { + QAction *actAsAdminAction = actionCollection->addAction(QStringLiteral("act_as_admin")); + actAsAdminAction->setText(i18nc("@action:inmenu", "Act as Administrator")); + actAsAdminAction->setIcon(QIcon::fromTheme(QStringLiteral("system-switch-user"))); + actAsAdminAction->setCheckable(true); + actionCollection->setDefaultShortcut(actAsAdminAction, Qt::CTRL | Qt::SHIFT | Qt::ALT | Qt::Key_A); + + instance = new WorkerIntegration(dolphinMainWindow, actAsAdminAction); + } +} + +void WorkerIntegration::exitAdminMode() +{ + if (instance->m_actAsAdminAction->isChecked()) { + instance->m_actAsAdminAction->trigger(); + } +} + +void WorkerIntegration::toggleActAsAdmin() +{ + auto dolphinMainWindow = static_cast<DolphinMainWindow *>(parent()); + QUrl url = dolphinMainWindow->activeViewContainer()->urlNavigator()->locationUrl(); + if (url.scheme() == QStringLiteral("file")) { + bool risksAccepted = !KMessageBox::shouldBeShownContinue(warningDontShowAgainName); + + if (!risksAccepted) { + KMessageDialog warningDialog{KMessageDialog::QuestionTwoActions, warningMessage(), dolphinMainWindow}; + warningDialog.setCaption(i18nc("@title:window", "Risks of Acting as an Administrator")); + warningDialog.setIcon(QIcon::fromTheme(QStringLiteral("security-low"))); + warningDialog.setButtons(KGuiItem{i18nc("@action:button", "I Understand and Accept These Risks"), QStringLiteral("data-warning")}, + KStandardGuiItem::cancel()); + warningDialog.setDontAskAgainText(i18nc("@option:check", "Do not warn me about these risks again")); + + risksAccepted = warningDialog.exec() != 4 /* Cancel */; + if (warningDialog.isDontAskAgainChecked()) { + KMessageBox::saveDontShowAgainContinue(warningDontShowAgainName); + } + + if (!risksAccepted) { + updateActAsAdminAction(); // Uncheck the action + return; + } + } + + url.setScheme(QStringLiteral("admin")); + } else if (url.scheme() == QStringLiteral("admin")) { + url.setScheme(QStringLiteral("file")); + } + dolphinMainWindow->changeUrl(url); +} + +void WorkerIntegration::updateActAsAdminAction() +{ + if (instance) { + const QString currentUrlScheme = static_cast<DolphinMainWindow *>(instance->parent())->activeViewContainer()->url().scheme(); + if (currentUrlScheme == QStringLiteral("file")) { + instance->m_actAsAdminAction->setEnabled(true); + instance->m_actAsAdminAction->setChecked(false); + } else if (currentUrlScheme == QStringLiteral("admin")) { + instance->m_actAsAdminAction->setEnabled(true); + instance->m_actAsAdminAction->setChecked(true); + } else { + instance->m_actAsAdminAction->setEnabled(false); + } + } +} |
