/* * This file is part of the Polkit-tqt project * Copyright (C) 2009 Daniel Nicoletti * Copyright (C) 2009 Dario Freddi * Copyright (C) 2009 Jaroslav Reznik * Copyright (C) 2009 Radek Novacek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include "polkit-tqt-authority.h" namespace PolkitTQt { //-------------------------------------- // General functions //-------------------------------------- Authority *Authority::m_theAuthority = NULL; Authority* Authority::instance(PolkitAuthority *authority) { if (!m_theAuthority) { m_theAuthority = new Authority(); } return m_theAuthority; } Authority::Result polkitResultToResult(PolkitAuthorizationResult *result) { if (polkit_authorization_result_get_is_challenge(result)) { return Authority::Challenge; } else if (polkit_authorization_result_get_is_authorized(result)) { return Authority::Yes; } else { return Authority::No; } } ActionDescription::List actionsToListAndFree(GList *glist) { ActionDescription::List result; for (GList *glist2 = glist; glist2; glist2 = g_list_next(glist2)) { gpointer i = glist2->data; result.append(ActionDescription(static_cast(i))); g_object_unref(i); } g_list_free(glist); return result; } //-------------------------------------- // Authority::Private //-------------------------------------- class Authority::Private { public: Private(Authority *qq) : q(qq), pkAuthority(NULL), m_hasError(false) { } ~Private(); void init(); /** Use this method to set the error message to \p message. Set recover to \c true * to try to reinitialize this object with init() method */ void setError(ErrorCode code, const TQString &details = TQString::null, bool recover = false); Authority *q; PolkitAuthority *pkAuthority; bool m_hasError; ErrorCode m_lastError; TQString m_errorDetails; GCancellable *m_checkAuthorizationCancellable; GCancellable *m_enumerateActionsCancellable; GCancellable *m_registerAuthenticationAgentCancellable; GCancellable *m_unregisterAuthenticationAgentCancellable; GCancellable *m_authenticationAgentResponseCancellable; GCancellable *m_enumerateTemporaryAuthorizationsCancellable; GCancellable *m_revokeTemporaryAuthorizationsCancellable; GCancellable *m_revokeTemporaryAuthorizationCancellable; static void pk_config_changed(); static void checkAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data); static void enumerateActionsCallback(GObject *object, GAsyncResult *result, gpointer user_data); static void registerAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data); static void unregisterAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data); static void authenticationAgentResponseCallback(GObject *object, GAsyncResult *result, gpointer user_data); static void enumerateTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data); static void revokeTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data); static void revokeTemporaryAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data); }; Authority::Private::~Private() { g_object_unref(m_checkAuthorizationCancellable); g_object_unref(m_enumerateActionsCancellable); g_object_unref(m_registerAuthenticationAgentCancellable); g_object_unref(m_unregisterAuthenticationAgentCancellable); g_object_unref(m_authenticationAgentResponseCancellable); g_object_unref(m_enumerateTemporaryAuthorizationsCancellable); g_object_unref(m_revokeTemporaryAuthorizationsCancellable); g_object_unref(m_revokeTemporaryAuthorizationCancellable); } void Authority::Private::init() { m_checkAuthorizationCancellable = g_cancellable_new(); m_enumerateActionsCancellable = g_cancellable_new(); m_registerAuthenticationAgentCancellable = g_cancellable_new(); m_unregisterAuthenticationAgentCancellable = g_cancellable_new(); m_authenticationAgentResponseCancellable = g_cancellable_new(); m_enumerateTemporaryAuthorizationsCancellable = g_cancellable_new(); m_revokeTemporaryAuthorizationsCancellable = g_cancellable_new(); m_revokeTemporaryAuthorizationCancellable = g_cancellable_new(); GError *gerror = NULL; if (pkAuthority == NULL) { pkAuthority = polkit_authority_get_sync(NULL, &gerror); if (gerror != NULL) { setError(E_GetAuthority, gerror->message); g_error_free(gerror); return; } } if (pkAuthority == NULL) { return; } // connect changed signal g_signal_connect(G_OBJECT(pkAuthority), "changed", G_CALLBACK(pk_config_changed), NULL); } void Authority::Private::setError(Authority::ErrorCode code, const TQString &details, bool recover) { if (recover) { init(); } m_lastError = code; m_errorDetails = details; m_hasError = true; } //-------------------------------------- // Authority //-------------------------------------- Authority::Authority(TQObject *parent) : TQObject(parent), d(new Private(this)) { d->init(); } Authority::~Authority() { g_object_unref(d->pkAuthority); delete d; } bool Authority::hasError() const { return d->m_hasError; } Authority::ErrorCode Authority::lastError() const { return d->m_lastError; } const TQString Authority::errorDetails() const { if (d->m_lastError == E_None) { return TQString::null; } else { return d->m_errorDetails; } } void Authority::clearError() { d->m_hasError = false; d->m_lastError = E_None; } void Authority::Private::pk_config_changed() { emit Authority::instance()->configChanged(); } PolkitAuthority* Authority::polkitAuthority() const { return d->pkAuthority; } Authority::Result Authority::checkAuthorizationSync(const TQString &actionId, const Subject &subject, AuthorizationFlags flags) { if (Authority::instance()->hasError()) { return Unknown; } if (!subject.isValid()) { d->setError(E_WrongSubject); return Unknown; } GError *error = NULL; PolkitAuthorizationResult *pk_result = polkit_authority_check_authorization_sync(d->pkAuthority, subject.subject(), actionId.ascii(), NULL, (PolkitCheckAuthorizationFlags)(int)flags, NULL, &error); if (error != NULL) { d->setError(E_CheckFailed, error->message); g_error_free(error); return Unknown; } if (!pk_result) { d->setError(E_UnknownResult); return Unknown; } else { Authority::Result res = polkitResultToResult(pk_result); g_object_unref(pk_result); return res; } } void Authority::checkAuthorization(const TQString &actionId, const Subject &subject, AuthorizationFlags flags) { if (Authority::instance()->hasError()) { return; } if (!subject.isValid()) { d->setError(E_WrongSubject); return; } polkit_authority_check_authorization(d->pkAuthority, subject.subject(), actionId.ascii(), NULL, (PolkitCheckAuthorizationFlags)(int)flags, d->m_checkAuthorizationCancellable, d->checkAuthorizationCallback, this); } void Authority::Private::checkAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data) { Authority *authority = (Authority*)user_data; if (!authority) { return; } GError *error = NULL; PolkitAuthorizationResult *pkResult = polkit_authority_check_authorization_finish( (PolkitAuthority*)object, result, &error); if (error != NULL) { // We don't want to set error if this is cancellation of some action if (error->code != 1) { authority->d->setError(E_CheckFailed, error->message); } g_error_free(error); return; } if (pkResult != NULL) { emit authority->checkAuthorizationFinished(polkitResultToResult(pkResult)); g_object_unref(pkResult); } else { authority->d->setError(E_UnknownResult); } } void Authority::checkAuthorizationCancel() { if (!g_cancellable_is_cancelled(d->m_checkAuthorizationCancellable)) { g_cancellable_cancel(d->m_checkAuthorizationCancellable); } } ActionDescription::List Authority::enumerateActionsSync() { if (Authority::instance()->hasError()) { return ActionDescription::List(); } GError *error = NULL; GList *glist = polkit_authority_enumerate_actions_sync(d->pkAuthority, NULL, &error); if (error != NULL) { d->setError(E_EnumFailed, error->message); g_error_free(error); return ActionDescription::List(); } return actionsToListAndFree(glist); } void Authority::enumerateActions() { if (Authority::instance()->hasError()) { return; } polkit_authority_enumerate_actions(d->pkAuthority, d->m_enumerateActionsCancellable, d->enumerateActionsCallback, Authority::instance()); } void Authority::Private::enumerateActionsCallback(GObject *object, GAsyncResult *result, gpointer user_data) { Authority *authority = (Authority*)user_data; if (!authority) { return; } GError *error = NULL; GList *list = polkit_authority_enumerate_actions_finish((PolkitAuthority*)object, result, &error); if (error != NULL) { // We don't want to set error if this is cancellation of some action if (error->code != 1) { authority->d->setError(E_EnumFailed, error->message); } g_error_free(error); return; } emit authority->enumerateActionsFinished(actionsToListAndFree(list)); } void Authority::enumerateActionsCancel() { if (!g_cancellable_is_cancelled(d->m_enumerateActionsCancellable)) { g_cancellable_cancel(d->m_enumerateActionsCancellable); } } bool Authority::registerAuthenticationAgentSync(const Subject &subject, const TQString &locale, const TQString &objectPath) { if (Authority::instance()->hasError()) { return false; } if (!subject.isValid()) { d->setError(E_WrongSubject); return false; } GError *error = NULL; gboolean result = polkit_authority_register_authentication_agent_sync(d->pkAuthority, subject.subject(), locale.ascii(), objectPath.ascii(), NULL, &error); if (error) { d->setError(E_RegisterFailed, error->message); g_error_free(error); return false; } return result; } void Authority::registerAuthenticationAgent(const Subject &subject, const TQString &locale, const TQString &objectPath) { if (Authority::instance()->hasError()) { return; } if (!subject.isValid()) { d->setError(E_WrongSubject); return; } polkit_authority_register_authentication_agent(d->pkAuthority, subject.subject(), locale.ascii(), objectPath.ascii(), d->m_registerAuthenticationAgentCancellable, d->registerAuthenticationAgentCallback, this); } void Authority::Private::registerAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data) { Authority *authority = (Authority*)user_data; if (!authority) { return; } GError *error = NULL; bool res = polkit_authority_register_authentication_agent_finish((PolkitAuthority*)object, result, &error); if (error != NULL) { // We don't want to set error if this is cancellation of some action if (error->code != 1) { authority->d->setError(E_EnumFailed , error->message); } g_error_free(error); return; } emit authority->registerAuthenticationAgentFinished(res); } void Authority::registerAuthenticationAgentCancel() { if (!g_cancellable_is_cancelled(d->m_registerAuthenticationAgentCancellable)) { g_cancellable_cancel(d->m_registerAuthenticationAgentCancellable); } } bool Authority::unregisterAuthenticationAgentSync(const Subject &subject, const TQString &objectPath) { if (d->pkAuthority) { return false; } if (!subject.isValid()) { d->setError(E_WrongSubject); return false; } GError *error = NULL; bool result = polkit_authority_unregister_authentication_agent_sync(d->pkAuthority, subject.subject(), objectPath.utf8().data(), NULL, &error); if (error != NULL) { d->setError(E_UnregisterFailed, error->message); g_error_free(error); return false; } return result; } void Authority::unregisterAuthenticationAgent(const Subject &subject, const TQString &objectPath) { if (Authority::instance()->hasError()) { return; } if (!subject.isValid()) { d->setError(E_WrongSubject); return; } polkit_authority_unregister_authentication_agent(d->pkAuthority, subject.subject(), objectPath.utf8().data(), d->m_unregisterAuthenticationAgentCancellable, d->unregisterAuthenticationAgentCallback, this); } void Authority::Private::unregisterAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data) { Authority *authority = (Authority*)user_data; if (!authority) { return; } GError *error = NULL; bool res = polkit_authority_unregister_authentication_agent_finish((PolkitAuthority*)object, result, &error); if (error != NULL) { // We don't want to set error if this is cancellation of some action if (error->code != 1) { authority->d->setError(E_UnregisterFailed, error->message); } g_error_free(error); return; } emit authority->unregisterAuthenticationAgentFinished(res); } void Authority::unregisterAuthenticationAgentCancel() { if (!g_cancellable_is_cancelled(d->m_unregisterAuthenticationAgentCancellable)) { g_cancellable_cancel(d->m_unregisterAuthenticationAgentCancellable); } } bool Authority::authenticationAgentResponseSync(const TQString &cookie, const Identity &identity) { if (Authority::instance()->hasError()) { return false; } if (cookie.isEmpty() || !identity.isValid()) { d->setError(E_CookieOrIdentityEmpty); return false; } GError *error = NULL; bool result = polkit_authority_authentication_agent_response_sync(d->pkAuthority, cookie.utf8().data(), identity.identity(), NULL, &error); if (error != NULL) { d->setError(E_AgentResponseFailed, error->message); g_error_free(error); return false; } return result; } void Authority::authenticationAgentResponse(const TQString &cookie, const Identity &identity) { if (Authority::instance()->hasError()) { return; } if (cookie.isEmpty() || !identity.isValid()) { d->setError(E_CookieOrIdentityEmpty); return; } polkit_authority_authentication_agent_response(d->pkAuthority, cookie.utf8().data(), identity.identity(), d->m_authenticationAgentResponseCancellable, d->authenticationAgentResponseCallback, this); } void Authority::Private::authenticationAgentResponseCallback(GObject *object, GAsyncResult *result, gpointer user_data) { Authority *authority = (Authority*)user_data; if (!authority) { return; } GError *error = NULL; bool res = polkit_authority_authentication_agent_response_finish((PolkitAuthority*)object, result, &error); if (error != NULL) { // We don't want to set error if this is cancellation of some action if (error->code != 1) { authority->d->setError(E_AgentResponseFailed, error->message); } g_error_free(error); return; } emit authority->authenticationAgentResponseFinished(res); } void Authority::authenticationAgentResponseCancel() { if (!g_cancellable_is_cancelled(d->m_authenticationAgentResponseCancellable)) { g_cancellable_cancel(d->m_authenticationAgentResponseCancellable); } } TemporaryAuthorization::List Authority::enumerateTemporaryAuthorizationsSync(const Subject &subject) { TemporaryAuthorization::List result; GError *error = NULL; GList *glist = polkit_authority_enumerate_temporary_authorizations_sync(d->pkAuthority, subject.subject(), NULL, &error); if (error != NULL) { d->setError(E_EnumFailed, error->message); g_error_free(error); return result; } GList *glist2; for (glist2 = glist; glist2 != NULL; glist2 = g_list_next(glist2)) { result.append(TemporaryAuthorization((PolkitTemporaryAuthorization*)glist2->data)); g_object_unref(glist2->data); } g_list_free(glist); return result; } void Authority::Private::enumerateTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data) { Authority *authority = (Authority*)user_data; if (!authority) { return; } GError *error = NULL; GList *glist = polkit_authority_enumerate_temporary_authorizations_finish((PolkitAuthority*)object, result, &error); if (error != NULL) { // We don't want to set error if this is cancellation of some action if (error->code != 1) { authority->d->setError(E_EnumFailed, error->message); } g_error_free(error); return; } TemporaryAuthorization::List res; GList *glist2; for (glist2 = glist; glist2 != NULL; glist2 = g_list_next(glist2)) { res.append(TemporaryAuthorization((PolkitTemporaryAuthorization*)glist2->data)); g_object_unref(glist2->data); } g_list_free(glist); emit authority->enumerateTemporaryAuthorizationsFinished(res); } void Authority::enumerateTemporaryAuthorizationsCancel() { if (!g_cancellable_is_cancelled(d->m_enumerateTemporaryAuthorizationsCancellable)) { g_cancellable_cancel(d->m_enumerateTemporaryAuthorizationsCancellable); } } bool Authority::revokeTemporaryAuthorizationsSync(const Subject &subject) { if (Authority::instance()->hasError()) { return false; } GError *error = NULL; bool result = polkit_authority_revoke_temporary_authorizations_sync(d->pkAuthority, subject.subject(), NULL, &error); if (error != NULL) { d->setError(E_RevokeFailed, error->message); g_error_free(error); return false; } return result; } void Authority::revokeTemporaryAuthorizations(const Subject &subject) { if (Authority::instance()->hasError()) { return; } polkit_authority_revoke_temporary_authorizations(d->pkAuthority, subject.subject(), d->m_revokeTemporaryAuthorizationsCancellable, d->revokeTemporaryAuthorizationsCallback, this); } void Authority::Private::revokeTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data) { Authority *authority = (Authority*)user_data; if (!authority) { return; } GError *error = NULL; bool res = polkit_authority_revoke_temporary_authorizations_finish((PolkitAuthority*)object, result, &error); if (error != NULL) { // We don't want to set error if this is cancellation of some action if (error->code != 1) { authority->d->setError(E_RevokeFailed, error->message); } g_error_free(error); return; } emit authority->revokeTemporaryAuthorizationsFinished(res); } void Authority::revokeTemporaryAuthorizationsCancel() { if (!g_cancellable_is_cancelled(d->m_revokeTemporaryAuthorizationsCancellable)) { g_cancellable_cancel(d->m_revokeTemporaryAuthorizationsCancellable); } } bool Authority::revokeTemporaryAuthorizationSync(const TQString &id) { if (Authority::instance()->hasError()) { return false; } GError *error = NULL; bool result = polkit_authority_revoke_temporary_authorization_by_id_sync(d->pkAuthority, id.utf8().data(), NULL, &error); if (error != NULL) { d->setError(E_RevokeFailed, error->message); g_error_free(error); return false; } return result; } void Authority::revokeTemporaryAuthorization(const TQString &id) { if (Authority::instance()->hasError()) { return; } polkit_authority_revoke_temporary_authorization_by_id(d->pkAuthority, id.utf8().data(), d->m_revokeTemporaryAuthorizationCancellable, d->revokeTemporaryAuthorizationCallback, this); } void Authority::Private::revokeTemporaryAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data) { Authority *authority = (Authority*)user_data; if (!authority) { return; } GError *error = NULL; bool res = polkit_authority_revoke_temporary_authorization_by_id_finish((PolkitAuthority*)object, result, &error); if (error != NULL) { // We don't want to set error if this is cancellation of some action if (error->code != 1) { authority->d->setError(E_RevokeFailed, error->message); } g_error_free(error); return; } emit authority->revokeTemporaryAuthorizationFinished(res); } void Authority::revokeTemporaryAuthorizationCancel() { if (!g_cancellable_is_cancelled(d->m_revokeTemporaryAuthorizationCancellable)) { g_cancellable_cancel(d->m_revokeTemporaryAuthorizationCancellable); } } } #include "polkit-tqt-authority.moc"