added retroshare certificate links: allows to paste certificates everywhere. Users need to click on them to launch the make friend wizard on the certificate. Certificates can be copied from each location of the Friends list

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4812 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2012-01-18 20:31:30 +00:00
parent 912e5339ca
commit 51cfb0c5fe
6 changed files with 373 additions and 191 deletions

View File

@ -37,6 +37,7 @@
#include "util/misc.h" #include "util/misc.h"
#include "common/PeerDefs.h" #include "common/PeerDefs.h"
#include "common/RsCollectionFile.h" #include "common/RsCollectionFile.h"
#include "gui/connect/ConnectFriendWizard.h"
#include "gui/connect/ConfCertDialog.h" #include "gui/connect/ConfCertDialog.h"
#include <retroshare/rsfiles.h> #include <retroshare/rsfiles.h>
@ -44,14 +45,16 @@
#include <retroshare/rsforums.h> #include <retroshare/rsforums.h>
#include <retroshare/rschannels.h> #include <retroshare/rschannels.h>
//#define DEBUG_RSLINK 1 #define DEBUG_RSLINK 1
#define HOST_FILE "file" #define HOST_FILE "file"
#define HOST_PERSON "person" #define HOST_PERSON "person"
#define HOST_FORUM "forum" #define HOST_FORUM "forum"
#define HOST_CHANNEL "channel" #define HOST_CHANNEL "channel"
#define HOST_MESSAGE "message" #define HOST_MESSAGE "message"
#define HOST_REGEXP "file|person|forum|channel|search|message" #define HOST_SEARCH "search"
#define HOST_CERTIFICATE "certificate"
#define HOST_REGEXP "file|person|forum|channel|search|message|certificate"
#define FILE_NAME "name" #define FILE_NAME "name"
#define FILE_SIZE "size" #define FILE_SIZE "size"
@ -71,8 +74,14 @@
#define MESSAGE_ID "id" #define MESSAGE_ID "id"
#define MESSAGE_SUBJECT "subject" #define MESSAGE_SUBJECT "subject"
#define HOST_SEARCH "search" #define SEARCH_KEYWORDS "keywords"
#define SEARCH_KEYWORDS "keywords"
#define CERTIFICATE_SSLID "sslid"
#define CERTIFICATE_GPG_ID "gpgid"
#define CERTIFICATE_GPG_BASE64 "gpgbase64"
#define CERTIFICATE_GPG_CHECKSUM "gpgchecksum"
#define CERTIFICATE_LOCATION "location"
#define CERTIFICATE_NAME "name"
RetroShareLink::RetroShareLink(const QUrl& url) RetroShareLink::RetroShareLink(const QUrl& url)
{ {
@ -208,6 +217,18 @@ void RetroShareLink::fromUrl(const QUrl& url)
return; return;
} }
if (url.host() == HOST_CERTIFICATE) {
_type = TYPE_CERTIFICATE;
_SSLid = url.queryItemValue(CERTIFICATE_SSLID);
_name = url.queryItemValue(CERTIFICATE_NAME);
_location = url.queryItemValue(CERTIFICATE_LOCATION);
_GPGBase64String = url.queryItemValue(CERTIFICATE_GPG_BASE64);
_GPGid = url.queryItemValue(CERTIFICATE_GPG_ID);
_GPGBase64CheckSum = url.queryItemValue(CERTIFICATE_GPG_CHECKSUM);
std::cerr << "Got a certificate link!!" << std::endl;
check() ;
return;
}
// bad link // bad link
#ifdef DEBUG_RSLINK #ifdef DEBUG_RSLINK
@ -256,6 +277,51 @@ bool RetroShareLink::createPerson(const std::string& id)
return valid(); return valid();
} }
bool RetroShareLink::createCertificate(const std::string& ssl_id)
{
std::string invite = rsPeers->GetRetroshareInvite(ssl_id,false) ;
if(invite == "")
{
std::cerr << "RetroShareLink::createPerson() Couldn't get retroshare invite for ssl id: " << ssl_id << std::endl;
return false;
}
RsPeerDetails detail;
if (rsPeers->getPeerDetails(ssl_id, detail) == false) {
std::cerr << "RetroShareLink::createPerson() Couldn't find peer id " << ssl_id << std::endl;
return false;
}
//_ssl_id = QString::fromStdString(id);
_name = QString::fromUtf8(detail.name.c_str());
QString gpg_cert = QString::fromStdString(invite) ;
QString gpg_base_64 = QString::fromStdString(invite).section("\n\n",1).section("-----",0,0) ;
_GPGBase64CheckSum = gpg_base_64.section("=",-1,-1).section("\n",0,0) ;
gpg_base_64 = gpg_base_64.section("\n=",0,0) ;
_type = TYPE_CERTIFICATE;
_GPGid = QString::fromStdString(detail.gpg_id).right(8);
_SSLid = QString::fromStdString(ssl_id) ;
_GPGBase64String = gpg_base_64.replace("\n","") ;
_location = QString::fromStdString(detail.location) ;
_name = QString::fromStdString(detail.name) ;
//_external_ipp = QString::fromStdString(invite).section("--EXT--",1,1) ;
QString lst = QString::fromStdString(invite).section("--EXT--",0,0) ;
//_local_ipp = lst.section("--LOCAL--",1,1) ;
std::cerr << "Found gpg base 64 string = " << _GPGBase64String.toStdString() << std::endl;
std::cerr << "Found gpg base 64 checksum = " << _GPGBase64CheckSum.toStdString() << std::endl;
std::cerr << "Found SSLId = " << _SSLid.toStdString() << std::endl;
std::cerr << "Found GPGId = " << _GPGid.toStdString() << std::endl;
//std::cerr << "Found External IP+Port = " << _external_ipp.toStdString() << std::endl;
//std::cerr << "Found External IP+Port = " << _local_ipp.toStdString() << std::endl;
std::cerr << "Found Location = " << _location.toStdString() << std::endl;
}
bool RetroShareLink::createForum(const std::string& id, const std::string& msgId) bool RetroShareLink::createForum(const std::string& id, const std::string& msgId)
{ {
clear(); clear();
@ -440,6 +506,8 @@ QString RetroShareLink::title() const
break; break;
case TYPE_MESSAGE: case TYPE_MESSAGE:
return PeerDefs::rsidFromId(hash().toStdString()); return PeerDefs::rsidFromId(hash().toStdString());
case TYPE_CERTIFICATE:
return QObject::tr("Click to add this RetroShare cert to your GPG keyring\nand open the Make Friend Wizard.\n") + QString("GPG Id = ") + GPGId() + QString("\nSSLId = ")+SSLId();
} }
return ""; return "";
@ -523,6 +591,20 @@ QString RetroShareLink::toString() const
return url.toString(); return url.toString();
} }
case TYPE_CERTIFICATE:
{
QUrl url ;
url.setScheme(RSLINK_SCHEME);
url.setHost(HOST_CERTIFICATE) ;
url.addQueryItem(CERTIFICATE_SSLID, _SSLid);
url.addQueryItem(CERTIFICATE_GPG_ID, _GPGid);
url.addQueryItem(CERTIFICATE_GPG_BASE64, _GPGBase64String);
url.addQueryItem(CERTIFICATE_GPG_CHECKSUM, _GPGBase64CheckSum);
url.addQueryItem(CERTIFICATE_LOCATION, encodeItem(_location));
url.addQueryItem(CERTIFICATE_NAME, encodeItem(_name));
return url.toString();
}
} }
return ""; return "";
@ -534,6 +616,9 @@ QString RetroShareLink::niceName() const
return PeerDefs::rsid(name().toUtf8().constData(), hash().toStdString()); return PeerDefs::rsid(name().toUtf8().constData(), hash().toStdString());
} }
if(type() == TYPE_CERTIFICATE)
return QString("RetroShare Certificate (") + _name + ", @ " + _location + ")" ; // should add SSL id there
return name(); return name();
} }
@ -743,6 +828,10 @@ static void processList(QStringList &list, const QString &textSingular, const QS
QStringList messageReceipientNotAccepted; QStringList messageReceipientNotAccepted;
QStringList messageReceipientUnknown; QStringList messageReceipientUnknown;
// Certificate
QStringList GPGBase64Strings ;
QStringList SSLIds ;
// summary // summary
QList<QStringList*> processedList; QList<QStringList*> processedList;
QList<QStringList*> errorList; QList<QStringList*> errorList;
@ -760,212 +849,245 @@ static void processList(QStringList &list, const QString &textSingular, const QS
continue; continue;
} }
switch (link.type()) { switch (link.type())
case TYPE_UNKNOWN: {
countUnknown++; case TYPE_UNKNOWN:
break; countUnknown++;
break;
case TYPE_FILE: case TYPE_CERTIFICATE:
{
#ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process FileRequest : fileName : " << link.name().toUtf8().constData() << ". fileHash : " << link.hash().toStdString() << ". fileSize : " << link.size() << std::endl;
#endif
needNotifySuccess = true;
// Get a list of available direct sources, in case the file is browsable only.
std::list<std::string> srcIds;
FileInfo finfo ;
rsFiles->FileDetails(link.hash().toStdString(), RS_FILE_HINTS_REMOTE, finfo) ;
for(std::list<TransferInfo>::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it)
{ {
#ifdef DEBUG_RSLINK #ifdef DEBUG_RSLINK
std::cerr << " adding peerid " << (*it).peerId << std::endl ; std::cerr << " RetroShareLink::process certificate." << std::endl;
#endif #endif
srcIds.push_back((*it).peerId) ; needNotifySuccess = true;
}
if (rsFiles->FileRequest(link.name().toUtf8().constData(), link.hash().toStdString(), link.size(), "", RS_FILE_HINTS_NETWORK_WIDE, srcIds)) { QString RS_Certificate ;
fileAdded.append(link.name()); RS_Certificate += "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" ;
} else { RS_Certificate += "Version: Retroshare Generated cert.\n" ;
fileExist.append(link.name()); RS_Certificate += "\n" ;
}
break;
}
case TYPE_PERSON: QString radix = link.GPGRadix64Key() ;
{
while(radix.size() > 64)
{
RS_Certificate += radix.left(64) + "\n" ;
radix = radix.right(radix.size() - 64) ;
}
RS_Certificate += radix.left(64) + "\n" ;
RS_Certificate += "=" + link.GPGBase64CheckSum() + "\n" ;
RS_Certificate += "-----END PGP PUBLIC KEY BLOCK-----\n" ;
RS_Certificate += "--SSLID--" + link.SSLId() + ";--LOCATION--" + link.location() + ";\n" ;
std::cerr << "Usign this certificate:" << std::endl;
std::cerr << RS_Certificate.toStdString() << std::endl;
ConnectFriendWizard(NULL,RS_Certificate).exec() ;
needNotifySuccess = false;
}
break ;
case TYPE_FILE:
{
#ifdef DEBUG_RSLINK #ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process FriendRequest : name : " << link.name().toStdString() << ". id : " << link.hash().toStdString() << std::endl; std::cerr << " RetroShareLink::process FileRequest : fileName : " << link.name().toUtf8().constData() << ". fileHash : " << link.hash().toStdString() << ". fileSize : " << link.size() << std::endl;
#endif #endif
needNotifySuccess = true; needNotifySuccess = true;
RsPeerDetails detail; // Get a list of available direct sources, in case the file is browsable only.
if (rsPeers->getPeerDetails(link.hash().toStdString(), detail)) { std::list<std::string> srcIds;
if (detail.gpg_id == rsPeers->getGPGOwnId()) { FileInfo finfo ;
// it's me, do nothing rsFiles->FileDetails(link.hash().toStdString(), RS_FILE_HINTS_REMOTE, finfo) ;
break;
}
if (detail.accept_connection) { for(std::list<TransferInfo>::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it)
// peer connection is already accepted {
personExist.append(PeerDefs::rsid(detail));
break;
}
if (rsPeers->addFriend("", link.hash().toStdString())) {
ConfCertDialog::loadAll();
personAdded.append(PeerDefs::rsid(detail));
break;
}
personFailed.append(PeerDefs::rsid(link.name().toUtf8().constData(), link.hash().toStdString()));
break;
}
personNotFound.append(PeerDefs::rsid(link.name().toUtf8().constData(), link.hash().toStdString()));
break;
}
case TYPE_FORUM:
{
#ifdef DEBUG_RSLINK #ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process ForumRequest : name : " << link.name().toStdString() << ". id : " << link.hash().toStdString() << ". msgId : " << link.msgId().toStdString() << std::endl; std::cerr << " adding peerid " << (*it).peerId << std::endl ;
#endif #endif
srcIds.push_back((*it).peerId) ;
}
ForumInfo fi; if (rsFiles->FileRequest(link.name().toUtf8().constData(), link.hash().toStdString(), link.size(), "", RS_FILE_HINTS_NETWORK_WIDE, srcIds)) {
if (!rsForums->getForumInfo(link.id().toStdString(), fi)) { fileAdded.append(link.name());
if (link.msgId().isEmpty()) {
forumUnknown.append(link.name());
} else { } else {
forumMsgUnknown.append(link.name()); fileExist.append(link.name());
} }
break; break;
} }
ForumMsgInfo msg; case TYPE_PERSON:
if (!link.msgId().isEmpty()) { {
if (!rsForums->getForumMessage(fi.forumId, link.msgId().toStdString(), msg)) {
forumMsgUnknown.append(link.name());
break;
}
}
MainWindow::showWindow(MainWindow::Forums);
ForumsDialog *forumsDialog = dynamic_cast<ForumsDialog*>(MainWindow::getPage(MainWindow::Forums));
if (!forumsDialog) {
return false;
}
if (forumsDialog->navigate(fi.forumId, msg.msgId)) {
if (link.msgId().isEmpty()) {
forumFound.append(link.name());
} else {
forumMsgFound.append(link.name());
}
} else {
if (link.msgId().isEmpty()) {
forumUnknown.append(link.name());
} else {
forumMsgUnknown.append(link.name());
}
}
break;
}
case TYPE_CHANNEL:
{
#ifdef DEBUG_RSLINK #ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process ChannelRequest : name : " << link.name().toStdString() << ". id : " << link.hash().toStdString() << ". msgId : " << link.msgId().toStdString() << std::endl; std::cerr << " RetroShareLink::process FriendRequest : name : " << link.name().toStdString() << ". id : " << link.hash().toStdString() << std::endl;
#endif #endif
ChannelInfo ci; needNotifySuccess = true;
if (!rsChannels->getChannelInfo(link.id().toStdString(), ci)) {
if (link.msgId().isEmpty()) {
channelUnknown.append(link.name());
} else {
channelMsgUnknown.append(link.name());
}
break;
}
ChannelMsgInfo msg; RsPeerDetails detail;
if (!link.msgId().isEmpty()) { if (rsPeers->getPeerDetails(link.hash().toStdString(), detail)) {
if (!rsChannels->getChannelMessage(ci.channelId, link.msgId().toStdString(), msg)) { if (detail.gpg_id == rsPeers->getGPGOwnId()) {
channelMsgUnknown.append(link.name()); // it's me, do nothing
break; break;
}
}
MainWindow::showWindow(MainWindow::Channels);
ChannelFeed *channelFeed = dynamic_cast<ChannelFeed*>(MainWindow::getPage(MainWindow::Channels));
if (!channelFeed) {
return false;
}
if (channelFeed->navigate(ci.channelId, msg.msgId)) {
if (link.msgId().isEmpty()) {
channelFound.append(link.name());
} else {
channelMsgFound.append(link.name());
}
} else {
if (link.msgId().isEmpty()) {
channelUnknown.append(link.name());
} else {
channelMsgUnknown.append(link.name());
}
}
break;
}
case TYPE_SEARCH:
{
#ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process SearchRequest : string : " << link.name().toStdString() << std::endl;
#endif
MainWindow::showWindow(MainWindow::Search);
SearchDialog *searchDialog = dynamic_cast<SearchDialog*>(MainWindow::getPage(MainWindow::Search));
if (!searchDialog) {
break;
}
searchDialog->searchKeywords(link.name());
searchStarted.append(link.name());
break;
}
case TYPE_MESSAGE:
{
#ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process MessageRequest : id : " << link.hash().toStdString() << ", subject : " << link.name().toStdString() << std::endl;
#endif
RsPeerDetails detail;
if (rsPeers->getPeerDetails(link.hash().toStdString(), detail)) {
if (detail.accept_connection || detail.id == rsPeers->getOwnId() || detail.id == rsPeers->getGPGOwnId()) {
MessageComposer *msg = MessageComposer::newMsg();
msg->addRecipient(MessageComposer::TO, detail.id, false);
if (link.subject().isEmpty() == false) {
msg->insertTitleText(link.subject());
} }
msg->show();
messageStarted.append(PeerDefs::nameWithLocation(detail)); if (detail.accept_connection) {
} else { // peer connection is already accepted
messageReceipientNotAccepted.append(PeerDefs::nameWithLocation(detail)); personExist.append(PeerDefs::rsid(detail));
break;
}
if (rsPeers->addFriend("", link.hash().toStdString())) {
ConfCertDialog::loadAll();
personAdded.append(PeerDefs::rsid(detail));
break;
}
personFailed.append(PeerDefs::rsid(link.name().toUtf8().constData(), link.hash().toStdString()));
break;
} }
} else {
messageReceipientUnknown.append(PeerDefs::rsidFromId(link.hash().toStdString())); personNotFound.append(PeerDefs::rsid(link.name().toUtf8().constData(), link.hash().toStdString()));
break;
} }
break; case TYPE_FORUM:
} {
#ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process ForumRequest : name : " << link.name().toStdString() << ". id : " << link.hash().toStdString() << ". msgId : " << link.msgId().toStdString() << std::endl;
#endif
default: ForumInfo fi;
std::cerr << " RetroShareLink::process unknown type: " << link.type() << std::endl; if (!rsForums->getForumInfo(link.id().toStdString(), fi)) {
countUnknown++; if (link.msgId().isEmpty()) {
forumUnknown.append(link.name());
} else {
forumMsgUnknown.append(link.name());
}
break;
}
ForumMsgInfo msg;
if (!link.msgId().isEmpty()) {
if (!rsForums->getForumMessage(fi.forumId, link.msgId().toStdString(), msg)) {
forumMsgUnknown.append(link.name());
break;
}
}
MainWindow::showWindow(MainWindow::Forums);
ForumsDialog *forumsDialog = dynamic_cast<ForumsDialog*>(MainWindow::getPage(MainWindow::Forums));
if (!forumsDialog) {
return false;
}
if (forumsDialog->navigate(fi.forumId, msg.msgId)) {
if (link.msgId().isEmpty()) {
forumFound.append(link.name());
} else {
forumMsgFound.append(link.name());
}
} else {
if (link.msgId().isEmpty()) {
forumUnknown.append(link.name());
} else {
forumMsgUnknown.append(link.name());
}
}
break;
}
case TYPE_CHANNEL:
{
#ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process ChannelRequest : name : " << link.name().toStdString() << ". id : " << link.hash().toStdString() << ". msgId : " << link.msgId().toStdString() << std::endl;
#endif
ChannelInfo ci;
if (!rsChannels->getChannelInfo(link.id().toStdString(), ci)) {
if (link.msgId().isEmpty()) {
channelUnknown.append(link.name());
} else {
channelMsgUnknown.append(link.name());
}
break;
}
ChannelMsgInfo msg;
if (!link.msgId().isEmpty()) {
if (!rsChannels->getChannelMessage(ci.channelId, link.msgId().toStdString(), msg)) {
channelMsgUnknown.append(link.name());
break;
}
}
MainWindow::showWindow(MainWindow::Channels);
ChannelFeed *channelFeed = dynamic_cast<ChannelFeed*>(MainWindow::getPage(MainWindow::Channels));
if (!channelFeed) {
return false;
}
if (channelFeed->navigate(ci.channelId, msg.msgId)) {
if (link.msgId().isEmpty()) {
channelFound.append(link.name());
} else {
channelMsgFound.append(link.name());
}
} else {
if (link.msgId().isEmpty()) {
channelUnknown.append(link.name());
} else {
channelMsgUnknown.append(link.name());
}
}
break;
}
case TYPE_SEARCH:
{
#ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process SearchRequest : string : " << link.name().toStdString() << std::endl;
#endif
MainWindow::showWindow(MainWindow::Search);
SearchDialog *searchDialog = dynamic_cast<SearchDialog*>(MainWindow::getPage(MainWindow::Search));
if (!searchDialog) {
break;
}
searchDialog->searchKeywords(link.name());
searchStarted.append(link.name());
break;
}
case TYPE_MESSAGE:
{
#ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process MessageRequest : id : " << link.hash().toStdString() << ", subject : " << link.name().toStdString() << std::endl;
#endif
RsPeerDetails detail;
if (rsPeers->getPeerDetails(link.hash().toStdString(), detail)) {
if (detail.accept_connection || detail.id == rsPeers->getOwnId() || detail.id == rsPeers->getGPGOwnId()) {
MessageComposer *msg = MessageComposer::newMsg();
msg->addRecipient(MessageComposer::TO, detail.id, false);
if (link.subject().isEmpty() == false) {
msg->insertTitleText(link.subject());
}
msg->show();
messageStarted.append(PeerDefs::nameWithLocation(detail));
} else {
messageReceipientNotAccepted.append(PeerDefs::nameWithLocation(detail));
}
} else {
messageReceipientUnknown.append(PeerDefs::rsidFromId(link.hash().toStdString()));
}
break;
}
default:
std::cerr << " RetroShareLink::process unknown type: " << link.type() << std::endl;
countUnknown++;
} }
} }
@ -1219,3 +1341,4 @@ bool RSLinkClipboard::empty(RetroShareLink::enumType type /*= RetroShareLink::TY
return RetroShareLink::process(linksToProcess, flag); return RetroShareLink::process(linksToProcess, flag);
} }

View File

@ -48,7 +48,7 @@
class RetroShareLink class RetroShareLink
{ {
public: public:
enum enumType { TYPE_UNKNOWN, TYPE_FILE, TYPE_PERSON, TYPE_FORUM, TYPE_CHANNEL, TYPE_SEARCH, TYPE_MESSAGE }; enum enumType { TYPE_UNKNOWN, TYPE_FILE, TYPE_PERSON, TYPE_FORUM, TYPE_CHANNEL, TYPE_SEARCH, TYPE_MESSAGE, TYPE_CERTIFICATE };
public: public:
RetroShareLink(); RetroShareLink();
@ -61,6 +61,7 @@ class RetroShareLink
bool createChannel(const std::string& id, const std::string& msgId); bool createChannel(const std::string& id, const std::string& msgId);
bool createSearch(const QString& keywords); bool createSearch(const QString& keywords);
bool createMessage(const std::string& peerId, const QString& subject); bool createMessage(const std::string& peerId, const QString& subject);
bool createCertificate(const std::string& peerId) ;
enumType type() const {return _type; } enumType type() const {return _type; }
uint64_t size() const { return _size ; } uint64_t size() const { return _size ; }
@ -69,6 +70,11 @@ class RetroShareLink
const QString& id() const { return _hash ; } const QString& id() const { return _hash ; }
const QString& msgId() const { return _msgId ; } const QString& msgId() const { return _msgId ; }
const QString& subject() const { return _subject ; } const QString& subject() const { return _subject ; }
const QString& GPGRadix64Key() const { return _GPGBase64String ; }
const QString& GPGBase64CheckSum() const { return _GPGBase64CheckSum ; }
const QString& SSLId() const { return _SSLid ; }
const QString& GPGId() const { return _GPGid ; }
const QString& location() const { return _location ; }
QString title() const; QString title() const;
// get nice name for anchor // get nice name for anchor
@ -110,6 +116,11 @@ class RetroShareLink
QString _hash; // or id (forum, channel, message) QString _hash; // or id (forum, channel, message)
QString _msgId; // id of the message (forum, channel) QString _msgId; // id of the message (forum, channel)
QString _subject; QString _subject;
QString _SSLid ; // ssl id for rs links
QString _GPGid ; // ssl id for rs links
QString _GPGBase64String ; // GPG Cert
QString _GPGBase64CheckSum ; // GPG Cert
QString _location ; // location
}; };
/// This class handles the copy/paste of links. Every member is static to ensure unicity. /// This class handles the copy/paste of links. Every member is static to ensure unicity.

View File

@ -382,6 +382,9 @@ void FriendList::peerTreeWidgetCostumPopupMenu()
contextMnu.addAction(QIcon(IMAGE_CONNECT), tr("Connect To Friend"), this, SLOT(connectfriend())); contextMnu.addAction(QIcon(IMAGE_CONNECT), tr("Connect To Friend"), this, SLOT(connectfriend()));
if (type == TYPE_SSL) {
contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy certificate link"), this, SLOT(copyFullCertificate()));
}
if (type == TYPE_GPG) { if (type == TYPE_GPG) {
contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyLink())); contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyLink()));
} }
@ -1254,6 +1257,20 @@ void FriendList::pastePerson()
RSLinkClipboard::process(RetroShareLink::TYPE_PERSON); RSLinkClipboard::process(RetroShareLink::TYPE_PERSON);
} }
void FriendList::copyFullCertificate()
{
QTreeWidgetItem *c = getCurrentPeer();
QList<RetroShareLink> urls;
RetroShareLink link ;
link.createCertificate(getRsId(c)) ;
urls.push_back(link);
std::cerr << "link: " << std::endl;
std::cerr<< link.toString().toStdString() << std::endl;
RSLinkClipboard::copyLinks(urls);
}
void FriendList::copyLink() void FriendList::copyLink()
{ {
QTreeWidgetItem *c = getCurrentPeer(); QTreeWidgetItem *c = getCurrentPeer();

View File

@ -107,6 +107,7 @@ private slots:
void chatfriend(QTreeWidgetItem *); void chatfriend(QTreeWidgetItem *);
void chatfriendproxy(); void chatfriendproxy();
void copyLink(); void copyLink();
void copyFullCertificate();
// void exportfriend(); // void exportfriend();
void addFriend(); void addFriend();
void msgfriend(); void msgfriend();

View File

@ -64,7 +64,7 @@
//============================================================================ //============================================================================
//! //!
ConnectFriendWizard::ConnectFriendWizard(QWidget *parent) ConnectFriendWizard::ConnectFriendWizard(QWidget *parent,const QString& cert)
: QWizard(parent) : QWizard(parent)
{ {
setPage(Page_Intro, new IntroPage); setPage(Page_Intro, new IntroPage);
@ -77,8 +77,38 @@ ConnectFriendWizard::ConnectFriendWizard(QWidget *parent)
setPage(Page_ErrorMessage, new ErrorMessagePage); setPage(Page_ErrorMessage, new ErrorMessagePage);
setPage(Page_Conclusion, new ConclusionPage); setPage(Page_Conclusion, new ConclusionPage);
setStartId(Page_Intro); if(cert.isNull())
setStartId(Page_Intro);
else
{
RsPeerDetails pd;
std::string error_string ;
if ( rsPeers->loadDetailsFromStringCert(cert.toUtf8().constData(), pd,error_string) )
{
#ifdef FRIEND_WIZARD_DEBUG
std::cerr << "ConnectFriendWizard got id : " << pd.id << "; gpg_id : " << pd.gpg_id << std::endl;
#endif
setField(SSL_ID_FIELD_CONNECT_FRIEND_WIZARD, QString::fromStdString(pd.id));
setField(GPG_ID_FIELD_CONNECT_FRIEND_WIZARD, QString::fromStdString(pd.gpg_id));
setField(LOCATION_FIELD_CONNECT_FRIEND_WIZARD, QString::fromUtf8(pd.location.c_str()));
setField(CERT_STRING_FIELD_CONNECT_FRIEND_WIZARD, cert);
setField("ext_friend_ip", QString::fromStdString(pd.extAddr));
setField("ext_friend_port", QString::number(pd.extPort));
setField("local_friend_ip", QString::fromStdString(pd.localAddr));
setField("local_friend_port", QString::number(pd.localPort));
setField("dyndns", QString::fromStdString(pd.dyndns));
setStartId(Page_Conclusion) ;
}
else
{
// error message
setField("errorMessage", tr("Certificate Load Failed")+": "+QString::fromStdString(error_string) );
setStartId(Page_ErrorMessage) ;
}
}
// this define comes from Qt example. I don't have mac, so it wasn't tested // this define comes from Qt example. I don't have mac, so it wasn't tested
#ifndef Q_WS_MAC #ifndef Q_WS_MAC

View File

@ -36,7 +36,7 @@ public:
enum { Page_Intro, Page_Text, Page_Cert, Page_ErrorMessage, Page_Conclusion,Page_Foff, Page_Rsid, Page_Email }; enum { Page_Intro, Page_Text, Page_Cert, Page_ErrorMessage, Page_Conclusion,Page_Foff, Page_Rsid, Page_Email };
ConnectFriendWizard(QWidget *parent = 0); ConnectFriendWizard(QWidget *parent = 0,const QString& cert = QString());
void setGroup(const std::string &groupId); void setGroup(const std::string &groupId);