Merge branch 'master'

This commit is contained in:
zeners 2016-03-12 16:46:33 +01:00
commit b1da4ed67e
55 changed files with 650 additions and 267 deletions

View file

@ -32,10 +32,10 @@ addons:
branch_pattern: coverity_scan branch_pattern: coverity_scan
before_script: before_script:
- qmake CONFIG+=NO_SQLCIPHER - qmake CONFIG+=NO_SQLCIPHER CONFIG+=tests
#script: make #script: make
script: if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make ; fi script: if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make && tests/unittests/unittests >/dev/null 2>&1 ; fi
#after_success: #after_success:

View file

@ -102,8 +102,7 @@ The webUI needs to be enabled as a parameter option in retroshare-nogui:
./retroshare-nogui --webinterface 9090 --docroot /usr/share/RetroShare06/webui/ ./retroshare-nogui --webinterface 9090 --docroot /usr/share/RetroShare06/webui/
``` ```
The webUI is only accessible on localhost:9090 (unless you canged that The webUI is only accessible on localhost:9090. It is advised to keep it that way so that your RS
option in the GUI). It is advised to keep it that way so that your RS
cannot be controlled using an untrusted connection. cannot be controlled using an untrusted connection.
To access your web UI from a distance, just open a SSH tunnel on it: To access your web UI from a distance, just open a SSH tunnel on it:
@ -118,3 +117,10 @@ distant_machine:~/ > ssh rs_host -L 9090:localhost:9090 -N
http://localhost:9090 http://localhost:9090
That also works with a retroshare GUI of course. That also works with a retroshare GUI of course.
Compile and run tests
---------------------
qmake CONFIG+=tests
make
tests/unittests/unittests

View file

@ -38,3 +38,12 @@ wikipoos {
pegmarkdown.file = supportlibs/pegmarkdown/pegmarkdown.pro pegmarkdown.file = supportlibs/pegmarkdown/pegmarkdown.pro
retroshare_gui.depends += pegmarkdown retroshare_gui.depends += pegmarkdown
} }
tests {
SUBDIRS += librssimulator
librssimulator.file = tests/librssimulator/librssimulator.pro
SUBDIRS += unittests
unittests.file = tests/unittests/unittests.pro
unittests.depends = libretroshare librssimulator
}

View file

@ -65,13 +65,15 @@ VOIP
M [ ] Video Snapshots https://support.skype.com/en/faq/FA1222/what-is-video-snapshot M [ ] Video Snapshots https://support.skype.com/en/faq/FA1222/what-is-video-snapshot
M [ ] Voice Messaging (record and send a voice message) M [ ] Voice Messaging (record and send a voice message)
M [ ] Video Messages (send a video greeting to multiple friends/coworkers/developers at once.) M [ ] Video Messages (send a video greeting to multiple friends/coworkers/developers at once.)
M [ ] Add Call status (when im on the phone changes my status with phone icon)
H [ ] Audio Conference H [ ] Audio Conference
H [ ] Video Conference H [ ] Video Conference
Messages Messages
H [X] make the mail system re-send failed emails notified by the global router. This is hard because it needs a proper management of duplicate messages H [X] make the mail system re-send failed emails notified by the global router. This is hard because it needs a proper management of duplicate messages
E [X] add flags to allow distant messaging from contact list only / everyone / noone / only signed ids. E [X] add flags to allow distant messaging from contact list only / everyone / noone / only signed ids.
M [ ] add Signature feature to rs messages M [ ] add Signature feature to messages
M [ ] add vacation responser for messages (automatic replies)
Chat Chat
E [X] add flags to allow distant chat from contact list only / everyone / noone / only signed ids. E [X] add flags to allow distant chat from contact list only / everyone / noone / only signed ids.

View file

@ -1,5 +1,70 @@
retroshare06 (0.6.0-1.XXXXXX~YYYYYY) YYYYYY; urgency=low retroshare06 (0.6.0-1.XXXXXX~YYYYYY) YYYYYY; urgency=low
bb26069 csoler Wed, 2 Mar 2016 19:00:51 -0500 attempt at fixing negative bw rates in GUI that may pop up when an erro
20fcf63 electron128 Fri, 26 Feb 2016 18:13:20 +0100 Merge pull request #285 from PhenomRetroShare/Fix_SSGxsChannelGro
1a110e4 Phenom Mon, 22 Feb 2016 19:07:49 +0100 Define empty service string as a valid case.
3c3d23b Phenom Wed, 17 Feb 2016 19:27:28 +0100 Fix error "(EE) SSGxsChannelGroup::load() asked to load a null string.
0bcf52c csoler Wed, 24 Feb 2016 16:51:25 -0500 added missing update of mRecvTS in database when updating a group meta
d1fd5d3 defnax Wed, 24 Feb 2016 21:51:34 +0100 update todo
7b1460c defnax Wed, 24 Feb 2016 21:45:43 +0100 Merge branch 'master' of https://github.com/RetroShare/RetroShare
f5eb791 csoler Tue, 23 Feb 2016 23:04:04 -0500 added notification for modified metadata in group. Does not yet work o
b8c42a9 csoler Tue, 23 Feb 2016 22:43:13 -0500 added copy of previous subscription flags when group update is receive
fafe75d csoler Tue, 23 Feb 2016 22:20:40 -0500 added update of mServerUpdateTS up to last mRecvTS of each group, whic
a6f0b8d csoler Mon, 22 Feb 2016 16:57:13 -0500 Merge pull request #290 from sehraf/pr-improved-unused-location-c
dbdfdcd sehraf Mon, 22 Feb 2016 21:09:10 +0100 removed unused map lookups
77166cb sehraf Mon, 22 Feb 2016 16:41:31 +0100 impoved cleanup of unused locations
cd4d743 csoler Mon, 22 Feb 2016 10:14:29 -0500 added missing -lpthread
3446e20 csoler Sun, 21 Feb 2016 11:47:44 -0500 removed debug output from p3grouter.cc
1222e82 electron128 Sun, 21 Feb 2016 11:23:33 +0100 fix format in readme
dcbd99f electron128 Sun, 21 Feb 2016 11:20:14 +0100 Merge pull request #202 from electron128/fixtests
5a48070 csoler Fri, 19 Feb 2016 10:45:18 -0500 Merge pull request #281 from sehraf/pr-disc-increase-auto-clean-t
4140969 sehraf Fri, 19 Feb 2016 16:32:57 +0100 added seperated limit for discovery (30 days)
6695a38 Thunder Thu, 18 Feb 2016 17:21:15 +0100 Merge pull request #283 from PhenomRetroShare/Fix_ChatMsgItemAvatar_u
e639dc5 Phenom Wed, 17 Feb 2016 17:37:09 +0100 Fix connect for avatar updateAvatar in ChatMsgItem and MessengerWindow
b059a8e Thunder Wed, 17 Feb 2016 20:23:44 +0100 Merge pull request #284 from PhenomRetroShare/Fix_CannotUpdateAvatarE
dc2578b Phenom Wed, 17 Feb 2016 18:18:56 +0100 Fix "(EE) cannot update avatar. mId has unhandled type." error.
697ef40 csoler Wed, 17 Feb 2016 09:38:36 -0500 added test against arbitrary large items in turtle search requests.
51d90a4 csoler Wed, 17 Feb 2016 09:37:34 -0500 added test against arbitrary large items in turtle search requests.
c15e8b5 csoler Tue, 16 Feb 2016 17:46:34 -0500 Merge pull request #282 from PhenomRetroShare/Add_MinSizeForStack
d878334 csoler Tue, 16 Feb 2016 17:45:49 -0500 Merge pull request #206 from realityfabric/master
3276790 Phenom Tue, 16 Feb 2016 23:15:33 +0100 Add minimal Size for stackPages in MainWindow for first start.
841299d sehraf Tue, 16 Feb 2016 20:20:41 +0100 discovery: don't remove new added locations too soon
efadc7d csoler Sun, 14 Feb 2016 13:38:08 -0500 Merge pull request #270 from PhenomRetroShare/Fix_GxsChannelFilte
44882b9 csoler Sun, 14 Feb 2016 13:35:32 -0500 Merge pull request #278 from PhenomRetroShare/Fix_bencode.c_Compi
3ab7c89 csoler Sun, 14 Feb 2016 13:33:27 -0500 Merge pull request #279 from cavebeat/single_dh_op
9843c83 cave beat Sun, 14 Feb 2016 18:49:37 +0100 added openSSL option SSL_OP_SINGLE_DH_USE regarding CVE-2016-0701
7d21666 Phenom Sun, 14 Feb 2016 17:40:10 +0100 Fix compilation of bencode.c for C compilator.
821c144 electron128 Sun, 14 Feb 2016 12:48:52 +0100 remove dead code from RsNotify (old forum and channel read status
63a8260 electron128 Sun, 14 Feb 2016 11:53:27 +0100 change RsNotify to use RsGxsId for chat lobby events
36135d4 electron128 Sun, 14 Feb 2016 10:23:37 +0100 added info about tests to readme
11dcbb7 electron128 Sun, 14 Feb 2016 10:23:26 +0100 remove wrong info about webui from readme (webui settings in gui
68cd1f9 electron128 Sun, 14 Feb 2016 10:21:48 +0100 disabled gxs_grp_sync test, because it fails after rebase to mast
abf7a72 defnax Sat, 13 Feb 2016 17:38:01 +0100 increase default font size for the ListWidget.
8637d3c defnax Sat, 13 Feb 2016 16:15:41 +0100 Fixed issue #263
a031d1e electron128 Thu, 24 Dec 2015 12:57:52 +0100 disabled tlvrandom test because it is buggy and fails sometimes
b874167 electron128 Thu, 24 Dec 2015 11:58:57 +0100 give gxs grp sync test more time, because of sync and timestamp u
8f64df0 electron128 Sun, 20 Dec 2015 17:24:13 +0100 fix compile for new gxs metadata serialisation
a6a3d66 electron128 Sun, 20 Dec 2015 14:32:11 +0100 exclude not serialised member from operator== for RsNxsTransac
a8b2bc7 electron128 Sun, 20 Dec 2015 14:31:26 +0100 fixed threading issue in NxsTestHub. NxsTesthub has to wait for i
63c6629 electron128 Sun, 20 Dec 2015 14:29:24 +0100 added missing initialisation of local, not serialised msg meta da
dca7dec electron128 Wed, 16 Dec 2015 17:34:35 +0100 attempt to fix output redirect for unittests in travis
218daa8 electron128 Sun, 13 Dec 2015 20:50:31 +0100 enabled RsNxsItem test
c03ce56 electron128 Sun, 13 Dec 2015 20:50:08 +0100 added missing mutex in nxstesthub
aa93505 electron128 Sun, 13 Dec 2015 20:49:44 +0100 added missing lock in RsSharedPtr destructor
64b9e34 electron128 Sun, 13 Dec 2015 20:48:55 +0100 fixed uninitialised memory read in test libretroshare_gxs.gxs_grp
7d0845e electron128 Sun, 13 Dec 2015 20:48:05 +0100 redirect travis testing output to /dev/null, because the logfile
8d15f44 electron128 Sun, 13 Dec 2015 18:44:24 +0100 added CONFIG+=NO_SQLCIPHER support to unittests (travis wants thi
9f92212 electron128 Sun, 13 Dec 2015 17:22:31 +0100 - make tests compile - added tests to travis.yml - excluded grout
3e4c154 csoler Fri, 12 Feb 2016 23:08:59 -0500 Merge pull request #275 from PhenomRetroShare/Fix_GenCertDialogOn
3ebb8c6 Phenom Fri, 12 Feb 2016 17:54:35 +0100 Fix GenCertDialog on Mac stay on.
4033f35 defnax Mon, 8 Feb 2016 21:34:45 +0100 update todo
5f0afb3 Phenom Mon, 8 Feb 2016 19:42:56 +0100 Fix Channel filter when loading big post. And fix "Not a GxsChannelPost
7ded128 thunder2 Sat, 6 Feb 2016 19:18:22 +0100 Update rsversion.in
-- Cyril Soler <csoler@users.sourceforge.net> Sun, 06 Mar 2016 20:00:00 -0500
retroshare06 (0.6.0-1.20160206.4a8edee6~trusty) trusty; urgency=low
a41d9df csoler Mon, 1 Feb 2016 09:59:13 -0500 fixed small bug in probability computation in grouter a41d9df csoler Mon, 1 Feb 2016 09:59:13 -0500 fixed small bug in probability computation in grouter
6d1a393 csoler Mon, 1 Feb 2016 00:33:11 -0500 fixed but in re-sending of failed grouter items 6d1a393 csoler Mon, 1 Feb 2016 00:33:11 -0500 fixed but in re-sending of failed grouter items
aa194ca csoler Sun, 31 Jan 2016 20:27:53 -0500 fixed bug preventing save of routage info in distant messaging aa194ca csoler Sun, 31 Jan 2016 20:27:53 -0500 fixed bug preventing save of routage info in distant messaging

View file

@ -1141,9 +1141,17 @@ void p3GRouter::locked_collectAvailableFriends(const GRouterKeyId& gxs_id,const
for(uint32_t i=0;i<tmp_peers.size();++i) for(uint32_t i=0;i<tmp_peers.size();++i)
if(incoming_routes.find(tmp_peers[i]) != incoming_routes.end()) if(incoming_routes.find(tmp_peers[i]) != incoming_routes.end())
{
#ifdef GROUTER_DEBUG
std::cerr << " removing " << tmp_peers[i] << " which is an incoming route" << std::endl; std::cerr << " removing " << tmp_peers[i] << " which is an incoming route" << std::endl;
#endif
}
else if(probas[i] < RS_GROUTER_PROBABILITY_THRESHOLD_BEST_PEERS_SELECT*max_probability) else if(probas[i] < RS_GROUTER_PROBABILITY_THRESHOLD_BEST_PEERS_SELECT*max_probability)
{
#ifdef GROUTER_DEBUG
std::cerr << " removing " << tmp_peers[i] << " because probability is below best peers threshold" << std::endl; std::cerr << " removing " << tmp_peers[i] << " because probability is below best peers threshold" << std::endl;
#endif
}
else else
{ {
tmp_peers[count] = tmp_peers[i] ; tmp_peers[count] = tmp_peers[i] ;
@ -1200,7 +1208,9 @@ void p3GRouter::locked_collectAvailableFriends(const GRouterKeyId& gxs_id,const
uint32_t real_dupl = std::min( duplication_factor - max_count+1,std::max(1u,uint32_t(rint(ideal_dupl)))) ; uint32_t real_dupl = std::min( duplication_factor - max_count+1,std::max(1u,uint32_t(rint(ideal_dupl)))) ;
duplication_factor_delta = real_dupl - ideal_dupl ; duplication_factor_delta = real_dupl - ideal_dupl ;
#ifdef GROUTER_DEBUG
std::cerr << " Peer " << mypairs[i].second << " prob=" << mypairs[i].first << ", ideal_dupl=" << ideal_dupl << ", real=" << real_dupl << ". Delta = " << duplication_factor_delta << std::endl; std::cerr << " Peer " << mypairs[i].second << " prob=" << mypairs[i].first << ", ideal_dupl=" << ideal_dupl << ", real=" << real_dupl << ". Delta = " << duplication_factor_delta << std::endl;
#endif
friend_peers_and_duplication_factors[ mypairs[i].second ] = real_dupl ; // should be updated correctly friend_peers_and_duplication_factors[ mypairs[i].second ] = real_dupl ; // should be updated correctly
} }
@ -1533,11 +1543,18 @@ void p3GRouter::handleIncomingReceiptItem(RsGRouterSignedReceiptItem *receipt_it
else else
std::cerr << " checking receipt hash : OK" << std::endl; std::cerr << " checking receipt hash : OK" << std::endl;
#endif #endif
// check signature. // check signature. The policy if the following:
// if we're the destination:
// signature should check and signing key should be available // always ensures the receipt is valid
// else
// if key is available, signature should check // early protects against frodulent receipts that we can check
if(! verifySignedDataItem(receipt_item)) uint32_t error_status ;
if(! verifySignedDataItem(receipt_item,error_status))
if( (it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_IS_ORIGIN) || (error_status != RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE))
{ {
std::cerr << " checking receipt signature : FAILED. Receipt is dropped." << std::endl; std::cerr << " checking receipt signature : FAILED. Receipt is dropped. Error status=" << error_status << std::endl;
return ; return ;
} }
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
@ -1688,7 +1705,9 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
std::cerr << " step B: item is for us and is new, so make sure it's authentic and create a receipt" << std::endl; std::cerr << " step B: item is for us and is new, so make sure it's authentic and create a receipt" << std::endl;
#endif #endif
if(!verifySignedDataItem(data_item)) // we should get proper flags out of this uint32_t error_status ;
if(!verifySignedDataItem(data_item,error_status)) // we should get proper flags out of this
{ {
std::cerr << " verifying item signature: FAILED! Droping that item" ; std::cerr << " verifying item signature: FAILED! Droping that item" ;
std::cerr << " You probably received a message from a person you don't have key." << std::endl; std::cerr << " You probably received a message from a person you don't have key." << std::endl;
@ -1968,7 +1987,7 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi
return false ; return false ;
} }
} }
bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item) bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,uint32_t& error_status)
{ {
try try
{ {
@ -1987,9 +2006,6 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item)
if(!item->serialise_signed_data(data,data_size)) if(!item->serialise_signed_data(data,data_size))
throw std::runtime_error("Cannot serialise signed data.") ; throw std::runtime_error("Cannot serialise signed data.") ;
uint32_t error_status ;
if(!mGixs->validateData(data,data_size,item->signature,true,error_status)) if(!mGixs->validateData(data,data_size,item->signature,true,error_status))
{ {
switch(error_status) switch(error_status)
@ -2105,8 +2121,9 @@ bool p3GRouter::sendData(const RsGxsId& destination,const GRouterServiceId& clie
} }
// Verify the signature. If that fails, there's a bug somewhere!! // Verify the signature. If that fails, there's a bug somewhere!!
uint32_t error_status;
if(!verifySignedDataItem(data_item)) if(!verifySignedDataItem(data_item,error_status))
{ {
std::cerr << "Cannot verify data item that was just signed. Some error occured!" << std::endl; std::cerr << "Cannot verify data item that was just signed. Some error occured!" << std::endl;
delete data_item; delete data_item;

View file

@ -263,7 +263,7 @@ private:
// signs an item with the given key. // signs an item with the given key.
bool signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& id) ; bool signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& id) ;
bool verifySignedDataItem(RsGRouterAbstractMsgItem *item) ; bool verifySignedDataItem(RsGRouterAbstractMsgItem *item, uint32_t &error_status) ;
bool encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& destination_key) ; bool encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& destination_key) ;
bool decryptDataItem(RsGRouterGenericDataItem *item) ; bool decryptDataItem(RsGRouterGenericDataItem *item) ;

View file

@ -950,6 +950,7 @@ int RsDataService::updateGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator.toStdString()); cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator.toStdString());
cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags); cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags);
cv.put(KEY_NXS_HASH, grpMetaPtr->mHash.toStdString()); cv.put(KEY_NXS_HASH, grpMetaPtr->mHash.toStdString());
cv.put(KEY_RECV_TS, (int32_t)grpMetaPtr->mRecvTS);
cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId.toStdString()); cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId.toStdString());
offset = 0; offset = 0;

