Ask for authentication only once

This commit is contained in:
Alessio Bonfiglio 2021-12-23 00:47:10 +00:00 committed by Andrius Štikonas
parent dffa270506
commit 4f17fc5548
6 changed files with 140 additions and 16 deletions

View File

@ -59,6 +59,8 @@ find_package(KF5 ${KF5_MIN_VERSION} REQUIRED
DocTools
)
find_package(PolkitQt5-1 REQUIRED)
# use sane compile flags
add_definitions(
-DQT_USE_QSTRINGBUILDER

View File

@ -38,6 +38,7 @@ target_link_libraries(partitionmanager ${BLKID_LIBRARIES}
KF5::KIOWidgets
KF5::WidgetsAddons
KF5::XmlGui
PolkitQt5-1::Core
)
target_compile_definitions(partitionmanager PRIVATE -DCMAKE_INSTALL_FULL_LIBEXECDIR_KF5=\"${CMAKE_INSTALL_FULL_LIBEXECDIR_KF5}\")

View File

@ -54,6 +54,8 @@
#include <util/guihelpers.h>
#include <util/report.h>
#include <algorithm>
#include <QApplication>
#include <QCloseEvent>
#include <QCollator>
@ -70,6 +72,9 @@
#include <QTemporaryFile>
#include <QTextStream>
#include <PolkitQt1/Authority>
#include <polkitqt1-version.h>
#include <KAboutApplicationDialog>
#include <KActionCollection>
#include <KMessageBox>
@ -126,10 +131,67 @@ void MainWindow::init()
loadConfig();
// this is done in order to hide the title bar of MessageWidget dock
findChild<QDockWidget*>(QStringLiteral("MessageWidgetDock"))->setTitleBarWidget(new QWidget());
MessageWidget().hide();
MessageWidget().setText(
i18nc("@info", "Partition Manager requires privileges in order to work. Please refresh the devices and authenticate when prompted."));
show();
pmWidget().init(&operationStack());
scanDevices();
scanProgressDialog().cancel();
setEnabled(false);
guiFactory()->container(QStringLiteral("selectedDevice"), this)->setEnabled(false);
askForPermissions();
if (m_permissionGranted) {
FileSystemFactory::init();
scanDevices();
} else
Q_EMIT showMessageWidget();
setEnabled(true);
}
void MainWindow::askForPermissions()
{
PolkitQt1::UnixProcessSubject subject(QApplication::applicationPid());
PolkitQt1::Authority *authority = PolkitQt1::Authority::instance();
PolkitQt1::Authority::Result result;
QEventLoop e;
connect(authority, &PolkitQt1::Authority::checkAuthorizationFinished, &e,
[&e, &result](PolkitQt1::Authority::Result _result) {
result = _result;
e.quit();
});
authority->checkAuthorization(QStringLiteral("org.kde.kpmcore.externalcommand.init"), subject, PolkitQt1::Authority::AllowUserInteraction);
e.exec();
if (authority->hasError()) {
qDebug() << "Encountered error while checking authorization, error code:"
<< authority->lastError() << authority->errorDetails();
authority->clearError();
}
m_permissionGranted = result == PolkitQt1::Authority::Yes;
}
QMenu *MainWindow::createPopupMenu()
{
auto menu = QMainWindow::createPopupMenu();
auto actions = menu->actions();
QAction *toRemove =
*std::find_if(actions.begin(), actions.end(),
[](QAction *x) { return x->text().isEmpty(); });
// this is done in order to hide the entry for the MessageWidget dock
menu->removeAction(toRemove);
return menu;
}
void MainWindow::closeEvent(QCloseEvent* event)
@ -409,6 +471,7 @@ void MainWindow::setupActions()
refreshDevices->setStatusTip(xi18nc("@info:status", "Renew the devices list."));
actionCollection()->setDefaultShortcut(refreshDevices, Qt::Key_F5);
refreshDevices->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh")));
MessageWidget().addAction(refreshDevices);
// Settings Actions
actionCollection()->addAction(QStringLiteral("toggleDockDevices"), dockDevices().toggleViewAction());
@ -459,6 +522,11 @@ void MainWindow::setupConnections()
connect(GlobalLog::instance(), &GlobalLog::newMessage,
&treeLog(), &TreeLog::onNewLogMessage);
connect(this, &MainWindow::showMessageWidget, &MessageWidget(),
&KMessageWidget::animatedShow);
connect(this, &MainWindow::hideMessageWidget, &MessageWidget(),
&KMessageWidget::animatedHide);
}
void MainWindow::setupStatusBar()
@ -741,7 +809,13 @@ void MainWindow::on_m_DeviceScanner_finished()
scanProgressDialog().setProgress(100);
if (!operationStack().previewDevices().isEmpty())
bool foundDevices = !operationStack().previewDevices().isEmpty();
guiFactory()
->container(QStringLiteral("selectedDevice"), this)
->setEnabled(foundDevices);
if (foundDevices)
pmWidget().setSelectedDevice(operationStack().previewDevices()[0]);
pmWidget().updatePartitions();
@ -751,7 +825,7 @@ void MainWindow::on_m_DeviceScanner_finished()
// try to set the seleted device, either from the saved one or just select the
// first device
if (!listDevices().setSelectedDevice(savedSelectedDeviceNode()) && !operationStack().previewDevices().isEmpty())
if (!listDevices().setSelectedDevice(savedSelectedDeviceNode()) && foundDevices)
listDevices().setSelectedDevice(operationStack().previewDevices()[0]->deviceNode());
updateSeletedDeviceMenu();
@ -815,7 +889,17 @@ void MainWindow::onRefreshDevices()
xi18nc("@title:window", "Really Rescan the Devices?"),
KGuiItem(xi18nc("@action:button", "Rescan Devices"), QStringLiteral("arrow-right")),
KStandardGuiItem::cancel(), QStringLiteral("reallyRescanDevices")) == KMessageBox::Continue) {
scanDevices();
if (m_permissionGranted) {
scanDevices();
} else {
askForPermissions();
if (m_permissionGranted) {
Q_EMIT hideMessageWidget();
FileSystemFactory::init();
scanDevices();
}
}
}
}

View File

@ -17,6 +17,7 @@
#include "ui_mainwindowbase.h"
#include <KMessageWidget>
#include <KXmlGuiWindow>
class ApplyProgressDialog;
@ -206,6 +207,15 @@ protected:
return *m_ScanProgressDialog;
}
KMessageWidget &MessageWidget() {
Q_ASSERT(m_MessageWidget);
return *m_MessageWidget;
}
const KMessageWidget &MessageWidget() const {
Q_ASSERT(m_MessageWidget);
return *m_MessageWidget;
}
void onSelectedDeviceMenuTriggered(bool);
protected Q_SLOTS:
@ -255,6 +265,15 @@ protected:
void onSmartStatusDevice();
void onPropertiesDevice(const QString& deviceNode = {});
private:
QMenu* createPopupMenu() override;
void askForPermissions();
Q_SIGNALS:
void showMessageWidget();
void hideMessageWidget();
private:
OperationStack* m_OperationStack;
OperationRunner* m_OperationRunner;
@ -263,6 +282,8 @@ private:
ScanProgressDialog* m_ScanProgressDialog;
QLabel* m_StatusText;
QString m_SavedSelectedDeviceNode;
bool m_permissionGranted;
};
#endif

View File

@ -17,8 +17,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<property name="windowTitle">
<string comment="@title:window">KDE Partition Manager</string>
</property>
<widget class="PartitionManagerWidget" name="m_PartitionManagerWidget">
</widget>
<widget class="PartitionManagerWidget" name="m_PartitionManagerWidget"/>
<widget class="QDockWidget" name="m_DockDevices">
<property name="allowedAreas">
<set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
@ -29,8 +28,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="ListDevices" name="m_ListDevices">
</widget>
<widget class="ListDevices" name="m_ListDevices"/>
</widget>
<widget class="QDockWidget" name="m_DockOperations">
<property name="allowedAreas">
@ -42,8 +40,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="ListOperations" name="m_ListOperations">
</widget>
<widget class="ListOperations" name="m_ListOperations"/>
</widget>
<widget class="QDockWidget" name="m_DockInformation">
<property name="windowTitle">
@ -52,8 +49,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="InfoPane" name="m_InfoPane">
</widget>
<widget class="InfoPane" name="m_InfoPane"/>
</widget>
<widget class="QDockWidget" name="m_DockLog">
<property name="allowedAreas">
@ -65,11 +61,34 @@ SPDX-License-Identifier: GPL-3.0-or-later
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="TreeLog" name="m_TreeLog">
<widget class="TreeLog" name="m_TreeLog"/>
</widget>
<widget class="QDockWidget" name="MessageWidgetDock">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="features">
<set>QDockWidget::NoDockWidgetFeatures</set>
</property>
<attribute name="dockWidgetArea">
<number>4</number>
</attribute>
<widget class="KMessageWidget" name="m_MessageWidget">
<property name="messageType">
<enum>KMessageWidget::Warning</enum>
</property>
</widget>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>KMessageWidget</class>
<extends>QFrame</extends>
<header>kmessagewidget.h</header>
</customwidget>
<customwidget>
<class>PartitionManagerWidget</class>
<extends>QWidget</extends>

View File

@ -94,9 +94,6 @@ void PartitionManagerWidget::init(OperationStack* ostack)
{
m_OperationStack = ostack;
// TODO: shouldn't this also go to the main window class?
FileSystemFactory::init();
loadConfig();
setupConnections();
}