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-agent-tde/src/AuthDialog.cpp

350 lines
9.8 KiB

/* This file is part of the TDE project
Copyright (C) 2007-2008 Gökçen Eraslan <gokcen@pardus.org.tr>
Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
Copyright (C) 2008 Daniel Nicoletti <dantti85-pk@yahoo.com.br>
Copyright (C) 2008-2010 Dario Freddi <drf@kde.org>
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 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 "AuthDialog.h"
#include "AuthDialogWidget.h"
#include <tqlabel.h>
#include <tqprocess.h>
#include <tqpainter.h>
#include <kcombobox.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klineedit.h>
#include "kuniqueapplication.h"
#include <kurllabel.h>
#include <kuser.h>
#include <tdelocale.h>
#include <PolkitTQt/Authority>
#include <PolkitTQt/Details>
using namespace PolkitTQt;
AuthDialog::AuthDialog(const TQString &actionId, const TQString &message,
const TQString &iconName, const PolkitTQt::Details &details,
const Identity::List &identities) :
KDialogBase(0, 0, true, TQString::null, Ok|Cancel|Details, Ok),
m_authWidget(new AuthDialogWidget(this))
{
setMainWidget(m_authWidget);
if (message.isEmpty())
{
kdWarning() << "Could not get action message for action." << endl;
m_authWidget->lblHeader->hide();
}
else
{
kdDebug() << "Message of action: " << message << endl;
m_authWidget->lblHeader->setText("<h3>" + message + "</h3>");
setCaption(message);
m_message = message;
}
// loads the standard key icon
TQPixmap icon = TDEGlobal::iconLoader()->loadIcon("password", TDEIcon::NoGroup,
TDEIcon::SizeHuge, TDEIcon::DefaultState);
// create a painter to paint the action icon over the key icon
TQPainter painter(&icon);
const int iconSize = icon.size().width();
int overlaySize = 32;
const TQPixmap pixmap = TDEGlobal::iconLoader()->loadIcon(iconName, TDEIcon::NoGroup,
overlaySize, TDEIcon::DefaultState, 0, true);
if (!pixmap.isNull())
{
// bottom right corner
TQPoint startPoint = TQPoint(iconSize - overlaySize - 2, iconSize - overlaySize - 2);
painter.drawPixmap(startPoint, pixmap);
}
setIcon(icon);
m_authWidget->lblPixmap->setPixmap(icon);
// find action description for actionId
for (const ActionDescription &desc : Authority::instance()->enumerateActionsSync())
{
if (actionId == desc.actionId())
{
m_actionDescription = desc;
kdDebug() << "Action description has been found" << endl;
break;
}
}
AuthDetails *detailsDialog = new AuthDetails(details, m_actionDescription, m_appname, this);
setDetailsWidget(detailsDialog);
m_authWidget->userCB->hide();
m_authWidget->lePassword->setFocus();
m_authWidget->errorMessageKTW->hide();
// If there is more than 1 identity we will show the combobox for user selection
if (identities.size() > 1)
{
connect(m_authWidget->userCB, TQ_SIGNAL(activated(int)),
this, TQ_SLOT(on_userCB_currentIndexChanged(int)));
createUserCB(identities);
}
else
{
m_authWidget->userCB->insertItem("");
m_userData.append(identities[0].toString());
m_authWidget->userCB->setCurrentItem(0);
}
on_userCB_currentIndexChanged(-1);
}
AuthDialog::~AuthDialog()
{
}
void AuthDialog::accept()
{
// Do nothing, do not close the dialog. This is needed so that the dialog stays
m_authWidget->lePassword->setEnabled(false);
return;
}
void AuthDialog::setRequest(const TQString &request, bool requiresAdmin)
{
kdDebug() << request << endl;
Identity identity = adminUserSelected();
if (request.startsWith("password:", false))
{
if (!identity.isValid())
{
m_authWidget->lblPassword->setText(i18n("Password for root:"));
}
else
{
if (!m_authWidget->userCB->isVisible())
{
TQString username = identity.toString().remove("unix-user:");
m_authWidget->lblPassword->setText(i18n("Password for %1:").arg(username));
}
else
{
m_authWidget->lblPassword->setText(i18n("Password:"));
}
}
}
else if (request.startsWith("password or swipe finger:"), false)
{
if (!identity.isValid())
{
m_authWidget->lblPassword->setText(i18n("Password or swipe finger for root:"));
}
else
{
if (!m_authWidget->userCB->isVisible())
{
TQString username = identity.toString().remove("unix-user:");
m_authWidget->lblPassword->setText(i18n("Password or swipe finger for %1:").arg(username));
}
else
{
m_authWidget->lblPassword->setText(i18n("Password or swipe finger:"));
}
}
}
else
{
m_authWidget->lblPassword->setText(request);
}
}
void AuthDialog::setOptions()
{
m_authWidget->lblContent->setText(i18n("An application is attempting to perform an action "
"that requires privileges. Authentication is required to perform this action."));
}
void AuthDialog::createUserCB(const Identity::List &identities)
{
/* if we've already built the list of admin users once, then avoid
* doing it again.. (this is mainly used when the user entered the
* wrong password and the dialog is recycled)
*/
if (identities.count() && (m_authWidget->userCB->count() - 1) != identities.count())
{
// Clears the combobox in the case some user be added
m_authWidget->userCB->clear();
m_userData.clear();
// Adds a Dummy user
m_authWidget->userCB->insertItem(i18n("Select User"));
m_userData.append(TQString::null);
// For each user
int index = 1; // Start at 1 because of the "Select User" entry
int currentUserIndex = -1;
const KUser currentUser;
for (const Identity &identity : identities)
{
// First check to see if the user is valid
kdDebug() << "User: " << identity.toString() << endl;
const KUser user(identity.toString().remove("unix-user:"));
if (!user.isValid())
{
kdWarning() << "User invalid: " << user.loginName() << endl;
continue;
}
// Display user full Name if available
TQString display;
if (!user.fullName().isEmpty())
{
display = user.fullName() + " (" + user.loginName() + ")";
}
else
{
display = user.loginName();
}
m_authWidget->userCB->insertItem(display);
m_userData.append(identity.toString());
if (user == currentUser)
{
currentUserIndex = index;
}
++index;
}
// Show the widget and set focus
if (currentUserIndex != -1)
{
m_authWidget->userCB->setCurrentItem(currentUserIndex);
}
m_authWidget->userCB->show();
}
}
Identity AuthDialog::adminUserSelected() const
{
if (m_authWidget->userCB->currentItem() == -1)
{
return Identity();
}
TQString id = m_userData[m_authWidget->userCB->currentItem()];
if (id.isEmpty())
{
return Identity();
}
return Identity::fromString(id);
}
void AuthDialog::on_userCB_currentIndexChanged(int /*index*/)
{
Identity identity = adminUserSelected();
// identity is now valid when "Select user" is selected
if (!identity.isValid())
{
m_authWidget->lePassword->setEnabled(false);
m_authWidget->lblPassword->setText(i18n("Password:"));
m_authWidget->lblPassword->setEnabled(false);
enableButtonOK(false);
}
else
{
m_authWidget->lePassword->setEnabled(true);
m_authWidget->lblPassword->setEnabled(true);
enableButtonOK(true);
// We need this to restart the auth with the new user
emit adminUserSelected(identity);
// give password label focus
m_authWidget->lePassword->setFocus();
}
}
TQString AuthDialog::password() const
{
return m_authWidget->lePassword->text();
}
void AuthDialog::authenticationFailure()
{
TQFont bold = font();
bold.setBold(true);
m_authWidget->errorMessageKTW->setText(i18n("Authentication failure, please try again."));
m_authWidget->errorMessageKTW->setFont(bold);
m_authWidget->errorMessageKTW->show();
m_authWidget->lePassword->setEnabled(true);
m_authWidget->lePassword->clear();
m_authWidget->lePassword->setFocus();
}
AuthDetails::AuthDetails(const Details &details, const ActionDescription &actionDescription,
const TQString &appname, TQWidget *parent) : AuthDetailsWidget(parent)
{
app_label->setText(appname);
for (const TQString &key : details.keys())
{
int row = AuthDetailsWidgetLayout->numRows() + 1;
TQLabel *keyLabel = new TQLabel(this);
keyLabel->setText(key);
AuthDetailsWidgetLayout->addWidget(keyLabel, row, 0);
TQLabel *valueLabel = new TQLabel(this);
valueLabel->setText(details.lookup(key));
AuthDetailsWidgetLayout->addWidget(valueLabel, row, 1);
}
action_label->setText(actionDescription.description());
TQString vendor = actionDescription.vendorName();
TQString vendorUrl = actionDescription.vendorUrl();
if (!vendor.isEmpty())
{
vendorUL->setText(vendor);
vendorUL->setTipText(vendorUrl);
vendorUL->setURL(vendorUrl);
}
else if (!vendorUrl.isEmpty())
{
vendorUL->setText(vendorUrl);
vendorUL->setTipText(vendorUrl);
vendorUL->setURL(vendorUrl);
}
else
{
vendorL->hide();
vendorUL->hide();
}
connect(vendorUL, TQ_SIGNAL(leftClickedURL(const TQString&)),
TQ_SLOT(openUrl(const TQString&)));
}
void AuthDetails::openUrl(const TQString &url)
{
kapp->invokeBrowser(url);
}
#include "AuthDialog.moc"