View file

@ -2013,8 +2013,12 @@ void RsGenExchange::publishMsgs()
grpId = msg->grpId; grpId = msg->grpId;
msg->metaData->recvTS = time(NULL); msg->metaData->recvTS = time(NULL);
// FIXTESTS global variable rsPeers not available in unittests!
if(rsPeers)
{
mRoutingClues[msg->metaData->mAuthorId].insert(rsPeers->getOwnId()) ; mRoutingClues[msg->metaData->mAuthorId].insert(rsPeers->getOwnId()) ;
mTrackingClues.push_back(std::make_pair(msg->msgId,rsPeers->getOwnId())) ; mTrackingClues.push_back(std::make_pair(msg->msgId,rsPeers->getOwnId())) ;
}
computeHash(msg->msg, msg->metaData->mHash); computeHash(msg->msg, msg->metaData->mHash);
mDataAccess->addMsgData(msg); mDataAccess->addMsgData(msg);
@ -2327,7 +2331,6 @@ void RsGenExchange::publishGrps()
{ {
grp->metaData = new RsGxsGrpMetaData(); grp->metaData = new RsGxsGrpMetaData();
grpItem->meta.mPublishTs = time(NULL); grpItem->meta.mPublishTs = time(NULL);
//grpItem->meta.mParentGrpId = std::string("empty");
*(grp->metaData) = grpItem->meta; *(grp->metaData) = grpItem->meta;
// TODO: change when publish key optimisation added (public groups don't have publish key // TODO: change when publish key optimisation added (public groups don't have publish key
@ -2802,10 +2805,14 @@ void RsGenExchange::processRecvdGroups()
if(!meta->mAuthorId.isNull()) if(!meta->mAuthorId.isNull())
mRoutingClues[meta->mAuthorId].insert(grp->PeerId()) ; mRoutingClues[meta->mAuthorId].insert(grp->PeerId()) ;
// This has been moved here (as opposed to inside part for new groups below) because it is used to update the server TS when updates
// of grp metadata arrive.
meta->mRecvTS = time(NULL);
// now check if group already existss // now check if group already existss
if(std::find(existingGrpIds.begin(), existingGrpIds.end(), grp->grpId) == existingGrpIds.end()) if(std::find(existingGrpIds.begin(), existingGrpIds.end(), grp->grpId) == existingGrpIds.end())
{ {
meta->mRecvTS = time(NULL);
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY) if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId(); meta->mOriginator = grp->PeerId();
@ -2919,6 +2926,11 @@ void RsGenExchange::performUpdateValidation()
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY) if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId(); gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information
// is received.
gu.newGrp->metaData->mSubscribeFlags = gu.oldGrpMeta->mSubscribeFlags ;
grps.insert(std::make_pair(gu.newGrp, gu.newGrp->metaData)); grps.insert(std::make_pair(gu.newGrp, gu.newGrp->metaData));
} }
else else
@ -2930,6 +2942,18 @@ void RsGenExchange::performUpdateValidation()
} }
mDataStore->updateGroup(grps); mDataStore->updateGroup(grps);
// notify the client
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, true);
for(uint32_t i=0;i<mGroupUpdates.size();++i)
c->mGrpIdList.push_back(mGroupUpdates[i].oldGrpMeta->mGroupId) ;
mNotifications.push_back(c);
// cleanup
mGroupUpdates.clear(); mGroupUpdates.clear();
} }

View file

