blob: 1fc62aa9ad544a5e768c11214e87d07a0d09c1af [file] [log] [blame]
Yingdi Yu9e0dc292013-10-10 11:39:45 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Yingdi Yu
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
9 */
10
Yingdi Yudef90612013-10-09 22:34:42 -070011#include "contactpanel.h"
12#include "ui_contactpanel.h"
13
Yingdi Yu01a942b2013-10-10 15:00:58 -070014
15#include <QStringList>
16#include <QItemSelectionModel>
17#include <QModelIndex>
Yingdi Yu0a6b6c52013-10-15 17:54:00 -070018#include <QDir>
Yingdi Yu8dacdf22013-11-05 23:06:43 -080019#include <QtSql/QSqlRecord>
20#include <QtSql/QSqlField>
21#include <QtSql/QSqlError>
Yingdi Yu01a942b2013-10-10 15:00:58 -070022
Yingdi Yu0a6b6c52013-10-15 17:54:00 -070023#ifndef Q_MOC_RUN
Yingdi Yu53eb8a72013-10-23 11:50:51 -070024#include <ndn.cxx/security/keychain.h>
Yingdi Yu53eb8a72013-10-23 11:50:51 -070025#include <ndn.cxx/security/identity/identity-manager.h>
Yingdi Yu100267f2013-10-21 15:01:40 -070026#include <ndn.cxx/common.h>
Yingdi Yu0a6b6c52013-10-15 17:54:00 -070027#include <boost/filesystem.hpp>
Yingdi Yu53eb8a72013-10-23 11:50:51 -070028#include <boost/random/random_device.hpp>
29#include <boost/random/uniform_int_distribution.hpp>
Yingdi Yu42f66462013-10-31 17:38:22 -070030#include "panel-policy-manager.h"
Yingdi Yu0a6b6c52013-10-15 17:54:00 -070031#include "logging.h"
32#include "exception.h"
33#endif
34
35namespace fs = boost::filesystem;
36using namespace ndn;
Yingdi Yu53eb8a72013-10-23 11:50:51 -070037
Yingdi Yu79c25a22013-10-21 13:38:38 -070038using namespace std;
Yingdi Yu0a6b6c52013-10-15 17:54:00 -070039
40INIT_LOGGER("ContactPanel");
41
Yingdi Yu53eb8a72013-10-23 11:50:51 -070042Q_DECLARE_METATYPE(ndn::security::IdentityCertificate)
Yingdi Yu42f66462013-10-31 17:38:22 -070043Q_DECLARE_METATYPE(ChronosInvitation)
Yingdi Yu53eb8a72013-10-23 11:50:51 -070044
Yingdi Yub29f78c2013-11-09 20:12:31 -080045ContactPanel::ContactPanel(QWidget *parent)
Yingdi Yua50c3252013-11-03 15:05:26 -080046 : QDialog(parent)
47 , ui(new Ui::ContactPanel)
Yingdi Yub29f78c2013-11-09 20:12:31 -080048 , m_warningDialog(new WarningDialog)
Yingdi Yua50c3252013-11-03 15:05:26 -080049 , m_contactListModel(new QStringListModel)
50 , m_startChatDialog(new StartChatDialog)
51 , m_invitationDialog(new InvitationDialog)
52 , m_settingDialog(new SettingDialog)
Yingdi Yudef90612013-10-09 22:34:42 -070053{
Yingdi Yu53eb8a72013-10-23 11:50:51 -070054 qRegisterMetaType<ndn::security::IdentityCertificate>("IdentityCertificate");
Yingdi Yu42f66462013-10-31 17:38:22 -070055 qRegisterMetaType<ChronosInvitation>("ChronosInvitation");
Yingdi Yu0a6b6c52013-10-15 17:54:00 -070056
Yingdi Yu42372442013-11-06 18:43:31 -080057 createAction();
58
Yingdi Yub29f78c2013-11-09 20:12:31 -080059 m_contactManager = Ptr<ContactManager>::Create();
Yingdi Yub35b8652013-11-07 11:32:40 -080060
Yingdi Yub29f78c2013-11-09 20:12:31 -080061 connect(&*m_contactManager, SIGNAL(noNdnConnection(const QString&)),
62 this, SLOT(showError(const QString&)));
63
64 m_contactManager->setWrapper();
65
Yingdi Yub35b8652013-11-07 11:32:40 -080066 openDB();
Yingdi Yu42372442013-11-06 18:43:31 -080067
Yingdi Yuc4d08d22013-10-23 23:07:29 -070068 refreshContactList();
Yingdi Yu01a942b2013-10-10 15:00:58 -070069
Yingdi Yuc4d08d22013-10-23 23:07:29 -070070 setKeychain();
Yingdi Yu42372442013-11-06 18:43:31 -080071
72 m_defaultIdentity = m_keychain->getDefaultIdentity();
Yingdi Yu908f8412013-11-09 00:03:26 -080073 m_contactManager->setDefaultIdentity(m_defaultIdentity);
Yingdi Yu42372442013-11-06 18:43:31 -080074 m_nickName = m_defaultIdentity.get(-1).toUri();
75 m_settingDialog->setIdentity(m_defaultIdentity.toUri(), m_nickName);
Yingdi Yu71ec9652013-11-09 22:18:26 -080076 Name defaultCertName = m_keychain->getIdentityManager()->getDefaultCertificateNameByIdentity(m_defaultIdentity);
77 if(defaultCertName.size() == 0)
78 showError(QString::fromStdString("Corresponding certificate is missing!\nHave you installed the certificate?"));
79
Yingdi Yu42372442013-11-06 18:43:31 -080080
Yingdi Yub35b8652013-11-07 11:32:40 -080081 m_profileEditor = new ProfileEditor(m_contactManager);
82 m_profileEditor->setCurrentIdentity(m_defaultIdentity);
83
Yingdi Yub29f78c2013-11-09 20:12:31 -080084 m_addContactPanel = new AddContactPanel(m_contactManager);
85 m_browseContactDialog = new BrowseContactDialog(m_contactManager);
86 m_setAliasDialog = new SetAliasDialog(m_contactManager);
Yingdi Yub35b8652013-11-07 11:32:40 -080087
88 ui->setupUi(this);
89
Yingdi Yub29f78c2013-11-09 20:12:31 -080090 try{
91 m_handler = Ptr<Wrapper>(new Wrapper(m_keychain));
92 }catch(ndn::Error::ndnOperation& e){
93 showError(QString::fromStdString("Cannot conect to ndnd!\n Have you started your ndnd?"));
94 }
95
Yingdi Yu42372442013-11-06 18:43:31 -080096
Yingdi Yuc4d08d22013-10-23 23:07:29 -070097 setLocalPrefix();
Yingdi Yu53eb8a72013-10-23 11:50:51 -070098
Yingdi Yuc4d08d22013-10-23 23:07:29 -070099 setInvitationListener();
Yingdi Yu42372442013-11-06 18:43:31 -0800100
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800101 collectEndorsement();
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700102
103 ui->ContactList->setModel(m_contactListModel);
104
Yingdi Yuc26af3c2013-10-17 17:03:46 -0700105
Yingdi Yu42372442013-11-06 18:43:31 -0800106 connect(ui->ContactList->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700107 this, SLOT(updateSelection(const QItemSelection &, const QItemSelection &)));
Yingdi Yu01a942b2013-10-10 15:00:58 -0700108
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700109 connect(ui->ContactList, SIGNAL(customContextMenuRequested(const QPoint&)),
110 this, SLOT(showContextMenu(const QPoint&)));
Yingdi Yud59b5932013-10-16 13:16:49 -0700111
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700112 connect(ui->EditProfileButton, SIGNAL(clicked()),
113 this, SLOT(openProfileEditor()));
Yingdi Yud59b5932013-10-16 13:16:49 -0700114
Yingdi Yu71ec9652013-11-09 22:18:26 -0800115 connect(m_profileEditor, SIGNAL(noKeyOrCert(const QString&)),
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800116 this, SLOT(showWarning(const QString&)));
Yingdi Yu71ec9652013-11-09 22:18:26 -0800117
Yingdi Yu908f8412013-11-09 00:03:26 -0800118 // connect(ui->AddContactButton, SIGNAL(clicked()),
119 // this, SLOT(openAddContactPanel()));
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700120 connect(ui->AddContactButton, SIGNAL(clicked()),
Yingdi Yu908f8412013-11-09 00:03:26 -0800121 this, SLOT(openBrowseContactDialog()));
122
123 connect(this, SIGNAL(refreshCertDirectory()),
124 m_browseContactDialog, SLOT(refreshList()));
125
126 connect(ui->DeleteContactButton, SIGNAL(clicked()),
127 this, SLOT(removeContactButton()));
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700128
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700129 connect(ui->settingButton, SIGNAL(clicked()),
130 this, SLOT(openSettingDialog()));
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700131
Yingdi Yu908f8412013-11-09 00:03:26 -0800132 connect(m_browseContactDialog, SIGNAL(newContactAdded()),
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700133 this, SLOT(refreshContactList()));
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700134 connect(m_setAliasDialog, SIGNAL(aliasChanged()),
135 this, SLOT(refreshContactList()));
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700136
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700137 connect(m_startChatDialog, SIGNAL(chatroomConfirmed(const QString&, const QString&, bool)),
138 this, SLOT(startChatroom(const QString&, const QString&, bool)));
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700139
Yingdi Yu42f66462013-10-31 17:38:22 -0700140 connect(m_invitationDialog, SIGNAL(invitationAccepted(const ChronosInvitation&, const ndn::security::IdentityCertificate&)),
141 this, SLOT(acceptInvitation(const ChronosInvitation&, const ndn::security::IdentityCertificate&)));
142 connect(m_invitationDialog, SIGNAL(invitationRejected(const ChronosInvitation&)),
143 this, SLOT(rejectInvitation(const ChronosInvitation&)));
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700144
Yingdi Yu42372442013-11-06 18:43:31 -0800145 connect(m_settingDialog, SIGNAL(identitySet(const QString&, const QString&)),
146 this, SLOT(updateDefaultIdentity(const QString&, const QString&)));
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700147
148 connect(this, SIGNAL(newInvitationReady()),
149 this, SLOT(openInvitationDialog()));
Yingdi Yu100267f2013-10-21 15:01:40 -0700150
Yingdi Yua50c3252013-11-03 15:05:26 -0800151 connect(ui->isIntroducer, SIGNAL(stateChanged(int)),
152 this, SLOT(isIntroducerChanged(int)));
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800153
154 connect(ui->addScope, SIGNAL(clicked()),
155 this, SLOT(addScopeClicked()));
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800156 connect(ui->deleteScope, SIGNAL(clicked()),
157 this, SLOT(deleteScopeClicked()));
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800158 connect(ui->saveButton, SIGNAL(clicked()),
159 this, SLOT(saveScopeClicked()));
160
161 connect(ui->endorseButton, SIGNAL(clicked()),
162 this, SLOT(endorseButtonClicked()));
Yingdi Yudef90612013-10-09 22:34:42 -0700163}
164
165ContactPanel::~ContactPanel()
166{
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700167 delete ui;
168 delete m_contactListModel;
Yingdi Yu42372442013-11-06 18:43:31 -0800169 delete m_startChatDialog;
170 delete m_invitationDialog;
171 delete m_settingDialog;
172
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700173 delete m_profileEditor;
174 delete m_addContactPanel;
Yingdi Yu908f8412013-11-09 00:03:26 -0800175 delete m_browseContactDialog;
Yingdi Yu42372442013-11-06 18:43:31 -0800176 delete m_setAliasDialog;
177
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800178 delete m_trustScopeModel;
179 delete m_endorseDataModel;
Yingdi Yu42372442013-11-06 18:43:31 -0800180 delete m_endorseComboBoxDelegate;
Yingdi Yu79c25a22013-10-21 13:38:38 -0700181
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700182 delete m_menuInvite;
Yingdi Yu42372442013-11-06 18:43:31 -0800183 delete m_menuAlias;
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700184
185 map<Name, ChatDialog*>::iterator it = m_chatDialogs.begin();
186 for(; it != m_chatDialogs.end(); it++)
187 delete it->second;
Yingdi Yudef90612013-10-09 22:34:42 -0700188}
Yingdi Yu9e0dc292013-10-10 11:39:45 -0700189
Yingdi Yu01a942b2013-10-10 15:00:58 -0700190void
Yingdi Yu42372442013-11-06 18:43:31 -0800191ContactPanel::createAction()
192{
193 m_menuInvite = new QAction("&Chat", this);
194 m_menuAlias = new QAction("&Set Alias", this);
195}
196
197void
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700198ContactPanel::openDB()
199{
200 QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
201 QString path = (QDir::home().path());
202 path.append(QDir::separator()).append(".chronos").append(QDir::separator()).append("chronos.db");
203 db.setDatabaseName(path);
204 bool ok = db.open();
Yingdi Yu42372442013-11-06 18:43:31 -0800205 _LOG_DEBUG("DB opened: " << std::boolalpha << ok );
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800206
207 m_trustScopeModel = new QSqlTableModel;
208 m_endorseDataModel = new QSqlTableModel;
209 m_endorseComboBoxDelegate = new EndorseComboBoxDelegate;
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700210}
211
212void
213ContactPanel::setKeychain()
214{
Yingdi Yued8cfc42013-11-01 17:37:51 -0700215 m_panelPolicyManager = Ptr<PanelPolicyManager>::Create();
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700216
217 vector<Ptr<ContactItem> >::const_iterator it = m_contactList.begin();
218 for(; it != m_contactList.end(); it++)
Yingdi Yub35b8652013-11-07 11:32:40 -0800219 {
220 m_panelPolicyManager->addTrustAnchor((*it)->getSelfEndorseCertificate());
221 }
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700222
Yingdi Yued8cfc42013-11-01 17:37:51 -0700223 m_keychain = Ptr<security::Keychain>(new security::Keychain(Ptr<security::IdentityManager>::Create(),
224 m_panelPolicyManager,
225 NULL));
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700226}
227
228void
229ContactPanel::setLocalPrefix()
230{
231 Ptr<Interest> interest = Ptr<Interest>(new Interest(Name("/local/ndn/prefix")));
232 interest->setChildSelector(Interest::CHILD_RIGHT);
233
234 Ptr<Closure> closure = Ptr<Closure>(new Closure(boost::bind(&ContactPanel::onLocalPrefixVerified,
235 this,
236 _1),
237 boost::bind(&ContactPanel::onLocalPrefixTimeout,
238 this,
239 _1,
240 _2),
241 boost::bind(&ContactPanel::onLocalPrefixVerified,
242 this,
243 _1)));
244
245 m_handler->sendInterest(interest, closure);
246}
247
248void
249ContactPanel::onLocalPrefixVerified(Ptr<Data> data)
250{
251 string originPrefix(data->content().buf(), data->content().size());
252 string prefix = QString::fromStdString (originPrefix).trimmed ().toUtf8().constData();
253 string randomSuffix = getRandomString();
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700254 m_localPrefix = Name(prefix);
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800255
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700256}
257
258void
259ContactPanel::onLocalPrefixTimeout(Ptr<Closure> closure, Ptr<Interest> interest)
Yingdi Yu42f66462013-10-31 17:38:22 -0700260{
261 string randomSuffix = getRandomString();
262 m_localPrefix = Name("/private/local");
Yingdi Yu42f66462013-10-31 17:38:22 -0700263}
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700264
265void
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700266ContactPanel::setInvitationListener()
267{
Yingdi Yu42372442013-11-06 18:43:31 -0800268 m_inviteListenPrefix = Name("/ndn/broadcast/chronos/invitation");
269 m_inviteListenPrefix.append(m_defaultIdentity);
270 _LOG_DEBUG("Listening for invitation on prefix: " << m_inviteListenPrefix.toUri());
271 m_handler->setInterestFilter (m_inviteListenPrefix,
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700272 boost::bind(&ContactPanel::onInvitation,
273 this,
274 _1));
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700275}
276
277void
278ContactPanel::onInvitation(Ptr<Interest> interest)
279{
Yingdi Yu42372442013-11-06 18:43:31 -0800280 _LOG_DEBUG("Receive invitation!" << interest->getName().toUri());
Yingdi Yub35b8652013-11-07 11:32:40 -0800281
282 Ptr<ChronosInvitation> invitation = NULL;
283 try{
284 invitation = Ptr<ChronosInvitation>(new ChronosInvitation(interest->getName()));
285 }catch(exception& e){
286 _LOG_ERROR("Exception: " << e.what());
287 return;
288 }
289
Yingdi Yu42372442013-11-06 18:43:31 -0800290 Name chatroomName("/ndn/broadcast/chronos");
291 chatroomName.append(invitation->getChatroom());
292 map<Name, ChatDialog*>::iterator it = m_chatDialogs.find(chatroomName);
293 if(it != m_chatDialogs.end())
294 {
Yingdi Yub35b8652013-11-07 11:32:40 -0800295 _LOG_ERROR("Exisiting chatroom!");
Yingdi Yu42372442013-11-06 18:43:31 -0800296 return;
297 }
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700298
Yingdi Yued8cfc42013-11-01 17:37:51 -0700299 Ptr<Interest> newInterest = Ptr<Interest>(new Interest(invitation->getInviterCertificateName()));
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700300 Ptr<Closure> closure = Ptr<Closure>(new Closure(boost::bind(&ContactPanel::onInvitationCertVerified,
301 this,
302 _1,
Yingdi Yued8cfc42013-11-01 17:37:51 -0700303 invitation),
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700304 boost::bind(&ContactPanel::onTimeout,
305 this,
306 _1,
307 _2),
308 boost::bind(&ContactPanel::onUnverified,
309 this,
310 _1)));
311 m_handler->sendInterest(newInterest, closure);
312}
313
314void
Yingdi Yu42372442013-11-06 18:43:31 -0800315ContactPanel::onInvitationCertVerified(Ptr<Data> data,
316 Ptr<ChronosInvitation> invitation)
317{
318 using namespace ndn::security;
319 Ptr<IdentityCertificate> certificate = Ptr<IdentityCertificate>(new IdentityCertificate(*data));
320
321 if(PolicyManager::verifySignature(invitation->getSignedBlob(), invitation->getSignatureBits(), certificate->getPublicKeyInfo()))
322 {
323 Name keyName = certificate->getPublicKeyName();
324 Name inviterNameSpace = keyName.getPrefix(keyName.size() - 1);
325 popChatInvitation(invitation, inviterNameSpace, certificate);
326 }
327}
328
329void
330ContactPanel::onUnverified(Ptr<Data> data)
331{}
332
333void
334ContactPanel::onTimeout(Ptr<Closure> closure, Ptr<Interest> interest)
335{}
336
337void
338ContactPanel::popChatInvitation(Ptr<ChronosInvitation> invitation,
339 const Name& inviterNameSpace,
340 Ptr<security::IdentityCertificate> certificate)
341{
342 string alias;
343 vector<Ptr<ContactItem> >::iterator it = m_contactList.begin();
344 for(; it != m_contactList.end(); it++)
345 if((*it)->getNameSpace() == inviterNameSpace)
346 alias = (*it)->getAlias();
347
348 if(it != m_contactList.end())
349 return;
350
351 m_invitationDialog->setInvitation(alias, invitation, certificate);
352 emit newInvitationReady();
353}
354
355void
356ContactPanel::collectEndorsement()
357{
358 m_collectStatus = Ptr<vector<bool> >::Create();
359 m_collectStatus->assign(m_contactList.size(), false);
360
361 vector<Ptr<ContactItem> >::iterator it = m_contactList.begin();
362 int count = 0;
363 for(; it != m_contactList.end(); it++, count++)
364 {
365 Name interestName = (*it)->getNameSpace();
366 interestName.append("DNS").append(m_defaultIdentity).append("ENDORSEE");
367 Ptr<Interest> interest = Ptr<Interest>(new Interest(interestName));
368 interest->setChildSelector(Interest::CHILD_RIGHT);
369 interest->setInterestLifetime(1);
370
371 Ptr<Closure> closure = Ptr<Closure>(new Closure(boost::bind(&ContactPanel::onDnsEndorseeVerified,
372 this,
373 _1,
374 count),
375 boost::bind(&ContactPanel::onDnsEndorseeTimeout,
376 this,
377 _1,
378 _2,
379 count),
380 boost::bind(&ContactPanel::onDnsEndorseeUnverified,
381 this,
382 _1,
383 count)));
384
385 m_handler->sendInterest(interest, closure);
386 }
387}
388
389void
390ContactPanel::onDnsEndorseeVerified(Ptr<Data> data, int count)
391{
392 Ptr<Blob> contentBlob = Ptr<Blob>(new Blob(data->content().buf(), data->content().size()));
393 Ptr<Data> endorseData = Data::decodeFromWire(contentBlob);
394 EndorseCertificate endorseCertificate(*endorseData);
395
396 m_contactManager->getContactStorage()->updateCollectEndorse(endorseCertificate);
397
398 updateCollectStatus(count);
399}
400
401void
402ContactPanel::onDnsEndorseeTimeout(Ptr<Closure> closure, Ptr<Interest> interest, int count)
403{ updateCollectStatus(count); }
404
405void
406ContactPanel::onDnsEndorseeUnverified(Ptr<Data> data, int count)
407{ updateCollectStatus(count); }
408
409void
410ContactPanel::updateCollectStatus(int count)
411{
412 m_collectStatus->at(count) = true;
413 vector<bool>::const_iterator it = m_collectStatus->begin();
414 for(; it != m_collectStatus->end(); it++)
415 if(*it == false)
416 return;
417
418 m_contactManager->publishEndorsedDataInDns(m_defaultIdentity);
419}
420
421static std::string chars("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789");
422
423string
424ContactPanel::getRandomString()
425{
426 string randStr;
427 boost::random::random_device rng;
428 boost::random::uniform_int_distribution<> index_dist(0, chars.size() - 1);
429 for (int i = 0; i < 10; i ++)
430 {
431 randStr += chars[index_dist(rng)];
432 }
433 return randStr;
434}
435
436void
Yingdi Yub29f78c2013-11-09 20:12:31 -0800437ContactPanel::showError(const QString& msg){
438 QMessageBox::critical(this, tr("Chronos"), msg, QMessageBox::Ok);
439 exit(1);
440}
441
442void
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800443ContactPanel::showWarning(const QString& msg){
444 QMessageBox::information(this, tr("Chronos"), msg);
445}
446
447void
Yingdi Yu01a942b2013-10-10 15:00:58 -0700448ContactPanel::updateSelection(const QItemSelection &selected,
449 const QItemSelection &deselected)
450{
451 QModelIndexList items = selected.indexes();
452 QString text = m_contactListModel->data(items.first(), Qt::DisplayRole).toString();
Yingdi Yu42372442013-11-06 18:43:31 -0800453 string alias = text.toStdString();
Yingdi Yu79c25a22013-10-21 13:38:38 -0700454
Yingdi Yu79c25a22013-10-21 13:38:38 -0700455 int i = 0;
456 for(; i < m_contactList.size(); i++)
457 {
458 if(alias == m_contactList[i]->getAlias())
459 break;
460 }
461
Yingdi Yua50c3252013-11-03 15:05:26 -0800462 m_currentSelectedContact = m_contactList[i];
Yingdi Yua0594092013-11-06 22:07:38 -0800463 ui->NameData->setText(QString::fromStdString(m_currentSelectedContact->getName()));
464 ui->NameSpaceData->setText(QString::fromStdString(m_currentSelectedContact->getNameSpace().toUri()));
465 ui->InstitutionData->setText(QString::fromStdString(m_currentSelectedContact->getInstitution()));
Yingdi Yu100267f2013-10-21 15:01:40 -0700466
Yingdi Yua50c3252013-11-03 15:05:26 -0800467 if(m_currentSelectedContact->isIntroducer())
468 {
469 ui->isIntroducer->setChecked(true);
470 ui->addScope->setEnabled(true);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800471 ui->deleteScope->setEnabled(true);
472 ui->trustScopeList->setEnabled(true);
473
474 string filter("contact_namespace = '");
475 filter.append(m_currentSelectedContact->getNameSpace().toUri()).append("'");
476
477 m_trustScopeModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
478 m_trustScopeModel->setTable("TrustScope");
479 m_trustScopeModel->setFilter(filter.c_str());
480 m_trustScopeModel->select();
481 m_trustScopeModel->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
482 m_trustScopeModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Contact"));
483 m_trustScopeModel->setHeaderData(2, Qt::Horizontal, QObject::tr("TrustScope"));
484
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800485 ui->trustScopeList->setModel(m_trustScopeModel);
486 ui->trustScopeList->setColumnHidden(0, true);
487 ui->trustScopeList->setColumnHidden(1, true);
488 ui->trustScopeList->show();
Yingdi Yua50c3252013-11-03 15:05:26 -0800489 }
490 else
491 {
492 ui->isIntroducer->setChecked(false);
493 ui->addScope->setEnabled(false);
494 ui->deleteScope->setEnabled(false);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800495
496 string filter("contact_namespace = '");
497 filter.append(m_currentSelectedContact->getNameSpace().toUri()).append("'");
498
499 m_trustScopeModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
500 m_trustScopeModel->setTable("TrustScope");
501 m_trustScopeModel->setFilter(filter.c_str());
502 m_trustScopeModel->select();
503 m_trustScopeModel->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
504 m_trustScopeModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Contact"));
505 m_trustScopeModel->setHeaderData(2, Qt::Horizontal, QObject::tr("TrustScope"));
506
507 ui->trustScopeList->setModel(m_trustScopeModel);
508 ui->trustScopeList->setColumnHidden(0, true);
509 ui->trustScopeList->setColumnHidden(1, true);
510 ui->trustScopeList->show();
511
512 ui->trustScopeList->setEnabled(false);
Yingdi Yua50c3252013-11-03 15:05:26 -0800513 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800514
515 string filter("profile_identity = '");
516 filter.append(m_currentSelectedContact->getNameSpace().toUri()).append("'");
517
518 m_endorseDataModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
519 m_endorseDataModel->setTable("ContactProfile");
520 m_endorseDataModel->setFilter(filter.c_str());
521 m_endorseDataModel->select();
522
523 m_endorseDataModel->setHeaderData(0, Qt::Horizontal, QObject::tr("Identity"));
524 m_endorseDataModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Type"));
525 m_endorseDataModel->setHeaderData(2, Qt::Horizontal, QObject::tr("Value"));
526 m_endorseDataModel->setHeaderData(3, Qt::Horizontal, QObject::tr("Endorse"));
527
528 ui->endorseList->setModel(m_endorseDataModel);
529 ui->endorseList->setColumnHidden(0, true);
530 ui->endorseList->resizeColumnToContents(1);
531 ui->endorseList->resizeColumnToContents(2);
532 ui->endorseList->setItemDelegateForColumn(3, m_endorseComboBoxDelegate);
533 ui->endorseList->show();
Yingdi Yu01a942b2013-10-10 15:00:58 -0700534}
Yingdi Yu9e0dc292013-10-10 11:39:45 -0700535
Yingdi Yu0a6b6c52013-10-15 17:54:00 -0700536void
Yingdi Yu42372442013-11-06 18:43:31 -0800537ContactPanel::updateDefaultIdentity(const QString& identity, const QString& nickName)
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700538{
Yingdi Yu71ec9652013-11-09 22:18:26 -0800539 // _LOG_DEBUG(identity.toStdString());
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800540 Name defaultIdentity = Name(identity.toStdString());
541 Name defaultKeyName = m_keychain->getIdentityManager()->getPublicStorage()->getDefaultKeyNameForIdentity(defaultIdentity);
Yingdi Yu71ec9652013-11-09 22:18:26 -0800542 if(defaultKeyName.size() == 0)
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800543 {
544 showWarning(QString::fromStdString("Corresponding key is missing!\nHave you created the key?"));
545 return;
546 }
Yingdi Yu71ec9652013-11-09 22:18:26 -0800547 Name defaultCertName = m_keychain->getIdentityManager()->getPublicStorage()->getDefaultCertificateNameForKey(defaultKeyName);
548 if(defaultCertName.size() == 0)
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800549 {
550 showWarning(QString::fromStdString("Corresponding certificate is missing!\nHave you installed the certificate?"));
551 return;
552 }
553 m_defaultIdentity = defaultIdentity;
Yingdi Yub35b8652013-11-07 11:32:40 -0800554 m_profileEditor->setCurrentIdentity(m_defaultIdentity);
Yingdi Yu42372442013-11-06 18:43:31 -0800555 m_nickName = nickName.toStdString();
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700556 m_handler->clearInterestFilter(m_inviteListenPrefix);
Yingdi Yu908f8412013-11-09 00:03:26 -0800557 m_contactManager->setDefaultIdentity(m_defaultIdentity);
Yingdi Yu42372442013-11-06 18:43:31 -0800558 setInvitationListener();
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800559 collectEndorsement();
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700560}
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700561
562void
Yingdi Yu0a6b6c52013-10-15 17:54:00 -0700563ContactPanel::openProfileEditor()
Yingdi Yud59b5932013-10-16 13:16:49 -0700564{ m_profileEditor->show(); }
Yingdi Yu0a6b6c52013-10-15 17:54:00 -0700565
Yingdi Yud59b5932013-10-16 13:16:49 -0700566void
567ContactPanel::openAddContactPanel()
568{ m_addContactPanel->show(); }
Yingdi Yu0a6b6c52013-10-15 17:54:00 -0700569
Yingdi Yu79c25a22013-10-21 13:38:38 -0700570void
Yingdi Yu908f8412013-11-09 00:03:26 -0800571ContactPanel::openBrowseContactDialog()
572{
573 m_browseContactDialog->show();
574 emit refreshCertDirectory();
575}
576
577void
578ContactPanel::removeContactButton()
579{
580 QItemSelectionModel* selectionModel = ui->ContactList->selectionModel();
581 QModelIndexList selectedList = selectionModel->selectedIndexes();
582 QModelIndexList::iterator it = selectedList.begin();
583 for(; it != selectedList.end(); it++)
584 {
585 string alias = m_contactListModel->data(*it, Qt::DisplayRole).toString().toStdString();
586 vector<Ptr<ContactItem> >::iterator contactIt = m_contactList.begin();
587 for(; contactIt != m_contactList.end(); contactIt++)
588 {
589 if((*contactIt)->getAlias() == alias)
590 {
591 m_contactManager->getContactStorage()->removeContact((*contactIt)->getNameSpace());
592 m_contactList.erase(contactIt);
593 break;
594 }
595 }
596 }
597 refreshContactList();
598}
599
600void
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700601ContactPanel::openInvitationDialog()
602{ m_invitationDialog->show(); }
603
604void
Yingdi Yu79c25a22013-10-21 13:38:38 -0700605ContactPanel::refreshContactList()
606{
607 m_contactList = m_contactManager->getContactItemList();
608 QStringList contactNameList;
609 for(int i = 0; i < m_contactList.size(); i++)
Yingdi Yua0594092013-11-06 22:07:38 -0800610 contactNameList << QString::fromStdString(m_contactList[i]->getAlias());
Yingdi Yu79c25a22013-10-21 13:38:38 -0700611
612 m_contactListModel->setStringList(contactNameList);
613}
614
615void
616ContactPanel::showContextMenu(const QPoint& pos)
617{
618 QMenu menu(ui->ContactList);
619 menu.addAction(m_menuInvite);
Yingdi Yu100267f2013-10-21 15:01:40 -0700620 connect(m_menuInvite, SIGNAL(triggered()),
621 this, SLOT(openStartChatDialog()));
Yingdi Yua0594092013-11-06 22:07:38 -0800622 menu.addSeparator();
Yingdi Yu79c25a22013-10-21 13:38:38 -0700623 menu.addAction(m_menuAlias);
624 connect(m_menuAlias, SIGNAL(triggered()),
625 this, SLOT(openSetAliasDialog()));
626 menu.exec(ui->ContactList->mapToGlobal(pos));
627
628}
629
630void
631ContactPanel::openSetAliasDialog()
632{
Yingdi Yua50c3252013-11-03 15:05:26 -0800633 m_setAliasDialog->setTargetIdentity(m_currentSelectedContact->getNameSpace().toUri());
Yingdi Yu79c25a22013-10-21 13:38:38 -0700634 m_setAliasDialog->show();
635}
636
Yingdi Yu100267f2013-10-21 15:01:40 -0700637void
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700638ContactPanel::openSettingDialog()
639{
Yingdi Yu42372442013-11-06 18:43:31 -0800640 m_settingDialog->setIdentity(m_defaultIdentity.toUri(), m_nickName);
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700641 m_settingDialog->show();
642}
643
644void
Yingdi Yu100267f2013-10-21 15:01:40 -0700645ContactPanel::openStartChatDialog()
646{
Yingdi Yu100267f2013-10-21 15:01:40 -0700647 Name chatroom("/ndn/broadcast/chronos");
Yingdi Yu42f66462013-10-31 17:38:22 -0700648 chatroom.append(string("chatroom-") + getRandomString());
Yingdi Yu100267f2013-10-21 15:01:40 -0700649
Yingdi Yua50c3252013-11-03 15:05:26 -0800650 m_startChatDialog->setInvitee(m_currentSelectedContact->getNameSpace().toUri(), chatroom.toUri());
Yingdi Yu100267f2013-10-21 15:01:40 -0700651 m_startChatDialog->show();
652}
653
Yingdi Yu42f66462013-10-31 17:38:22 -0700654// For inviter
Yingdi Yu100267f2013-10-21 15:01:40 -0700655void
656ContactPanel::startChatroom(const QString& chatroom, const QString& invitee, bool isIntroducer)
657{
Yingdi Yu42f66462013-10-31 17:38:22 -0700658 Name chatroomName(chatroom.toUtf8().constData());
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800659
660 Name inviteeNamespace(invitee.toStdString());
661 Ptr<ContactItem> inviteeItem = m_contactManager->getContact(inviteeNamespace);
662
Yingdi Yuc90deb12013-11-06 18:51:19 -0800663 ChatDialog* chatDialog = new ChatDialog(m_contactManager, chatroomName, m_localPrefix, m_defaultIdentity, m_nickName);
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700664 m_chatDialogs.insert(pair <Name, ChatDialog*> (chatroomName, chatDialog));
Yingdi Yu42372442013-11-06 18:43:31 -0800665
666 connect(chatDialog, SIGNAL(closeChatDialog(const ndn::Name&)),
667 this, SLOT(removeChatDialog(const ndn::Name&)));
Yingdi Yub29f78c2013-11-09 20:12:31 -0800668 connect(chatDialog, SIGNAL(noNdnConnection(const QString&)),
669 this, SLOT(showError(const QString&)));
Yingdi Yu42372442013-11-06 18:43:31 -0800670
Yingdi Yuc90deb12013-11-06 18:51:19 -0800671 // send invitation
Yingdi Yu42f66462013-10-31 17:38:22 -0700672 chatDialog->sendInvitation(inviteeItem, isIntroducer);
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700673
674 chatDialog->show();
Yingdi Yu100267f2013-10-21 15:01:40 -0700675}
676
Yingdi Yu42f66462013-10-31 17:38:22 -0700677// For Invitee
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700678void
Yingdi Yu42f66462013-10-31 17:38:22 -0700679ContactPanel::startChatroom2(const ChronosInvitation& invitation,
680 const security::IdentityCertificate& identityCertificate)
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700681{
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800682 Ptr<ContactItem> inviterItem = m_contactManager->getContact(invitation.getInviterNameSpace());
683
Yingdi Yu42f66462013-10-31 17:38:22 -0700684 Name chatroomName("/ndn/broadcast/chronos");
685 chatroomName.append(invitation.getChatroom());
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800686
Yingdi Yuc90deb12013-11-06 18:51:19 -0800687 ChatDialog* chatDialog = new ChatDialog(m_contactManager, chatroomName, m_localPrefix, m_defaultIdentity, m_nickName, true);
Yingdi Yua0594092013-11-06 22:07:38 -0800688
Yingdi Yu42372442013-11-06 18:43:31 -0800689 connect(chatDialog, SIGNAL(closeChatDialog(const ndn::Name&)),
690 this, SLOT(removeChatDialog(const ndn::Name&)));
Yingdi Yub29f78c2013-11-09 20:12:31 -0800691 connect(chatDialog, SIGNAL(noNdnConnection(const QString&)),
692 this, SLOT(showError(const QString&)));
Yingdi Yu42f66462013-10-31 17:38:22 -0700693
Yingdi Yuc90deb12013-11-06 18:51:19 -0800694 chatDialog->addChatDataRule(invitation.getInviterPrefix(), identityCertificate, true);
Yingdi Yua0594092013-11-06 22:07:38 -0800695 chatDialog->publishIntroCert(identityCertificate, true);
Yingdi Yu42f66462013-10-31 17:38:22 -0700696
Yingdi Yu42f66462013-10-31 17:38:22 -0700697 chatDialog->addTrustAnchor(inviterItem->getSelfEndorseCertificate());
698
699 m_chatDialogs.insert(pair <Name, ChatDialog*> (chatroomName, chatDialog));
700
701 chatDialog->show();
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700702}
703
704void
Yingdi Yu42f66462013-10-31 17:38:22 -0700705ContactPanel::acceptInvitation(const ChronosInvitation& invitation,
706 const security::IdentityCertificate& identityCertificate)
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700707{
708 string prefix = m_localPrefix.toUri();
Yingdi Yu42f66462013-10-31 17:38:22 -0700709 m_handler->publishDataByIdentity (invitation.getInterestName(), prefix);
Yingdi Yu42f66462013-10-31 17:38:22 -0700710 startChatroom2(invitation, identityCertificate);
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700711}
712
713void
Yingdi Yu42f66462013-10-31 17:38:22 -0700714ContactPanel::rejectInvitation(const ChronosInvitation& invitation)
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700715{
Yingdi Yu97936352013-11-08 14:13:42 -0800716 string empty("nack");
Yingdi Yu42f66462013-10-31 17:38:22 -0700717 m_handler->publishDataByIdentity (invitation.getInterestName(), empty);
Yingdi Yu53eb8a72013-10-23 11:50:51 -0700718}
719
Yingdi Yua50c3252013-11-03 15:05:26 -0800720void
721ContactPanel::isIntroducerChanged(int state)
722{
723 if(state == Qt::Checked)
724 {
725 ui->addScope->setEnabled(true);
726 ui->deleteScope->setEnabled(true);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800727 ui->trustScopeList->setEnabled(true);
728
729 string filter("contact_namespace = '");
730 filter.append(m_currentSelectedContact->getNameSpace().toUri()).append("'");
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800731
732 m_trustScopeModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
733 m_trustScopeModel->setTable("TrustScope");
734 m_trustScopeModel->setFilter(filter.c_str());
735 m_trustScopeModel->select();
736 m_trustScopeModel->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
737 m_trustScopeModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Contact"));
738 m_trustScopeModel->setHeaderData(2, Qt::Horizontal, QObject::tr("TrustScope"));
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800739
740 ui->trustScopeList->setModel(m_trustScopeModel);
741 ui->trustScopeList->setColumnHidden(0, true);
742 ui->trustScopeList->setColumnHidden(1, true);
743 ui->trustScopeList->show();
744
745 m_currentSelectedContact->setIsIntroducer(true);
Yingdi Yua50c3252013-11-03 15:05:26 -0800746 }
747 else
748 {
Yingdi Yua50c3252013-11-03 15:05:26 -0800749 ui->addScope->setEnabled(false);
750 ui->deleteScope->setEnabled(false);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800751
752 string filter("contact_namespace = '");
753 filter.append(m_currentSelectedContact->getNameSpace().toUri()).append("'");
754
755 m_trustScopeModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
756 m_trustScopeModel->setTable("TrustScope");
757 m_trustScopeModel->setFilter(filter.c_str());
758 m_trustScopeModel->select();
759 m_trustScopeModel->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
760 m_trustScopeModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Contact"));
761 m_trustScopeModel->setHeaderData(2, Qt::Horizontal, QObject::tr("TrustScope"));
762
763 ui->trustScopeList->setModel(m_trustScopeModel);
764 ui->trustScopeList->setColumnHidden(0, true);
765 ui->trustScopeList->setColumnHidden(1, true);
766 ui->trustScopeList->show();
767
768 ui->trustScopeList->setEnabled(false);
769
770 m_currentSelectedContact->setIsIntroducer(false);
Yingdi Yua50c3252013-11-03 15:05:26 -0800771 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800772 m_contactManager->getContactStorage()->updateIsIntroducer(m_currentSelectedContact->getNameSpace(), m_currentSelectedContact->isIntroducer());
773}
774
775void
776ContactPanel::addScopeClicked()
777{
778 int rowCount = m_trustScopeModel->rowCount();
779 QSqlRecord record;
780 QSqlField identityField("contact_namespace", QVariant::String);
781 record.append(identityField);
782 record.setValue("contact_namespace", QString(m_currentSelectedContact->getNameSpace().toUri().c_str()));
783 m_trustScopeModel->insertRow(rowCount);
784 m_trustScopeModel->setRecord(rowCount, record);
785}
786
787void
788ContactPanel::deleteScopeClicked()
789{
790 QItemSelectionModel* selectionModel = ui->trustScopeList->selectionModel();
791 QModelIndexList indexList = selectionModel->selectedIndexes();
792
793 int i = indexList.size() - 1;
794 for(; i >= 0; i--)
795 m_trustScopeModel->removeRow(indexList[i].row());
796
797 m_trustScopeModel->submitAll();
798}
799
800void
801ContactPanel::saveScopeClicked()
Yingdi Yua0594092013-11-06 22:07:38 -0800802{ m_trustScopeModel->submitAll(); }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800803
804void
805ContactPanel::endorseButtonClicked()
806{
807 m_endorseDataModel->submitAll();
808 m_contactManager->updateEndorseCertificate(m_currentSelectedContact->getNameSpace(), m_defaultIdentity);
Yingdi Yua50c3252013-11-03 15:05:26 -0800809}
Yingdi Yu100267f2013-10-21 15:01:40 -0700810
Yingdi Yu42372442013-11-06 18:43:31 -0800811void
812ContactPanel::removeChatDialog(const ndn::Name& chatroomName)
813{
814 map<Name, ChatDialog*>::iterator it = m_chatDialogs.find(chatroomName);
Yingdi Yua0594092013-11-06 22:07:38 -0800815
816 ChatDialog* deletedChat = NULL;
Yingdi Yu42372442013-11-06 18:43:31 -0800817 if(it != m_chatDialogs.end())
818 {
Yingdi Yu42372442013-11-06 18:43:31 -0800819 deletedChat = it->second;
820 m_chatDialogs.erase(it);
821 }
Yingdi Yua0594092013-11-06 22:07:38 -0800822 if (deletedChat != NULL)
823 delete deletedChat;
Yingdi Yu42372442013-11-06 18:43:31 -0800824}
825
Yingdi Yu9e0dc292013-10-10 11:39:45 -0700826#if WAF
827#include "contactpanel.moc"
828#include "contactpanel.cpp.moc"
829#endif