You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
polkit-tqt/examples/PkExample.cpp

241 lines
12 KiB

// 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);
}
}