@ -482,6 +482,13 @@ public:
static float computeCurrentSendingProbability() static float computeCurrentSendingProbability()
{ {
// FIXTESTS global variable rsConfig not available in unittests!
if(rsConfig == 0)
{
std::cerr << "computeCurrentSendingProbability(): rsConfig not initialised, returning 1.0"<<std::endl;
return 1.0;
}
int maxIn=50,maxOut=50; int maxIn=50,maxOut=50;
float currIn=0,currOut=0 ; float currIn=0,currOut=0 ;
@ -1830,19 +1837,15 @@ void RsGxsNetService::updateServerSyncTS()
// retrieve all grps and update TS // retrieve all grps and update TS
mDataStore->retrieveGxsGrpMetaData(gxsMap); mDataStore->retrieveGxsGrpMetaData(gxsMap);
#ifdef TO_REMOVE // (cyril) This code was previously removed because it sounded inconsistent: the list of grps normally does not need to be updated when
// (cyril) This code is removed because it is inconsistent: the list of grps does not need to be updated when // new posts arrive. The two (grp list and msg list) are handled independently. Still, when group meta data updates are received,
// new posts arrive. The two (grp list and msg list) are handled independently. // the server TS needs to be updated, because it is the only way to propagate the changes. So we update it to the publish time stamp,
// if needed.
// as a grp list server also note this is the latest item you have // as a grp list server also note this is the latest item you have
if(mGrpServerUpdateItem == NULL) if(mGrpServerUpdateItem == NULL)
mGrpServerUpdateItem = new RsGxsServerGrpUpdateItem(mServType); mGrpServerUpdateItem = new RsGxsServerGrpUpdateItem(mServType);
// First reset it. That's important because it will re-compute correct TS in case
// we have unsubscribed a group.
mGrpServerUpdateItem->grpUpdateTS = 0 ;
#endif
bool change = false; bool change = false;
// then remove from mServerMsgUpdateMap, all items that are not in the group list! // then remove from mServerMsgUpdateMap, all items that are not in the group list!
@ -1914,19 +1917,18 @@ void RsGxsNetService::updateServerSyncTS()
#endif #endif
} }
#ifdef TO_REMOVE // This is needed for group metadata updates to actually propagate: only a new grpUpdateTS will trigger the exchange of groups mPublishTs which
// This might be very inefficient with time. This is needed because an old message might have been received, so the last modification time // will then be compared and pssibly trigger a MetaData transmission. mRecvTS is upated when creating, receiving for the first time, or receiving
// needs to account for this so that a friend who hasn't // an update, all in rsgenexchange.cc, after group/update validation. It is therefore a local TS, that can be compared to grpUpdateTS (same machine).
if(mGrpServerUpdateItem->grpUpdateTS < grpMeta->mRecvTS) if(mGrpServerUpdateItem->grpUpdateTS < grpMeta->mRecvTS)
{ {
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
GXSNETDEBUG__G(grpId) << " updated msgUpdateTS to last RecvTS = " << time(NULL) - grpMeta->mRecvTS << " secs ago for group "<< grpId << std::endl; GXSNETDEBUG__G(grpId) << " updated msgUpdateTS to last RecvTS = " << time(NULL) - grpMeta->mRecvTS << " secs ago for group "<< grpId << ". This is probably because an update has been received." << std::endl;
#endif #endif
mGrpServerUpdateItem->grpUpdateTS = grpMeta->mRecvTS; mGrpServerUpdateItem->grpUpdateTS = grpMeta->mRecvTS;
change = true; change = true;
} }
#endif
} }
// actual change in config settings, then save configuration // actual change in config settings, then save configuration
@ -2705,8 +2707,9 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
#endif #endif
continue; continue;
} }
// FIXTESTS global variable rsReputations not available in unittests!
if(rsReputations->isIdentityBanned(syncItem->authorId)) if(rsReputations == 0){ std::cerr << "rsReputations==0, accepting all messages!" << std::endl; }
if(rsReputations && rsReputations->isIdentityBanned(syncItem->authorId))
{ {
#ifdef NXS_NET_DEBUG_1 #ifdef NXS_NET_DEBUG_1
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", Identity " << syncItem->authorId << " is banned. Not requesting message!" << std::endl; GXSNETDEBUG_PG(item->PeerId(),grpId) << ", Identity " << syncItem->authorId << " is banned. Not requesting message!" << std::endl;
@ -2944,8 +2947,9 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
haveItem = true; haveItem = true;
latestVersion = grpSyncItem->publishTs > metaIter->second->mPublishTs; latestVersion = grpSyncItem->publishTs > metaIter->second->mPublishTs;
} }
// FIXTESTS global variable rsReputations not available in unittests!
if(!grpSyncItem->authorId.isNull() && rsReputations->isIdentityBanned(grpSyncItem->authorId)) if(rsReputations == 0){ std::cerr << "rsReputations==0, accepting all groups!" << std::endl; }
if(!grpSyncItem->authorId.isNull() && rsReputations && rsReputations->isIdentityBanned(grpSyncItem->authorId))
{ {
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << " Identity " << grpSyncItem->authorId << " is banned. Not syncing group." << std::endl; GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << " Identity " << grpSyncItem->authorId << " is banned. Not syncing group." << std::endl;

View file

@ -2732,11 +2732,52 @@ bool p3PeerMgrIMPL::removeBannedIps()
// return ret; // return ret;
// } // }
/**
* @brief p3PeerMgrIMPL::removeUnusedLocations Removes all location offline for RS_PEER_OFFLINE_DELETE seconds or more. Keeps the most recent location per PGP id.
* @return true on success
*
* This function removes all location that are offline for too long defined by RS_PEER_OFFLINE_DELETE.
* It also makes sure that at least one location (the most recent) is kept.
*
* The idea of the function is the following:
* - keep track if there is at least one location per PGP id that is not offline for too long
* -> hasRecentLocation
* - keep track of most recent location per PGP id that is offline for too long (and its time stamp)
* -> mostRecentLocation
* -> mostRecentTime
*
* When a location is found that is offline for too long the following points are checked from the top to the bottom:
* 1) remove it when the PGP id has a location that is not offline for too long
* 2) remove it when the PGP id has a more recent location
* 3) keep it when it is the most recent location
* This location will possibly be removed when a more recent (but still offline for too long) is found
*/
bool p3PeerMgrIMPL::removeUnusedLocations() bool p3PeerMgrIMPL::removeUnusedLocations()
{ {
std::list<RsPeerId> toRemove; std::list<RsPeerId> toRemove;
std::map<RsPgpId, bool> hasRecentLocation;
std::map<RsPgpId, time_t> mostRecentTime;
std::map<RsPgpId, RsPeerId> mostRecentLocation;
// init maps
{
std::list<RsPgpId> pgpList;
if(!rsPeers->getGPGAcceptedList(pgpList))
return false;
std::list<RsPgpId>::iterator it;
for(it = pgpList.begin(); it != pgpList.end(); ++it)
{
hasRecentLocation[*it] = false;
mostRecentTime[*it] = (time_t)0;
}
}
const time_t now = time(NULL);
RsPgpId pgpID;
{ {
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
@ -2744,19 +2785,71 @@ bool p3PeerMgrIMPL::removeUnusedLocations()
std::cerr << "p3PeerMgr::removeUnusedLocations()" << std::endl; std::cerr << "p3PeerMgr::removeUnusedLocations()" << std::endl;
#endif #endif
time_t now = time(NULL);
std::map<RsPeerId, peerState>::iterator it; std::map<RsPeerId, peerState>::iterator it;
for(it = mFriendList.begin(); it != mFriendList.end(); ++it) for(it = mFriendList.begin(); it != mFriendList.end(); ++it)
{ {
pgpID = it->second.gpg_id;
// store some references to speed up accessing
RsPeerId &idRef = mostRecentLocation[pgpID];
bool &recentRef = hasRecentLocation[pgpID];
if (now > it->second.lastcontact + RS_PEER_OFFLINE_DELETE) if (now > it->second.lastcontact + RS_PEER_OFFLINE_DELETE)
{ {
// location is too old
if(recentRef)
{
// there is already one location that won't get removed
// -> we can safely remove this one
toRemove.push_back(it->first); toRemove.push_back(it->first);
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "p3PeerMgr::removeUnusedLocations() removing Old SSL Id: " << it->first << std::endl; std::cerr << "p3PeerMgr::removeUnusedLocations() removing Old SSL Id: " << it->first << std::endl;
#endif #endif
}
else
{
// we need to take care that the most recent location it not removed
time_t &timeRef = mostRecentTime[pgpID];
if(timeRef > it->second.lastcontact)
{
// this (it) location is longer offline compared to mostRecentLocation
// -> we can remove this one
toRemove.push_back(it->first);
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgr::removeUnusedLocations() removing Old SSL Id: " << it->first << std::endl;
#endif
}
else
{
// this (it) location is more recent compared to mostRecentLocation
// -> we can remove mostRecentLocation
if(!idRef.isNull())
{
toRemove.push_back(idRef);
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgr::removeUnusedLocations() removing Old SSL Id: " << it->first << std::endl;
#endif
}
// update maps
idRef = it->first;
timeRef = it->second.lastcontact;
}
}
}
else
{
// found a location that won't get removed
recentRef = true;
// we can remove mostRecentLocation if it is set
if(!idRef.isNull())
{
toRemove.push_back(idRef);
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgr::removeUnusedLocations() removing Old SSL Id: " << it->first << std::endl;
#endif
}
} }
// if (isDummyFriend(it->first)) // if (isDummyFriend(it->first))
@ -2771,8 +2864,8 @@ bool p3PeerMgrIMPL::removeUnusedLocations()
} }
} }
std::list<RsPeerId>::iterator it;
std::list<RsPeerId>::iterator it;
for(it = toRemove.begin(); it != toRemove.end(); ++it) for(it = toRemove.begin(); it != toRemove.end(); ++it)
{ {
removeFriend(*it, false); removeFriend(*it, false);

View file

@ -823,8 +823,6 @@ continue_packet:
std::cerr << "[" << (void*)pthread_self() << "] " << "deserializing. Size=" << pktlen << std::endl ; std::cerr << "[" << (void*)pthread_self() << "] " << "deserializing. Size=" << pktlen << std::endl ;
#endif #endif
inReadBytes_locked(pktlen); // only count deserialised packets, because that's what is actually been transfered.
RsItem *pkt = mRsSerialiser->deserialise(block, &pktlen); RsItem *pkt = mRsSerialiser->deserialise(block, &pktlen);
if ((pkt != NULL) && (0 < handleincomingitem_locked(pkt,pktlen))) if ((pkt != NULL) && (0 < handleincomingitem_locked(pkt,pktlen)))
@ -832,6 +830,7 @@ continue_packet:
#ifdef DEBUG_PQISTREAMER #ifdef DEBUG_PQISTREAMER
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "Successfully Read a Packet!"); pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "Successfully Read a Packet!");
#endif #endif
inReadBytes_locked(pktlen); // only count deserialised packets, because that's what is actually been transfered.
} }
else else
{ {
@ -952,7 +951,7 @@ int pqistreamer::inAllowedBytes_locked()
static const float AVG_PERIOD = 5; // sec static const float AVG_PERIOD = 5; // sec
static const float AVG_FRAC = 0.8; // for low pass filter. static const float AVG_FRAC = 0.8; // for low pass filter.
void pqistreamer::outSentBytes_locked(int outb) void pqistreamer::outSentBytes_locked(uint32_t outb)
{ {
#ifdef DEBUG_PQISTREAMER #ifdef DEBUG_PQISTREAMER
{ {
@ -1022,7 +1021,7 @@ void pqistreamer::outSentBytes_locked(int outb)
return; return;
} }
void pqistreamer::inReadBytes_locked(int inb) void pqistreamer::inReadBytes_locked(uint32_t inb)
{ {
#ifdef DEBUG_PQISTREAMER #ifdef DEBUG_PQISTREAMER
{ {

View file

@ -102,10 +102,10 @@ class pqistreamer: public PQInterface
float outTimeSlice_locked(); float outTimeSlice_locked();
int outAllowedBytes_locked(); int outAllowedBytes_locked();
void outSentBytes_locked(int ); void outSentBytes_locked(uint32_t );
int inAllowedBytes_locked(); int inAllowedBytes_locked();
void inReadBytes_locked(int ); void inReadBytes_locked(uint32_t );

View file

@ -514,20 +514,20 @@ bool p3GxsChannels::setChannelDownloadDirectory(const RsGxsGroupId &groupId, con
return true; return true;
} }
bool p3GxsChannels::getChannelDownloadDirectory(const RsGxsGroupId & id,std::string& directory) bool p3GxsChannels::getChannelDownloadDirectory(const RsGxsGroupId & groupId,std::string& directory)
{ {
#ifdef GXSCHANNELS_DEBUG #ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::autoDownloadEnabled(" << id << ")" << std::endl; std::cerr << "p3GxsChannels::getChannelDownloadDirectory(" << id << ")" << std::endl;
#endif #endif
std::map<RsGxsGroupId, RsGroupMetaData>::iterator it; std::map<RsGxsGroupId, RsGroupMetaData>::iterator it;
it = mSubscribedGroups.find(id); it = mSubscribedGroups.find(groupId);
if (it == mSubscribedGroups.end()) if (it == mSubscribedGroups.end())
{ {
#ifdef GXSCHANNELS_DEBUG #ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::autoDownloadEnabled() No Entry" << std::endl; std::cerr << "p3GxsChannels::getChannelDownloadDirectory() No Entry" << std::endl;
#endif #endif
return false; return false;
@ -904,7 +904,7 @@ void p3GxsChannels::handleResponse(uint32_t token, uint32_t req_type)
/********************************************************************************************/ /********************************************************************************************/
bool p3GxsChannels::autoDownloadEnabled(const RsGxsGroupId &id,bool& enabled) bool p3GxsChannels::autoDownloadEnabled(const RsGxsGroupId &groupId,bool& enabled)
{ {
#ifdef GXSCHANNELS_DEBUG #ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::autoDownloadEnabled(" << id << ")"; std::cerr << "p3GxsChannels::autoDownloadEnabled(" << id << ")";
@ -913,7 +913,7 @@ bool p3GxsChannels::autoDownloadEnabled(const RsGxsGroupId &id,bool& enabled)
std::map<RsGxsGroupId, RsGroupMetaData>::iterator it; std::map<RsGxsGroupId, RsGroupMetaData>::iterator it;
it = mSubscribedGroups.find(id); it = mSubscribedGroups.find(groupId);
if (it == mSubscribedGroups.end()) if (it == mSubscribedGroups.end())
{ {
#ifdef GXSCHANNELS_DEBUG #ifdef GXSCHANNELS_DEBUG
@ -934,15 +934,17 @@ bool p3GxsChannels::autoDownloadEnabled(const RsGxsGroupId &id,bool& enabled)
bool SSGxsChannelGroup::load(const std::string &input) bool SSGxsChannelGroup::load(const std::string &input)
{ {
if(input.empty())
{
#ifdef GXSCHANNELS_DEBUG
std::cerr << "SSGxsChannelGroup::load() asked to load a null string." << std::endl;
#endif
return true ;
}
int download_val; int download_val;
mAutoDownload = false; mAutoDownload = false;
mDownloadDirectory.clear(); mDownloadDirectory.clear();
if(input.empty())
{
std::cerr << "(EE) SSGxsChannelGroup::load() asked to load a null string. Weird." << std::endl;
return false ;
}
RsTemporaryMemory tmpmem(input.length()); RsTemporaryMemory tmpmem(input.length());

View file

@ -45,7 +45,7 @@
class SSGxsChannelGroup class SSGxsChannelGroup
{ {
public: public:
SSGxsChannelGroup(): mAutoDownload(false), mDownloadDirectory("") {}
bool load(const std::string &input); bool load(const std::string &input);
std::string save() const; std::string save() const;
@ -176,7 +176,7 @@ static uint32_t channelsAuthenPolicy();
void updateSubscribedGroup(const RsGroupMetaData &group); void updateSubscribedGroup(const RsGroupMetaData &group);
void clearUnsubscribedGroup(const RsGxsGroupId &id); void clearUnsubscribedGroup(const RsGxsGroupId &id);
bool setAutoDownload(const RsGxsGroupId &groupId, bool enabled); bool setAutoDownload(const RsGxsGroupId &groupId, bool enabled);
bool autoDownloadEnabled(const RsGxsGroupId &id, bool &enabled); bool autoDownloadEnabled(const RsGxsGroupId &groupId, bool &enabled);

View file

@ -70,7 +70,7 @@ void PeerNode::provideFileHash(const RsFileHash& hash)
void PeerNode::manageFileHash(const RsFileHash& hash) void PeerNode::manageFileHash(const RsFileHash& hash)
{ {
_managed_hashes.insert(hash) ; _managed_hashes.insert(hash) ;
_turtle->monitorTunnels(hash,_turtle_client) ; _turtle->monitorTunnels(hash,_turtle_client, false) ;
} }
void PeerNode::sendToGRKey(const GRouterKeyId& key_id) void PeerNode::sendToGRKey(const GRouterKeyId& key_id)
{ {

View file

@ -859,7 +859,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << " Dropping, because the serial size exceeds the accepted limit." << std::endl ; std::cerr << " Dropping, because the serial size exceeds the accepted limit." << std::endl ;
#endif #endif
std::cerr << " Caught a turtle search item with arbitrary large size from " << item->PeerId() << " of size " << item->serial_size() << ". This is not allowed => dropping." << std::endl; std::cerr << " Caught a turtle search item with arbitrary large size from " << item->PeerId() << " of size " << item->serial_size() << " and depth " << item->depth << ". This is not allowed => dropping." << std::endl;
return ; return ;
} }

View file

@ -65,7 +65,9 @@ public:
~RsSharedPtr() ~RsSharedPtr()
{ {
lock();
DecrementAndDeleteIfLast(); DecrementAndDeleteIfLast();
unlock();
} }
private: private:

View file

@ -65,7 +65,7 @@
#define HOST_SEARCH "search" #define HOST_SEARCH "search"
#define HOST_CERTIFICATE "certificate" #define HOST_CERTIFICATE "certificate"
#define HOST_PUBLIC_MSG "public_msg" #define HOST_PUBLIC_MSG "public_msg"
#define HOST_REGEXP "file|person|forum|channel|search|message|certificate|private_chat|public_msg" #define HOST_REGEXP "file|extra|person|forum|channel|search|message|certificate|private_chat|public_msg"
#define FILE_NAME "name" #define FILE_NAME "name"
#define FILE_SIZE "size" #define FILE_SIZE "size"

View file

@ -85,6 +85,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
ui.participantsList->setColumnHidden(COLUMN_ID,true); ui.participantsList->setColumnHidden(COLUMN_ID,true);
muteAct = new QAction(QIcon(), tr("Mute participant"), this); muteAct = new QAction(QIcon(), tr("Mute participant"), this);
banAct = new QAction(QIcon(":/icons/yellow_biohazard64.png"), tr("Ban this person (Sets negative opinion)"), this);
distantChatAct = new QAction(QIcon(":/images/chat_24.png"), tr("Start private chat"), this); distantChatAct = new QAction(QIcon(":/images/chat_24.png"), tr("Start private chat"), this);
sendMessageAct = new QAction(QIcon(":/images/mail_new.png"), tr("Send Message"), this); sendMessageAct = new QAction(QIcon(":/images/mail_new.png"), tr("Send Message"), this);
@ -103,6 +104,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
connect(muteAct, SIGNAL(triggered()), this, SLOT(changePartipationState())); connect(muteAct, SIGNAL(triggered()), this, SLOT(changePartipationState()));
connect(distantChatAct, SIGNAL(triggered()), this, SLOT(distantChatParticipant())); connect(distantChatAct, SIGNAL(triggered()), this, SLOT(distantChatParticipant()));
connect(sendMessageAct, SIGNAL(triggered()), this, SLOT(sendMessage())); connect(sendMessageAct, SIGNAL(triggered()), this, SLOT(sendMessage()));
connect(banAct, SIGNAL(triggered()), this, SLOT(banParticipant()));
connect(actionSortByName, SIGNAL(triggered()), this, SLOT(sortParcipants())); connect(actionSortByName, SIGNAL(triggered()), this, SLOT(sortParcipants()));
connect(actionSortByActivity, SIGNAL(triggered()), this, SLOT(sortParcipants())); connect(actionSortByActivity, SIGNAL(triggered()), this, SLOT(sortParcipants()));
@ -201,15 +203,16 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
contextMnu.addAction(distantChatAct); contextMnu.addAction(distantChatAct);
contextMnu.addAction(sendMessageAct); contextMnu.addAction(sendMessageAct);
contextMnu.addSeparator(); contextMnu.addSeparator();
contextMnu.addAction(muteAct);
contextMnu.addSeparator();
contextMnu.addAction(actionSortByActivity); contextMnu.addAction(actionSortByActivity);
contextMnu.addAction(actionSortByName); contextMnu.addAction(actionSortByName);
contextMnu.addSeparator();
contextMnu.addAction(muteAct);
contextMnu.addAction(banAct);
muteAct->setCheckable(true); muteAct->setCheckable(true);
muteAct->setEnabled(false); muteAct->setEnabled(false);
muteAct->setChecked(false); muteAct->setChecked(false);
banAct->setEnabled(false);
if (selectedItems.size()) if (selectedItems.size())
{ {
@ -219,6 +222,7 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
if(selectedItems.count()>1 || (RsGxsId(selectedItems.at(0)->text(COLUMN_ID).toStdString())!=nickName)) if(selectedItems.count()>1 || (RsGxsId(selectedItems.at(0)->text(COLUMN_ID).toStdString())!=nickName))
{ {
muteAct->setEnabled(true); muteAct->setEnabled(true);
banAct->setEnabled(true);
QList<QTreeWidgetItem*>::iterator item; QList<QTreeWidgetItem*>::iterator item;
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) { for (item = selectedItems.begin(); item != selectedItems.end(); ++item) {
@ -237,6 +241,40 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
contextMnu.exec(QCursor::pos()); contextMnu.exec(QCursor::pos());
} }
/**
* @brief Called when the "ban" menu is selected. Sets a negative reputation on the selected user.
*/
void ChatLobbyDialog::banParticipant()
{
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems();
if (selectedItems.isEmpty()) {
return;
}
QList<QTreeWidgetItem*>::iterator item;
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) {
RsGxsId nickname;
dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->getId(nickname) ;
RsGxsId gxs_id;
rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
// This test avoids to mute/ban your own identity
if (gxs_id!=nickname)
{
std::cerr << "Giving negative opinion to GXS id " << nickname << std::endl;
rsReputations->setOwnOpinion(nickname, RsReputations::OPINION_NEGATIVE);
dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->forceUpdate();
}
}
}
void ChatLobbyDialog::init() void ChatLobbyDialog::init()
{ {
ChatLobbyInfo linfo ; ChatLobbyInfo linfo ;
@ -502,6 +540,8 @@ void ChatLobbyDialog::updateParticipantsList()
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_yellow_128.png")); if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_yellow_128.png"));
widgetitem->updateBannedState();
QTime qtLastAct=QTime(0,0,0).addSecs(now-tLastAct); QTime qtLastAct=QTime(0,0,0).addSecs(now-tLastAct);
widgetitem->setToolTip(COLUMN_ICON,tr("Right click to mute/unmute participants<br/>Double click to address this person<br/>") widgetitem->setToolTip(COLUMN_ICON,tr("Right click to mute/unmute participants<br/>Double click to address this person<br/>")
+tr("This participant is not active since:") +tr("This participant is not active since:")

View file

@ -79,6 +79,7 @@ protected slots:
void distantChatParticipant(); void distantChatParticipant();
void participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item, int column); void participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item, int column);
void sendMessage(); void sendMessage();
void banParticipant();
private: private:
void updateParticipantsList(); void updateParticipantsList();
@ -104,6 +105,7 @@ private:
std::set<RsGxsId> mutedParticipants; std::set<RsGxsId> mutedParticipants;
QAction *muteAct; QAction *muteAct;
QAction *banAct;
QAction *distantChatAct; QAction *distantChatAct;
QAction *actionSortByName; QAction *actionSortByName;
QAction *actionSortByActivity; QAction *actionSortByActivity;

View file

@ -265,7 +265,13 @@ static QString getStyle(const QDir &styleDir, const QString &styleVariant, enumG
return style; return style;
} }
QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, const QDateTime &timestamp, const QString &message, unsigned int flag) QString ChatStyle::formatMessage(enumFormatMessage type
, const QString &name
, const QDateTime &timestamp
, const QString &message
, unsigned int flag
, const QColor &backgroundColor /*= Qt::white*/
)
{ {
bool me = false; bool me = false;
QDomDocument doc ; QDomDocument doc ;
@ -344,6 +350,8 @@ QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, co
#ifdef COLORED_NICKNAMES #ifdef COLORED_NICKNAMES
QColor color; QColor color;
QString colorName;
if (flag & CHAT_FORMATMSG_SYSTEM) { if (flag & CHAT_FORMATMSG_SYSTEM) {
color = Qt::darkBlue; color = Qt::darkBlue;
} else { } else {
@ -354,9 +362,14 @@ QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, co
} }
color.setHsv(hash, 255, 150); color.setHsv(hash, 255, 150);
// Always fix colors
qreal desiredContrast = Settings->valueFromGroup("Chat", "MinimumContrast", 4.5).toDouble();
colorName = color.name();
RsHtml::findBestColor(colorName, backgroundColor, desiredContrast);
} }
#else #else
Q_UNUSED(flag); Q_UNUSED(flag);
Q_UNUSED(backgroundColor);
#endif #endif
QString strName = RsHtml::plainText(name).prepend(QString("<a name=\"name\">")).append(QString("</a>")); QString strName = RsHtml::plainText(name).prepend(QString("<a name=\"name\">")).append(QString("</a>"));
@ -381,7 +394,7 @@ QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, co
.replace("%date%", strDate) .replace("%date%", strDate)
.replace("%time%", strTime) .replace("%time%", strTime)
#ifdef COLORED_NICKNAMES #ifdef COLORED_NICKNAMES
.replace("%color%", color.name()) .replace("%color%", colorName)
#endif #endif
.replace("%message%", messageBody ) ; .replace("%message%", messageBody ) ;
if ( !styleOptimized.isEmpty() ) { if ( !styleOptimized.isEmpty() ) {

View file

@ -23,6 +23,7 @@
#ifndef _CHATSTYLE_H #ifndef _CHATSTYLE_H
#define _CHATSTYLE_H #define _CHATSTYLE_H
#include <QColor>
#include <QString> #include <QString>
#include <QDateTime> #include <QDateTime>
#include <QHash> #include <QHash>
@ -82,7 +83,7 @@ public:
bool setStylePath(const QString &stylePath, const QString &styleVariant); bool setStylePath(const QString &stylePath, const QString &styleVariant);
bool setStyleFromSettings(enumStyleType styleType); bool setStyleFromSettings(enumStyleType styleType);
QString formatMessage(enumFormatMessage type, const QString &name, const QDateTime &timestamp, const QString &message, unsigned int flag = 0); QString formatMessage(enumFormatMessage type, const QString &name, const QDateTime &timestamp, const QString &message, unsigned int flag = 0, const QColor &backgroundColor = Qt::white);
static bool getAvailableStyles(enumStyleType styleType, QList<ChatStyleInfo> &styles); static bool getAvailableStyles(enumStyleType styleType, QList<ChatStyleInfo> &styles);
static bool getAvailableVariants(const QString &stylePath, QStringList &variants); static bool getAvailableVariants(const QString &stylePath, QStringList &variants);

View file

@ -914,7 +914,7 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const RsGxsId gx
QString formattedMessage = RsHtml().formatText(ui->textBrowser->document(), message, formatTextFlag, backgroundColor, desiredContrast, desiredMinimumFontSize); QString formattedMessage = RsHtml().formatText(ui->textBrowser->document(), message, formatTextFlag, backgroundColor, desiredContrast, desiredMinimumFontSize);
QDateTime dtTimestamp=incoming ? sendTime : recvTime; QDateTime dtTimestamp=incoming ? sendTime : recvTime;
QString formatMsg = chatStyle.formatMessage(type, name, dtTimestamp, formattedMessage, formatFlag); QString formatMsg = chatStyle.formatMessage(type, name, dtTimestamp, formattedMessage, formatFlag, backgroundColor);
QString timeStamp = dtTimestamp.toString(Qt::ISODate); QString timeStamp = dtTimestamp.toString(Qt::ISODate);
//replace Date and Time anchors //replace Date and Time anchors

View file

@ -32,10 +32,11 @@
#include "RsCollectionFile.h" #include "RsCollectionFile.h"
#include "util/misc.h" #include "util/misc.h"
#define COLUMN_FILE 0 #define COLUMN_FILE 0
#define COLUMN_SIZE 1 #define COLUMN_FILEPATH 1
#define COLUMN_HASH 2 #define COLUMN_SIZE 2
#define COLUMN_FILEC 3 #define COLUMN_HASH 3
#define COLUMN_COUNT 4 #define COLUMN_FILEC 4
#define COLUMN_COUNT 5
// In COLUMN_HASH (COLUMN_FILE reserved for CheckState) // In COLUMN_HASH (COLUMN_FILE reserved for CheckState)
#define ROLE_NAME Qt::UserRole + 1 #define ROLE_NAME Qt::UserRole + 1
#define ROLE_PATH Qt::UserRole + 2 #define ROLE_PATH Qt::UserRole + 2
@ -145,6 +146,7 @@ RsCollectionDialog::RsCollectionDialog(const QString& collectionFileName
QTreeWidgetItem *headerItem = ui._fileEntriesTW->headerItem(); QTreeWidgetItem *headerItem = ui._fileEntriesTW->headerItem();
headerItem->setText(COLUMN_FILE, tr("File")); headerItem->setText(COLUMN_FILE, tr("File"));
headerItem->setText(COLUMN_FILEPATH, tr("File Path"));
headerItem->setText(COLUMN_SIZE, tr("Size")); headerItem->setText(COLUMN_SIZE, tr("Size"));
headerItem->setText(COLUMN_HASH, tr("Hash")); headerItem->setText(COLUMN_HASH, tr("Hash"));
headerItem->setText(COLUMN_FILEC, tr("File Count")); headerItem->setText(COLUMN_FILEC, tr("File Count"));
@ -342,6 +344,7 @@ QTreeWidgetItem* RsCollectionDialog::getRootItem()
root->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate); root->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate);
root->setText(COLUMN_FILE, "/"); root->setText(COLUMN_FILE, "/");
root->setToolTip(COLUMN_FILE,tr("This is the root directory.")); root->setToolTip(COLUMN_FILE,tr("This is the root directory."));
root->setText(COLUMN_FILEPATH, "/");
root->setText(COLUMN_HASH, ""); root->setText(COLUMN_HASH, "");
root->setData(COLUMN_HASH, ROLE_NAME, ""); root->setData(COLUMN_HASH, ROLE_NAME, "");
root->setData(COLUMN_HASH, ROLE_PATH, ""); root->setData(COLUMN_HASH, ROLE_PATH, "");
@ -401,9 +404,9 @@ bool RsCollectionDialog::addChild(QTreeWidgetItem* parent, const std::vector<Col
QList<QTreeWidgetItem*> founds; QList<QTreeWidgetItem*> founds;
QList<QTreeWidgetItem*> parentsFounds; QList<QTreeWidgetItem*> parentsFounds;
parentsFounds = ui._fileEntriesTW->findItems(colFileInfo.path , Qt::MatchExactly | Qt::MatchRecursive, COLUMN_FILE); parentsFounds = ui._fileEntriesTW->findItems(colFileInfo.path , Qt::MatchExactly | Qt::MatchRecursive, COLUMN_FILEPATH);
if (colFileInfo.type == DIR_TYPE_DIR){ if (colFileInfo.type == DIR_TYPE_DIR){
founds = ui._fileEntriesTW->findItems(colFileInfo.path + "/" +colFileInfo.name, Qt::MatchExactly | Qt::MatchRecursive, COLUMN_FILE); founds = ui._fileEntriesTW->findItems(colFileInfo.path + "/" +colFileInfo.name, Qt::MatchExactly | Qt::MatchRecursive, COLUMN_FILEPATH);
} else { } else {
founds = ui._fileEntriesTW->findItems(colFileInfo.hash, Qt::MatchExactly | Qt::MatchRecursive, COLUMN_HASH); founds = ui._fileEntriesTW->findItems(colFileInfo.hash, Qt::MatchExactly | Qt::MatchRecursive, COLUMN_HASH);
} }
@ -413,7 +416,8 @@ bool RsCollectionDialog::addChild(QTreeWidgetItem* parent, const std::vector<Col
//item->setFlags(Qt::ItemIsUserCheckable | item->flags()); //item->setFlags(Qt::ItemIsUserCheckable | item->flags());
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate);
item->setCheckState(COLUMN_FILE, Qt::Checked); item->setCheckState(COLUMN_FILE, Qt::Checked);
item->setText(COLUMN_FILE, colFileInfo.path + "/" + colFileInfo.name); item->setText(COLUMN_FILE, colFileInfo.name);
item->setText(COLUMN_FILEPATH, colFileInfo.path + "/" + colFileInfo.name);
item->setText(COLUMN_HASH, colFileInfo.hash); item->setText(COLUMN_HASH, colFileInfo.hash);
item->setData(COLUMN_HASH, ROLE_NAME, colFileInfo.name); item->setData(COLUMN_HASH, ROLE_NAME, colFileInfo.name);
item->setData(COLUMN_HASH, ROLE_PATH, colFileInfo.path); item->setData(COLUMN_HASH, ROLE_PATH, colFileInfo.path);
@ -704,7 +708,7 @@ void RsCollectionDialog::addRecursive(bool recursive)
ColFileInfo root; ColFileInfo root;
if (item && (item != getRootItem())) { if (item && (item != getRootItem())) {
root.name = ""; root.name = "";
root.path = item->text(COLUMN_FILE); root.path = item->text(COLUMN_FILEPATH);
} else { } else {
root.name = ""; root.name = "";
root.path = ""; root.path = "";
@ -725,7 +729,7 @@ void RsCollectionDialog::addRecursive(bool recursive)
it.value() = dirToAdd.value(path); it.value() = dirToAdd.value(path);
} else if(item) { } else if(item) {
if (item->data(COLUMN_HASH, ROLE_NAME) != "") { if (item->data(COLUMN_HASH, ROLE_NAME) != "") {
it.value() = item->text(COLUMN_FILE); it.value() = item->text(COLUMN_FILEPATH);
}//if (item->data(COLUMN_HASH, ROLE_NAME) != "") }//if (item->data(COLUMN_HASH, ROLE_NAME) != "")
}//if (dirToAdd.contains(path)) }//if (dirToAdd.contains(path))
}//for (QHash<QString,QString>::Iterator it }//for (QHash<QString,QString>::Iterator it

View file

@ -46,6 +46,7 @@ void GxsIdRSTreeWidgetItem::init()
{ {
mIdFound = false; mIdFound = false;
mRetryWhenFailed = false; mRetryWhenFailed = false;
mBannedState = false ;
} }
static void fillGxsIdRSTreeWidgetItemCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/) static void fillGxsIdRSTreeWidgetItemCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/)
@ -114,6 +115,20 @@ void GxsIdRSTreeWidgetItem::setId(const RsGxsId &id, int column, bool retryWhenF
startProcess(); startProcess();
} }
void GxsIdRSTreeWidgetItem::updateBannedState()
{
if(mBannedState != rsReputations->isIdentityBanned(mId))
forceUpdate() ;
}
void GxsIdRSTreeWidgetItem::forceUpdate()
{
mIdFound = false;
mBannedState = rsReputations->isIdentityBanned(mId) ;
startProcess();
}
void GxsIdRSTreeWidgetItem::startProcess() void GxsIdRSTreeWidgetItem::startProcess()
{ {
if (mRetryWhenFailed) { if (mRetryWhenFailed) {

View file

@ -52,6 +52,10 @@ public:
void setAvatar(const RsGxsImage &avatar); void setAvatar(const RsGxsImage &avatar);
virtual QVariant data(int column, int role) const; virtual QVariant data(int column, int role) const;
void forceUpdate();
void setBannedState(bool b) { mBannedState = b; } // does not actually change the state, but used instead by callbacks to leave a trace
void updateBannedState() ; // checks reputation, and update is needed
private slots: private slots:
void startProcess(); void startProcess();
@ -62,6 +66,7 @@ private:
RsGxsId mId; RsGxsId mId;
int mColumn; int mColumn;
bool mIdFound; bool mIdFound;
bool mBannedState ;
bool mRetryWhenFailed; bool mRetryWhenFailed;
uint32_t mIconTypeMask; uint32_t mIconTypeMask;
RsGxsImage mAvatar; RsGxsImage mAvatar;

View file

@ -285,7 +285,8 @@ void ImHistoryBrowser::fillItem(QListWidgetItem *itemWidget, HistoryMsg& msg)
name = QString::fromUtf8(msg.peerName.c_str()); name = QString::fromUtf8(msg.peerName.c_str());
} }
QString formatMsg = style.formatMessage(type, name, QDateTime::fromTime_t(msg.sendTime), messageText); QColor backgroundColor = ui.listWidget->palette().base().color();
QString formatMsg = style.formatMessage(type, name, QDateTime::fromTime_t(msg.sendTime), messageText, 0, backgroundColor);
itemWidget->setData(Qt::DisplayRole, qVariantFromValue(IMHistoryItemPainter(formatMsg))); itemWidget->setData(Qt::DisplayRole, qVariantFromValue(IMHistoryItemPainter(formatMsg)));
itemWidget->setData(ROLE_MSGID, msg.msgId); itemWidget->setData(ROLE_MSGID, msg.msgId);

View file

@ -339,14 +339,15 @@ void ChatPage::setPreviewMessages(QString &stylePath, QString styleVariant, QTex
QString nameIncoming = tr("Incoming"); QString nameIncoming = tr("Incoming");
QString nameOutgoing = tr("Outgoing"); QString nameOutgoing = tr("Outgoing");
QDateTime timestmp = QDateTime::fromTime_t(time(NULL)); QDateTime timestmp = QDateTime::fromTime_t(time(NULL));
QColor backgroundColor = textBrowser->palette().base().color();
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_HINCOMING, nameIncoming, timestmp, tr("Incoming message in history"))); textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_HINCOMING, nameIncoming, timestmp, tr("Incoming message in history"), 0, backgroundColor));
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_HOUTGOING, nameOutgoing, timestmp, tr("Outgoing message in history"))); textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_HOUTGOING, nameOutgoing, timestmp, tr("Outgoing message in history"), 0, backgroundColor));
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_INCOMING, nameIncoming, timestmp, tr("Incoming message"))); textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_INCOMING, nameIncoming, timestmp, tr("Incoming message"), 0, backgroundColor));
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OUTGOING, nameOutgoing, timestmp, tr("Outgoing message"))); textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OUTGOING, nameOutgoing, timestmp, tr("Outgoing message"), 0, backgroundColor));
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OOUTGOING, nameOutgoing, timestmp, tr("Outgoing offline message"))); textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OOUTGOING, nameOutgoing, timestmp, tr("Outgoing offline message"), 0, backgroundColor));
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_SYSTEM, tr("System"), timestmp, tr("System message"))); textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_SYSTEM, tr("System"), timestmp, tr("System message"), 0, backgroundColor));
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OUTGOING, tr("UserName"), timestmp, tr("/me is sending a message with /me"))); textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OUTGOING, tr("UserName"), timestmp, tr("/me is sending a message with /me"), 0, backgroundColor));
} }
void ChatPage::fillPreview(QListWidget *listWidget, QComboBox *comboBox, QTextBrowser *textBrowser) void ChatPage::fillPreview(QListWidget *listWidget, QComboBox *comboBox, QTextBrowser *textBrowser)

