blob: 1e3cecbe360fc62271e9b18b7b74891054e76952 [file] [log] [blame]
Yingdi Yuae8217c2013-11-09 00:03:26 -08001/* -*- 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
11
12#include "browsecontactdialog.h"
13#include "ui_browsecontactdialog.h"
14
15#ifndef Q_MOC_RUN
16#include <boost/asio.hpp>
17#include <boost/tokenizer.hpp>
18#include "logging.h"
19#include "exception.h"
20#endif
21
22using namespace std;
23using namespace ndn;
24
25INIT_LOGGER("BrowseContactDialog");
26
27// Q_DECLARE_METATYPE(ndn::security::IdentityCertificate)
28
29BrowseContactDialog::BrowseContactDialog(Ptr<ContactManager> contactManager,
30 QWidget *parent)
31 : QDialog(parent)
32 , ui(new Ui::BrowseContactDialog)
33 , m_contactManager(contactManager)
34 , m_warningDialog(new WarningDialog)
35 , m_contactListModel(new QStringListModel)
36{
37 // qRegisterMetaType<ndn::security::IdentityCertificate>("NDNIdentityCertificate");
38
39 ui->setupUi(this);
40
41 ui->ContactList->setModel(m_contactListModel);
42
43 connect(ui->ContactList->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
44 this, SLOT(updateSelection(const QItemSelection &, const QItemSelection &)));
45 connect(&*m_contactManager, SIGNAL(contactCertificateFetched(const ndn::security::IdentityCertificate &)),
46 this, SLOT(onCertificateFetched(const ndn::security::IdentityCertificate &)));
47 connect(&*m_contactManager, SIGNAL(contactCertificateFetchFailed(const ndn::Name&)),
48 this, SLOT(onCertificateFetchFailed(const ndn::Name&)));
49 connect(&*m_contactManager, SIGNAL(warning(QString)),
50 this, SLOT(onWarning(QString)));
51
52 connect(ui->AddButton, SIGNAL(clicked()),
53 this, SLOT(onAddClicked()));
54
55 connect(ui->CancelButton, SIGNAL(clicked()),
56 this, SLOT(onCancelClicked()));
57}
58
59BrowseContactDialog::~BrowseContactDialog()
60{
61 delete ui;
62}
63
64
65vector<string>
66BrowseContactDialog::getCertName()
67{
68 vector<string> result;
69 try{
70 using namespace boost::asio::ip;
71 tcp::iostream request_stream;
72 request_stream.expires_from_now(boost::posix_time::milliseconds(3000));
73 request_stream.connect("ndncert.named-data.net","80");
74 if(!request_stream)
75 {
76 m_warningDialog->setMsg("Fail to fetch certificate directory! #1");
77 m_warningDialog->show();
78 return result;
79 }
80 request_stream << "GET /cert/list/ HTTP/1.0\r\n";
81 request_stream << "Host: ndncert.named-data.net\r\n\r\n";
82 request_stream.flush();
83
84 string line1;
85 std::getline(request_stream,line1);
86 if (!request_stream)
87 {
88 m_warningDialog->setMsg("Fail to fetch certificate directory! #2");
89 m_warningDialog->show();
90 return result;
91 }
92 std::stringstream response_stream(line1);
93 std::string http_version;
94 response_stream >> http_version;
95 unsigned int status_code;
96 response_stream >> status_code;
97 std::string status_message;
98 std::getline(response_stream,status_message);
99
100 if (!response_stream||http_version.substr(0,5)!="HTTP/")
101 {
102 m_warningDialog->setMsg("Fail to fetch certificate directory! #3");
103 m_warningDialog->show();
104 return result;
105 }
106 if (status_code!=200)
107 {
108 m_warningDialog->setMsg("Fail to fetch certificate directory! #4");
109 m_warningDialog->show();
110 return result;
111 }
112 vector<string> headers;
113 std::string header;
114 while (std::getline(request_stream, header) && header != "\r")
115 headers.push_back(header);
116
117 std::stringbuf buffer;
118 std::ostream os (&buffer);
119
120 os << request_stream.rdbuf();
121
122 using boost::tokenizer;
123 using boost::escaped_list_separator;
124
125 tokenizer<escaped_list_separator<char> > certItems(buffer.str(), escaped_list_separator<char> ('\\', '\n', '"'));
126 tokenizer<escaped_list_separator<char> >::iterator it = certItems.begin();
127 try{
128 while (it != certItems.end())
129 {
130 result.push_back(*it);
131 it++;
132 }
133 }catch (exception &e){
134 m_warningDialog->setMsg("Fail to fetch certificate directory! #5");
135 m_warningDialog->show();
136 return vector<string>();
137 }
138 result.pop_back();
139
140 return result;
141 }catch(std::exception &e){
142 m_warningDialog->setMsg("Fail to fetch certificate directory! #N");
143 m_warningDialog->show();
144 return result;
145 }
146}
147
148void
149BrowseContactDialog::updateCertificateMap(bool filter)
150{
151 vector<string> certNameList = getCertName();
152 if(filter)
153 {
154 map<Name, Name> certificateMap;
155
156 vector<string>::iterator it = certNameList.begin();
157
158 for(; it != certNameList.end(); it++)
159 {
160 Name newCertName(*it);
161 Name keyName = security::IdentityCertificate::certificateNameToPublicKeyName(newCertName, true);
162 Name identity = keyName.getPrefix(keyName.size()-1);
163
164 map<Name, Name>::iterator map_it = certificateMap.find(identity);
165 if(map_it != certificateMap.end())
166 {
167 Name oldCertName = map_it->second;
168 Name oldKeyName = security::IdentityCertificate::certificateNameToPublicKeyName(oldCertName, true);
169 if(keyName > oldKeyName)
170 map_it->second = newCertName;
171 else if(keyName == oldKeyName && newCertName > oldCertName)
172 map_it->second = newCertName;
173 }
174 else
175 {
176 certificateMap.insert(pair<Name, Name>(identity, newCertName));
177 }
178 }
179 map<Name, Name>::iterator map_it = certificateMap.begin();
180 for(; map_it != certificateMap.end(); map_it++)
181 m_certificateNameList.push_back(map_it->second);
182 }
183 else
184 {
185 vector<string>::iterator it = certNameList.begin();
186
187 for(; it != certNameList.end(); it++)
188 {
189 m_certificateNameList.push_back(*it);
190 }
191 }
192}
193
194void
195BrowseContactDialog::fetchCertificate()
196{
197 vector<Name>::iterator it = m_certificateNameList.begin();
198 int count = 0;
199 for(; it != m_certificateNameList.end(); it++)
200 {
201 m_contactManager->fetchIdCertificate(*it);
202 }
203}
204
205void
206BrowseContactDialog::onCertificateFetched(const security::IdentityCertificate& identityCertificate)
207{
208 Name certName = identityCertificate.getName();
209 Name certNameNoVersion = certName.getPrefix(certName.size()-1);
210 m_certificateMap.insert(pair<Name, security::IdentityCertificate>(certNameNoVersion, identityCertificate));
211 m_profileMap.insert(pair<Name, Profile>(certNameNoVersion, Profile(identityCertificate)));
212 string name(m_profileMap[certNameNoVersion].getProfileEntry("name")->buf(), m_profileMap[certNameNoVersion].getProfileEntry("name")->size());
213 // Name contactName = m_profileMap[certNameNoVersion].getIdentityName();
214 {
215 UniqueRecLock lock(m_mutex);
216 m_contactList << QString::fromStdString(name);
217 m_contactListModel->setStringList(m_contactList);
218 m_contactNameList.push_back(certNameNoVersion);
219 }
220}
221
222void
223BrowseContactDialog::onCertificateFetchFailed(const Name& identity)
224{}
225
226void
227BrowseContactDialog::refreshList()
228{
229 {
230 UniqueRecLock lock(m_mutex);
231 m_contactList.clear();
232 m_contactNameList.clear();
233 }
234 m_certificateNameList.clear();
235 m_certificateMap.clear();
236 m_profileMap.clear();
237
238 updateCertificateMap();
239
240 fetchCertificate();
241}
242
243void
244BrowseContactDialog::updateSelection(const QItemSelection &selected,
245 const QItemSelection &deselected)
246{
247 QModelIndexList items = selected.indexes();
248 Name certName = m_contactNameList[items.first().row()];
249
250 ui->InfoTable->clear();
251 for(int i = ui->InfoTable->rowCount() - 1; i >= 0 ; i--)
252 ui->InfoTable->removeRow(i);
253
254 map<Name, Profile>::iterator it = m_profileMap.find(certName);
255 if(it != m_profileMap.end())
256 {
257 ui->InfoTable->setColumnCount(2);
258
259 QTableWidgetItem *typeHeader = new QTableWidgetItem(QString::fromUtf8("Type"));
260 ui->InfoTable->setHorizontalHeaderItem(0, typeHeader);
261 QTableWidgetItem *valueHeader = new QTableWidgetItem(QString::fromUtf8("Value"));
262 ui->InfoTable->setHorizontalHeaderItem(1, valueHeader);
263
264 Profile::const_iterator pro_it = it->second.begin();
265 int rowCount = 0;
266
267 for(; pro_it != it->second.end(); pro_it++, rowCount++)
268 {
269 ui->InfoTable->insertRow(rowCount);
270 QTableWidgetItem *type = new QTableWidgetItem(QString::fromStdString(pro_it->first));
271 ui->InfoTable->setItem(rowCount, 0, type);
272
273 string valueString(pro_it->second.buf(), pro_it->second.size());
274 QTableWidgetItem *value = new QTableWidgetItem(QString::fromStdString(valueString));
275 ui->InfoTable->setItem(rowCount, 1, value);
276 }
277 }
278}
279
280void
281BrowseContactDialog::onWarning(QString msg)
282{
283 m_warningDialog->setMsg(msg.toStdString());
284 m_warningDialog->show();
285}
286
287void
288BrowseContactDialog::onAddClicked()
289{
290 QItemSelectionModel* selectionModel = ui->ContactList->selectionModel();
291 QModelIndexList selectedList = selectionModel->selectedIndexes();
292 QModelIndexList::iterator it = selectedList.begin();
293 for(; it != selectedList.end(); it++)
294 {
295 Name certName = m_contactNameList[it->row()];
296 if(m_certificateMap.find(certName) != m_certificateMap.end() && m_profileMap.find(certName) != m_profileMap.end())
297 m_contactManager->addContact(m_certificateMap[certName], m_profileMap[certName]);
298 else
299 {
300 m_warningDialog->setMsg("Not enough information to add contact!");
301 m_warningDialog->show();
302 }
303 }
304 emit newContactAdded();
305 this->close();
306}
307
308void
309BrowseContactDialog::onCancelClicked()
310{ this->close(); }
311
312#if WAF
313#include "browsecontactdialog.moc"
314#include "browsecontactdialog.cpp.moc"
315#endif