Changeset View
Changeset View
Standalone View
Standalone View
src/util/externalcommand.cpp
Show All 19 Lines | |||||
20 | #include "core/device.h" | 20 | #include "core/device.h" | ||
21 | #include "core/copysource.h" | 21 | #include "core/copysource.h" | ||
22 | #include "core/copytarget.h" | 22 | #include "core/copytarget.h" | ||
23 | #include "core/copytargetbytearray.h" | 23 | #include "core/copytargetbytearray.h" | ||
24 | #include "core/copysourcedevice.h" | 24 | #include "core/copysourcedevice.h" | ||
25 | #include "core/copytargetdevice.h" | 25 | #include "core/copytargetdevice.h" | ||
26 | #include "util/globallog.h" | 26 | #include "util/globallog.h" | ||
27 | #include "util/externalcommand.h" | 27 | #include "util/externalcommand.h" | ||
28 | #include "util/externalcommand_polkitbackend.h" | ||||
28 | #include "util/report.h" | 29 | #include "util/report.h" | ||
29 | | ||||
30 | #include "externalcommandhelper_interface.h" | 30 | #include "externalcommandhelper_interface.h" | ||
31 | 31 | | |||
32 | #include <QCryptographicHash> | | |||
33 | #include <QDBusConnection> | 32 | #include <QDBusConnection> | ||
34 | #include <QDBusInterface> | 33 | #include <QDBusInterface> | ||
35 | #include <QDBusReply> | 34 | #include <QDBusReply> | ||
36 | #include <QEventLoop> | 35 | #include <QEventLoop> | ||
37 | #include <QtGlobal> | 36 | #include <QtGlobal> | ||
38 | #include <QStandardPaths> | 37 | #include <QStandardPaths> | ||
39 | #include <QString> | 38 | #include <QString> | ||
40 | #include <QStringList> | 39 | #include <QStringList> | ||
41 | #include <QTimer> | 40 | #include <QTimer> | ||
42 | #include <QThread> | 41 | #include <QThread> | ||
43 | #include <QVariant> | 42 | #include <QVariant> | ||
44 | 43 | | |||
45 | #include <KAuth> | 44 | #include <KAuth> | ||
46 | #include <KJob> | 45 | #include <KJob> | ||
47 | #include <KLocalizedString> | 46 | #include <KLocalizedString> | ||
48 | 47 | | |||
48 | #include <PolkitQt1/Authority> | ||||
49 | | ||||
49 | struct ExternalCommandPrivate | 50 | struct ExternalCommandPrivate | ||
50 | { | 51 | { | ||
51 | Report *m_Report; | 52 | Report *m_Report; | ||
52 | QString m_Command; | 53 | QString m_Command; | ||
53 | QStringList m_Args; | 54 | QStringList m_Args; | ||
54 | int m_ExitCode; | 55 | int m_ExitCode; | ||
55 | QByteArray m_Output; | 56 | QByteArray m_Output; | ||
56 | QByteArray m_Input; | 57 | QByteArray m_Input; | ||
57 | DBusThread *m_thread; | 58 | DBusThread *m_thread; | ||
58 | QProcess::ProcessChannelMode processChannelMode; | 59 | QProcess::ProcessChannelMode processChannelMode; | ||
59 | }; | 60 | }; | ||
60 | 61 | | |||
61 | KAuth::ExecuteJob* ExternalCommand::m_job; | 62 | KAuth::ExecuteJob* ExternalCommand::m_job; | ||
62 | bool ExternalCommand::helperStarted = false; | 63 | bool ExternalCommand::helperStarted = false; | ||
63 | QWidget* ExternalCommand::parent; | 64 | QWidget* ExternalCommand::parent; | ||
64 | 65 | Auth::PolkitQt1Backend* ExternalCommand::m_authJob; | |||
65 | 66 | | |||
66 | /** Creates a new ExternalCommand instance without Report. | 67 | /** Creates a new ExternalCommand instance without Report. | ||
67 | @param cmd the command to run | 68 | @param cmd the command to run | ||
68 | @param args the arguments to pass to the command | 69 | @param args the arguments to pass to the command | ||
69 | */ | 70 | */ | ||
70 | ExternalCommand::ExternalCommand(const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) : | 71 | ExternalCommand::ExternalCommand(const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) : | ||
71 | d(std::make_unique<ExternalCommandPrivate>()) | 72 | d(std::make_unique<ExternalCommandPrivate>()) | ||
72 | { | 73 | { | ||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Line(s) | 181 | if (!QDBusConnection::systemBus().isConnected()) { | |||
182 | return false; | 183 | return false; | ||
183 | } | 184 | } | ||
184 | 185 | | |||
185 | // TODO KF6:Use new signal-slot syntax | 186 | // TODO KF6:Use new signal-slot syntax | ||
186 | connect(m_job, SIGNAL(percent(KJob*, unsigned long)), this, SLOT(emitProgress(KJob*, unsigned long))); | 187 | connect(m_job, SIGNAL(percent(KJob*, unsigned long)), this, SLOT(emitProgress(KJob*, unsigned long))); | ||
187 | connect(m_job, &KAuth::ExecuteJob::newData, this, &ExternalCommand::emitReport); | 188 | connect(m_job, &KAuth::ExecuteJob::newData, this, &ExternalCommand::emitReport); | ||
188 | 189 | | |||
189 | auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | 190 | auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | ||
190 | QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); | 191 | QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); | ||
shubham: these connect gives error and correctly so because of m_authJob. Any suggestion how to tackle? | |||||
Well, report progress used KAuth, Now progress will have to be sent via DBus message. So ExternalCommandHelper class will act as DBus client and send messages to ExternalCommand class. Comment it out for now. It will obviously make kpmcore not fully functional until it is reimplemnted, but I think it might still work (just no progress reporting). stikonas: Well, report progress used KAuth, Now progress will have to be sent via DBus message. So… | |||||
progress() and reportProgress() signals have been reimplemented in the qdbus patch. We are now NOT using KAuth's HelperSupport::reportProgress() function which internally used to emit the signal. shubham: progress() and reportProgress() signals have been reimplemented in the qdbus patch. We are now… | |||||
191 | interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days | 192 | interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days | ||
192 | 193 | | |||
193 | QDBusPendingCall pcall = interface->copyblocks(source.path(), source.firstByte(), source.length(), | 194 | QDBusPendingCall pcall = interface->copyblocks(source.path(), source.firstByte(), source.length(), | ||
194 | target.path(), target.firstByte(), blockSize); | 195 | target.path(), target.firstByte(), blockSize); | ||
195 | 196 | | |||
196 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); | 197 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); | ||
197 | QEventLoop loop; | 198 | QEventLoop loop; | ||
198 | 199 | | |||
▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Line(s) | |||||
349 | bool ExternalCommand::startHelper() | 350 | bool ExternalCommand::startHelper() | ||
350 | { | 351 | { | ||
351 | if (!QDBusConnection::systemBus().isConnected()) { | 352 | if (!QDBusConnection::systemBus().isConnected()) { | ||
352 | qWarning() << QDBusConnection::systemBus().lastError().message(); | 353 | qWarning() << QDBusConnection::systemBus().lastError().message(); | ||
353 | return false; | 354 | return false; | ||
354 | } | 355 | } | ||
355 | 356 | | |||
356 | QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); | 357 | QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); | ||
358 | | ||||
357 | if (iface.isValid()) { | 359 | if (iface.isValid()) { | ||
358 | exit(0); | 360 | exit(0); | ||
359 | } | 361 | } | ||
360 | 362 | | |||
361 | d->m_thread = new DBusThread; | 363 | d->m_thread = new DBusThread; | ||
362 | d->m_thread->start(); | 364 | d->m_thread->start(); | ||
363 | 365 | | |||
364 | KAuth::Action action = KAuth::Action(QStringLiteral("org.kde.kpmcore.externalcommand.init")); | 366 | KAuth::Action action = KAuth::Action(QStringLiteral("org.kde.kpmcore.externalcommand.init")); | ||
365 | action.setHelperId(QStringLiteral("org.kde.kpmcore.externalcommand")); | 367 | action.setHelperId(QStringLiteral("org.kde.kpmcore.externalcommand")); | ||
366 | action.setTimeout(10 * 24 * 3600 * 1000); // 10 days | 368 | action.setTimeout(10 * 24 * 3600 * 1000); // 10 days | ||
367 | action.setParentWidget(parent); | 369 | action.setParentWidget(parent); | ||
368 | QVariantMap arguments; | 370 | QVariantMap arguments; | ||
369 | action.setArguments(arguments); | 371 | action.setArguments(arguments); | ||
370 | m_job = action.execute(); | 372 | m_job = action.execute(); | ||
371 | m_job->start(); | 373 | m_job->start(); | ||
372 | 374 | | |||
373 | // Wait until ExternalCommand Helper is ready (helper sends newData signal just before it enters event loop) | 375 | // Wait until ExternalCommand Helper is ready (helper sends newData signal just before it enters event loop) | ||
374 | QEventLoop loop; | 376 | QEventLoop loop; | ||
375 | auto exitLoop = [&] () { loop.exit(); }; | 377 | auto exitLoop = [&] () { loop.exit(); }; | ||
376 | auto conn = QObject::connect(m_job, &KAuth::ExecuteJob::newData, exitLoop); | 378 | auto conn = QObject::connect(m_job, &KAuth::ExecuteJob::newData, exitLoop); | ||
377 | QObject::connect(m_job, &KJob::finished, [=] () { if(m_job->error()) exitLoop(); } ); | 379 | QObject::connect(m_job, &KJob::finished, [=] () { if(m_job->error()) exitLoop(); } ); | ||
378 | loop.exec(); | 380 | loop.exec(); | ||
379 | QObject::disconnect(conn); | 381 | QObject::disconnect(conn); | ||
380 | 382 | | |||
383 | ////////////////////////////////////// | ||||
384 | // Authorize using Polkit backend /// | ||||
385 | /// Remove above code once complte/// | ||||
stikonas: spelling, `executeAction()` | |||||
386 | //////////////////////////////////// | ||||
387 | | ||||
388 | // initialize KDE Polkit daemon | ||||
389 | m_authJob->initPolkitAgent(QStringLiteral("org.kde.kpmcore.externalcommand.init"), parent); | ||||
390 | | ||||
391 | bool isActionAuthorized = m_authJob->authorizeAction(QStringLiteral("org.kde.kpmcore.externalcommand.init"), m_authJob->callerID()); | ||||
392 | | ||||
393 | auto authResult = m_authJob->actionStatus(QStringLiteral("org.kde.kpmcore.externalcommand.init"), m_authJob->callerID()); | ||||
394 | | ||||
395 | if (!isActionAuthorized || authResult == PolkitQt1::Authority::No) { | ||||
396 | qDebug() << "Unable to obtain Administrative privileges, the action can not be executed!!"; | ||||
397 | } | ||||
398 | | ||||
381 | helperStarted = true; | 399 | helperStarted = true; | ||
382 | return true; | 400 | return true; | ||
383 | } | 401 | } | ||
384 | 402 | | |||
385 | void ExternalCommand::stopHelper() | 403 | void ExternalCommand::stopHelper() | ||
386 | { | 404 | { | ||
387 | auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | 405 | auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | ||
388 | QStringLiteral("/Helper"), QDBusConnection::systemBus()); | 406 | QStringLiteral("/Helper"), QDBusConnection::systemBus()); | ||
389 | interface->exit(); | 407 | interface->exit(); | ||
390 | | ||||
391 | } | 408 | } | ||
392 | 409 | | |||
393 | void DBusThread::run() | 410 | void DBusThread::run() | ||
394 | { | 411 | { | ||
395 | if (!QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.applicationinterface")) || | 412 | if (!QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.applicationinterface")) || | ||
396 | !QDBusConnection::systemBus().registerObject(QStringLiteral("/Application"), this, QDBusConnection::ExportAllSlots)) { | 413 | !QDBusConnection::systemBus().registerObject(QStringLiteral("/Application"), this, QDBusConnection::ExportAllSlots)) { | ||
397 | qWarning() << QDBusConnection::systemBus().lastError().message(); | 414 | qWarning() << QDBusConnection::systemBus().lastError().message(); | ||
398 | return; | 415 | return; | ||
399 | } | 416 | } | ||
400 | 417 | | |||
401 | QEventLoop loop; | 418 | QEventLoop loop; | ||
402 | loop.exec(); | 419 | loop.exec(); | ||
403 | } | 420 | } |
these connect gives error and correctly so because of m_authJob. Any suggestion how to tackle? Ditto at line 377