┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/admin/workerintegration.cpp
blob: f9b58739196099fdb63c02fe5671d5e0f76e4fde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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);
        }
    }
}