Adding browsing existing certificates feature
diff --git a/src/browsecontactdialog.cpp b/src/browsecontactdialog.cpp
new file mode 100644
index 0000000..1e3cecb
--- /dev/null
+++ b/src/browsecontactdialog.cpp
@@ -0,0 +1,315 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+
+#include "browsecontactdialog.h"
+#include "ui_browsecontactdialog.h"
+
+#ifndef Q_MOC_RUN
+#include <boost/asio.hpp>
+#include <boost/tokenizer.hpp>
+#include "logging.h"
+#include "exception.h"
+#endif
+
+using namespace std;
+using namespace ndn;
+
+INIT_LOGGER("BrowseContactDialog");
+
+// Q_DECLARE_METATYPE(ndn::security::IdentityCertificate)
+
+BrowseContactDialog::BrowseContactDialog(Ptr<ContactManager> contactManager,
+ QWidget *parent)
+ : QDialog(parent)
+ , ui(new Ui::BrowseContactDialog)
+ , m_contactManager(contactManager)
+ , m_warningDialog(new WarningDialog)
+ , m_contactListModel(new QStringListModel)
+{
+ // qRegisterMetaType<ndn::security::IdentityCertificate>("NDNIdentityCertificate");
+
+ ui->setupUi(this);
+
+ ui->ContactList->setModel(m_contactListModel);
+
+ connect(ui->ContactList->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
+ this, SLOT(updateSelection(const QItemSelection &, const QItemSelection &)));
+ connect(&*m_contactManager, SIGNAL(contactCertificateFetched(const ndn::security::IdentityCertificate &)),
+ this, SLOT(onCertificateFetched(const ndn::security::IdentityCertificate &)));
+ connect(&*m_contactManager, SIGNAL(contactCertificateFetchFailed(const ndn::Name&)),
+ this, SLOT(onCertificateFetchFailed(const ndn::Name&)));
+ connect(&*m_contactManager, SIGNAL(warning(QString)),
+ this, SLOT(onWarning(QString)));
+
+ connect(ui->AddButton, SIGNAL(clicked()),
+ this, SLOT(onAddClicked()));
+
+ connect(ui->CancelButton, SIGNAL(clicked()),
+ this, SLOT(onCancelClicked()));
+}
+
+BrowseContactDialog::~BrowseContactDialog()
+{
+ delete ui;
+}
+
+
+vector<string>
+BrowseContactDialog::getCertName()
+{
+ vector<string> result;
+ try{
+ using namespace boost::asio::ip;
+ tcp::iostream request_stream;
+ request_stream.expires_from_now(boost::posix_time::milliseconds(3000));
+ request_stream.connect("ndncert.named-data.net","80");
+ if(!request_stream)
+ {
+ m_warningDialog->setMsg("Fail to fetch certificate directory! #1");
+ m_warningDialog->show();
+ return result;
+ }
+ request_stream << "GET /cert/list/ HTTP/1.0\r\n";
+ request_stream << "Host: ndncert.named-data.net\r\n\r\n";
+ request_stream.flush();
+
+ string line1;
+ std::getline(request_stream,line1);
+ if (!request_stream)
+ {
+ m_warningDialog->setMsg("Fail to fetch certificate directory! #2");
+ m_warningDialog->show();
+ return result;
+ }
+ std::stringstream response_stream(line1);
+ std::string http_version;
+ response_stream >> http_version;
+ unsigned int status_code;
+ response_stream >> status_code;
+ std::string status_message;
+ std::getline(response_stream,status_message);
+
+ if (!response_stream||http_version.substr(0,5)!="HTTP/")
+ {
+ m_warningDialog->setMsg("Fail to fetch certificate directory! #3");
+ m_warningDialog->show();
+ return result;
+ }
+ if (status_code!=200)
+ {
+ m_warningDialog->setMsg("Fail to fetch certificate directory! #4");
+ m_warningDialog->show();
+ return result;
+ }
+ vector<string> headers;
+ std::string header;
+ while (std::getline(request_stream, header) && header != "\r")
+ headers.push_back(header);
+
+ std::stringbuf buffer;
+ std::ostream os (&buffer);
+
+ os << request_stream.rdbuf();
+
+ using boost::tokenizer;
+ using boost::escaped_list_separator;
+
+ tokenizer<escaped_list_separator<char> > certItems(buffer.str(), escaped_list_separator<char> ('\\', '\n', '"'));
+ tokenizer<escaped_list_separator<char> >::iterator it = certItems.begin();
+ try{
+ while (it != certItems.end())
+ {
+ result.push_back(*it);
+ it++;
+ }
+ }catch (exception &e){
+ m_warningDialog->setMsg("Fail to fetch certificate directory! #5");
+ m_warningDialog->show();
+ return vector<string>();
+ }
+ result.pop_back();
+
+ return result;
+ }catch(std::exception &e){
+ m_warningDialog->setMsg("Fail to fetch certificate directory! #N");
+ m_warningDialog->show();
+ return result;
+ }
+}
+
+void
+BrowseContactDialog::updateCertificateMap(bool filter)
+{
+ vector<string> certNameList = getCertName();
+ if(filter)
+ {
+ map<Name, Name> certificateMap;
+
+ vector<string>::iterator it = certNameList.begin();
+
+ for(; it != certNameList.end(); it++)
+ {
+ Name newCertName(*it);
+ Name keyName = security::IdentityCertificate::certificateNameToPublicKeyName(newCertName, true);
+ Name identity = keyName.getPrefix(keyName.size()-1);
+
+ map<Name, Name>::iterator map_it = certificateMap.find(identity);
+ if(map_it != certificateMap.end())
+ {
+ Name oldCertName = map_it->second;
+ Name oldKeyName = security::IdentityCertificate::certificateNameToPublicKeyName(oldCertName, true);
+ if(keyName > oldKeyName)
+ map_it->second = newCertName;
+ else if(keyName == oldKeyName && newCertName > oldCertName)
+ map_it->second = newCertName;
+ }
+ else
+ {
+ certificateMap.insert(pair<Name, Name>(identity, newCertName));
+ }
+ }
+ map<Name, Name>::iterator map_it = certificateMap.begin();
+ for(; map_it != certificateMap.end(); map_it++)
+ m_certificateNameList.push_back(map_it->second);
+ }
+ else
+ {
+ vector<string>::iterator it = certNameList.begin();
+
+ for(; it != certNameList.end(); it++)
+ {
+ m_certificateNameList.push_back(*it);
+ }
+ }
+}
+
+void
+BrowseContactDialog::fetchCertificate()
+{
+ vector<Name>::iterator it = m_certificateNameList.begin();
+ int count = 0;
+ for(; it != m_certificateNameList.end(); it++)
+ {
+ m_contactManager->fetchIdCertificate(*it);
+ }
+}
+
+void
+BrowseContactDialog::onCertificateFetched(const security::IdentityCertificate& identityCertificate)
+{
+ Name certName = identityCertificate.getName();
+ Name certNameNoVersion = certName.getPrefix(certName.size()-1);
+ m_certificateMap.insert(pair<Name, security::IdentityCertificate>(certNameNoVersion, identityCertificate));
+ m_profileMap.insert(pair<Name, Profile>(certNameNoVersion, Profile(identityCertificate)));
+ string name(m_profileMap[certNameNoVersion].getProfileEntry("name")->buf(), m_profileMap[certNameNoVersion].getProfileEntry("name")->size());
+ // Name contactName = m_profileMap[certNameNoVersion].getIdentityName();
+ {
+ UniqueRecLock lock(m_mutex);
+ m_contactList << QString::fromStdString(name);
+ m_contactListModel->setStringList(m_contactList);
+ m_contactNameList.push_back(certNameNoVersion);
+ }
+}
+
+void
+BrowseContactDialog::onCertificateFetchFailed(const Name& identity)
+{}
+
+void
+BrowseContactDialog::refreshList()
+{
+ {
+ UniqueRecLock lock(m_mutex);
+ m_contactList.clear();
+ m_contactNameList.clear();
+ }
+ m_certificateNameList.clear();
+ m_certificateMap.clear();
+ m_profileMap.clear();
+
+ updateCertificateMap();
+
+ fetchCertificate();
+}
+
+void
+BrowseContactDialog::updateSelection(const QItemSelection &selected,
+ const QItemSelection &deselected)
+{
+ QModelIndexList items = selected.indexes();
+ Name certName = m_contactNameList[items.first().row()];
+
+ ui->InfoTable->clear();
+ for(int i = ui->InfoTable->rowCount() - 1; i >= 0 ; i--)
+ ui->InfoTable->removeRow(i);
+
+ map<Name, Profile>::iterator it = m_profileMap.find(certName);
+ if(it != m_profileMap.end())
+ {
+ ui->InfoTable->setColumnCount(2);
+
+ QTableWidgetItem *typeHeader = new QTableWidgetItem(QString::fromUtf8("Type"));
+ ui->InfoTable->setHorizontalHeaderItem(0, typeHeader);
+ QTableWidgetItem *valueHeader = new QTableWidgetItem(QString::fromUtf8("Value"));
+ ui->InfoTable->setHorizontalHeaderItem(1, valueHeader);
+
+ Profile::const_iterator pro_it = it->second.begin();
+ int rowCount = 0;
+
+ for(; pro_it != it->second.end(); pro_it++, rowCount++)
+ {
+ ui->InfoTable->insertRow(rowCount);
+ QTableWidgetItem *type = new QTableWidgetItem(QString::fromStdString(pro_it->first));
+ ui->InfoTable->setItem(rowCount, 0, type);
+
+ string valueString(pro_it->second.buf(), pro_it->second.size());
+ QTableWidgetItem *value = new QTableWidgetItem(QString::fromStdString(valueString));
+ ui->InfoTable->setItem(rowCount, 1, value);
+ }
+ }
+}
+
+void
+BrowseContactDialog::onWarning(QString msg)
+{
+ m_warningDialog->setMsg(msg.toStdString());
+ m_warningDialog->show();
+}
+
+void
+BrowseContactDialog::onAddClicked()
+{
+ QItemSelectionModel* selectionModel = ui->ContactList->selectionModel();
+ QModelIndexList selectedList = selectionModel->selectedIndexes();
+ QModelIndexList::iterator it = selectedList.begin();
+ for(; it != selectedList.end(); it++)
+ {
+ Name certName = m_contactNameList[it->row()];
+ if(m_certificateMap.find(certName) != m_certificateMap.end() && m_profileMap.find(certName) != m_profileMap.end())
+ m_contactManager->addContact(m_certificateMap[certName], m_profileMap[certName]);
+ else
+ {
+ m_warningDialog->setMsg("Not enough information to add contact!");
+ m_warningDialog->show();
+ }
+ }
+ emit newContactAdded();
+ this->close();
+}
+
+void
+BrowseContactDialog::onCancelClicked()
+{ this->close(); }
+
+#if WAF
+#include "browsecontactdialog.moc"
+#include "browsecontactdialog.cpp.moc"
+#endif
diff --git a/src/browsecontactdialog.h b/src/browsecontactdialog.h
new file mode 100644
index 0000000..f74a14f
--- /dev/null
+++ b/src/browsecontactdialog.h
@@ -0,0 +1,106 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+
+#ifndef BROWSECONTACTDIALOG_H
+#define BROWSECONTACTDIALOG_H
+
+#include <QDialog>
+#include <QStringListModel>
+#include "warningdialog.h"
+
+
+#ifndef Q_MOC_RUN
+#include <ndn.cxx/security/certificate/identity-certificate.h>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include "profile.h"
+#include "contact-manager.h"
+#endif
+
+namespace Ui {
+class BrowseContactDialog;
+}
+
+class BrowseContactDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit BrowseContactDialog(ndn::Ptr<ContactManager> contactManager,
+ QWidget *parent = 0);
+
+ ~BrowseContactDialog();
+
+protected:
+ typedef boost::recursive_mutex RecLock;
+ typedef boost::unique_lock<RecLock> UniqueRecLock;
+
+private:
+ std::vector<std::string>
+ getCertName();
+
+ void
+ updateCertificateMap(bool filter = false);
+
+ void
+ updateCertificateFetchingStatus(int count);
+
+ void
+ fetchCertificate();
+
+private slots:
+ void
+ updateSelection(const QItemSelection &selected,
+ const QItemSelection &deselected);
+
+ void
+ onCertificateFetched(const ndn::security::IdentityCertificate& identityCertificate);
+
+ void
+ onCertificateFetchFailed(const ndn::Name& identity);
+
+ void
+ onWarning(QString msg);
+
+ void
+ onAddClicked();
+
+ void
+ onCancelClicked();
+
+public slots:
+ void
+ refreshList();
+
+signals:
+ void
+ newContactAdded();
+
+private:
+ Ui::BrowseContactDialog *ui;
+
+ ndn::Ptr<ContactManager> m_contactManager;
+
+ WarningDialog* m_warningDialog;
+ QStringListModel* m_contactListModel;
+
+ QStringList m_contactList;
+ std::vector<ndn::Name> m_contactNameList;
+ std::vector<ndn::Name> m_certificateNameList;
+ std::map<ndn::Name, ndn::security::IdentityCertificate> m_certificateMap;
+ std::map<ndn::Name, Profile> m_profileMap;
+
+ RecLock m_mutex;
+
+
+};
+
+#endif // BROWSECONTACTDIALOG_H
diff --git a/src/browsecontactdialog.ui b/src/browsecontactdialog.ui
new file mode 100644
index 0000000..28958b9
--- /dev/null
+++ b/src/browsecontactdialog.ui
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BrowseContactDialog</class>
+ <widget class="QDialog" name="BrowseContactDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>BrowseContacts</string>
+ </property>
+ <widget class="QWidget" name="">
+ <property name="geometry">
+ <rect>
+ <x>12</x>
+ <y>10</y>
+ <width>581</width>
+ <height>471</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="20,1">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="2,3">
+ <item>
+ <widget class="QListView" name="ContactList">
+ <property name="contextMenuPolicy">
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTableWidget" name="InfoTable">
+ <attribute name="horizontalHeaderStretchLastSection">
+ <bool>true</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1">
+ <item>
+ <widget class="QPushButton" name="CancelButton">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="AddButton">
+ <property name="text">
+ <string>Add </string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/contact-manager.cpp b/src/contact-manager.cpp
index 651ab82..371a317 100644
--- a/src/contact-manager.cpp
+++ b/src/contact-manager.cpp
@@ -192,6 +192,7 @@
Ptr<Interest> interestPtr = Ptr<Interest>(new Interest(interestName));
interestPtr->setChildSelector(Interest::CHILD_RIGHT);
+ interestPtr->setInterestLifetime(1);
Ptr<Closure> closure = Ptr<Closure> (new Closure(boost::bind(&ContactManager::onKeyVerified,
this,
_1,
@@ -210,6 +211,31 @@
}
void
+ContactManager::fetchIdCertificate(const ndn::Name& certName)
+{
+ Name interestName = certName;
+
+ Ptr<Interest> interestPtr = Ptr<Interest>(new Interest(interestName));
+ interestPtr->setChildSelector(Interest::CHILD_RIGHT);
+ interestPtr->setInterestLifetime(1);
+ Ptr<Closure> closure = Ptr<Closure> (new Closure(boost::bind(&ContactManager::onIdCertificateVerified,
+ this,
+ _1,
+ certName),
+ boost::bind(&ContactManager::onIdCertificateTimeout,
+ this,
+ _1,
+ _2,
+ certName,
+ 0),
+ boost::bind(&ContactManager::onIdCertificateUnverified,
+ this,
+ _1,
+ certName)));
+ m_wrapper->sendInterest(interestPtr, closure);
+}
+
+void
ContactManager::onDnsCollectEndorseVerified(Ptr<Data> data, const Name& identity)
{ emit collectEndorseFetched (*data); }
@@ -254,6 +280,21 @@
{ emit contactKeyFetchFailed(identity); }
void
+ContactManager::onIdCertificateVerified(Ptr<Data> data, const Name& identity)
+{
+ IdentityCertificate identityCertificate(*data);
+ emit contactCertificateFetched(identityCertificate);
+}
+
+void
+ContactManager::onIdCertificateUnverified(Ptr<Data> data, const Name& identity)
+{ emit contactCertificateFetchFailed (identity); }
+
+void
+ContactManager::onIdCertificateTimeout(Ptr<Closure> closure, Ptr<Interest> interest, const Name& identity, int retry)
+{ emit contactCertificateFetchFailed (identity); }
+
+void
ContactManager::updateProfileData(const Name& identity)
{
// Get current profile;
@@ -547,6 +588,37 @@
m_wrapper->putToNdnd(*dnsBlob);
}
+void
+ContactManager::addContact(const IdentityCertificate& identityCertificate, const Profile& profile)
+{
+ Ptr<ProfileData> profileData = Ptr<ProfileData>(new ProfileData(profile));
+
+ Ptr<IdentityManager> identityManager = m_keychain->getIdentityManager();
+ Name certificateName = identityManager->getDefaultCertificateNameByIdentity (m_defaultIdentity);
+ identityManager->signByCertificate(*profileData, certificateName);
+
+ Ptr<EndorseCertificate> endorseCertificate = NULL;
+ try{
+ endorseCertificate = Ptr<EndorseCertificate>(new EndorseCertificate(identityCertificate, profileData));
+ }catch(exception& e){
+ _LOG_ERROR("Exception: " << e.what());
+ return;
+ }
+
+ identityManager->signByCertificate(*endorseCertificate, certificateName);
+
+ ContactItem contactItem(*endorseCertificate);
+
+ try{
+ m_contactStorage->addContact(contactItem);
+ }catch(exception& e){
+ emit warning(e.what());
+ _LOG_ERROR("Exception: " << e.what());
+ return;
+ }
+}
+
+
#if WAF
#include "contact-manager.moc"
diff --git a/src/contact-manager.h b/src/contact-manager.h
index b8498cc..26a2a63 100644
--- a/src/contact-manager.h
+++ b/src/contact-manager.h
@@ -43,6 +43,9 @@
fetchCollectEndorse(const ndn::Name& identity);
void
+ fetchIdCertificate(const ndn::Name& certName);
+
+ void
updateProfileData(const ndn::Name& identity);
void
@@ -73,6 +76,13 @@
void
publishEndorsedDataInDns(const ndn::Name& identity);
+ inline void
+ setDefaultIdentity(const ndn::Name& identity)
+ { m_defaultIdentity = identity; }
+
+ void
+ addContact(const ndn::security::IdentityCertificate& idCert, const Profile& profile);
+
private:
void
setKeychain();
@@ -116,6 +126,14 @@
void
onDnsCollectEndorseUnverified(ndn::Ptr<ndn::Data> data, const ndn::Name& identity);
+ void
+ onIdCertificateVerified(ndn::Ptr<ndn::Data> data, const ndn::Name& identity);
+
+ void
+ onIdCertificateUnverified(ndn::Ptr<ndn::Data> data, const ndn::Name& identity);
+
+ void
+ onIdCertificateTimeout(ndn::Ptr<ndn::Closure> closure, ndn::Ptr<ndn::Interest> interest, const ndn::Name& identity, int retry);
signals:
@@ -132,11 +150,20 @@
contactKeyFetchFailed(const ndn::Name& identity);
void
+ contactCertificateFetched(const ndn::security::IdentityCertificate& identityCertificate);
+
+ void
+ contactCertificateFetchFailed(const ndn::Name& identity);
+
+ void
collectEndorseFetched(const ndn::Data& data);
void
collectEndorseFetchFailed(const ndn::Name& identity);
+ void
+ warning(QString msg);
+
private slots:
@@ -145,6 +172,7 @@
ndn::Ptr<DnsStorage> m_dnsStorage;
ndn::Ptr<ndn::security::Keychain> m_keychain;
ndn::Ptr<ndn::Wrapper> m_wrapper;
+ ndn::Name m_defaultIdentity;
};
#endif
diff --git a/src/contact-storage.cpp b/src/contact-storage.cpp
index b3ee977..595dd68 100644
--- a/src/contact-storage.cpp
+++ b/src/contact-storage.cpp
@@ -306,6 +306,35 @@
return profile;
}
+
+void
+ContactStorage::removeContact(const Name& contactNameSpace)
+{
+ Ptr<ContactItem> contact = getContact(contactNameSpace);
+ string identity = contactNameSpace.toUri();
+
+ if(contact == NULL)
+ return;
+
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db, "DELETE FROM Contact WHERE contact_namespace=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size (), SQLITE_TRANSIENT);
+ int res = sqlite3_step (stmt);
+ sqlite3_finalize (stmt);
+
+ sqlite3_prepare_v2 (m_db, "DELETE FROM ContactProfile WHERE profile_identity=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size (), SQLITE_TRANSIENT);
+ res = sqlite3_step (stmt);
+ sqlite3_finalize (stmt);
+
+ if(contact->isIntroducer())
+ {
+ sqlite3_prepare_v2 (m_db, "DELETE FROM TrustScope WHERE contact_namespace=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size (), SQLITE_TRANSIENT);
+ res = sqlite3_step (stmt);
+ sqlite3_finalize (stmt);
+ }
+}
void
ContactStorage::addContact(const ContactItem& contact)
diff --git a/src/contact-storage.h b/src/contact-storage.h
index ee5f032..4887dbf 100644
--- a/src/contact-storage.h
+++ b/src/contact-storage.h
@@ -34,6 +34,9 @@
getSelfProfile(const ndn::Name& identity);
void
+ removeContact(const ndn::Name& identity);
+
+ void
addContact(const ContactItem& contactItem);
void
diff --git a/src/contactpanel.cpp b/src/contactpanel.cpp
index 4d281d6..56db0a7 100644
--- a/src/contactpanel.cpp
+++ b/src/contactpanel.cpp
@@ -64,6 +64,7 @@
setKeychain();
m_defaultIdentity = m_keychain->getDefaultIdentity();
+ m_contactManager->setDefaultIdentity(m_defaultIdentity);
m_nickName = m_defaultIdentity.get(-1).toUri();
m_settingDialog->setIdentity(m_defaultIdentity.toUri(), m_nickName);
@@ -71,6 +72,7 @@
m_profileEditor->setCurrentIdentity(m_defaultIdentity);
m_addContactPanel = new AddContactPanel(contactManager);
+ m_browseContactDialog = new BrowseContactDialog(contactManager);
m_setAliasDialog = new SetAliasDialog(contactManager);
ui->setupUi(this);
@@ -95,13 +97,21 @@
connect(ui->EditProfileButton, SIGNAL(clicked()),
this, SLOT(openProfileEditor()));
+ // connect(ui->AddContactButton, SIGNAL(clicked()),
+ // this, SLOT(openAddContactPanel()));
connect(ui->AddContactButton, SIGNAL(clicked()),
- this, SLOT(openAddContactPanel()));
+ this, SLOT(openBrowseContactDialog()));
+
+ connect(this, SIGNAL(refreshCertDirectory()),
+ m_browseContactDialog, SLOT(refreshList()));
+
+ connect(ui->DeleteContactButton, SIGNAL(clicked()),
+ this, SLOT(removeContactButton()));
connect(ui->settingButton, SIGNAL(clicked()),
this, SLOT(openSettingDialog()));
- connect(m_addContactPanel, SIGNAL(newContactAdded()),
+ connect(m_browseContactDialog, SIGNAL(newContactAdded()),
this, SLOT(refreshContactList()));
connect(m_setAliasDialog, SIGNAL(aliasChanged()),
this, SLOT(refreshContactList()));
@@ -144,6 +154,7 @@
delete m_profileEditor;
delete m_addContactPanel;
+ delete m_browseContactDialog;
delete m_setAliasDialog;
delete m_trustScopeModel;
@@ -499,6 +510,7 @@
m_profileEditor->setCurrentIdentity(m_defaultIdentity);
m_nickName = nickName.toStdString();
m_handler->clearInterestFilter(m_inviteListenPrefix);
+ m_contactManager->setDefaultIdentity(m_defaultIdentity);
setInvitationListener();
collectEndorsement();
}
@@ -512,6 +524,36 @@
{ m_addContactPanel->show(); }
void
+ContactPanel::openBrowseContactDialog()
+{
+ m_browseContactDialog->show();
+ emit refreshCertDirectory();
+}
+
+void
+ContactPanel::removeContactButton()
+{
+ QItemSelectionModel* selectionModel = ui->ContactList->selectionModel();
+ QModelIndexList selectedList = selectionModel->selectedIndexes();
+ QModelIndexList::iterator it = selectedList.begin();
+ for(; it != selectedList.end(); it++)
+ {
+ string alias = m_contactListModel->data(*it, Qt::DisplayRole).toString().toStdString();
+ vector<Ptr<ContactItem> >::iterator contactIt = m_contactList.begin();
+ for(; contactIt != m_contactList.end(); contactIt++)
+ {
+ if((*contactIt)->getAlias() == alias)
+ {
+ m_contactManager->getContactStorage()->removeContact((*contactIt)->getNameSpace());
+ m_contactList.erase(contactIt);
+ break;
+ }
+ }
+ }
+ refreshContactList();
+}
+
+void
ContactPanel::openInvitationDialog()
{ m_invitationDialog->show(); }
diff --git a/src/contactpanel.h b/src/contactpanel.h
index f6e794c..55f9daf 100644
--- a/src/contactpanel.h
+++ b/src/contactpanel.h
@@ -24,6 +24,7 @@
#include "settingdialog.h"
#include "chatdialog.h"
#include "endorse-combobox-delegate.h"
+#include "browsecontactdialog.h"
#ifndef Q_MOC_RUN
#include "contact-manager.h"
@@ -112,6 +113,9 @@
void
newInvitationReady();
+ void
+ refreshCertDirectory();
+
private slots:
void
updateSelection(const QItemSelection &selected,
@@ -126,9 +130,15 @@
void
openAddContactPanel();
+
+ void
+ openBrowseContactDialog();
void
openSetAliasDialog();
+
+ void
+ removeContactButton();
void
openStartChatDialog();
@@ -187,6 +197,7 @@
QStringListModel* m_contactListModel;
ProfileEditor* m_profileEditor;
AddContactPanel* m_addContactPanel;
+ BrowseContactDialog* m_browseContactDialog;
SetAliasDialog* m_setAliasDialog;
StartChatDialog* m_startChatDialog;
InvitationDialog* m_invitationDialog;
diff --git a/src/contactpanel.ui b/src/contactpanel.ui
index b79ef5d..2f31a1a 100644
--- a/src/contactpanel.ui
+++ b/src/contactpanel.ui
@@ -22,16 +22,16 @@
<property name="windowTitle">
<string>ChronoChat Contacts</string>
</property>
- <widget class="QWidget" name="layoutWidget">
+ <widget class="QWidget" name="">
<property name="geometry">
<rect>
- <x>11</x>
- <y>11</y>
+ <x>12</x>
+ <y>12</y>
<width>581</width>
- <height>461</height>
+ <height>471</height>
</rect>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
+ <layout class="QVBoxLayout" name="verticalLayout_2" stretch="30,1">
<item>
<layout class="QHBoxLayout" name="ContactPanelLayout" stretch="3,7">
<property name="spacing">
@@ -279,19 +279,33 @@
</layout>
</item>
<item>
- <layout class="QHBoxLayout" name="ButtonsLayout" stretch="1,1,1">
- <property name="spacing">
- <number>50</number>
- </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_6" stretch="1,1,1">
<item>
- <widget class="QPushButton" name="AddContactButton">
- <property name="text">
- <string>Add Contact</string>
+ <layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,1">
+ <property name="spacing">
+ <number>-1</number>
</property>
- <property name="autoDefault">
- <bool>false</bool>
- </property>
- </widget>
+ <item>
+ <widget class="QPushButton" name="AddContactButton">
+ <property name="text">
+ <string>Add </string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="DeleteContactButton">
+ <property name="text">
+ <string>Delete</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item>
<widget class="QPushButton" name="settingButton">
diff --git a/src/profile.cpp b/src/profile.cpp
index 5261207..24372a4 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -26,9 +26,10 @@
static string advisor("2.5.4.80");
static string emailOid("1.2.840.113549.1.9.1");
-Profile::Profile(security::IdentityCertificate& identityCertificate)
+Profile::Profile(const security::IdentityCertificate& oldIdentityCertificate)
{
using namespace ndn::security;
+ security::IdentityCertificate identityCertificate(oldIdentityCertificate);
Name keyName = identityCertificate.getPublicKeyName();
m_identityName = keyName.getPrefix(keyName.size()-1);
diff --git a/src/profile.h b/src/profile.h
index b020408..7a65553 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -26,7 +26,7 @@
public:
Profile() {}
- Profile(ndn::security::IdentityCertificate& identityCertificate);
+ Profile(const ndn::security::IdentityCertificate& identityCertificate);
Profile(const ndn::Name& identityName);