diff options
Diffstat (limited to 'examples/PkExample.cpp')
-rw-r--r-- | examples/PkExample.cpp | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/examples/PkExample.cpp b/examples/PkExample.cpp new file mode 100644 index 000000000..2168a9117 --- /dev/null +++ b/examples/PkExample.cpp @@ -0,0 +1,240 @@ +// This is an example not a library +/*************************************************************************** + * Copyright (C) 2009 Radek Novacek <rnovacek@redhat.com> * + * Copyright (C) 2008 Daniel Nicoletti <dantti85-pk@yahoo.com.br> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "PkExample.h" + +#include "gui/polkitqt1-gui-actionbutton.h" +#include "gui/polkitqt1-gui-actionbuttons.h" +#include "core/polkitqt1-authority.h" +#include <QtCore/QDebug> + +#include <QtDBus/QDBusMessage> +#include <QtDBus/QDBusConnection> + +using namespace PolkitQt1; +using namespace PolkitQt1::Gui; + +PkExample::PkExample(QMainWindow *parent) + : QMainWindow(parent) +{ + setupUi(this); + + ActionButton *bt; + + // Here we create an ActionButton that is a subclass of Action + // always pass a QAbstractButton pointer and action id + // You can change the action id later if you want + bt = new ActionButton(kickPB, "org.qt.policykit.examples.kick", this); + // Here we are setting the text and icon to all four states + // an action might have + bt->setText("Kick!"); + bt->setIcon(QPixmap(":/Icons/custom-no.png")); + // By using set{Yes|No|Auth}Enabled you can set the states + // when the button is enabled + bt->setEnabled(true, Action::No); + // As ActionButton is also an Action we cast it to add to menu + menuActions->addAction(qobject_cast<Action *>(bt)); + toolBar->addAction(qobject_cast<Action *>(bt)); + // this signal is emitted when the user click on the action, + // it will only happen if it was inserted in a QMenu or a QToolBar + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + // This signal was propagated from the QAbstractButton just for + // convenience in this case we don't have any benefit but the code + // look cleaner + connect(bt, SIGNAL(clicked(QAbstractButton *, bool)), bt, SLOT(activate())); + // this is the Action activated signal, it is always emmited whenever + // someone click and get authorized to do the action + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(cryPB, "org.qt.policykit.examples.cry", this); + bt->setText("Cry!"); + bt->setIcon(QPixmap(":/Icons/custom-yes.png")); + menuActions->addAction(qobject_cast<Action *>(bt)); + toolBar->addAction(qobject_cast<Action *>(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton *, bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(bleedPB, "org.qt.policykit.examples.bleed", this); + bt->setText("Bleed!"); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png")); + menuActions->addAction(qobject_cast<Action *>(bt)); + toolBar->addAction(qobject_cast<Action *>(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton *, bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + // This action is more customized + bt = new ActionButton(playPB, "org.qt.policykit.examples.play", this); + bt->setText("Play!"); + bt->setVisible(true, Action::No | Action::Auth | Action::Yes); + bt->setEnabled(true, Action::No | Action::Auth | Action::Yes); + // here we set the behavior of PolKitResul = No + bt->setText("Can't play!", Action::No); + bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); + bt->setToolTip("If your admin wasn't annoying, you could do this", Action::No); + // here we set the behavior of PolKitResul = Auth + bt->setText("Play?", Action::Auth); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); + bt->setToolTip("Only card carrying tweakers can do this!", Action::Auth); + // here we set the behavior of PolKitResul = Yes + bt->setText("Play!", Action::Yes); + bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); + bt->setToolTip("Go ahead, play!", Action::Yes); + + menuActions->addAction(qobject_cast<Action *>(bt)); + toolBar->addAction(qobject_cast<Action *>(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton *, bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(deletePB, "org.qt.policykit.examples.delete", this); + bt->setText("Delete!"); + bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); + bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); + menuActions->addAction(qobject_cast<Action *>(bt)); + toolBar->addAction(qobject_cast<Action *>(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton *, bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(listenPB, "org.qt.policykit.examples.listen", this); + bt->setText("Listen!"); + bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); + bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); + menuActions->addAction(qobject_cast<Action *>(bt)); + toolBar->addAction(qobject_cast<Action *>(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton *, bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(setPB, "org.qt.policykit.examples.set", this); + bt->setText("Set!"); + bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); + bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); + menuActions->addAction(qobject_cast<Action *>(bt)); + toolBar->addAction(qobject_cast<Action *>(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton *, bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + bt = new ActionButton(shoutPB, "org.qt.policykit.examples.shout", this); + bt->setIcon(QPixmap(":/Icons/custom-no.png"), Action::No); + bt->setIcon(QPixmap(":/Icons/action-locked-default.png"), Action::Auth); + bt->setIcon(QPixmap(":/Icons/custom-yes.png"), Action::Yes); + bt->setText("Can't shout!", Action::No); + bt->setText("Shout?", Action::Auth); + bt->setText("Shout!", Action::Yes); + menuActions->addAction(qobject_cast<Action *>(bt)); + toolBar->addAction(qobject_cast<Action *>(bt)); + connect(bt, SIGNAL(triggered(bool)), this, SLOT(activateAction())); + connect(bt, SIGNAL(clicked(QAbstractButton *, bool)), bt, SLOT(activate())); + connect(bt, SIGNAL(authorized()), this, SLOT(actionActivated())); + + // test configChanged +} + +PkExample::~PkExample() +{ +} + +void PkExample::activateAction() +{ + // Here we cast the sender() to an Action and call activate() + // on it. + // Be careful in doing the same for ActionButton won't work as expected + // as action->activate() is calling Action::activate() and + // not ActionButton::activate which are different. + // You can cast then to ActionButton but be carefull + // an Action casted to ActionButton may crash you app + Action *action = qobject_cast<Action *>(sender()); + // calling activate with winId() makes the auth dialog + // be correct parented with your application. + action->activate(); +} + +void PkExample::actionActivated() +{ + // This slot is called whenever an action is allowed + // here you will do your dirt job by calling a helper application + // that might erase your hardrive ;) + Action *action = qobject_cast<Action *>(sender()); + + // this is our Special Action that after allowed will call the helper + if (action->is("org.qt.policykit.examples.set")) { + qDebug() << "toggled for: org.qt.policykit.examples.set"; + + QDBusMessage message; + message = QDBusMessage::createMethodCall("org.qt.policykit.examples", + "/", + "org.qt.policykit.examples", + QLatin1String("set")); + QList<QVariant> argumentList; + argumentList << qVariantFromValue(setCB->currentText()); + message.setArguments(argumentList); + // notice the systemBus here.. + QDBusMessage reply = QDBusConnection::systemBus().call(message); + if (reply.type() == QDBusMessage::ReplyMessage + && reply.arguments().size() == 1) { + // the reply can be anything, here we receive a bool + QListWidgetItem *item; + if (reply.arguments().first().toBool()) + item = new QListWidgetItem(QPixmap(":/Icons/custom-yes.png"), + QString("Implicit authorization for shout has been set to %0") + .arg(setCB->currentText())); + else + item = new QListWidgetItem(QPixmap(":/Icons/custom-no.png"), + QString("Can't change the implicit authorization. Denied.")); + actionList->addItem(item); + qDebug() << reply.arguments().first().toString(); + } else if (reply.type() == QDBusMessage::MethodCallMessage) { + qWarning() << "Message did not receive a reply (timeout by message bus)"; + } + return; + } + + // As debug message says we are pretending to be the mechanism for the + // following action, here you will actually call your DBus helper that + // will run as root (setuid is not needed, see DBus docs). + // In the helper application you will issue checkAuthorizationSync, + // passing the action id and the caller pid (which DBus will tell you). + qDebug() << "pretending to be the mechanism for action:" << action->actionId(); + + Authority::Result result; + UnixProcessSubject subject(static_cast<uint>(QCoreApplication::applicationPid())); + + result = Authority::instance()->checkAuthorizationSync(action->actionId(), subject, + Authority::AllowUserInteraction); + if (result == Authority::Yes) { + // in the helper you will do the action + qDebug() << "caller is authorized to do:" << action->actionId(); + QListWidgetItem *item = new QListWidgetItem(QPixmap(":/Icons/custom-yes.png"), action->actionId()); + actionList->addItem(item); + } else { + // OR return false to notify the caller that the action is not authorized. + qDebug() << "caller is NOT authorized to do:" << action->actionId(); + QListWidgetItem *item = new QListWidgetItem(QIcon(":/Icons/custom-no.png"), action->actionId()); + actionList->addItem(item); + } +} |