Commit a2fa844b authored by El Mehdi Fekari's avatar El Mehdi Fekari Committed by Nicolas Arnaud-Cormos

Qnx: Manage user debug token list

N.B: This patch implements the basic actions to manage user
debug tokens, and doesn't provide yet all actions and advanced
features available in Momentics IDE regarding the debug token support.

Change-Id: I912bdbcc3348b8ddd4335a7995bec900bd04bf62
Reviewed-by: Nicolas Arnaud-Cormos's avatarNicolas Arnaud-Cormos <nicolas@kdab.com>
parent c5febb44
/**************************************************************************
**
** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
**
** Contact: BlackBerry (qt@blackberry.com)
** Contact: KDAB (info@kdab.com)
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "blackberrydebugtokenpinsdialog.h"
#include "ui_blackberrydebugtokenpinsdialog.h"
#include "blackberrydebugtokenreader.h"
#include "blackberryconfigurationmanager.h"
#include "blackberrysigningutils.h"
#include <QStandardItemModel>
#include <QMessageBox>
#include <QLineEdit>
namespace Qnx {
namespace Internal {
BlackBerryDebugTokenPinsDialog::BlackBerryDebugTokenPinsDialog(const QString &debugToken, QWidget *parent) :
QDialog(parent),
ui(new Ui_BlackBerryDebugTokenPinsDialog),
m_model(new QStandardItemModel(this)),
m_debugTokenPath(debugToken),
m_updated(false)
{
ui->setupUi(this);
setWindowTitle(tr("Debug Token PINs"));
ui->pins->setModel(m_model);
ui->pathLabel->setText(debugToken);
BlackBerryDebugTokenReader reader(debugToken);
if (reader.isValid()) {
QStringList pins = reader.pins().split(QLatin1Char(','));
foreach (const QString &pin, pins)
m_model->appendRow(new QStandardItem(pin));
}
m_okButton = ui->buttonBox->button(QDialogButtonBox::Ok);
ui->editButton->setEnabled(false);
ui->removeButton->setEnabled(false);
connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addPin()));
connect(ui->editButton, SIGNAL(clicked()), this, SLOT(editPin()));
connect(ui->removeButton, SIGNAL(clicked()), this, SLOT(removePin()));
connect(m_okButton, SIGNAL(clicked()), this, SLOT(emitUpdatedPins()));
connect(ui->pins, SIGNAL(pressed(QModelIndex)), this, SLOT(updateUi(QModelIndex)));
}
BlackBerryDebugTokenPinsDialog::~BlackBerryDebugTokenPinsDialog()
{
delete ui;
}
void BlackBerryDebugTokenPinsDialog::addPin()
{
bool ok;
const QString pin = promptPIN(QString(), &ok);
if (ok && !pin.isEmpty()) {
m_model->appendRow(new QStandardItem(pin));
m_updated = true;
}
}
void BlackBerryDebugTokenPinsDialog::editPin()
{
const QModelIndex index = ui->pins->currentIndex();
if (!index.isValid())
return;
bool ok;
QString pin = m_model->item(index.row(), 0)->text();
QString newPin = promptPIN(pin, &ok);
if (ok && newPin != pin) {
m_model->item(index.row(), 0)->setText(newPin);
m_updated = true;
}
}
void BlackBerryDebugTokenPinsDialog::removePin()
{
const QModelIndex index = ui->pins->currentIndex();
if (!index.isValid())
return;
const QString pin = m_model->item(index.row(), 0)->text();
const int result = QMessageBox::question(this, tr("Confirmation"),
tr("Are you sure you want to remove PIN: %1")
.arg(pin), QMessageBox::Yes | QMessageBox::No);
if (result == QMessageBox::Yes) {
m_model->removeRow(index.row());
m_updated = true;
}
}
void BlackBerryDebugTokenPinsDialog::updateUi(const QModelIndex& index)
{
ui->editButton->setEnabled(index.isValid());
ui->removeButton->setEnabled(index.isValid());
}
void BlackBerryDebugTokenPinsDialog::emitUpdatedPins()
{
if (!m_updated)
return;
QStringList pins;
for (int i = 0; i < m_model->rowCount(); i++)
pins << m_model->item(i)->text();
emit pinsUpdated(pins);
}
QString BlackBerryDebugTokenPinsDialog::promptPIN(const QString &value, bool *ok)
{
QDialog dialog(this);
QVBoxLayout *layout = new QVBoxLayout;
QLineEdit *lineEdit = new QLineEdit;
QDialogButtonBox *buttonBox = new QDialogButtonBox;
lineEdit->setMaxLength(8);
lineEdit->setText(value);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
connect(buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
layout->addWidget(lineEdit);
layout->addWidget(buttonBox);
dialog.setWindowTitle(tr("Debug Token PIN"));
dialog.setLayout(layout);
const bool rejected = dialog.exec() == QDialog::Rejected;
if (ok)
*ok = !rejected;
if (rejected)
return QString();
return lineEdit->text();
}
} // Internal
} // Qnx
/**************************************************************************
**
** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
**
** Contact: BlackBerry (qt@blackberry.com)
** Contact: KDAB (info@kdab.com)
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef BLACKBERRYDEBUGTOKENSDIALOG_H
#define BLACKBERRYDEBUGTOKENSDIALOG_H
#include <QDialog>
QT_BEGIN_NAMESPACE
class QStandardItemModel;
QT_END_NAMESPACE
namespace Qnx {
namespace Internal {
class Ui_BlackBerryDebugTokenPinsDialog;
class BlackBerryDebugTokenPinsDialog : public QDialog
{
Q_OBJECT
public:
explicit BlackBerryDebugTokenPinsDialog(const QString &debugToken, QWidget *parent = 0);
~BlackBerryDebugTokenPinsDialog();
private slots:
void addPin();
void editPin();
void removePin();
void updateUi(const QModelIndex& index);
void emitUpdatedPins();
QString promptPIN(const QString& defaultValue, bool *ok = 0);
signals:
void pinsUpdated(const QStringList &pins);
private:
Ui_BlackBerryDebugTokenPinsDialog *ui;
QStandardItemModel *m_model;
QPushButton *m_okButton;
QString m_debugTokenPath;
bool m_updated;
};
} // Internal
} // Qnx
#endif // BLACKBERRYDEBUGTOKENSDIALOG_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Qnx::Internal::BlackBerryDebugTokenPinsDialog</class>
<widget class="QDialog" name="Qnx::Internal::BlackBerryDebugTokenPinsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>432</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Debug Token: &lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="pathLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListView" name="pins">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="addButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="editButton">
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Qnx::Internal::BlackBerryDebugTokenPinsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Qnx::Internal::BlackBerryDebugTokenPinsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
......@@ -31,6 +31,8 @@
#include "blackberrydebugtokenreader.h"
#include <QStringList>
#ifdef QNX_ZIP_FILE_SUPPORT
#include <private/qzipreader_p.h>
#endif
......@@ -43,6 +45,8 @@ const char MANIFEST_FILENAME[] = "META-INF/MANIFEST.MF";
const char MANIFEST_AUTHOR_KEY[] = "Package-Author: ";
const char MANIFEST_AUTHOR_ID_KEY[] = "Package-Author-Id: ";
const char MANIFEST_EXPIRY[] = "Debug-Token-Expiry-Date: ";
const char MANIFEST_PINS[] = "Debug-Token-Device-Id: ";
}
BlackBerryDebugTokenReader::BlackBerryDebugTokenReader(const QString &filePath)
......@@ -83,6 +87,24 @@ QString BlackBerryDebugTokenReader::authorId() const
return manifestValue(MANIFEST_AUTHOR_ID_KEY);
}
QString BlackBerryDebugTokenReader::expiry() const
{
return manifestValue(MANIFEST_EXPIRY);
}
QString BlackBerryDebugTokenReader::pins() const
{
const QString value = manifestValue(MANIFEST_PINS);
QStringList pins = value.split(QLatin1Char(','));
QStringList pinsHexa;
foreach (const QString &pin, pins) {
QString hexa;
pinsHexa << hexa.setNum(pin.toUInt(), 16);
}
return pinsHexa.join(QLatin1Char(','));
}
bool BlackBerryDebugTokenReader::isSupported()
{
#ifdef QNX_ZIP_FILE_SUPPORT
......
......@@ -51,6 +51,8 @@ public:
QString author() const;
QString authorId() const;
QString expiry() const;
QString pins() const;
static bool isSupported();
......
......@@ -56,8 +56,8 @@ BlackBerryDebugTokenRequester::BlackBerryDebugTokenRequester(QObject *parent) :
}
void BlackBerryDebugTokenRequester::requestDebugToken(const QString &path,
const QString &cskPassword, const QString &keyStore,
const QString &keyStorePassword, const QString &devicePin)
const QString &cskPassword, const QString &keyStore,
const QString &keyStorePassword, const QString &devicePin)
{
QStringList arguments;
......@@ -66,10 +66,14 @@ void BlackBerryDebugTokenRequester::requestDebugToken(const QString &path,
<< QLatin1String("-storepass")
<< keyStorePassword
<< QLatin1String("-cskpass")
<< cskPassword
<< QLatin1String("-devicepin")
<< devicePin
<< path;
<< cskPassword;
// devicePin may contain multiple pins
QStringList pins = devicePin.split(QLatin1Char(','));
foreach (const QString &pin, pins)
arguments << QLatin1String("-devicepin") << pin;
arguments << path;
start(arguments);
......
......@@ -35,6 +35,7 @@
#include "ui_blackberrydeviceconfigurationwidget.h"
#include "blackberryconfiguration.h"
#include "blackberrydeviceconnectionmanager.h"
#include "blackberrysigningutils.h"
#include "qnxconstants.h"
#include "qnxutils.h"
......@@ -57,20 +58,22 @@ BlackBerryDeviceConfigurationWidget::BlackBerryDeviceConfigurationWidget(const I
IDeviceWidget(device, parent),
ui(new Ui::BlackBerryDeviceConfigurationWidget),
progressDialog(new QProgressDialog(this)),
uploader(new BlackBerryDebugTokenUploader(this))
uploader(new BlackBerryDebugTokenUploader(this)),
m_utils(BlackBerrySigningUtils::instance())
{
ui->setupUi(this);
ui->connectionLog->setFont(TextEditor::TextEditorSettings::fontSettings().font());
populateDebugTokenCombo(deviceConfiguration()->debugToken());
connect(ui->hostLineEdit, SIGNAL(editingFinished()), this, SLOT(hostNameEditingFinished()));
connect(ui->pwdLineEdit, SIGNAL(editingFinished()), this, SLOT(passwordEditingFinished()));
connect(ui->keyFileLineEdit, SIGNAL(editingFinished()), this, SLOT(keyFileEditingFinished()));
connect(ui->keyFileLineEdit, SIGNAL(browsingFinished()), this, SLOT(keyFileEditingFinished()));
connect(ui->showPasswordCheckBox, SIGNAL(toggled(bool)), this, SLOT(showPassword(bool)));
connect(ui->debugToken, SIGNAL(changed(QString)), this, SLOT(updateUploadButton()));
connect(ui->debugToken, SIGNAL(editingFinished()), this, SLOT(debugTokenEditingFinished()));
connect(ui->debugToken, SIGNAL(browsingFinished()), this, SLOT(debugTokenEditingFinished()));
connect(ui->debugToken, SIGNAL(currentTextChanged(QString)), this, SLOT(updateUploadButton()));
connect(ui->debugToken, SIGNAL(currentTextChanged(QString)), this, SLOT(debugTokenEditingFinished()));
connect(uploader, SIGNAL(finished(int)), this, SLOT(uploadFinished(int)));
connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(connectionOutput(Core::Id,QString)),
......@@ -81,16 +84,14 @@ BlackBerryDeviceConfigurationWidget::BlackBerryDeviceConfigurationWidget(const I
connect(ui->requestButton, SIGNAL(clicked()), this, SLOT(requestDebugToken()));
connect(ui->uploadButton, SIGNAL(clicked()), this, SLOT(uploadDebugToken()));
QString debugTokenBrowsePath = QnxUtils::dataDirPath();
if (!QFileInfo(debugTokenBrowsePath).exists())
debugTokenBrowsePath = QDir::homePath();
ui->debugToken->setInitialBrowsePathBackup(debugTokenBrowsePath);
connect(&m_utils, SIGNAL(debugTokenListChanged()), this, SLOT(updateDebugTokenCombo()));
initGui();
}
BlackBerryDeviceConfigurationWidget::~BlackBerryDeviceConfigurationWidget()
{
m_utils.saveDebugTokens();
delete ui;
}
......@@ -123,7 +124,7 @@ void BlackBerryDeviceConfigurationWidget::showPassword(bool showClearText)
void BlackBerryDeviceConfigurationWidget::debugTokenEditingFinished()
{
deviceConfiguration()->setDebugToken(ui->debugToken->path());
deviceConfiguration()->setDebugToken(ui->debugToken->currentText());
}
void BlackBerryDeviceConfigurationWidget::requestDebugToken()
......@@ -138,27 +139,29 @@ void BlackBerryDeviceConfigurationWidget::requestDebugToken()
if (result != QDialog::Accepted)
return;
ui->debugToken->setPath(dialog.debugToken());
m_utils.addDebugToken(dialog.debugToken());
populateDebugTokenCombo(dialog.debugToken());
debugTokenEditingFinished();
}
void BlackBerryDeviceConfigurationWidget::uploadDebugToken()
{
// check the debug token path before even laucnhing the uploader process
if (!QFileInfo(ui->debugToken->fileName().toString()).exists()) {
if (!QFileInfo(ui->debugToken->currentText()).exists()) {
QMessageBox::critical(this, tr("Error"), tr("Invalid debug token path."));
return;
}
progressDialog->show();
uploader->uploadDebugToken(ui->debugToken->path(),
uploader->uploadDebugToken(ui->debugToken->currentText(),
ui->hostLineEdit->text(), ui->pwdLineEdit->text());
}
void BlackBerryDeviceConfigurationWidget::updateUploadButton()
{
ui->uploadButton->setEnabled(!ui->debugToken->path().isEmpty());
const QString path = ui->debugToken->currentText();
ui->uploadButton->setEnabled(QFileInfo(path).exists());
}
void BlackBerryDeviceConfigurationWidget::uploadFinished(int status)
......@@ -213,6 +216,20 @@ void BlackBerryDeviceConfigurationWidget::clearConnectionLog(Core::Id deviceId)
ui->connectionLog->clear();
}
void BlackBerryDeviceConfigurationWidget::populateDebugTokenCombo(const QString& current)
{
ui->debugToken->clear();
ui->debugToken->addItems(m_utils.debugTokens());
const int index = ui->debugToken->findText(current);
if (index != -1)
ui->debugToken->setCurrentIndex(index);
}
void BlackBerryDeviceConfigurationWidget::updateDebugTokenCombo()
{
populateDebugTokenCombo(ui->debugToken->currentText());
}
void BlackBerryDeviceConfigurationWidget::updateDeviceFromUi()
{
hostNameEditingFinished();
......@@ -223,9 +240,6 @@ void BlackBerryDeviceConfigurationWidget::updateDeviceFromUi()
void BlackBerryDeviceConfigurationWidget::initGui()
{
ui->debugToken->setExpectedKind(Utils::PathChooser::File);
ui->debugToken->setPromptDialogFilter(QLatin1String("*.bar"));
ui->keyFileLineEdit->setExpectedKind(Utils::PathChooser::File);
ui->keyFileLineEdit->lineEdit()->setMinimumWidth(0);
......@@ -237,8 +251,6 @@ void BlackBerryDeviceConfigurationWidget::initGui()
ui->pwdLineEdit->setText(sshParams.password);
ui->keyFileLineEdit->setPath(sshParams.privateKeyFile);
ui->showPasswordCheckBox->setChecked(false);
ui->debugToken->setPath(deviceConfiguration()->debugToken());
if (deviceConfiguration()->machineType() == IDevice::Emulator) {
ui->debugToken->setEnabled(false);
ui->requestButton->setEnabled(false);
......
......@@ -45,6 +45,7 @@ namespace Qnx {
namespace Internal {
class BlackBerryDebugTokenUploader;
class BlackBerrySigningUtils;
namespace Ui {
class BlackBerryDeviceConfigurationWidget;
......@@ -71,6 +72,8 @@ private slots:
void uploadFinished(int status);
void appendConnectionLog(Core::Id deviceId, const QString &line);
void clearConnectionLog(Core::Id deviceId);
void populateDebugTokenCombo(const QString &current);
void updateDebugTokenCombo();
private:
void updateDeviceFromUi();
......@@ -84,6 +87,7 @@ private:
QProgressDialog *progressDialog;
BlackBerryDebugTokenUploader *uploader;
BlackBerrySigningUtils &m_utils;
};
......
......@@ -14,16 +14,7 @@
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
......@@ -76,14 +67,8 @@
<property name="text">
<string>Debug token:</string>
</property>
<property name="buddy">
<cstring>debugToken</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Utils::PathChooser" name="debugToken" native="true"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="keyLabel">
<property name="text">
......@@ -145,8 +130,14 @@
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="debugToken">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
<zorder>debugToken</zorder>
<zorder>keyFileLineEdit</zorder>
<zorder>hostNameLabel</zorder>
<zorder>hostLineEdit</zorder>
......@@ -155,6 +146,7 @@
<zorder>debugTokenLabel</zorder>
<zorder>label</zorder>
<zorder>connectionLog</zorder>
<zorder>debugToken</zorder>
</widget>
<customwidgets>
<customwidget>
......