Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Backports:SLE-15-SP1:Update
plasma5-pk-updates
0001-Add-support-for-license-prompts.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Add-support-for-license-prompts.patch of Package plasma5-pk-updates
From 5c8d02a6631dec390d430dd08a3524e6b136df28 Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fabian@ritter-vogt.de> Date: Mon, 26 Aug 2019 13:22:25 +0200 Subject: [PATCH] Add support for license prompts Summary: Currently, if a transaction requires accepting a license, it just fails. This implements a basic dialog (which makes it easier to read the license than displaying it inline) and the necessary backend functionality. It was necessary to move the list of packages out of a QObject property into a new member to allow restarting the transaction outside of the onFinished slot. Test Plan: Downgraded two packages with EULAs and searched for updates. Hit the install updates button and got two license prompts. Only after accepting both with the "Yes" button are the updates installed. Reviewers: lukas, jgrulich Differential Revision: https://phabricator.kde.org/D23462 --- src/declarative/pkupdates.cpp | 61 ++++++++++++++++++++++++++++----- src/declarative/pkupdates.h | 29 ++++++++++++++++ src/plasma/contents/ui/Full.qml | 59 +++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 8 deletions(-) Index: plasma-pk-updates-0.3.2/src/declarative/pkupdates.cpp =================================================================== --- plasma-pk-updates-0.3.2.orig/src/declarative/pkupdates.cpp +++ plasma-pk-updates-0.3.2/src/declarative/pkupdates.cpp @@ -276,8 +276,9 @@ void PkUpdates::installUpdates(const QSt flags = PackageKit::Transaction::TransactionFlagNone; } - m_installTrans = PackageKit::Daemon::updatePackages(packageIds, flags); - m_installTrans->setProperty("packages", packageIds); + m_requiredEulas.clear(); + m_packages = packageIds; + m_installTrans = PackageKit::Daemon::updatePackages(m_packages, flags); setActivity(InstallingUpdates); connect(m_installTrans.data(), &PackageKit::Transaction::statusChanged, this, &PkUpdates::onStatusChanged); @@ -286,6 +287,7 @@ void PkUpdates::installUpdates(const QSt connect(m_installTrans.data(), &PackageKit::Transaction::package, this, &PkUpdates::onPackageUpdating); connect(m_installTrans.data(), &PackageKit::Transaction::requireRestart, this, &PkUpdates::onRequireRestart); connect(m_installTrans.data(), &PackageKit::Transaction::repoSignatureRequired, this, &PkUpdates::onRepoSignatureRequired); + connect(m_installTrans.data(), &PackageKit::Transaction::eulaRequired, this, &PkUpdates::onEulaRequired); } void PkUpdates::onChanged() @@ -399,21 +401,24 @@ void PkUpdates::onFinished(PackageKit::T qCDebug(PLASMA_PK_UPDATES) << "Total number of updates: " << count(); emit done(); } else if (trans->role() == PackageKit::Transaction::RoleUpdatePackages) { - const QStringList packages = trans->property("packages").toStringList(); - qCDebug(PLASMA_PK_UPDATES) << "Finished updating packages:" << packages; + qCDebug(PLASMA_PK_UPDATES) << "Finished updating packages:" << m_packages; if (status == PackageKit::Transaction::ExitNeedUntrusted) { qCDebug(PLASMA_PK_UPDATES) << "Transaction needs untrusted packages"; // restart transaction with "untrusted" flag - installUpdates(packages, false /*simulate*/, true /*untrusted*/); + installUpdates(m_packages, false /*simulate*/, true /*untrusted*/); + return; + } else if (status == PackageKit::Transaction::ExitEulaRequired) { + qCDebug(PLASMA_PK_UPDATES) << "Acceptance of EULAs required"; + promptNextEulaAgreement(); return; } else if (status == PackageKit::Transaction::ExitSuccess && trans->transactionFlags().testFlag(PackageKit::Transaction::TransactionFlagSimulate)) { qCDebug(PLASMA_PK_UPDATES) << "Simulation finished with success, restarting the transaction"; - installUpdates(packages, false /*simulate*/, false /*untrusted*/); + installUpdates(m_packages, false /*simulate*/, false /*untrusted*/); return; } else if (status == PackageKit::Transaction::ExitSuccess) { qCDebug(PLASMA_PK_UPDATES) << "Update packages transaction finished successfully"; KNotification::event(KNotification::Notification, i18n("Updates Installed"), - i18np("Successfully updated %1 package", "Successfully updated %1 packages", packages.count()), + i18np("Successfully updated %1 package", "Successfully updated %1 packages", m_packages.count()), KIconLoader::global()->loadIcon("system-software-update", KIconLoader::Desktop), 0, KNotification::Persistent); emit updatesInstalled(); } else { @@ -437,7 +442,7 @@ void PkUpdates::onFinished(PackageKit::T void PkUpdates::onErrorCode(PackageKit::Transaction::Error error, const QString &details) { qWarning() << "PK error:" << details << "type:" << PackageKit::Daemon::enumToString<PackageKit::Transaction>((int)error, "Error"); - if (error == PackageKit::Transaction::ErrorBadGpgSignature) + if (error == PackageKit::Transaction::ErrorBadGpgSignature || error == PackageKit::Transaction::ErrorNoLicenseAgreement) return; KNotification::event(KNotification::Error, i18n("Update Error"), details, @@ -511,6 +516,46 @@ void PkUpdates::onRepoSignatureRequired( qCDebug(PLASMA_PK_UPDATES) << "Repo sig required" << packageID; } +void PkUpdates::onEulaRequired(const QString &eulaID, const QString &packageID, const QString &vendor, const QString &licenseAgreement) +{ + m_requiredEulas[eulaID] = {packageID, vendor, licenseAgreement}; +} + +void PkUpdates::promptNextEulaAgreement() +{ + if(m_requiredEulas.empty()) { + // Restart the transaction + installUpdates(m_packages, false, false); + return; + } + + QString eulaID = m_requiredEulas.firstKey(); + const EulaData &eula = m_requiredEulas[eulaID]; + emit eulaRequired(eulaID, eula.packageID, eula.vendor, eula.licenseAgreement); +} + +void PkUpdates::eulaAgreementResult(const QString &eulaID, bool agreed) +{ + if(!agreed) { + qCDebug(PLASMA_PK_UPDATES) << "EULA declined"; + // Do the same as the failure case in onFinished + checkUpdates(false /* force */); + return; + } + + m_eulaTrans = PackageKit::Daemon::acceptEula(eulaID); + connect(m_eulaTrans.data(), &PackageKit::Transaction::finished, this, + [this, eulaID] (PackageKit::Transaction::Exit exit, uint) { + if (exit == PackageKit::Transaction::ExitSuccess) { + m_requiredEulas.remove(eulaID); + promptNextEulaAgreement(); + } else { + qCWarning(PLASMA_PK_UPDATES) << "EULA acceptance failed"; + } + } + ); +} + void PkUpdates::setStatusMessage(const QString &message) { m_statusMessage = message; Index: plasma-pk-updates-0.3.2/src/declarative/pkupdates.h =================================================================== --- plasma-pk-updates-0.3.2.orig/src/declarative/pkupdates.h +++ plasma-pk-updates-0.3.2/src/declarative/pkupdates.h @@ -155,6 +155,17 @@ signals: */ void updateDetail(const QString &packageID, const QString &updateText, const QStringList &urls); + /** + * Emitted when an EULA agreement prevents the transaction from running + * @param eulaId the EULA identifier + * @param packageID ID of the package for which an EULA is required + * @param vendorName the vendor name + * @param licenseAgreement the EULA text + * + * @see eulaAgreementResult() + */ + void eulaRequired(const QString &eulaID, const QString &packageID, const QString &vendor, const QString &licenseAgreement); + // private ;) void statusMessageChanged(); void isActiveChanged(); @@ -204,6 +215,11 @@ public slots: Q_INVOKABLE void doDelayedCheckUpdates(); + /** + * If agreed to eulaID, starts an EULA acceptance transaction and continues. + */ + Q_INVOKABLE void eulaAgreementResult(const QString &eulaID, bool agreed); + private slots: void getUpdates(); void onChanged(); @@ -220,15 +236,25 @@ private slots: const QDateTime &issued, const QDateTime &updated); void onRepoSignatureRequired(const QString & packageID, const QString & repoName, const QString & keyUrl, const QString & keyUserid, const QString & keyId, const QString & keyFingerprint, const QString & keyTimestamp, PackageKit::Transaction::SigType type); + void onEulaRequired(const QString &eulaID, const QString &packageID, const QString &vendor, const QString &licenseAgreement); private: + struct EulaData { + QString packageID; + QString vendor; + QString licenseAgreement; + }; + void setStatusMessage(const QString &message); void setActivity(Activity act); void setPercentage(int value); + void promptNextEulaAgreement(); QPointer<PackageKit::Transaction> m_updatesTrans; QPointer<PackageKit::Transaction> m_cacheTrans; QPointer<PackageKit::Transaction> m_installTrans; QPointer<PackageKit::Transaction> m_detailTrans; + QPointer<PackageKit::Transaction> m_eulaTrans; + QStringList m_packages; QVariantMap m_updateList; QStringList m_importantList; QStringList m_securityList; @@ -237,6 +263,9 @@ private: Activity m_activity = Idle; bool m_lastCheckSuccessful = false; bool m_checkUpdatesWhenNetworkOnline = false; + // If a transaction failed because of required EULAs, + // this contains a map of their IDs to their data + QMap<QString, EulaData> m_requiredEulas; }; #endif // PLASMA_PK_UPDATES_H Index: plasma-pk-updates-0.3.2/src/plasma/contents/ui/Full.qml =================================================================== --- plasma-pk-updates-0.3.2.orig/src/plasma/contents/ui/Full.qml +++ plasma-pk-updates-0.3.2/src/plasma/contents/ui/Full.qml @@ -22,6 +22,7 @@ import QtQuick 2.1 import QtQuick.Layouts 1.1 import QtQuick.Controls 1.3 +import QtQuick.Dialogs 1.2 import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.plasma.core 2.0 as PlasmaCore @@ -46,10 +47,68 @@ Item { onUpdatesChanged: populateModel() onUpdateDetail: updateDetails(packageID, updateText, urls) onUpdatesInstalled: plasmoid.expanded = false + onEulaRequired: eulaDialog.showPrompt(eulaID, packageID, vendor, licenseAgreement) } Component.onCompleted: populateModel() + Dialog { + property string eulaID: "" + property string packageName: "" + property string vendor: "" + property string licenseText: "" + + property bool buttonClicked: false + + id: eulaDialog + title: i18n("License Agreement for %1").arg(packageName) + standardButtons: StandardButton.Yes | StandardButton.No + + ColumnLayout { + anchors.fill: parent + + Label { + text: i18n("License agreement required for %1 (from %2):").arg(eulaDialog.packageName).arg(eulaDialog.vendor) + } + + TextArea { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.minimumWidth: 400 + Layout.minimumHeight: 200 + text: eulaDialog.licenseText + readOnly: true + } + + Label { + text: i18n("Do you accept?") + } + } + + onVisibleChanged: { + // onRejected does not fire on dialog closing, so implement that ourselves + if(!visible && !buttonClicked) + onNo(); + } + onNo: { + buttonClicked = true; + PkUpdates.eulaAgreementResult(this.eulaID, false); + } + onYes: { + buttonClicked = true; + PkUpdates.eulaAgreementResult(this.eulaID, true); + } + + function showPrompt(eulaID, packageID, vendor, licenseAgreement) { + this.eulaID = eulaID; + this.packageName = PkUpdates.packageName(packageID); + this.vendor = vendor; + this.licenseText = licenseAgreement; + + this.visible = true; + } + } + ListModel { id: updatesModel }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor