mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-01-11 07:17:53 +00:00
implement directmessage's copy-to-self to sync DMs between twister instances.
based upon @dryabov patches and long discussion in PR#258, see: https://github.com/miguelfreitas/twister-core/pull/258/files
This commit is contained in:
parent
c1274dcb20
commit
4a0a21550b
@ -1300,6 +1300,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
|
|||||||
if (strMethod == "newpostmsg" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "newpostmsg" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
if (strMethod == "newpostmsg" && n > 4) ConvertTo<boost::int64_t>(params[4]);
|
if (strMethod == "newpostmsg" && n > 4) ConvertTo<boost::int64_t>(params[4]);
|
||||||
if (strMethod == "newdirectmsg" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "newdirectmsg" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
|
if (strMethod == "newdirectmsg" && n > 4) ConvertTo<bool>(params[4]);
|
||||||
if (strMethod == "newrtmsg" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
if (strMethod == "newrtmsg" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||||
if (strMethod == "newrtmsg" && n > 2) ConvertTo<Object>(params[2]);
|
if (strMethod == "newrtmsg" && n > 2) ConvertTo<Object>(params[2]);
|
||||||
if (strMethod == "getposts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
if (strMethod == "getposts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||||
|
124
src/twister.cpp
124
src/twister.cpp
@ -1055,6 +1055,8 @@ bool verifySignature(std::string const &strMessage, std::string const &strUserna
|
|||||||
|
|
||||||
bool processReceivedDM(lazy_entry const* post)
|
bool processReceivedDM(lazy_entry const* post)
|
||||||
{
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
lazy_entry const* dm = post->dict_find_dict("dm");
|
lazy_entry const* dm = post->dict_find_dict("dm");
|
||||||
if( dm ) {
|
if( dm ) {
|
||||||
ecies_secure_t sec;
|
ecies_secure_t sec;
|
||||||
@ -1072,29 +1074,48 @@ bool processReceivedDM(lazy_entry const* post)
|
|||||||
} else {
|
} else {
|
||||||
std::string textOut;
|
std::string textOut;
|
||||||
if( key.Decrypt(sec, textOut) ) {
|
if( key.Decrypt(sec, textOut) ) {
|
||||||
|
result = true;
|
||||||
/* this printf is good for debug, but bad for security.
|
/* this printf is good for debug, but bad for security.
|
||||||
printf("Received DM for user '%s' text = '%s'\n",
|
printf("Received DM for user '%s' text = '%s'\n",
|
||||||
item.second.username.c_str(),
|
item.second.username.c_str(),
|
||||||
textOut.c_str());
|
textOut.c_str());
|
||||||
*/
|
*/
|
||||||
|
|
||||||
std::string n = post->dict_find_string_value("n");
|
std::string from = post->dict_find_string_value("n");
|
||||||
|
std::string to = item.second.username; // default (old format)
|
||||||
|
std::string msg = textOut; // default (old format)
|
||||||
|
bool fromMe = (from == to);
|
||||||
|
// try bdecoding the new format (copy to self etc)
|
||||||
|
{
|
||||||
|
lazy_entry v;
|
||||||
|
int pos;
|
||||||
|
libtorrent::error_code ec;
|
||||||
|
if (lazy_bdecode(textOut.data(), textOut.data()+textOut.size(), v, ec, &pos) == 0) {
|
||||||
|
msg = v.dict_find_string_value("msg");
|
||||||
|
to = v.dict_find_string_value("to");
|
||||||
|
// new features here: key distribution etc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !msg.length() || !to.length() )
|
||||||
|
break;
|
||||||
|
|
||||||
StoredDirectMsg stoDM;
|
StoredDirectMsg stoDM;
|
||||||
stoDM.m_fromMe = false;
|
stoDM.m_fromMe = fromMe;
|
||||||
stoDM.m_text = textOut;
|
stoDM.m_text = msg;
|
||||||
stoDM.m_utcTime = post->dict_find_int_value("time");
|
stoDM.m_utcTime = post->dict_find_int_value("time");
|
||||||
|
|
||||||
LOCK(cs_twister);
|
LOCK(cs_twister);
|
||||||
// store this dm in memory list, but prevent duplicates
|
// store this dm in memory list, but prevent duplicates
|
||||||
std::vector<StoredDirectMsg> &dmsFromToUser = m_users[item.second.username].m_directmsg[n];
|
std::vector<StoredDirectMsg> &dmsFromToUser = m_users[item.second.username].
|
||||||
|
m_directmsg[fromMe ? to : from];
|
||||||
std::vector<StoredDirectMsg>::iterator it;
|
std::vector<StoredDirectMsg>::iterator it;
|
||||||
for( it = dmsFromToUser.begin(); it != dmsFromToUser.end(); ++it ) {
|
for( it = dmsFromToUser.begin(); it != dmsFromToUser.end(); ++it ) {
|
||||||
if( stoDM.m_utcTime == (*it).m_utcTime &&
|
if( stoDM.m_utcTime == (*it).m_utcTime &&
|
||||||
stoDM.m_text == (*it).m_text ) {
|
stoDM.m_text == (*it).m_text ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( stoDM.m_utcTime < (*it).m_utcTime && !(*it).m_fromMe) {
|
if( stoDM.m_utcTime < (*it).m_utcTime ) {
|
||||||
dmsFromToUser.insert(it, stoDM);
|
dmsFromToUser.insert(it, stoDM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1103,12 +1124,12 @@ bool processReceivedDM(lazy_entry const* post)
|
|||||||
dmsFromToUser.push_back(stoDM);
|
dmsFromToUser.push_back(stoDM);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg, boost::uint32_t *flags)
|
bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg, boost::uint32_t *flags)
|
||||||
@ -1784,10 +1805,11 @@ Value newpostmsg(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
Value newdirectmsg(const Array& params, bool fHelp)
|
Value newdirectmsg(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() != 4)
|
if (fHelp || params.size() < 4 || params.size() > 5 )
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"newdirectmsg <from> <k> <to> <msg>\n"
|
"newdirectmsg <from> <k> <to> <msg> [copy_self=false]\n"
|
||||||
"Post a new dm to swarm");
|
"Post a new dm to swarm.\n"
|
||||||
|
"if copy_self true will increase k twice (two DMs).");
|
||||||
|
|
||||||
EnsureWalletIsUnlocked();
|
EnsureWalletIsUnlocked();
|
||||||
|
|
||||||
@ -1795,40 +1817,70 @@ Value newdirectmsg(const Array& params, bool fHelp)
|
|||||||
int k = params[1].get_int();
|
int k = params[1].get_int();
|
||||||
string strTo = params[2].get_str();
|
string strTo = params[2].get_str();
|
||||||
string strMsg = params[3].get_str();
|
string strMsg = params[3].get_str();
|
||||||
|
bool copySelf = (params.size() > 4) ? params[4].get_bool() : false;
|
||||||
|
|
||||||
entry dm;
|
std::list<entry *> dmsToSend;
|
||||||
if( !createDirectMessage(dm, strTo, strMsg) )
|
|
||||||
|
entry dmOldFormat;
|
||||||
|
if( !createDirectMessage(dmOldFormat, strTo, strMsg) )
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR,
|
throw JSONRPCError(RPC_INTERNAL_ERROR,
|
||||||
"error encrypting to pubkey of destination user");
|
"error encrypting to pubkey of destination user");
|
||||||
|
|
||||||
entry v;
|
entry payloadNewFormat;
|
||||||
if( !createSignedUserpost(v, strFrom, k, "",
|
payloadNewFormat["msg"] = strMsg;
|
||||||
NULL, NULL, &dm,
|
payloadNewFormat["to"] = strTo;
|
||||||
std::string(""), 0) )
|
std::vector<char> payloadbuf;
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR,"error signing post with private key of user");
|
bencode(std::back_inserter(payloadbuf), payloadNewFormat);
|
||||||
|
std::string strMsgData = std::string(payloadbuf.data(),payloadbuf.size());
|
||||||
|
|
||||||
std::vector<char> buf;
|
entry dmNewFormat;
|
||||||
bencode(std::back_inserter(buf), v);
|
if( copySelf ) {
|
||||||
|
// use new format to send a copy to ourselves. in future, message
|
||||||
std::string errmsg;
|
// to others might use the new format as well.
|
||||||
if( !acceptSignedPost(buf.data(),buf.size(),strFrom,k,errmsg,NULL) )
|
if( !createDirectMessage(dmNewFormat, strFrom, strMsgData) )
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMS,errmsg);
|
throw JSONRPCError(RPC_INTERNAL_ERROR,
|
||||||
|
"error encrypting to pubkey of destination user");
|
||||||
{
|
// TODO: random order
|
||||||
StoredDirectMsg stoDM;
|
dmsToSend.push_back(&dmOldFormat);
|
||||||
stoDM.m_fromMe = true;
|
dmsToSend.push_back(&dmNewFormat);
|
||||||
stoDM.m_text = strMsg;
|
} else {
|
||||||
stoDM.m_utcTime = v["userpost"]["time"].integer();
|
dmsToSend.push_back(&dmOldFormat);
|
||||||
|
|
||||||
LOCK(cs_twister);
|
|
||||||
m_users[strFrom].m_directmsg[strTo].push_back(stoDM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent_handle h = startTorrentUser(strFrom, true);
|
Value ret;
|
||||||
h.add_piece(k,buf.data(),buf.size());
|
|
||||||
|
|
||||||
hexcapePost(v);
|
BOOST_FOREACH(entry *dm, dmsToSend) {
|
||||||
return entryToJson(v);
|
entry v;
|
||||||
|
if( !createSignedUserpost(v, strFrom, k, "",
|
||||||
|
NULL, NULL, dm,
|
||||||
|
std::string(""), 0) )
|
||||||
|
throw JSONRPCError(RPC_INTERNAL_ERROR,"error signing post with private key of user");
|
||||||
|
|
||||||
|
std::vector<char> buf;
|
||||||
|
bencode(std::back_inserter(buf), v);
|
||||||
|
|
||||||
|
std::string errmsg;
|
||||||
|
if( !acceptSignedPost(buf.data(),buf.size(),strFrom,k,errmsg,NULL) )
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMS,errmsg);
|
||||||
|
|
||||||
|
if( !copySelf ) {
|
||||||
|
// do not send a copy to self, so just store it locally.
|
||||||
|
StoredDirectMsg stoDM;
|
||||||
|
stoDM.m_fromMe = true;
|
||||||
|
stoDM.m_text = strMsg;
|
||||||
|
stoDM.m_utcTime = v["userpost"]["time"].integer();
|
||||||
|
|
||||||
|
LOCK(cs_twister);
|
||||||
|
m_users[strFrom].m_directmsg[strTo].push_back(stoDM);
|
||||||
|
}
|
||||||
|
|
||||||
|
torrent_handle h = startTorrentUser(strFrom, true);
|
||||||
|
h.add_piece(k++,buf.data(),buf.size());
|
||||||
|
|
||||||
|
hexcapePost(v);
|
||||||
|
ret = entryToJson(v);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value newrtmsg(const Array& params, bool fHelp)
|
Value newrtmsg(const Array& params, bool fHelp)
|
||||||
|
Loading…
Reference in New Issue
Block a user