View file

@ -23,7 +23,16 @@
<property name="spacing"> <property name="spacing">
<number>6</number> <number>6</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -103,6 +112,11 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="defaultDropAction"> <property name="defaultDropAction">
<enum>Qt::IgnoreAction</enum> <enum>Qt::IgnoreAction</enum>
</property> </property>
@ -165,11 +179,20 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>540</width> <width>540</width>
<height>495</height> <height>517</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="margin"> <property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number> <number>3</number>
</property> </property>
<item> <item>

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>611</width> <width>1468</width>
<height>408</height> <height>659</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -34,8 +34,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>593</width> <width>1450</width>
<height>156</height> <height>317</height>
</rect> </rect>
</property> </property>
</widget> </widget>
@ -83,7 +83,7 @@
</column> </column>
<column> <column>
<property name="text"> <property name="text">
<string>Data size</string> <string>Stored data size</string>
</property> </property>
</column> </column>
<column> <column>
@ -93,12 +93,12 @@
</column> </column>
<column> <column>
<property name="text"> <property name="text">
<string>Received</string> <string>Receive time (secs ago)</string>
</property> </property>
</column> </column>
<column> <column>
<property name="text"> <property name="text">
<string>Send</string> <string>Sending time (secs ago)</string>
</property> </property>
</column> </column>
<column> <column>

