File indexing completed on 2024-04-21 04:43:22

0001 /*
0002     This file is part of the Polkit-qt project
0003     SPDX-FileCopyrightText: 2009 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
0004     SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
0005     SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com>
0006     SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com>
0007 
0008     SPDX-License-Identifier: LGPL-2.0-or-later
0009 */
0010 
0011 #include "polkitqt1-authority.h"
0012 
0013 #include <QDBusInterface>
0014 #include <QDBusMessage>
0015 #include <QDBusReply>
0016 
0017 #include <polkit/polkit.h>
0018 
0019 namespace PolkitQt1
0020 {
0021 
0022 class AuthorityHelper
0023 {
0024 public:
0025     AuthorityHelper() : q(nullptr) {}
0026     ~AuthorityHelper() {
0027         delete q;
0028     }
0029     Authority *q;
0030 };
0031 
0032 Q_GLOBAL_STATIC(AuthorityHelper, s_globalAuthority)
0033 
0034 Authority *Authority::instance(PolkitAuthority *authority)
0035 {
0036     if (!s_globalAuthority()->q) {
0037         new Authority(authority);
0038     }
0039 
0040     return s_globalAuthority()->q;
0041 }
0042 
0043 Authority::Result polkitResultToResult(PolkitAuthorizationResult *result)
0044 {
0045     if (polkit_authorization_result_get_is_challenge(result)) {
0046         return Authority::Challenge;
0047     } else if (polkit_authorization_result_get_is_authorized(result)) {
0048         return Authority::Yes;
0049     } else {
0050         return Authority::No;
0051     }
0052 }
0053 
0054 ActionDescription::List actionsToListAndFree(GList *glist)
0055 {
0056     ActionDescription::List result;
0057     for (GList *glist2 = glist; glist2; glist2 = g_list_next(glist2)) {
0058         gpointer i = glist2->data;
0059         result.append(ActionDescription(static_cast<PolkitActionDescription *>(i)));
0060         g_object_unref(i);
0061     }
0062 
0063     g_list_free(glist);
0064     return result;
0065 }
0066 
0067 class Q_DECL_HIDDEN Authority::Private
0068 {
0069 public:
0070     // Polkit will return NULL on failures, hence we use it instead of 0
0071     Private(Authority *qq) : q(qq)
0072             , pkAuthority(nullptr)
0073             , m_hasError(false)
0074             , m_systemBus(nullptr)
0075     {
0076     }
0077 
0078     ~Private();
0079 
0080     void init();
0081 
0082     /** Use this method to set the error message to \p message. Set recover to \c true
0083      * to try to reinitialize this object with init() method
0084      */
0085     void setError(Authority::ErrorCode code, const QString &details = QString(), bool recover = false);
0086 
0087     void dbusFilter(const QDBusMessage &message);
0088     void dbusSignalAdd(const QString &service, const QString &path, const QString &interface, const QString &name);
0089     void seatSignalsConnect(const QString &seat);
0090 
0091     Authority *q;
0092     PolkitAuthority *pkAuthority;
0093     bool m_hasError;
0094     Authority::ErrorCode m_lastError;
0095     QString m_errorDetails;
0096     // Local system bus. QDBusConnection::systemBus() may only be safely used
0097     // inside a QCoreApplication scope as for example destruction of connected
0098     // objects need to happen before the bus disappears. Since this class however
0099     // is a global static and systemBus() internally is a global static we
0100     // cannot assure destruction order. Instead we create a local copy of the
0101     // global systemBus instance so we can make life time to our needs.
0102     // This prevents crashes when cleaning up the global statics.
0103     QDBusConnection *m_systemBus;
0104     GCancellable *m_checkAuthorizationCancellable,
0105     *m_enumerateActionsCancellable,
0106     *m_registerAuthenticationAgentCancellable,
0107     *m_unregisterAuthenticationAgentCancellable,
0108     *m_authenticationAgentResponseCancellable,
0109     *m_enumerateTemporaryAuthorizationsCancellable,
0110     *m_revokeTemporaryAuthorizationsCancellable,
0111     *m_revokeTemporaryAuthorizationCancellable;
0112 
0113     /**
0114      * \brief Convert a Qt DetailsMap to the lower level PolkitDetails type
0115      *
0116      * The returned pointer needs to be freed via g_object_unref when no
0117      * longer needed. Returns nullptr if details is empty.
0118      */
0119     static PolkitDetails* convertDetailsMap(const DetailsMap &details);
0120     static void pk_config_changed();
0121     static void checkAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data);
0122     static void enumerateActionsCallback(GObject *object, GAsyncResult *result, gpointer user_data);
0123     static void registerAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data);
0124     static void unregisterAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data);
0125     static void authenticationAgentResponseCallback(GObject *object, GAsyncResult *result, gpointer user_data);
0126     static void enumerateTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data);
0127     static void revokeTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data);
0128     static void revokeTemporaryAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data);
0129 };
0130 
0131 Authority::Private::~Private()
0132 {
0133     delete m_systemBus;
0134     g_object_unref(m_checkAuthorizationCancellable);
0135     g_object_unref(m_enumerateActionsCancellable);
0136     g_object_unref(m_registerAuthenticationAgentCancellable);
0137     g_object_unref(m_unregisterAuthenticationAgentCancellable);
0138     g_object_unref(m_authenticationAgentResponseCancellable);
0139     g_object_unref(m_enumerateTemporaryAuthorizationsCancellable);
0140     g_object_unref(m_revokeTemporaryAuthorizationsCancellable);
0141     g_object_unref(m_revokeTemporaryAuthorizationCancellable);
0142 }
0143 
0144 Authority::Authority(PolkitAuthority *authority, QObject *parent)
0145         : QObject(parent)
0146         , d(new Private(this))
0147 {
0148     qRegisterMetaType<PolkitQt1::Authority::Result> ();
0149     qRegisterMetaType<PolkitQt1::ActionDescription::List>();
0150 
0151     Q_ASSERT(!s_globalAuthority()->q);
0152     s_globalAuthority()->q = this;
0153 
0154     if (authority) {
0155         d->pkAuthority = authority;
0156     }
0157 
0158     d->init();
0159 }
0160 
0161 Authority::~Authority()
0162 {
0163     if (d->pkAuthority != nullptr) {
0164         g_object_unref(d->pkAuthority);
0165     }
0166 
0167     delete d;
0168 }
0169 
0170 void Authority::Private::init()
0171 {
0172     QDBusError error;
0173     QDBusError dbus_error;
0174 
0175     m_systemBus = new QDBusConnection(QDBusConnection::connectToBus(QDBusConnection::SystemBus,
0176                                                                     QStringLiteral("polkit_qt_system_bus")));
0177 
0178     m_checkAuthorizationCancellable = g_cancellable_new();
0179     m_enumerateActionsCancellable = g_cancellable_new();
0180     m_registerAuthenticationAgentCancellable = g_cancellable_new();
0181     m_unregisterAuthenticationAgentCancellable = g_cancellable_new();
0182     m_authenticationAgentResponseCancellable = g_cancellable_new();
0183     m_enumerateTemporaryAuthorizationsCancellable = g_cancellable_new();
0184     m_revokeTemporaryAuthorizationsCancellable = g_cancellable_new();
0185     m_revokeTemporaryAuthorizationCancellable = g_cancellable_new();
0186 
0187 #ifndef POLKIT_QT_1_COMPATIBILITY_MODE
0188     GError *gerror = nullptr;
0189 #endif
0190     if (pkAuthority == nullptr) {
0191 #ifndef POLKIT_QT_1_COMPATIBILITY_MODE
0192         pkAuthority = polkit_authority_get_sync(nullptr, &gerror);
0193         if (gerror != nullptr) {
0194             setError(E_GetAuthority, gerror->message);
0195             g_error_free(gerror);
0196             return;
0197         }
0198 #else
0199         pkAuthority = polkit_authority_get();
0200 #endif
0201     }
0202 
0203     if (pkAuthority == nullptr) {
0204 #ifdef POLKIT_QT_1_COMPATIBILITY_MODE
0205         (E_GetAuthority);
0206 #endif
0207         return;
0208     }
0209 
0210     // connect changed signal
0211     g_signal_connect(G_OBJECT(pkAuthority), "changed", G_CALLBACK(pk_config_changed), NULL);
0212 
0213     // need to listen to NameOwnerChanged
0214     dbusSignalAdd("org.freedesktop.DBus", "/", "org.freedesktop.DBus", "NameOwnerChanged");
0215 
0216     QString consoleKitService("org.freedesktop.ConsoleKit");
0217     QString consoleKitManagerPath("/org/freedesktop/ConsoleKit/Manager");
0218     QString consoleKitManagerInterface("org.freedesktop.ConsoleKit.Manager");
0219 
0220     // first, add signals SeadAdded and SeatRemoved from ConsoleKit Manager
0221     dbusSignalAdd(consoleKitService, consoleKitManagerPath, consoleKitManagerInterface, "SeatAdded");
0222     dbusSignalAdd(consoleKitService, consoleKitManagerPath, consoleKitManagerInterface, "SeatRemoved");
0223 
0224     // then we need to extract all seats from ConsoleKit
0225     QDBusMessage msg = QDBusMessage::createMethodCall(consoleKitService, consoleKitManagerPath, consoleKitManagerInterface, "GetSeats");
0226     const QDBusMessage reply = m_systemBus->call(msg);
0227 
0228     if (reply.type() != QDBusMessage::ErrorMessage && !reply.arguments().isEmpty()) {
0229         // this method returns a list with present seats
0230         QStringList seats;
0231         QVariant arg = reply.arguments()[0];
0232         if (arg.type() == qMetaTypeId<QDBusArgument>()) {
0233             arg.value<QDBusArgument>() >> seats;
0234         } else {
0235             seats = arg.toStringList();
0236         }
0237         // it can be multiple seats present so connect all their signals
0238         Q_FOREACH(const QString &seat, seats) {
0239             seatSignalsConnect(seat);
0240         }
0241     }
0242 }
0243 
0244 void Authority::Private::setError(Authority::ErrorCode code, const QString &details, bool recover)
0245 {
0246     if (recover) {
0247         init();
0248     }
0249     m_lastError = code;
0250     m_errorDetails = details;
0251     m_hasError = true;
0252 }
0253 
0254 void Authority::Private::seatSignalsConnect(const QString &seat)
0255 {
0256     QString consoleKitService("org.freedesktop.ConsoleKit");
0257     QString consoleKitSeatInterface("org.freedesktop.ConsoleKit.Seat");
0258     // we want to connect to all slots of the seat
0259     dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "DeviceAdded");
0260     dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "DeviceRemoved");
0261     dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "SessionAdded");
0262     dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "SessionRemoved");
0263     dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "ActiveSessionChanged");
0264 }
0265 
0266 void Authority::Private::dbusSignalAdd(const QString &service, const QString &path, const QString &interface, const QString &name)
0267 {
0268     // FIXME: This code seems to be nonfunctional - it needs to be fixed somewhere (is it Qt BUG?)
0269     m_systemBus->connect(service, path, interface, name, q, SLOT(dbusFilter(QDBusMessage)));
0270 }
0271 
0272 void Authority::Private::dbusFilter(const QDBusMessage &message)
0273 {
0274     if (message.type() == QDBusMessage::SignalMessage) {
0275         Q_EMIT q->consoleKitDBChanged();
0276 
0277         // TODO: Test this with the multiseat support
0278         if (message.member() == "SeatAdded") {
0279             seatSignalsConnect(message.arguments()[0].value<QDBusObjectPath>().path());
0280         }
0281     }
0282 }
0283 
0284 bool Authority::hasError() const
0285 {
0286     return d->m_hasError;
0287 }
0288 
0289 Authority::ErrorCode Authority::lastError() const
0290 {
0291     return d->m_lastError;
0292 }
0293 
0294 const QString Authority::errorDetails() const
0295 {
0296     if (d->m_lastError == E_None) {
0297         return QString();
0298     } else {
0299         return d->m_errorDetails;
0300     }
0301 }
0302 
0303 void Authority::clearError()
0304 {
0305     d->m_hasError = false;
0306     d->m_lastError = E_None;
0307 }
0308 
0309 PolkitDetails* Authority::Private::convertDetailsMap(const DetailsMap &details)
0310 {
0311     if (details.empty())
0312         return nullptr;
0313 
0314     auto ret = polkit_details_new();
0315 
0316     for (const auto &entry: details.toStdMap()) {
0317         const auto &key = entry.first;
0318         const auto &value = entry.second;
0319 
0320         polkit_details_insert(ret, key.toUtf8().constData(), value.toUtf8().data());
0321     }
0322 
0323     return ret;
0324 }
0325 
0326 void Authority::Private::pk_config_changed()
0327 {
0328     Q_EMIT Authority::instance()->configChanged();
0329 }
0330 
0331 PolkitAuthority *Authority::polkitAuthority() const
0332 {
0333     return d->pkAuthority;
0334 }
0335 
0336 Authority::Result Authority::checkAuthorizationSyncWithDetails(const QString &actionId, const Subject &subject, AuthorizationFlags flags, const DetailsMap &details)
0337 {
0338     PolkitAuthorizationResult *pk_result;
0339     GError *error = nullptr;
0340 
0341     if (Authority::instance()->hasError()) {
0342         return Unknown;
0343     }
0344 
0345     if (!subject.isValid()) {
0346         d->setError(E_WrongSubject);
0347         return Unknown;
0348     }
0349 
0350     auto pk_details = Authority::Private::convertDetailsMap(details);
0351 
0352     pk_result = polkit_authority_check_authorization_sync(d->pkAuthority,
0353                 subject.subject(),
0354                 actionId.toLatin1().data(),
0355                 pk_details,
0356                 (PolkitCheckAuthorizationFlags)(int)flags,
0357                 nullptr,
0358                 &error);
0359 
0360     if (pk_details) {
0361         g_object_unref(pk_details);
0362     }
0363 
0364     if (error != nullptr) {
0365         d->setError(E_CheckFailed, error->message);
0366         g_error_free(error);
0367         return Unknown;
0368     }
0369 
0370     if (!pk_result) {
0371         d->setError(E_UnknownResult);
0372         return Unknown;
0373     } else {
0374         Authority::Result res = polkitResultToResult(pk_result);
0375         g_object_unref(pk_result);
0376         return res;
0377     }
0378 }
0379 
0380 Authority::Result Authority::checkAuthorizationSync(const QString &actionId, const Subject &subject, AuthorizationFlags flags)
0381 {
0382     return checkAuthorizationSyncWithDetails(actionId, subject, flags, DetailsMap());
0383 }
0384 
0385 void Authority::checkAuthorizationWithDetails(const QString &actionId, const Subject &subject, AuthorizationFlags flags, const DetailsMap &details)
0386 {
0387     if (Authority::instance()->hasError()) {
0388         return;
0389     }
0390 
0391     if (!subject.isValid()) {
0392         d->setError(E_WrongSubject);
0393         return;
0394     }
0395 
0396     auto pk_details = Authority::Private::convertDetailsMap(details);
0397 
0398     polkit_authority_check_authorization(d->pkAuthority,
0399                                          subject.subject(),
0400                                          actionId.toLatin1().data(),
0401                                          pk_details,
0402                                          (PolkitCheckAuthorizationFlags)(int)flags,
0403                                          d->m_checkAuthorizationCancellable,
0404                                          d->checkAuthorizationCallback, this);
0405 
0406     if (pk_details) {
0407         g_object_unref(pk_details);
0408     }
0409 }
0410 
0411 void Authority::checkAuthorization(const QString &actionId, const Subject &subject, AuthorizationFlags flags)
0412 {
0413     checkAuthorizationWithDetails(actionId, subject, flags, DetailsMap());
0414 }
0415 
0416 void Authority::Private::checkAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data)
0417 {
0418     Authority *authority = (Authority *) user_data;
0419 
0420     Q_ASSERT(authority != nullptr);
0421 
0422     GError *error = nullptr;
0423     PolkitAuthorizationResult *pkResult = polkit_authority_check_authorization_finish((PolkitAuthority *) object, result, &error);
0424 
0425     if (error != nullptr) {
0426         // We don't want to set error if this is cancellation of some action
0427         if (error->code != 1) {
0428             authority->d->setError(E_CheckFailed, error->message);
0429         }
0430         g_error_free(error);
0431         return;
0432     }
0433     if (pkResult != nullptr) {
0434         Q_EMIT authority->checkAuthorizationFinished(polkitResultToResult(pkResult));
0435         g_object_unref(pkResult);
0436     } else {
0437         authority->d->setError(E_UnknownResult);
0438     }
0439 }
0440 
0441 void Authority::checkAuthorizationCancel()
0442 {
0443     if (!g_cancellable_is_cancelled(d->m_checkAuthorizationCancellable)) {
0444         g_cancellable_cancel(d->m_checkAuthorizationCancellable);
0445     }
0446 }
0447 
0448 ActionDescription::List Authority::enumerateActionsSync()
0449 {
0450     if (Authority::instance()->hasError()) {
0451         return ActionDescription::List();
0452     }
0453 
0454     GError *error = nullptr;
0455 
0456     GList *glist = polkit_authority_enumerate_actions_sync(d->pkAuthority,
0457                    nullptr,
0458                    &error);
0459 
0460     if (error != nullptr) {
0461         d->setError(E_EnumFailed, error->message);
0462         g_error_free(error);
0463         return ActionDescription::List();
0464     }
0465 
0466     return actionsToListAndFree(glist);
0467 }
0468 
0469 void Authority::enumerateActions()
0470 {
0471     if (Authority::instance()->hasError()) {
0472         return;
0473     }
0474 
0475     polkit_authority_enumerate_actions(d->pkAuthority,
0476                                        d->m_enumerateActionsCancellable,
0477                                        d->enumerateActionsCallback,
0478                                        Authority::instance());
0479 }
0480 
0481 void Authority::Private::enumerateActionsCallback(GObject *object, GAsyncResult *result, gpointer user_data)
0482 {
0483     Authority *authority = (Authority *) user_data;
0484     Q_ASSERT(authority != nullptr);
0485     GError *error = nullptr;
0486     GList *list = polkit_authority_enumerate_actions_finish((PolkitAuthority *) object, result, &error);
0487     if (error != nullptr) {
0488         // We don't want to set error if this is cancellation of some action
0489         if (error->code != 1) {
0490             authority->d->setError(E_EnumFailed, error->message);
0491         }
0492         g_error_free(error);
0493         return;
0494     }
0495 
0496     Q_EMIT authority->enumerateActionsFinished(actionsToListAndFree(list));
0497 }
0498 
0499 void Authority::enumerateActionsCancel()
0500 {
0501     if (!g_cancellable_is_cancelled(d->m_enumerateActionsCancellable)) {
0502         g_cancellable_cancel(d->m_enumerateActionsCancellable);
0503     }
0504 }
0505 
0506 bool Authority::registerAuthenticationAgentSync(const Subject &subject, const QString &locale, const QString &objectPath)
0507 {
0508     if (Authority::instance()->hasError()) {
0509         return false;
0510     }
0511 
0512     gboolean result;
0513     GError *error = nullptr;
0514 
0515     if (!subject.isValid()) {
0516         d->setError(E_WrongSubject);
0517         return false;
0518     }
0519 
0520     result = polkit_authority_register_authentication_agent_sync(d->pkAuthority,
0521              subject.subject(), locale.toLatin1().data(),
0522              objectPath.toLatin1().data(), nullptr, &error);
0523 
0524     if (error) {
0525         d->setError(E_RegisterFailed, error->message);
0526         g_error_free(error);
0527         return false;
0528     }
0529 
0530     return result;
0531 }
0532 
0533 void Authority::registerAuthenticationAgent(const Subject &subject, const QString &locale, const QString &objectPath)
0534 {
0535     if (Authority::instance()->hasError()) {
0536         return;
0537     }
0538 
0539     if (!subject.isValid()) {
0540         d->setError(E_WrongSubject);
0541         return;
0542     }
0543 
0544     polkit_authority_register_authentication_agent(d->pkAuthority,
0545             subject.subject(),
0546             locale.toLatin1().data(),
0547             objectPath.toLatin1().data(),
0548             d->m_registerAuthenticationAgentCancellable,
0549             d->registerAuthenticationAgentCallback,
0550             this);
0551 }
0552 
0553 void Authority::Private::registerAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data)
0554 {
0555     Authority *authority = (Authority *) user_data;
0556     Q_ASSERT(authority != nullptr);
0557     GError *error = nullptr;
0558     bool res = polkit_authority_register_authentication_agent_finish((PolkitAuthority *) object, result, &error);
0559     if (error != nullptr) {
0560         // We don't want to set error if this is cancellation of some action
0561         if (error->code != 1) {
0562             authority->d->setError(E_EnumFailed , error->message);
0563         }
0564         g_error_free(error);
0565         return;
0566     }
0567 
0568     Q_EMIT authority->registerAuthenticationAgentFinished(res);
0569 }
0570 
0571 void Authority::registerAuthenticationAgentCancel()
0572 {
0573     if (!g_cancellable_is_cancelled(d->m_registerAuthenticationAgentCancellable)) {
0574         g_cancellable_cancel(d->m_registerAuthenticationAgentCancellable);
0575     }
0576 }
0577 
0578 bool Authority::unregisterAuthenticationAgentSync(const Subject &subject, const QString &objectPath)
0579 {
0580     if (d->pkAuthority) {
0581         return false;
0582     }
0583 
0584     if (!subject.isValid()) {
0585         d->setError(E_WrongSubject);
0586         return false;
0587     }
0588 
0589     GError *error = nullptr;
0590 
0591     bool result = polkit_authority_unregister_authentication_agent_sync(d->pkAuthority,
0592                   subject.subject(),
0593                   objectPath.toUtf8().data(),
0594                   nullptr,
0595                   &error);
0596 
0597     if (error != nullptr) {
0598         d->setError(E_UnregisterFailed, error->message);
0599         g_error_free(error);
0600         return false;
0601     }
0602 
0603     return result;
0604 }
0605 
0606 void Authority::unregisterAuthenticationAgent(const Subject &subject, const QString &objectPath)
0607 {
0608     if (Authority::instance()->hasError()) {
0609         return;
0610     }
0611 
0612     if (!subject.isValid()) {
0613         d->setError(E_WrongSubject);
0614         return;
0615     }
0616 
0617     polkit_authority_unregister_authentication_agent(d->pkAuthority,
0618             subject.subject(),
0619             objectPath.toUtf8().data(),
0620             d->m_unregisterAuthenticationAgentCancellable,
0621             d->unregisterAuthenticationAgentCallback,
0622             this);
0623 }
0624 
0625 void Authority::Private::unregisterAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data)
0626 {
0627     Authority *authority = (Authority *) user_data;
0628     Q_ASSERT(authority);
0629     GError *error = nullptr;
0630     bool res = polkit_authority_unregister_authentication_agent_finish((PolkitAuthority *) object, result, &error);
0631     if (error != nullptr) {
0632         // We don't want to set error if this is cancellation of some action
0633         if (error->code != 1) {
0634             authority->d->setError(E_UnregisterFailed, error->message);
0635         }
0636         g_error_free(error);
0637         return;
0638     }
0639 
0640     Q_EMIT authority->unregisterAuthenticationAgentFinished(res);
0641 }
0642 
0643 void Authority::unregisterAuthenticationAgentCancel()
0644 {
0645     if (!g_cancellable_is_cancelled(d->m_unregisterAuthenticationAgentCancellable)) {
0646         g_cancellable_cancel(d->m_unregisterAuthenticationAgentCancellable);
0647     }
0648 }
0649 
0650 bool Authority::authenticationAgentResponseSync(const QString &cookie, const Identity &identity)
0651 {
0652     if (Authority::instance()->hasError()) {
0653         return false;
0654     }
0655 
0656     if (cookie.isEmpty() || !identity.isValid()) {
0657         d->setError(E_CookieOrIdentityEmpty);
0658         return false;
0659     }
0660 
0661     GError *error = nullptr;
0662 
0663     bool result = polkit_authority_authentication_agent_response_sync(d->pkAuthority,
0664                   cookie.toUtf8().data(),
0665                   identity.identity(),
0666                   nullptr,
0667                   &error);
0668     if (error != nullptr) {
0669         d->setError(E_AgentResponseFailed, error->message);
0670         g_error_free(error);
0671         return false;
0672     }
0673 
0674     return result;
0675 }
0676 
0677 void Authority::authenticationAgentResponse(const QString &cookie, const Identity &identity)
0678 {
0679     if (Authority::instance()->hasError()) {
0680         return;
0681     }
0682 
0683     if (cookie.isEmpty() || !identity.isValid()) {
0684         d->setError(E_CookieOrIdentityEmpty);
0685         return;
0686     }
0687 
0688     polkit_authority_authentication_agent_response(d->pkAuthority,
0689             cookie.toUtf8().data(),
0690             identity.identity(),
0691             d->m_authenticationAgentResponseCancellable,
0692             d->authenticationAgentResponseCallback,
0693             this);
0694 }
0695 
0696 void Authority::Private::authenticationAgentResponseCallback(GObject *object, GAsyncResult *result, gpointer user_data)
0697 {
0698     Authority *authority = (Authority *) user_data;
0699     Q_ASSERT(authority);
0700     GError *error = nullptr;
0701     bool res = polkit_authority_authentication_agent_response_finish((PolkitAuthority *) object, result, &error);
0702     if (error != nullptr) {
0703         // We don't want to set error if this is cancellation of some action
0704         if (error->code != 1) {
0705             authority->d->setError(E_AgentResponseFailed, error->message);
0706         }
0707         g_error_free(error);
0708         return;
0709     }
0710 
0711     Q_EMIT authority->authenticationAgentResponseFinished(res);
0712 }
0713 
0714 void Authority::authenticationAgentResponseCancel()
0715 {
0716     if (!g_cancellable_is_cancelled(d->m_authenticationAgentResponseCancellable)) {
0717         g_cancellable_cancel(d->m_authenticationAgentResponseCancellable);
0718     }
0719 }
0720 
0721 TemporaryAuthorization::List Authority::enumerateTemporaryAuthorizationsSync(const Subject &subject)
0722 {
0723     TemporaryAuthorization::List result;
0724 
0725     GError *error = nullptr;
0726     GList *glist = polkit_authority_enumerate_temporary_authorizations_sync(d->pkAuthority,
0727                    subject.subject(),
0728                    nullptr,
0729                    &error);
0730     if (error != nullptr) {
0731         d->setError(E_EnumFailed, error->message);
0732         g_error_free(error);
0733         return result;
0734     }
0735 
0736     GList *glist2;
0737     for (glist2 = glist; glist2 != nullptr; glist2 = g_list_next(glist2)) {
0738         result.append(TemporaryAuthorization((PolkitTemporaryAuthorization *) glist2->data));
0739         g_object_unref(glist2->data);
0740     }
0741 
0742     g_list_free(glist);
0743 
0744     return result;
0745 }
0746 
0747 void Authority::Private::enumerateTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data)
0748 {
0749     Authority *authority = (Authority *) user_data;
0750     Q_ASSERT(authority);
0751     GError *error = nullptr;
0752 
0753     GList *glist = polkit_authority_enumerate_temporary_authorizations_finish((PolkitAuthority *) object, result, &error);
0754 
0755     if (error != nullptr) {
0756         // We don't want to set error if this is cancellation of some action
0757         if (error->code != 1) {
0758             authority->d->setError(E_EnumFailed, error->message);
0759         }
0760         g_error_free(error);
0761         return;
0762     }
0763     TemporaryAuthorization::List res;
0764     GList *glist2;
0765     for (glist2 = glist; glist2 != nullptr; glist2 = g_list_next(glist2)) {
0766         res.append(TemporaryAuthorization((PolkitTemporaryAuthorization *) glist2->data));
0767         g_object_unref(glist2->data);
0768     }
0769 
0770     g_list_free(glist);
0771 
0772     Q_EMIT authority->enumerateTemporaryAuthorizationsFinished(res);
0773 }
0774 
0775 void Authority::enumerateTemporaryAuthorizationsCancel()
0776 {
0777     if (!g_cancellable_is_cancelled(d->m_enumerateTemporaryAuthorizationsCancellable)) {
0778         g_cancellable_cancel(d->m_enumerateTemporaryAuthorizationsCancellable);
0779     }
0780 }
0781 
0782 bool Authority::revokeTemporaryAuthorizationsSync(const Subject &subject)
0783 {
0784     bool result;
0785     if (Authority::instance()->hasError()) {
0786         return false;
0787     }
0788 
0789     GError *error = nullptr;
0790     result = polkit_authority_revoke_temporary_authorizations_sync(d->pkAuthority,
0791              subject.subject(),
0792              nullptr,
0793              &error);
0794     if (error != nullptr) {
0795         d->setError(E_RevokeFailed, error->message);
0796         g_error_free(error);
0797         return false;
0798     }
0799     return result;
0800 }
0801 
0802 void Authority::revokeTemporaryAuthorizations(const Subject &subject)
0803 {
0804     if (Authority::instance()->hasError()) {
0805         return;
0806     }
0807 
0808     polkit_authority_revoke_temporary_authorizations(d->pkAuthority,
0809             subject.subject(),
0810             d->m_revokeTemporaryAuthorizationsCancellable,
0811             d->revokeTemporaryAuthorizationsCallback,
0812             this);
0813 }
0814 
0815 void Authority::Private::revokeTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data)
0816 {
0817     Authority *authority = (Authority *) user_data;
0818     Q_ASSERT(authority != nullptr);
0819     GError *error = nullptr;
0820 
0821     bool res = polkit_authority_revoke_temporary_authorizations_finish((PolkitAuthority *) object, result, &error);
0822 
0823     if (error != nullptr) {
0824         // We don't want to set error if this is cancellation of some action
0825         if (error->code != 1) {
0826             authority->d->setError(E_RevokeFailed, error->message);
0827         }
0828         g_error_free(error);
0829         return;
0830     }
0831 
0832     Q_EMIT authority->revokeTemporaryAuthorizationsFinished(res);
0833 }
0834 
0835 void Authority::revokeTemporaryAuthorizationsCancel()
0836 {
0837     if (!g_cancellable_is_cancelled(d->m_revokeTemporaryAuthorizationsCancellable)) {
0838         g_cancellable_cancel(d->m_revokeTemporaryAuthorizationsCancellable);
0839     }
0840 }
0841 
0842 bool Authority::revokeTemporaryAuthorizationSync(const QString &id)
0843 {
0844     bool result;
0845     if (Authority::instance()->hasError()) {
0846         return false;
0847     }
0848 
0849     GError *error = nullptr;
0850     result =  polkit_authority_revoke_temporary_authorization_by_id_sync(d->pkAuthority,
0851               id.toUtf8().data(),
0852               nullptr,
0853               &error);
0854     if (error != nullptr) {
0855         d->setError(E_RevokeFailed, error->message);
0856         g_error_free(error);
0857         return false;
0858     }
0859     return result;
0860 }
0861 
0862 void Authority::revokeTemporaryAuthorization(const QString &id)
0863 {
0864     if (Authority::instance()->hasError()) {
0865         return;
0866     }
0867 
0868     polkit_authority_revoke_temporary_authorization_by_id(d->pkAuthority,
0869             id.toUtf8().data(),
0870             d->m_revokeTemporaryAuthorizationCancellable,
0871             d->revokeTemporaryAuthorizationCallback,
0872             this);
0873 }
0874 
0875 void Authority::Private::revokeTemporaryAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data)
0876 {
0877     Authority *authority = (Authority *) user_data;
0878     Q_ASSERT(authority != nullptr);
0879     GError *error = nullptr;
0880 
0881     bool res = polkit_authority_revoke_temporary_authorization_by_id_finish((PolkitAuthority *) object, result, &error);
0882 
0883     if (error != nullptr) {
0884         // We don't want to set error if this is cancellation of some action
0885         if (error->code != 1) {
0886             authority->d->setError(E_RevokeFailed, error->message);
0887         }
0888         g_error_free(error);
0889         return;
0890     }
0891 
0892     Q_EMIT authority->revokeTemporaryAuthorizationFinished(res);
0893 }
0894 
0895 void Authority::revokeTemporaryAuthorizationCancel()
0896 {
0897     if (!g_cancellable_is_cancelled(d->m_revokeTemporaryAuthorizationCancellable)) {
0898         g_cancellable_cancel(d->m_revokeTemporaryAuthorizationCancellable);
0899     }
0900 }
0901 
0902 }
0903 
0904 #include "moc_polkitqt1-authority.cpp"