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 DocTools
) )
find_package(PolkitQt5-1 REQUIRED)
# use sane compile flags # use sane compile flags
add_definitions( add_definitions(
-DQT_USE_QSTRINGBUILDER -DQT_USE_QSTRINGBUILDER

View File

@ -38,6 +38,7 @@ target_link_libraries(partitionmanager ${BLKID_LIBRARIES}
KF5::KIOWidgets KF5::KIOWidgets
KF5::WidgetsAddons KF5::WidgetsAddons
KF5::XmlGui KF5::XmlGui
PolkitQt5-1::Core
) )
target_compile_definitions(partitionmanager PRIVATE -DCMAKE_INSTALL_FULL_LIBEXECDIR_KF5=\"${CMAKE_INSTALL_FULL_LIBEXECDIR_KF5}\") 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/guihelpers.h>
#include <util/report.h> #include <util/report.h>
#include <algorithm>
#include <QApplication> #include <QApplication>
#include <QCloseEvent> #include <QCloseEvent>
#include <QCollator> #include <QCollator>
@ -70,6 +72,9 @@
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QTextStream> #include <QTextStream>
#include <PolkitQt1/Authority>
#include <polkitqt1-version.h>
#include <KAboutApplicationDialog> #include <KAboutApplicationDialog>
#include <KActionCollection> #include <KActionCollection>
#include <KMessageBox> #include <KMessageBox>
@ -126,10 +131,67 @@ void MainWindow::init()
loadConfig(); 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(); show();
pmWidget().init(&operationStack()); 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) void MainWindow::closeEvent(QCloseEvent* event)
@ -409,6 +471,7 @@ void MainWindow::setupActions()
refreshDevices->setStatusTip(xi18nc("@info:status", "Renew the devices list.")); refreshDevices->setStatusTip(xi18nc("@info:status", "Renew the devices list."));
actionCollection()->setDefaultShortcut(refreshDevices, Qt::Key_F5); actionCollection()->setDefaultShortcut(refreshDevices, Qt::Key_F5);
refreshDevices->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); refreshDevices->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh")));
MessageWidget().addAction(refreshDevices);
// Settings Actions // Settings Actions
actionCollection()->addAction(QStringLiteral("toggleDockDevices"), dockDevices().toggleViewAction()); actionCollection()->addAction(QStringLiteral("toggleDockDevices"), dockDevices().toggleViewAction());
@ -459,6 +522,11 @@ void MainWindow::setupConnections()
connect(GlobalLog::instance(), &GlobalLog::newMessage, connect(GlobalLog::instance(), &GlobalLog::newMessage,
&treeLog(), &TreeLog::onNewLogMessage); &treeLog(), &TreeLog::onNewLogMessage);
connect(this, &MainWindow::showMessageWidget, &MessageWidget(),
&KMessageWidget::animatedShow);
connect(this, &MainWindow::hideMessageWidget, &MessageWidget(),
&KMessageWidget::animatedHide);
} }
void MainWindow::setupStatusBar() void MainWindow::setupStatusBar()
@ -741,7 +809,13 @@ void MainWindow::on_m_DeviceScanner_finished()
scanProgressDialog().setProgress(100); 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().setSelectedDevice(operationStack().previewDevices()[0]);
pmWidget().updatePartitions(); 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 // try to set the seleted device, either from the saved one or just select the
// first device // first device
if (!listDevices().setSelectedDevice(savedSelectedDeviceNode()) && !operationStack().previewDevices().isEmpty()) if (!listDevices().setSelectedDevice(savedSelectedDeviceNode()) && foundDevices)
listDevices().setSelectedDevice(operationStack().previewDevices()[0]->deviceNode()); listDevices().setSelectedDevice(operationStack().previewDevices()[0]->deviceNode());
updateSeletedDeviceMenu(); updateSeletedDeviceMenu();
@ -815,7 +889,17 @@ void MainWindow::onRefreshDevices()
xi18nc("@title:window", "Really Rescan the Devices?"), xi18nc("@title:window", "Really Rescan the Devices?"),
KGuiItem(xi18nc("@action:button", "Rescan Devices"), QStringLiteral("arrow-right")), KGuiItem(xi18nc("@action:button", "Rescan Devices"), QStringLiteral("arrow-right")),
KStandardGuiItem::cancel(), QStringLiteral("reallyRescanDevices")) == KMessageBox::Continue) { 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 "ui_mainwindowbase.h"
#include <KMessageWidget>
#include <KXmlGuiWindow> #include <KXmlGuiWindow>
class ApplyProgressDialog; class ApplyProgressDialog;
@ -206,6 +207,15 @@ protected:
return *m_ScanProgressDialog; 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); void onSelectedDeviceMenuTriggered(bool);
protected Q_SLOTS: protected Q_SLOTS:
@ -255,6 +265,15 @@ protected:
void onSmartStatusDevice(); void onSmartStatusDevice();
void onPropertiesDevice(const QString& deviceNode = {}); void onPropertiesDevice(const QString& deviceNode = {});
private:
QMenu* createPopupMenu() override;
void askForPermissions();
Q_SIGNALS:
void showMessageWidget();
void hideMessageWidget();
private: private:
OperationStack* m_OperationStack; OperationStack* m_OperationStack;
OperationRunner* m_OperationRunner; OperationRunner* m_OperationRunner;
@ -263,6 +282,8 @@ private:
ScanProgressDialog* m_ScanProgressDialog; ScanProgressDialog* m_ScanProgressDialog;
QLabel* m_StatusText; QLabel* m_StatusText;
QString m_SavedSelectedDeviceNode; QString m_SavedSelectedDeviceNode;
bool m_permissionGranted;
}; };
#endif #endif

View File

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

View File

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