View file

@ -258,7 +258,7 @@ void RsHtml::embedHtml(QTextDocument *textDocument, QDomDocument& doc, QDomEleme
return; return;
QDomNodeList children = currentElement.childNodes(); QDomNodeList children = currentElement.childNodes();
for(uint index = 0; index < children.length(); index++) { for(uint index = 0; index < (uint)children.length(); index++) {
QDomNode node = children.item(index); QDomNode node = children.item(index);
if(node.isElement()) { if(node.isElement()) {
// child is an element, we skip it if it's an <a> tag // child is an element, we skip it if it's an <a> tag
@ -473,7 +473,7 @@ static void findElements(QDomDocument& doc, QDomElement& currentElement, const Q
} }
QDomNodeList children = currentElement.childNodes(); QDomNodeList children = currentElement.childNodes();
for (uint index = 0; index < children.length(); index++) { for (uint index = 0; index < (uint)children.length(); index++) {
QDomNode node = children.item(index); QDomNode node = children.item(index);
if (node.isElement()) { if (node.isElement()) {
QDomElement element = node.toElement(); QDomElement element = node.toElement();
@ -555,6 +555,7 @@ static qreal getContrastRatio(qreal lum1, qreal lum2)
* @brief Find a color with the same hue that provides the desired contrast with bglum. * @brief Find a color with the same hue that provides the desired contrast with bglum.
* @param[in,out] val Name of the original color. Will be modified. * @param[in,out] val Name of the original color. Will be modified.
* @param bglum Background's relative luminance as returned by getRelativeLuminance(). * @param bglum Background's relative luminance as returned by getRelativeLuminance().
* @param desiredContrast Contrast to get.
*/ */
static void findBestColor(QString &val, qreal bglum, qreal desiredContrast) static void findBestColor(QString &val, qreal bglum, qreal desiredContrast)
{ {
@ -651,7 +652,7 @@ static void optimizeHtml(QDomDocument& doc
bool addBR = false; bool addBR = false;
QDomNodeList children = currentElement.childNodes(); QDomNodeList children = currentElement.childNodes();
for (uint index = 0; index < children.length(); ) { for (uint index = 0; index < (uint)children.length(); ) {
QDomNode node = children.item(index); QDomNode node = children.item(index);
if (node.isElement()) { if (node.isElement()) {
QDomElement element = node.toElement(); QDomElement element = node.toElement();
@ -1087,3 +1088,9 @@ void RsHtml::insertSpoilerText(QTextCursor cursor)
QString html = QString("<a href=\"hidden:%1\" title=\"%1\">%2</a>").arg(encoded, publictext); QString html = QString("<a href=\"hidden:%1\" title=\"%1\">%2</a>").arg(encoded, publictext);
cursor.insertHtml(html); cursor.insertHtml(html);
} }
void RsHtml::findBestColor(QString &val, const QColor &backgroundColor /*= Qt::white*/, qreal desiredContrast /*= 1.0*/)
{
::findBestColor(val, ::getRelativeLuminance(backgroundColor), desiredContrast);
}

View file

@ -77,6 +77,7 @@ public:
static QString makeQuotedText(RSTextBrowser* browser); static QString makeQuotedText(RSTextBrowser* browser);
static void insertSpoilerText(QTextCursor cursor); static void insertSpoilerText(QTextCursor cursor);
static void findBestColor(QString &val, const QColor &backgroundColor = Qt::white, qreal desiredContrast = 1.0);
protected: protected:
void embedHtml(QTextDocument *textDocument, QDomDocument &doc, QDomElement &currentElement, EmbedInHtml& embedInfos, ulong flag); void embedHtml(QTextDocument *textDocument, QDomDocument &doc, QDomElement &currentElement, EmbedInHtml& embedInfos, ulong flag);

View file

@ -624,7 +624,8 @@ bool RsIntroStore::loadPeers()
std::cerr << "RsIntroStore::loadPeers() Cannot open file, trying tmp"; std::cerr << "RsIntroStore::loadPeers() Cannot open file, trying tmp";
std::cerr << std::endl; std::cerr << std::endl;
FILE *fd = fopen(mTempStoreFile.c_str(), "r"); fd = fopen(mTempStoreFile.c_str(), "r");
if (!fd) if (!fd)
{ {
std::cerr << "RsIntroStore::loadPeers() Cannot open tmp file"; std::cerr << "RsIntroStore::loadPeers() Cannot open tmp file";

View file

@ -32,6 +32,7 @@ bool operator ==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r)
if(!(l.keys == r.keys)) return false; if(!(l.keys == r.keys)) return false;
if(l.mGroupFlags != r.mGroupFlags) return false; if(l.mGroupFlags != r.mGroupFlags) return false;
if(l.mPublishTs != r.mPublishTs) return false; if(l.mPublishTs != r.mPublishTs) return false;
if(l.mSignFlags != r.mSignFlags) return false;
if(l.mAuthorId != r.mAuthorId) return false; if(l.mAuthorId != r.mAuthorId) return false;
if(l.mGroupName != r.mGroupName) return false; if(l.mGroupName != r.mGroupName) return false;
if(l.mGroupId != r.mGroupId) return false; if(l.mGroupId != r.mGroupId) return false;
@ -282,7 +283,8 @@ bool operator==(const RsNxsTransac& l, const RsNxsTransac& r){
if(l.transactFlag != r.transactFlag) return false; if(l.transactFlag != r.transactFlag) return false;
if(l.transactionNumber != r.transactionNumber) return false; if(l.transactionNumber != r.transactionNumber) return false;
if(l.timestamp != r.timestamp) return false; // timestamp is not serialised, see rsnxsitems.h
//if(l.timestamp != r.timestamp) return false;
if(l.nItems != r.nItems) return false; if(l.nItems != r.nItems) return false;

View file

@ -17,12 +17,12 @@ TEST(libretroshare_gxs, RsGxsData)
msgMeta1.clear(); msgMeta1.clear();
init_item(&msgMeta1); init_item(&msgMeta1);
uint32_t pktsize = grpMeta1.serial_size(); uint32_t pktsize = grpMeta1.serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
char grp_data[pktsize]; char grp_data[pktsize];
bool ok = true; bool ok = true;
ok &= grpMeta1.serialise(grp_data, pktsize); ok &= grpMeta1.serialise(grp_data, pktsize, RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
grpMeta2.clear(); grpMeta2.clear();
ok &= grpMeta2.deserialise(grp_data, pktsize); ok &= grpMeta2.deserialise(grp_data, pktsize);

View file

@ -25,8 +25,8 @@
* *
*/ */
// disabled, because it fails in GxsPublishGroupTest::testGrpMetaRetrieval()
TEST(libretroshare_gxs, RsGenExchange) TEST(libretroshare_gxs, DISABLED_RsGenExchange)
{ {
RsGeneralDataService* dataStore = new RsDataService("./", "testServiceDb", RS_SERVICE_TYPE_DUMMY, NULL, ""); RsGeneralDataService* dataStore = new RsDataService("./", "testServiceDb", RS_SERVICE_TYPE_DUMMY, NULL, "");

View file

@ -15,7 +15,8 @@ using namespace rs_nxs_test;
NxsGrpSync::NxsGrpSync(RsGcxs* circle, RsGixsReputation* reputation) NxsGrpSync::NxsGrpSync(RsGcxs* circle, RsGixsReputation* reputation):
mServType(0)
{ {
int numPeers = 2; int numPeers = 2;

View file

@ -17,7 +17,7 @@
using namespace rs_nxs_test; using namespace rs_nxs_test;
rs_nxs_test::NxsMsgSync::NxsMsgSync() rs_nxs_test::NxsMsgSync::NxsMsgSync()
: mPgpUtils(NULL) { : mPgpUtils(NULL), mServType(0) {
int numPeers = 2; int numPeers = 2;
// create 2 peers // create 2 peers

View file

@ -1,6 +1,6 @@
#include "nxstesthub.h" #include "nxstesthub.h"
#include <unistd.h>
class NotifyWithPeerId : public RsNxsObserver class NotifyWithPeerId : public RsNxsObserver
{ {
@ -21,6 +21,16 @@ public:
mTestHub.notifyNewGroups(mPeerId, groups); mTestHub.notifyNewGroups(mPeerId, groups);
} }
void notifyReceivePublishKey(const RsGxsGroupId& )
{
}
void notifyChangedGroupStats(const RsGxsGroupId&)
{
}
private: private:
RsPeerId mPeerId; RsPeerId mPeerId;
@ -50,7 +60,7 @@ private:
}; };
rs_nxs_test::NxsTestHub::NxsTestHub(NxsTestScenario::pointer testScenario) rs_nxs_test::NxsTestHub::NxsTestHub(NxsTestScenario::pointer testScenario)
: mTestScenario(testScenario) : mTestScenario(testScenario), mMtx("NxsTestHub Mutex")
{ {
std::list<RsPeerId> peers; std::list<RsPeerId> peers;
mTestScenario->getPeers(peers); mTestScenario->getPeers(peers);
@ -94,27 +104,6 @@ bool rs_nxs_test::NxsTestHub::testsPassed()
return mTestScenario->checkTestPassed(); return mTestScenario->checkTestPassed();
} }
void rs_nxs_test::NxsTestHub::run()
{
bool running = isRunning();
double timeDelta = .2;
while(running)
{
#ifndef WINDOWS_SYS
usleep((int) (timeDelta * 1000000));
#else
Sleep((int) (timeDelta * 1000));
#endif
tick();
running = isRunning();
}
}
void rs_nxs_test::NxsTestHub::StartTest() void rs_nxs_test::NxsTestHub::StartTest()
{ {
// get all services up and running // get all services up and running
@ -144,6 +133,7 @@ void rs_nxs_test::NxsTestHub::EndTest()
void rs_nxs_test::NxsTestHub::notifyNewMessages(const RsPeerId& pid, void rs_nxs_test::NxsTestHub::notifyNewMessages(const RsPeerId& pid,
std::vector<RsNxsMsg*>& messages) std::vector<RsNxsMsg*>& messages)
{ {
RS_STACK_MUTEX(mMtx); /***** MTX LOCKED *****/
std::map<RsNxsMsg*, RsGxsMsgMetaData*> toStore; std::map<RsNxsMsg*, RsGxsMsgMetaData*> toStore;
std::vector<RsNxsMsg*>::iterator it = messages.begin(); std::vector<RsNxsMsg*>::iterator it = messages.begin();
@ -151,6 +141,13 @@ void rs_nxs_test::NxsTestHub::notifyNewMessages(const RsPeerId& pid,
{ {
RsNxsMsg* msg = *it; RsNxsMsg* msg = *it;
RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); RsGxsMsgMetaData* meta = new RsGxsMsgMetaData();
// local meta is not touched by the deserialisation routine
// have to initialise it
meta->mMsgStatus = 0;
meta->mMsgSize = 0;
meta->mChildTs = 0;
meta->recvTS = 0;
meta->validated = false;
bool ok = meta->deserialise(msg->meta.bin_data, &(msg->meta.bin_len)); bool ok = meta->deserialise(msg->meta.bin_data, &(msg->meta.bin_len));
toStore.insert(std::make_pair(msg, meta)); toStore.insert(std::make_pair(msg, meta));
} }
@ -162,6 +159,8 @@ void rs_nxs_test::NxsTestHub::notifyNewMessages(const RsPeerId& pid,
void rs_nxs_test::NxsTestHub::notifyNewGroups(const RsPeerId& pid, std::vector<RsNxsGrp*>& groups) void rs_nxs_test::NxsTestHub::notifyNewGroups(const RsPeerId& pid, std::vector<RsNxsGrp*>& groups)
{ {
RS_STACK_MUTEX(mMtx); /***** MTX LOCKED *****/
std::map<RsNxsGrp*, RsGxsGrpMetaData*> toStore; std::map<RsNxsGrp*, RsGxsGrpMetaData*> toStore;
std::vector<RsNxsGrp*>::iterator it = groups.begin(); std::vector<RsNxsGrp*>::iterator it = groups.begin();
for(; it != groups.end(); it++) for(; it != groups.end(); it++)
@ -189,6 +188,7 @@ void rs_nxs_test::NxsTestHub::Wait(int seconds) {
bool rs_nxs_test::NxsTestHub::recvItem(RsRawItem* item, const RsPeerId& peerFrom) bool rs_nxs_test::NxsTestHub::recvItem(RsRawItem* item, const RsPeerId& peerFrom)
{ {
RS_STACK_MUTEX(mMtx); /***** MTX LOCKED *****/
PayLoad p(peerFrom, item); PayLoad p(peerFrom, item);
mPayLoad.push(p); mPayLoad.push(p);
return true; return true;
@ -199,13 +199,14 @@ void rs_nxs_test::NxsTestHub::CleanUpTest()
mTestScenario->cleanTestScenario(); mTestScenario->cleanTestScenario();
} }
void rs_nxs_test::NxsTestHub::tick() void rs_nxs_test::NxsTestHub::data_tick()
{ {
// for each nxs instance pull out all items from each and then move to destination peer // for each nxs instance pull out all items from each and then move to destination peer
PeerNxsMap::iterator it = mPeerNxsMap.begin(); PeerNxsMap::iterator it = mPeerNxsMap.begin();
// deliver payloads to peer's net services // deliver payloads to peer's net services
mMtx.lock();
while(!mPayLoad.empty()) while(!mPayLoad.empty())
{ {
PayLoad& p = mPayLoad.front(); PayLoad& p = mPayLoad.front();
@ -214,9 +215,12 @@ void rs_nxs_test::NxsTestHub::tick()
RsPeerId peerFrom = p.first; RsPeerId peerFrom = p.first;
RsPeerId peerTo = item->PeerId(); RsPeerId peerTo = item->PeerId();
item->PeerId(peerFrom); item->PeerId(peerFrom);
mPeerNxsMap[peerTo]->recv(item); // mMtx.unlock();
mPeerNxsMap[peerTo]->recv(item);
mMtx.lock();
mPayLoad.pop(); mPayLoad.pop();
} }
mMtx.unlock();
// then tick net services // then tick net services
for(; it != mPeerNxsMap.end(); it++) for(; it != mPeerNxsMap.end(); it++)
@ -226,6 +230,8 @@ void rs_nxs_test::NxsTestHub::tick()
} }
double timeDelta = .2;
usleep(timeDelta * 1000000);
} }

View file

@ -35,7 +35,7 @@ namespace rs_nxs_test
* and synchronise according to their subscriptions. The default is to subscribe to all groups held by other peer * and synchronise according to their subscriptions. The default is to subscribe to all groups held by other peer
* The threads for both net instances are started which begins their processing of transactions * The threads for both net instances are started which begins their processing of transactions
*/ */
class NxsTestHub : public RsThread, public RecvPeerItemIface class NxsTestHub : public RsTickingThread, public RecvPeerItemIface
{ {
public: public:
@ -58,12 +58,6 @@ namespace rs_nxs_test
*/ */
bool testsPassed(); bool testsPassed();
/*!
* This simulates the p3Service ticker and calls both gxs net services tick methods
* Also enables transport of messages between both services
*/
void run();
/*! /*!
* Begings test, equivalent to CreateThread(this) * Begings test, equivalent to CreateThread(this)
*/ */
@ -97,13 +91,19 @@ namespace rs_nxs_test
private: private:
void tick(); /*!
* This simulates the p3Service ticker and calls both gxs net services tick methods
* Also enables transport of messages between both services
*/
virtual void data_tick();
private: private:
typedef std::pair<RsPeerId, RsRawItem*> PayLoad; typedef std::pair<RsPeerId, RsRawItem*> PayLoad;
typedef std::map<RsPeerId, RsGxsNetService::pointer > PeerNxsMap ; typedef std::map<RsPeerId, RsGxsNetService::pointer > PeerNxsMap ;
RsMutex mMtx;
PeerNxsMap mPeerNxsMap; PeerNxsMap mPeerNxsMap;
NxsTestScenario::pointer mTestScenario; NxsTestScenario::pointer mTestScenario;
std::queue<PayLoad> mPayLoad; std::queue<PayLoad> mPayLoad;

View file

@ -12,15 +12,16 @@
#include "nxstesthub.h" #include "nxstesthub.h"
#include "nxsgrpsyncdelayed.h" #include "nxsgrpsyncdelayed.h"
TEST(libretroshare_gxs, gxs_grp_sync) // disabled, because it fails after rebase to current master (did not fail in 2015, fails in 2016)
TEST(libretroshare_gxs, DISABLED_gxs_grp_sync)
{ {
rs_nxs_test::NxsTestScenario::pointer gsync_test = rs_nxs_test::NxsTestScenario::pointer( rs_nxs_test::NxsTestScenario::pointer gsync_test = rs_nxs_test::NxsTestScenario::pointer(
new rs_nxs_test::NxsGrpSync()); new rs_nxs_test::NxsGrpSync());
rs_nxs_test::NxsTestHub tHub(gsync_test); rs_nxs_test::NxsTestHub tHub(gsync_test);
tHub.StartTest(); tHub.StartTest();
// wait for ten seconds // wait xx secs, because sync happens every 60sec
rs_nxs_test::NxsTestHub::Wait(10); rs_nxs_test::NxsTestHub::Wait(1.5*60);
tHub.EndTest(); tHub.EndTest();
@ -29,15 +30,16 @@ TEST(libretroshare_gxs, gxs_grp_sync)
tHub.CleanUpTest(); tHub.CleanUpTest();
} }
TEST(libretroshare_gxs, gxs_grp_sync_delayed) // disabled, not implemented (does currently the same as NxsGrpSync)
TEST(libretroshare_gxs, DISABLED_gxs_grp_sync_delayed)
{ {
rs_nxs_test::NxsTestScenario::pointer gsync_test = rs_nxs_test::NxsTestScenario::pointer( rs_nxs_test::NxsTestScenario::pointer gsync_test = rs_nxs_test::NxsTestScenario::pointer(
new rs_nxs_test::NxsGrpSyncDelayed()); new rs_nxs_test::NxsGrpSyncDelayed());
rs_nxs_test::NxsTestHub tHub(gsync_test); rs_nxs_test::NxsTestHub tHub(gsync_test);
tHub.StartTest(); tHub.StartTest();
// wait for ten seconds // wait xx secs, because sync happens every 60sec
rs_nxs_test::NxsTestHub::Wait(20); rs_nxs_test::NxsTestHub::Wait(2.5*60);
tHub.EndTest(); tHub.EndTest();

View file

@ -75,9 +75,9 @@ TEST(libretroshare_gxs, GxsSecurity)
// test encryption/decryption // test encryption/decryption
uint8_t *out = NULL ; uint8_t *out = NULL ;
int outlen = 0 ; uint32_t outlen = 0 ;
uint8_t *out2 = NULL ; uint8_t *out2 = NULL ;
int outlen2 = 0 ; uint32_t outlen2 = 0 ;
EXPECT_TRUE(GxsSecurity::encrypt(out,outlen,(const uint8_t*)data,data_len,pub_key) ); EXPECT_TRUE(GxsSecurity::encrypt(out,outlen,(const uint8_t*)data,data_len,pub_key) );

View file

@ -49,11 +49,13 @@ RsSerialType* init_item(RsGRouterGenericDataItem& cmi)
return new RsGRouterSerialiser(); return new RsGRouterSerialiser();
} }
RsSerialType* init_item(RsGRouterReceiptItem& cmi) RsSerialType* init_item(RsGRouterSignedReceiptItem& cmi)
{ {
cmi.mid = RSRandom::random_u64() ; cmi.routing_id = RSRandom::random_u64() ;
cmi.state = RSRandom::random_u32() ;
cmi.destination_key = GRouterKeyId::random() ; cmi.destination_key = GRouterKeyId::random() ;
cmi.service_id = RSRandom::random_u32() ;
cmi.flags = RSRandom::random_u32() ;
init_item(cmi.signature) ; init_item(cmi.signature) ;

View file

@ -34,14 +34,13 @@
bool operator==(const RsGxsIdGroupItem& it1,const RsGxsIdGroupItem& it2) bool operator==(const RsGxsIdGroupItem& it1,const RsGxsIdGroupItem& it2)
{ {
if(it1.group.mPgpIdSign != it2.group.mPgpIdSign) return false ; if(it1.mPgpIdSign != it2.mPgpIdSign) return false ;
return true ; return true ;
} }
RsSerialType* init_item(RsGxsIdGroupItem& item) RsSerialType* init_item(RsGxsIdGroupItem& item)
{ {
item.group.mPgpIdSign = "hello"; item.mPgpIdSign = "hello";
item.group.mPgpKnown = false;
return new RsGxsIdSerialiser(); return new RsGxsIdSerialiser();
} }

View file

@ -25,11 +25,13 @@ RsSerialType* init_item(RsGxsMsgUpdateItem& i)
i.peerId = RsPeerId::random(); i.peerId = RsPeerId::random();
int numUpdates = rand()%123; int numUpdates = rand()%123;
RsPeerId peer; i.peerId = RsPeerId::random();
peer = RsPeerId::random();
for(int j=0; j < numUpdates; j++) for(int j=0; j < numUpdates; j++)
{ {
i.msgUpdateTS.insert(std::make_pair(peer, rand()%45)); struct RsGxsMsgUpdateItem::MsgUpdateInfo info;
info.message_count = rand();
info.time_stamp = rand()%45;
i.msgUpdateInfos[RsGxsGroupId::random()] = info;
} }
return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
@ -59,15 +61,20 @@ bool operator ==(const RsGxsGrpUpdateItem& l, const RsGxsGrpUpdateItem& r)
return ok; return ok;
} }
bool operator ==(const RsGxsMsgUpdateItem::MsgUpdateInfo& l, const RsGxsMsgUpdateItem::MsgUpdateInfo& r)
{
return (l.message_count == r.message_count) && (l.time_stamp == r.time_stamp);
}
bool operator ==(const RsGxsMsgUpdateItem& l, const RsGxsMsgUpdateItem& r) bool operator ==(const RsGxsMsgUpdateItem& l, const RsGxsMsgUpdateItem& r)
{ {
bool ok = l.peerId == r.peerId; bool ok = l.peerId == r.peerId;
const std::map<RsGxsGroupId, uint32_t>& lUp = l.msgUpdateTS, rUp = r.msgUpdateTS; const std::map<RsGxsGroupId, RsGxsMsgUpdateItem::MsgUpdateInfo>& lUp = l.msgUpdateInfos, rUp = r.msgUpdateInfos;
ok &= lUp.size() == rUp.size(); ok &= lUp.size() == rUp.size();
std::map<RsGxsGroupId, uint32_t>::const_iterator lit = lUp.begin(), rit; std::map<RsGxsGroupId, RsGxsMsgUpdateItem::MsgUpdateInfo>::const_iterator lit = lUp.begin(), rit;
for(; lit != lUp.end(); lit++) for(; lit != lUp.end(); lit++)
{ {

View file

@ -49,19 +49,15 @@ RsSerialType* init_item(RsChatLobbyListItem& cmi)
{ {
int n = rand()%20 ; int n = rand()%20 ;
cmi.lobby_ids.resize(n) ;
cmi.lobby_names.resize(n) ;
cmi.lobby_topics.resize(n) ;
cmi.lobby_counts.resize(n) ;
cmi.lobby_privacy_levels.resize(n) ;
for(int i=0;i<n;++i) for(int i=0;i<n;++i)
{ {
cmi.lobby_ids[i] = RSRandom::random_u64() ; struct VisibleChatLobbyInfo info;
randString(5+(rand()%10), cmi.lobby_names[i]); info.id = RSRandom::random_u64() ;
randString(20+(rand()%15), cmi.lobby_topics[i]); randString(5+(rand()%10), info.name);
cmi.lobby_counts[i] = RSRandom::random_u32() ; randString(20+(rand()%15), info.topic);
cmi.lobby_privacy_levels[i] = RSRandom::random_u32()%3 ; info.count = RSRandom::random_u32() ;
info.flags = ChatLobbyFlags(RSRandom::random_u32()%3) ;
cmi.lobbies.push_back(info);
} }
return new RsChatSerialiser(); return new RsChatSerialiser();
@ -73,7 +69,6 @@ RsSerialType* init_item(RsChatLobbyMsgItem& cmi)
cmi.msg_id = RSRandom::random_u64() ; cmi.msg_id = RSRandom::random_u64() ;
cmi.lobby_id = RSRandom::random_u64() ; cmi.lobby_id = RSRandom::random_u64() ;
cmi.nick = "My nickname" ; cmi.nick = "My nickname" ;
cmi.subpacket_id = rand()%256 ;
cmi.parent_msg_id = RSRandom::random_u64() ; cmi.parent_msg_id = RSRandom::random_u64() ;
return serial ; return serial ;
@ -187,19 +182,18 @@ RsSerialType* init_item(RsMsgParentId& ms)
return new RsMsgSerialiser(); return new RsMsgSerialiser();
} }
bool operator ==(const struct VisibleChatLobbyInfo& l, const struct VisibleChatLobbyInfo& r)
{
return l.id == r.id
&& l.name == r.name
&& l.topic == r.topic
&& l.count == r.count
&& l.flags == r.flags;
}
bool operator ==(const RsChatLobbyListItem& cmiLeft,const RsChatLobbyListItem& cmiRight) bool operator ==(const RsChatLobbyListItem& cmiLeft,const RsChatLobbyListItem& cmiRight)
{ {
if(cmiLeft.lobby_ids.size() != cmiRight.lobby_ids.size()) return false; return cmiLeft.lobbies == cmiRight.lobbies;
if(cmiLeft.lobby_names.size() != cmiRight.lobby_names.size()) return false;
if(cmiLeft.lobby_counts.size() != cmiRight.lobby_counts.size()) return false;
for(uint32_t i=0;i<cmiLeft.lobby_ids.size();++i)
{
if(cmiLeft.lobby_ids[i] != cmiRight.lobby_ids[i]) return false ;
if(cmiLeft.lobby_names[i] != cmiRight.lobby_names[i]) return false ;
if(cmiLeft.lobby_counts[i] != cmiRight.lobby_counts[i]) return false ;
}
return true ;
} }
bool operator ==(const RsChatLobbyListRequestItem& ,const RsChatLobbyListRequestItem& ) bool operator ==(const RsChatLobbyListRequestItem& ,const RsChatLobbyListRequestItem& )
{ {

View file

@ -8,7 +8,6 @@
#define NUM_SYNC_MSGS 8 #define NUM_SYNC_MSGS 8
#define NUM_SYNC_GRPS 5 #define NUM_SYNC_GRPS 5
TEST(libretroshare_serialiser, RsNxsItem) TEST(libretroshare_serialiser, RsNxsItem)
{ {
test_RsItem<RsNxsGrp>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); test_RsItem<RsNxsGrp>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);

View file

@ -141,7 +141,7 @@ bool operator==(const RsTlvKeySignatureSet& kss1, const RsTlvKeySignatureSet& ks
bool operator==(const RsTlvPeerIdSet& pids1, const RsTlvPeerIdSet& pids2) bool operator==(const RsTlvPeerIdSet& pids1, const RsTlvPeerIdSet& pids2)
{ {
std::list<RsPeerId>::const_iterator it1 = pids1.ids.begin(), std::set<RsPeerId>::const_iterator it1 = pids1.ids.begin(),
it2 = pids2.ids.begin(); it2 = pids2.ids.begin();
@ -239,7 +239,7 @@ bool operator==(const RsTlvImage& img1, const RsTlvImage& img2)
void init_item(RsTlvHashSet& hs) void init_item(RsTlvHashSet& hs)
{ {
for(int i=0; i < 10; i++) for(int i=0; i < 10; i++)
hs.ids.push_back(RsFileHash::random()); hs.ids.insert(RsFileHash::random());
return; return;
} }
@ -247,14 +247,14 @@ void init_item(RsTlvHashSet& hs)
void init_item(RsTlvPeerIdSet& ps) void init_item(RsTlvPeerIdSet& ps)
{ {
for(int i=0; i < 10; i++) for(int i=0; i < 10; i++)
ps.ids.push_back(RsPeerId::random()); ps.ids.insert(RsPeerId::random());
return; return;
} }
bool operator==(const RsTlvHashSet& hs1,const RsTlvHashSet& hs2) bool operator==(const RsTlvHashSet& hs1,const RsTlvHashSet& hs2)
{ {
std::list<RsFileHash>::const_iterator it1 = hs1.ids.begin(), std::set<RsFileHash>::const_iterator it1 = hs1.ids.begin(),
it2 = hs2.ids.begin(); it2 = hs2.ids.begin();
for(; ((it1 != hs1.ids.end()) && (it2 != hs2.ids.end())); it1++, it2++) for(; ((it1 != hs1.ids.end()) && (it2 != hs2.ids.end())); it1++, it2++)

View file

@ -53,6 +53,8 @@
#include "rstlvutil.h" #include "rstlvutil.h"
#define TEST_LENGTH 10 #define TEST_LENGTH 10
// more time for valgrind
//#define TEST_LENGTH 500
#define BIN_LEN 523456 /* bigger than 64k */ #define BIN_LEN 523456 /* bigger than 64k */
@ -147,7 +149,7 @@ bool test_SetTlvItem(RsTlvItem *item, uint16_t type, void *data, uint32_t size,
} }
TEST(libretroshare_serialiser, test_RsTlvRandom) TEST(libretroshare_serialiser, DISABLED_test_RsTlvRandom)
{ {
/* random data array to work through */ /* random data array to work through */
uint32_t dsize = 100000; uint32_t dsize = 100000;
@ -175,7 +177,16 @@ TEST(libretroshare_serialiser, test_RsTlvRandom)
int count = 0; int count = 0;
for(i = 0; endTs > time(NULL); i += 2) for(i = 0; endTs > time(NULL); i += 2)
{ {
uint32_t len = dsize - i; uint32_t len = dsize - 2*i; // two times i, because we also use it as offset
// no point in testing smaller than header size,
// because items currently don't check if they can read the header
if(len < TLV_HEADER_SIZE)
{
std::cerr << "reached the end of our datablock!";
std::cerr << std::endl;
return;
}
count += test_TlvRandom(&(data[i]), len, i); count += test_TlvRandom(&(data[i]), len, i);
std::cerr << "Run: " << count << " tests"; std::cerr << "Run: " << count << " tests";

View file

@ -177,7 +177,7 @@ TEST(libretroshare_serialiser, test_RsTlvPeerIdSet)
for(int i = 0; i < 15 ; i++) for(int i = 0; i < 15 ; i++)
{ {
testId = RsPeerId::random(); testId = RsPeerId::random();
i1.ids.push_back(testId); i1.ids.insert(testId);
} }
EXPECT_TRUE(test_SerialiseTlvItem(std::cerr, &i1, &i2)); EXPECT_TRUE(test_SerialiseTlvItem(std::cerr, &i1, &i2));
@ -297,7 +297,7 @@ TEST(libretroshare_serialiser, test_RsTlvHashSet)
{ {
RsPeerId randId; RsPeerId randId;
randId = RsPeerId::random(); randId = RsPeerId::random();
i1.ids.push_back(randId); i1.ids.insert(randId);
} }
EXPECT_TRUE(test_SerialiseTlvItem(std::cerr, &i1, &i2)); EXPECT_TRUE(test_SerialiseTlvItem(std::cerr, &i1, &i2));

View file

@ -18,6 +18,8 @@
#include "RsGxsNetServiceTester.h" #include "RsGxsNetServiceTester.h"
#endif #endif
#include <unistd.h>
GxsPeerNode::GxsPeerNode(const RsPeerId &ownId, const std::list<RsPeerId> &friends, int testMode, bool useIdentityService) GxsPeerNode::GxsPeerNode(const RsPeerId &ownId, const std::list<RsPeerId> &friends, int testMode, bool useIdentityService)
:PeerNode(ownId, friends, false), :PeerNode(ownId, friends, false),
@ -262,8 +264,8 @@ bool GxsPeerNode::createCircle(const std::string &name,
uint32_t circleType, uint32_t circleType,
const RsGxsCircleId &circleId, const RsGxsCircleId &circleId,
const RsGxsId &authorId, const RsGxsId &authorId,
std::list<RsPgpId> localMembers, std::set<RsPgpId> localMembers,
std::list<RsGxsId> externalMembers, std::set<RsGxsId> externalMembers,
RsGxsGroupId &groupId) RsGxsGroupId &groupId)
{ {
/* create a couple of groups */ /* create a couple of groups */

View file

@ -40,8 +40,8 @@ bool createCircle(const std::string &name,
uint32_t circleType, uint32_t circleType,
const RsGxsCircleId &circleId, const RsGxsCircleId &circleId,
const RsGxsId &authorId, const RsGxsId &authorId,
std::list<RsPgpId> localMembers, std::set<RsPgpId> localMembers,
std::list<RsGxsId> externalMembers, std::set<RsGxsId> externalMembers,
RsGxsGroupId &groupId); RsGxsGroupId &groupId);
bool createGroup(const std::string &name, bool createGroup(const std::string &name,

View file

@ -30,13 +30,16 @@
* This test is rather slow - should speed it up. * This test is rather slow - should speed it up.
*/ */
//TEST(libretroshare_services, DISABLED_GxsCircles1) // test is currently broken, it does not go further than "Create Identities"
TEST(libretroshare_services, GxsCircles1) // probably because it does not return from peerNode1->createIdentity
// TODO: fix test
TEST(libretroshare_services, DISABLED_GxsCircles1)
//TEST(libretroshare_services, GxsCircles1)
{ {
time_t starttime = time(NULL); time_t starttime = time(NULL);
RsGxsCircleId nullCircleId; RsGxsCircleId nullCircleId;
RsGxsId nullAuthorId; RsGxsId nullAuthorId;
std::list<RsPgpId> nullLocalMembers; std::set<RsPgpId> nullLocalMembers;
std::list<RsGxsId> nullExtMembers; std::list<RsGxsId> nullExtMembers;
RsPeerId p1 = RsPeerId::random(); RsPeerId p1 = RsPeerId::random();
@ -182,11 +185,11 @@ TEST(libretroshare_services, GxsCircles1)
std::string circleName1 = "p1c1-EC-public-p1p2p3p4"; std::string circleName1 = "p1c1-EC-public-p1p2p3p4";
// Ext Group, containing everyone, shared publicly. // Ext Group, containing everyone, shared publicly.
RsGxsGroupId p1c1_circleId; RsGxsGroupId p1c1_circleId;
std::list<RsGxsId> p1c1_members; std::set<RsGxsId> p1c1_members;
p1c1_members.push_back(gxsId1); p1c1_members.insert(gxsId1);
p1c1_members.push_back(gxsId2); p1c1_members.insert(gxsId2);
p1c1_members.push_back(gxsId3); p1c1_members.insert(gxsId3);
p1c1_members.push_back(gxsId4); p1c1_members.insert(gxsId4);
EXPECT_TRUE(peerNode1->createCircle(circleName1, GXS_CIRCLE_TYPE_PUBLIC, EXPECT_TRUE(peerNode1->createCircle(circleName1, GXS_CIRCLE_TYPE_PUBLIC,
nullCircleId, nullAuthorId, nullLocalMembers, p1c1_members, p1c1_circleId)); nullCircleId, nullAuthorId, nullLocalMembers, p1c1_members, p1c1_circleId));
@ -194,27 +197,27 @@ TEST(libretroshare_services, GxsCircles1)
// Ext Group containing p1,p2, shared publicly. // Ext Group containing p1,p2, shared publicly.
std::string circleName2 = "p1c2-EC-public-p1p2"; std::string circleName2 = "p1c2-EC-public-p1p2";
RsGxsGroupId p1c2_circleId; RsGxsGroupId p1c2_circleId;
std::list<RsGxsId> p1c2_members; std::set<RsGxsId> p1c2_members;
p1c2_members.push_back(gxsId1); p1c2_members.insert(gxsId1);
p1c2_members.push_back(gxsId2); p1c2_members.insert(gxsId2);
EXPECT_TRUE(peerNode1->createCircle(circleName2, GXS_CIRCLE_TYPE_PUBLIC, EXPECT_TRUE(peerNode1->createCircle(circleName2, GXS_CIRCLE_TYPE_PUBLIC,
nullCircleId, nullAuthorId, nullLocalMembers, p1c2_members, p1c2_circleId)); nullCircleId, nullAuthorId, nullLocalMembers, p1c2_members, p1c2_circleId));
// Ext Group containing p2 (missing creator!) shared publicly. // Ext Group containing p2 (missing creator!) shared publicly.
std::string circleName3 = "p1c3-EC-public-p2"; std::string circleName3 = "p1c3-EC-public-p2";
RsGxsGroupId p1c3_circleId; RsGxsGroupId p1c3_circleId;
std::list<RsGxsId> p1c3_members; std::set<RsGxsId> p1c3_members;
p1c3_members.push_back(gxsId2); p1c3_members.insert(gxsId2);
EXPECT_TRUE(peerNode1->createCircle(circleName3, GXS_CIRCLE_TYPE_PUBLIC, EXPECT_TRUE(peerNode1->createCircle(circleName3, GXS_CIRCLE_TYPE_PUBLIC,
nullCircleId, nullAuthorId, nullLocalMembers, p1c3_members, p1c3_circleId)); nullCircleId, nullAuthorId, nullLocalMembers, p1c3_members, p1c3_circleId));
// Ext Group containing p1,p2,p3 shared SELF-REF. // Ext Group containing p1,p2,p3 shared SELF-REF.
std::string circleName4 = "p1c4-EC-self-p1p2p3"; std::string circleName4 = "p1c4-EC-self-p1p2p3";
RsGxsGroupId p1c4_circleId; RsGxsGroupId p1c4_circleId;
std::list<RsGxsId> p1c4_members; std::set<RsGxsId> p1c4_members;
p1c4_members.push_back(gxsId1); p1c4_members.insert(gxsId1);
p1c4_members.push_back(gxsId2); p1c4_members.insert(gxsId2);
p1c4_members.push_back(gxsId3); p1c4_members.insert(gxsId3);
EXPECT_TRUE(peerNode1->createCircle(circleName4, GXS_CIRCLE_TYPE_EXT_SELF, EXPECT_TRUE(peerNode1->createCircle(circleName4, GXS_CIRCLE_TYPE_EXT_SELF,
nullCircleId, nullAuthorId, nullLocalMembers, p1c4_members, p1c4_circleId)); nullCircleId, nullAuthorId, nullLocalMembers, p1c4_members, p1c4_circleId));
@ -222,9 +225,9 @@ TEST(libretroshare_services, GxsCircles1)
RsGxsCircleId constrain_circleId(p1c4_circleId.toStdString()); RsGxsCircleId constrain_circleId(p1c4_circleId.toStdString());
std::string circleName5 = "p1c5-EC-ext-p1p2"; std::string circleName5 = "p1c5-EC-ext-p1p2";
RsGxsGroupId p1c5_circleId; RsGxsGroupId p1c5_circleId;
std::list<RsGxsId> p1c5_members; std::set<RsGxsId> p1c5_members;
p1c5_members.push_back(gxsId1); p1c5_members.insert(gxsId1);
p1c5_members.push_back(gxsId2); p1c5_members.insert(gxsId2);
EXPECT_TRUE(peerNode1->createCircle(circleName5, GXS_CIRCLE_TYPE_EXTERNAL, EXPECT_TRUE(peerNode1->createCircle(circleName5, GXS_CIRCLE_TYPE_EXTERNAL,
constrain_circleId, nullAuthorId, nullLocalMembers, p1c5_members, p1c5_circleId)); constrain_circleId, nullAuthorId, nullLocalMembers, p1c5_members, p1c5_circleId));
@ -233,9 +236,9 @@ TEST(libretroshare_services, GxsCircles1)
// (does p4 get stuff). // (does p4 get stuff).
std::string circleName6 = "p1c6-EC-ext-p1p4"; std::string circleName6 = "p1c6-EC-ext-p1p4";
RsGxsGroupId p1c6_circleId; RsGxsGroupId p1c6_circleId;
std::list<RsGxsId> p1c6_members; std::set<RsGxsId> p1c6_members;
p1c6_members.push_back(gxsId1); p1c6_members.insert(gxsId1);
p1c6_members.push_back(gxsId4); p1c6_members.insert(gxsId4);
EXPECT_TRUE(peerNode1->createCircle(circleName6, GXS_CIRCLE_TYPE_EXTERNAL, EXPECT_TRUE(peerNode1->createCircle(circleName6, GXS_CIRCLE_TYPE_EXTERNAL,
constrain_circleId, nullAuthorId, nullLocalMembers, p1c6_members, p1c6_circleId)); constrain_circleId, nullAuthorId, nullLocalMembers, p1c6_members, p1c6_circleId));

View file

@ -3,8 +3,6 @@ CONFIG += bitdht
CONFIG += gxs debug CONFIG += gxs debug
LIBS += -lgtest
gxs { gxs {
DEFINES += RS_ENABLE_GXS DEFINES += RS_ENABLE_GXS
} }
@ -15,6 +13,21 @@ TARGET = unittests
OPENPGPSDK_DIR = ../../openpgpsdk/src OPENPGPSDK_DIR = ../../openpgpsdk/src
INCLUDEPATH *= $${OPENPGPSDK_DIR} ../openpgpsdk INCLUDEPATH *= $${OPENPGPSDK_DIR} ../openpgpsdk
# it is impossible to use precompield googletest lib
# because googletest must be compiled with same compiler flags as the tests!
!exists(../googletest/googletest/src/gtest-all.cc){
message(trying to git clone googletest...)
!system(git clone https://github.com/google/googletest.git ../googletest){
error(Could not git clone googletest files. You can manually download them to /tests/googletest)
}
}
INCLUDEPATH += \
../googletest/googletest/include \
../googletest/googletest
SOURCES += ../googletest/googletest/src/gtest-all.cc
################################# Linux ########################################## ################################# Linux ##########################################
# Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib # Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib
linux-* { linux-* {
@ -28,10 +41,14 @@ linux-* {
LIBS += ../librssimulator/lib/librssimulator.a LIBS += ../librssimulator/lib/librssimulator.a
LIBS += ../../openpgpsdk/src/lib/libops.a -lbz2 LIBS += ../../openpgpsdk/src/lib/libops.a -lbz2
LIBS += -lssl -lupnp -lixml -lXss -lgnome-keyring LIBS += -lssl -lupnp -lixml -lXss -lgnome-keyring
LIBS *= -lcrypto -ldl -lX11 -lz LIBS *= -lcrypto -ldl -lX11 -lz -lpthread
LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a #LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a
contains(CONFIG, NO_SQLCIPHER) {
DEFINES *= NO_SQLCIPHER
PKGCONFIG *= sqlite3
} else {
# We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database.
SQLCIPHER_OK = $$system(pkg-config --exists sqlcipher && echo yes) SQLCIPHER_OK = $$system(pkg-config --exists sqlcipher && echo yes)
@ -46,10 +63,10 @@ linux-* {
LIBS += ../../../lib/sqlcipher/.libs/libsqlcipher.a LIBS += ../../../lib/sqlcipher/.libs/libsqlcipher.a
INCLUDEPATH += ../../../lib/sqlcipher/src/ INCLUDEPATH += ../../../lib/sqlcipher/src/
INCLUDEPATH += ../../../lib/sqlcipher/tsrc/ INCLUDEPATH += ../../../lib/sqlcipher/tsrc/
} else { } else {
LIBS += -lsqlcipher LIBS += -lsqlcipher
} }
}
LIBS *= -lglib-2.0 LIBS *= -lglib-2.0
@ -256,13 +273,13 @@ SOURCES += libretroshare/serialiser/rsturtleitem_test.cc \
libretroshare/serialiser/rsstatusitem_test.cc \ libretroshare/serialiser/rsstatusitem_test.cc \
libretroshare/serialiser/rsnxsitems_test.cc \ libretroshare/serialiser/rsnxsitems_test.cc \
libretroshare/serialiser/rsgxsiditem_test.cc \ libretroshare/serialiser/rsgxsiditem_test.cc \
libretroshare/serialiser/rsphotoitem_test.cc \ # libretroshare/serialiser/rsphotoitem_test.cc \
libretroshare/serialiser/tlvbase_test2.cc \ libretroshare/serialiser/tlvbase_test2.cc \
libretroshare/serialiser/tlvrandom_test.cc \ libretroshare/serialiser/tlvrandom_test.cc \
libretroshare/serialiser/tlvbase_test.cc \ libretroshare/serialiser/tlvbase_test.cc \
libretroshare/serialiser/tlvstack_test.cc \ libretroshare/serialiser/tlvstack_test.cc \
libretroshare/serialiser/tlvitems_test.cc \ libretroshare/serialiser/tlvitems_test.cc \
libretroshare/serialiser/rsgrouteritem_test.cc \ # libretroshare/serialiser/rsgrouteritem_test.cc \
libretroshare/serialiser/tlvtypes_test.cc \ libretroshare/serialiser/tlvtypes_test.cc \
libretroshare/serialiser/tlvkey_test.cc \ libretroshare/serialiser/tlvkey_test.cc \
libretroshare/serialiser/support.cc \ libretroshare/serialiser/support.cc \