mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
commit
85e6f61f02
@ -138,7 +138,7 @@ bool DistributedChatService::handleRecvChatLobbyMsgItem(RsChatMsgItem *ci)
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rsIdentity->isBanned(cli->signature.keyId))
|
if(rsIdentity->overallReputationLevel(cli->signature.keyId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
{
|
{
|
||||||
std::cerr << "(WW) Received lobby msg/item from banned identity " << cli->signature.keyId << ". Dropping it." << std::endl;
|
std::cerr << "(WW) Received lobby msg/item from banned identity " << cli->signature.keyId << ". Dropping it." << std::endl;
|
||||||
return false ;
|
return false ;
|
||||||
@ -220,7 +220,7 @@ bool DistributedChatService::checkSignature(RsChatLobbyBouncingObject *obj,const
|
|||||||
|
|
||||||
// network pre-request key to allow message authentication.
|
// network pre-request key to allow message authentication.
|
||||||
|
|
||||||
mGixs->requestKey(obj->signature.keyId,peer_list);
|
mGixs->requestKey(obj->signature.keyId,peer_list,"Needed for chat lobby "+RsUtil::NumberToString(obj->lobby_id,true));
|
||||||
|
|
||||||
uint32_t size = obj->signed_serial_size() ;
|
uint32_t size = obj->signed_serial_size() ;
|
||||||
RsTemporaryMemory memory(size) ;
|
RsTemporaryMemory memory(size) ;
|
||||||
@ -238,7 +238,7 @@ bool DistributedChatService::checkSignature(RsChatLobbyBouncingObject *obj,const
|
|||||||
|
|
||||||
uint32_t error_status ;
|
uint32_t error_status ;
|
||||||
|
|
||||||
if(!mGixs->validateData(memory,obj->signed_serial_size(),obj->signature,false,error_status))
|
if(!mGixs->validateData(memory,obj->signed_serial_size(),obj->signature,false,"Chat lobby "+RsUtil::NumberToString(obj->lobby_id,true),error_status))
|
||||||
{
|
{
|
||||||
bool res = false ;
|
bool res = false ;
|
||||||
|
|
||||||
@ -647,7 +647,7 @@ void DistributedChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *
|
|||||||
#endif
|
#endif
|
||||||
time_t now = time(NULL) ;
|
time_t now = time(NULL) ;
|
||||||
|
|
||||||
if(rsIdentity->isBanned(item->signature.keyId))
|
if(rsIdentity->overallReputationLevel(item->signature.keyId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
{
|
{
|
||||||
std::cerr << "(WW) Received lobby msg/item from banned identity " << item->signature.keyId << ". Dropping it." << std::endl;
|
std::cerr << "(WW) Received lobby msg/item from banned identity " << item->signature.keyId << ". Dropping it." << std::endl;
|
||||||
return ;
|
return ;
|
||||||
|
@ -1555,7 +1555,7 @@ void p3GRouter::handleIncomingReceiptItem(RsGRouterSignedReceiptItem *receipt_it
|
|||||||
|
|
||||||
uint32_t error_status ;
|
uint32_t error_status ;
|
||||||
|
|
||||||
if(! verifySignedDataItem(receipt_item,error_status))
|
if(! verifySignedDataItem(receipt_item,"GRouter incoming receipt item",error_status))
|
||||||
if( (it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_IS_ORIGIN) || (error_status != RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE))
|
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. Error status=" << error_status << std::endl;
|
std::cerr << " checking receipt signature : FAILED. Receipt is dropped. Error status=" << error_status << std::endl;
|
||||||
@ -1711,7 +1711,7 @@ void p3GRouter::handleIncomingDataItem(RsGRouterGenericDataItem *data_item)
|
|||||||
#endif
|
#endif
|
||||||
uint32_t error_status ;
|
uint32_t error_status ;
|
||||||
|
|
||||||
if(!verifySignedDataItem(data_item,error_status)) // we should get proper flags out of this
|
if(!verifySignedDataItem(data_item,"Incoming distant message",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;
|
||||||
@ -1980,11 +1980,11 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,uint32_t& error_status)
|
bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,const std::string& info,uint32_t& error_status)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(rsIdentity->isBanned(item->signature.keyId))
|
if(rsIdentity->overallReputationLevel(item->signature.keyId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
{
|
{
|
||||||
std::cerr << "(WW) received global router message from banned identity " << item->signature.keyId << ". Rejecting the message." << std::endl;
|
std::cerr << "(WW) received global router message from banned identity " << item->signature.keyId << ". Rejecting the message." << std::endl;
|
||||||
return false ;
|
return false ;
|
||||||
@ -1999,7 +1999,7 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,uint32_t& er
|
|||||||
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.") ;
|
||||||
|
|
||||||
if(!mGixs->validateData(data,data_size,item->signature,true,error_status))
|
if(!mGixs->validateData(data,data_size,item->signature,true,info, error_status))
|
||||||
{
|
{
|
||||||
switch(error_status)
|
switch(error_status)
|
||||||
{
|
{
|
||||||
@ -2010,7 +2010,7 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item,uint32_t& er
|
|||||||
|
|
||||||
std::cerr << "(EE) Key for GXS Id " << item->signature.keyId << " is not available. Cannot verify. Asking key to peer " << item->PeerId() << std::endl;
|
std::cerr << "(EE) Key for GXS Id " << item->signature.keyId << " is not available. Cannot verify. Asking key to peer " << item->PeerId() << std::endl;
|
||||||
|
|
||||||
mGixs->requestKey(item->signature.keyId,peer_ids) ; // request the key around
|
mGixs->requestKey(item->signature.keyId,peer_ids,info) ; // request the key around
|
||||||
}
|
}
|
||||||
break ;
|
break ;
|
||||||
case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH: std::cerr << "(EE) Signature mismatch. Spoofing/Corrupted/MITM?." << std::endl;
|
case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH: std::cerr << "(EE) Signature mismatch. Spoofing/Corrupted/MITM?." << std::endl;
|
||||||
@ -2116,7 +2116,7 @@ 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;
|
uint32_t error_status;
|
||||||
|
|
||||||
if(!verifySignedDataItem(data_item,error_status))
|
if(!verifySignedDataItem(data_item,"GRouter own signature check for outgoing msg",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;
|
||||||
|
@ -254,7 +254,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, uint32_t &error_status) ;
|
bool verifySignedDataItem(RsGRouterAbstractMsgItem *item, const std::string &info, 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) ;
|
||||||
|
|
||||||
|
@ -86,14 +86,14 @@ RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService
|
|||||||
CREATE_FAIL(0),
|
CREATE_FAIL(0),
|
||||||
CREATE_SUCCESS(1),
|
CREATE_SUCCESS(1),
|
||||||
CREATE_FAIL_TRY_LATER(2),
|
CREATE_FAIL_TRY_LATER(2),
|
||||||
SIGN_MAX_ATTEMPTS(5),
|
SIGN_MAX_WAITING_TIME(60),
|
||||||
SIGN_FAIL(0),
|
SIGN_FAIL(0),
|
||||||
SIGN_SUCCESS(1),
|
SIGN_SUCCESS(1),
|
||||||
SIGN_FAIL_TRY_LATER(2),
|
SIGN_FAIL_TRY_LATER(2),
|
||||||
VALIDATE_FAIL(0),
|
VALIDATE_FAIL(0),
|
||||||
VALIDATE_SUCCESS(1),
|
VALIDATE_SUCCESS(1),
|
||||||
VALIDATE_FAIL_TRY_LATER(2),
|
VALIDATE_FAIL_TRY_LATER(2),
|
||||||
VALIDATE_MAX_ATTEMPTS(5)
|
VALIDATE_MAX_WAITING_TIME(60)
|
||||||
{
|
{
|
||||||
|
|
||||||
mDataAccess = new RsGxsDataAccess(gds);
|
mDataAccess = new RsGxsDataAccess(gds);
|
||||||
@ -472,8 +472,8 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin
|
|||||||
if(GxsSecurity::getSignature((char*)grpData.bin_data, grpData.bin_len, authorKey, sign))
|
if(GxsSecurity::getSignature((char*)grpData.bin_data, grpData.bin_len, authorKey, sign))
|
||||||
{
|
{
|
||||||
id_ret = SIGN_SUCCESS;
|
id_ret = SIGN_SUCCESS;
|
||||||
mGixs->timeStampKey(grpMeta.mAuthorId) ;
|
mGixs->timeStampKey(grpMeta.mAuthorId,"Creation of group author signature for GrpId" + grpMeta.mGroupId.toStdString()) ;
|
||||||
signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign;
|
signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
id_ret = SIGN_FAIL;
|
id_ret = SIGN_FAIL;
|
||||||
@ -640,7 +640,7 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar
|
|||||||
if(GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, authorKey, sign))
|
if(GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, authorKey, sign))
|
||||||
{
|
{
|
||||||
id_ret = SIGN_SUCCESS;
|
id_ret = SIGN_SUCCESS;
|
||||||
mGixs->timeStampKey(msgMeta.mAuthorId) ;
|
mGixs->timeStampKey(msgMeta.mAuthorId,"Creating author signature in group " + msgMeta.mGroupId.toStdString() + ", msg " + msgMeta.mMsgId.toStdString()) ;
|
||||||
signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign;
|
signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -857,7 +857,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
|
|||||||
{
|
{
|
||||||
RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_IDENTITY];
|
RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_IDENTITY];
|
||||||
idValidate &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey);
|
idValidate &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey);
|
||||||
mGixs->timeStampKey(metaData.mAuthorId) ;
|
mGixs->timeStampKey(metaData.mAuthorId,"Validation of author signature, service: " + rsServiceControl->getServiceName(serviceFullType()) + ". Grp="+metaData.mGroupId.toStdString()+", msg="+metaData.mMsgId.toStdString()) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -882,20 +882,13 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// now check reputation of the message author
|
// now check reputation of the message author. The reputation will need to be at least as high as this value for the msg to validate.
|
||||||
float reputation_threshold = RsReputations::REPUTATION_THRESHOLD_DEFAULT;
|
// At validation step, we accept all messages, except the ones signed by locally rejected identities.
|
||||||
|
|
||||||
if( (signFlag & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) && !(details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN))
|
if(details.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
reputation_threshold = RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM;
|
|
||||||
else if( (signFlag & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) && !(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
|
|
||||||
reputation_threshold = RsReputations::REPUTATION_THRESHOLD_ANTI_SPAM;
|
|
||||||
else
|
|
||||||
reputation_threshold = RsReputations::REPUTATION_THRESHOLD_DEFAULT;
|
|
||||||
|
|
||||||
if(details.mReputation.mOverallReputationScore < reputation_threshold)
|
|
||||||
{
|
{
|
||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation score (" << details.mReputation.mOverallReputationScore <<") is below the accepted threshold (" << reputation_threshold << ")" << std::endl;
|
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation score (" << details.mReputation.mOverallReputationLevel <<") is below the accepted threshold (" << reputation_threshold << ")" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
idValidate = false ;
|
idValidate = false ;
|
||||||
}
|
}
|
||||||
@ -905,13 +898,13 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::list<RsPeerId> peers;
|
std::list<RsPeerId> peers;
|
||||||
peers.push_back(msg->PeerId());
|
peers.push_back(msg->PeerId());
|
||||||
mGixs->requestKey(metaData.mAuthorId, peers);
|
mGixs->requestKey(metaData.mAuthorId, peers,"Validation of author signature, service: " + rsServiceControl->getServiceName(serviceFullType()) + ". Grp="+metaData.mGroupId.toStdString()+", msg="+metaData.mMsgId.toStdString());
|
||||||
|
|
||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
std::cerr << ", Key missing. Retry later." << std::endl;
|
std::cerr << ", Key missing. Retry later." << std::endl;
|
||||||
@ -988,7 +981,7 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp)
|
|||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
std::cerr << " key ID validation result: " << idValidate << std::endl;
|
std::cerr << " key ID validation result: " << idValidate << std::endl;
|
||||||
#endif
|
#endif
|
||||||
mGixs->timeStampKey(metaData.mAuthorId) ;
|
mGixs->timeStampKey(metaData.mAuthorId,"Group author signature validation. GrpId=" + metaData.mGroupId.toStdString()) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1006,7 +999,7 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp)
|
|||||||
#endif
|
#endif
|
||||||
std::list<RsPeerId> peers;
|
std::list<RsPeerId> peers;
|
||||||
peers.push_back(grp->PeerId());
|
peers.push_back(grp->PeerId());
|
||||||
mGixs->requestKey(metaData.mAuthorId, peers);
|
mGixs->requestKey(metaData.mAuthorId, peers,"Group author signature validation. GrpId=" + metaData.mGroupId.toStdString());
|
||||||
return VALIDATE_FAIL_TRY_LATER;
|
return VALIDATE_FAIL_TRY_LATER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1485,7 +1478,7 @@ void RsGenExchange::notifyNewGroups(std::vector<RsNxsGrp *> &groups)
|
|||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GxsPendingItem<RsNxsGrp*, RsGxsGroupId> gpsi(grp, grp->grpId);
|
GxsPendingItem<RsNxsGrp*, RsGxsGroupId> gpsi(grp, grp->grpId,time(NULL));
|
||||||
mReceivedGrps.push_back(gpsi);
|
mReceivedGrps.push_back(gpsi);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1623,6 +1616,10 @@ uint32_t RsGenExchange::getDefaultSyncPeriod()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RsReputations::ReputationLevel RsGenExchange::minReputationForForwardingMessages(uint32_t group_sign_flags,uint32_t identity_sign_flags)
|
||||||
|
{
|
||||||
|
return RsNetworkExchangeService::minReputationForForwardingMessages(group_sign_flags,identity_sign_flags);
|
||||||
|
}
|
||||||
uint32_t RsGenExchange::getSyncPeriod(const RsGxsGroupId& grpId)
|
uint32_t RsGenExchange::getSyncPeriod(const RsGxsGroupId& grpId)
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mGenMtx) ;
|
RS_STACK_MUTEX(mGenMtx) ;
|
||||||
@ -1926,7 +1923,9 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC
|
|||||||
void RsGenExchange::publishMsgs()
|
void RsGenExchange::publishMsgs()
|
||||||
{
|
{
|
||||||
|
|
||||||
RS_STACK_MUTEX(mGenMtx) ;
|
RS_STACK_MUTEX(mGenMtx) ;
|
||||||
|
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
// stick back msgs pending signature
|
// stick back msgs pending signature
|
||||||
typedef std::map<uint32_t, GxsPendingItem<RsGxsMsgItem*, uint32_t> > PendSignMap;
|
typedef std::map<uint32_t, GxsPendingItem<RsGxsMsgItem*, uint32_t> > PendSignMap;
|
||||||
@ -1995,22 +1994,20 @@ void RsGenExchange::publishMsgs()
|
|||||||
// sign attempt
|
// sign attempt
|
||||||
if(pit == mMsgPendingSign.end())
|
if(pit == mMsgPendingSign.end())
|
||||||
{
|
{
|
||||||
GxsPendingItem<RsGxsMsgItem*, uint32_t> gsi(msgItem, token);
|
GxsPendingItem<RsGxsMsgItem*, uint32_t> gsi(msgItem, token,time(NULL));
|
||||||
mMsgPendingSign.insert(std::make_pair(token, gsi));
|
mMsgPendingSign.insert(std::make_pair(token, gsi));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// remove from attempts queue if over sign
|
// remove from attempts queue if over sign
|
||||||
// attempts limit
|
// attempts limit
|
||||||
if(pit->second.mAttempts == SIGN_MAX_ATTEMPTS)
|
if(pit->second.mFirstTryTS + SIGN_MAX_WAITING_TIME < now)
|
||||||
{
|
{
|
||||||
|
std::cerr << "Pending signature grp=" << pit->second.mItem->meta.mGroupId << ", msg=" << pit->second.mItem->meta.mMsgId << ", has exceeded validation time limit. The author's key can probably not be obtained. This is unexpected." << std::endl;
|
||||||
|
|
||||||
mMsgPendingSign.erase(token);
|
mMsgPendingSign.erase(token);
|
||||||
tryLater = false;
|
tryLater = false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
++pit->second.mAttempts;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createOk = false;
|
createOk = false;
|
||||||
@ -2656,28 +2653,22 @@ void RsGenExchange::processRecvdMessages()
|
|||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mGenMtx) ;
|
RS_STACK_MUTEX(mGenMtx) ;
|
||||||
|
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
if(!mMsgPendingValidate.empty())
|
if(!mMsgPendingValidate.empty())
|
||||||
std::cerr << "processing received messages" << std::endl;
|
std::cerr << "processing received messages" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
NxsMsgPendingVect::iterator pend_it = mMsgPendingValidate.begin();
|
NxsMsgPendingVect::iterator pend_it = mMsgPendingValidate.begin();
|
||||||
|
|
||||||
#ifdef GEN_EXCH_DEBUG
|
|
||||||
if(!mMsgPendingValidate.empty())
|
|
||||||
std::cerr << " pending validation" << std::endl;
|
|
||||||
#endif
|
|
||||||
for(; pend_it != mMsgPendingValidate.end();)
|
for(; pend_it != mMsgPendingValidate.end();)
|
||||||
{
|
{
|
||||||
GxsPendingItem<RsNxsMsg*, RsGxsGrpMsgIdPair>& gpsi = *pend_it;
|
GxsPendingItem<RsNxsMsg*, RsGxsGrpMsgIdPair>& gpsi = *pend_it;
|
||||||
|
|
||||||
#ifdef GEN_EXCH_DEBUG
|
if(gpsi.mFirstTryTS + VALIDATE_MAX_WAITING_TIME < now)
|
||||||
std::cerr << " grp=" << gpsi.mId.first << ", msg=" << gpsi.mId.second << ", attempts=" << gpsi.mAttempts ;
|
|
||||||
#endif
|
|
||||||
if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS)
|
|
||||||
{
|
{
|
||||||
#ifdef GEN_EXCH_DEBUG
|
std::cerr << "Pending validation grp=" << gpsi.mId.first << ", msg=" << gpsi.mId.second << ", has exceeded validation time limit. The author's key can probably not be obtained. This is unexpected." << std::endl;
|
||||||
std::cerr << " = max! deleting." << std::endl;
|
|
||||||
#endif
|
|
||||||
delete gpsi.mItem;
|
delete gpsi.mItem;
|
||||||
pend_it = mMsgPendingValidate.erase(pend_it);
|
pend_it = mMsgPendingValidate.erase(pend_it);
|
||||||
}
|
}
|
||||||
@ -2839,16 +2830,12 @@ void RsGenExchange::processRecvdMessages()
|
|||||||
|
|
||||||
// first check you haven't made too many attempts
|
// first check you haven't made too many attempts
|
||||||
|
|
||||||
NxsMsgPendingVect::iterator vit = std::find(
|
NxsMsgPendingVect::iterator vit = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), id);
|
||||||
mMsgPendingValidate.begin(), mMsgPendingValidate.end(), id);
|
|
||||||
|
|
||||||
if(vit == mMsgPendingValidate.end())
|
if(vit == mMsgPendingValidate.end())
|
||||||
{
|
{
|
||||||
GxsPendingItem<RsNxsMsg*, RsGxsGrpMsgIdPair> item(msg, id);
|
GxsPendingItem<RsNxsMsg*, RsGxsGrpMsgIdPair> item(msg, id,time(NULL));
|
||||||
mMsgPendingValidate.push_back(item);
|
mMsgPendingValidate.push_back(item);
|
||||||
}else
|
|
||||||
{
|
|
||||||
vit->mAttempts++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2981,18 +2968,16 @@ void RsGenExchange::processRecvdGroups()
|
|||||||
std::cerr << " failed to validate incoming grp, trying again. grpId: " << grp->grpId << std::endl;
|
std::cerr << " failed to validate incoming grp, trying again. grpId: " << grp->grpId << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS)
|
if(gpsi.mFirstTryTS + VALIDATE_MAX_WAITING_TIME < time(NULL))
|
||||||
{
|
{
|
||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
std::cerr << " max attempts " << VALIDATE_MAX_ATTEMPTS << " reached. Will delete group " << grp->grpId << std::endl;
|
std::cerr << " validation time got group " << grp->grpId << " exceeded maximum. Will delete group " << std::endl;
|
||||||
#endif
|
#endif
|
||||||
delete grp;
|
delete grp;
|
||||||
erase = true;
|
erase = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
erase = false;
|
erase = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3147,7 +3132,7 @@ bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp)
|
|||||||
// also check this is the latest published group
|
// also check this is the latest published group
|
||||||
bool latest = newGrp.metaData->mPublishTs > oldGrpMeta.mPublishTs;
|
bool latest = newGrp.metaData->mPublishTs > oldGrpMeta.mPublishTs;
|
||||||
|
|
||||||
mGixs->timeStampKey(newGrp.metaData->mAuthorId) ;
|
mGixs->timeStampKey(newGrp.metaData->mAuthorId,"Validation of signature for updated grp " + oldGrpMeta.mGroupId.toStdString()) ;
|
||||||
return GxsSecurity::validateNxsGrp(newGrp, adminSign, keyMit->second) && latest;
|
return GxsSecurity::validateNxsGrp(newGrp, adminSign, keyMit->second) && latest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,17 +43,10 @@ template<class GxsItem, typename Identity = std::string>
|
|||||||
class GxsPendingItem
|
class GxsPendingItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GxsPendingItem(GxsItem item, Identity id) :
|
GxsPendingItem(GxsItem item, Identity id,time_t ts) :
|
||||||
mItem(item), mId(id), mAttempts(0)
|
mItem(item), mId(id), mFirstTryTS(ts)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
GxsPendingItem(const GxsPendingItem& gpsi)
|
|
||||||
{
|
|
||||||
this->mItem = gpsi.mItem;
|
|
||||||
this->mId = gpsi.mId;
|
|
||||||
this->mAttempts = gpsi.mAttempts;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Identity& id)
|
bool operator==(const Identity& id)
|
||||||
{
|
{
|
||||||
return this->mId == id;
|
return this->mId == id;
|
||||||
@ -61,7 +54,7 @@ public:
|
|||||||
|
|
||||||
GxsItem mItem;
|
GxsItem mItem;
|
||||||
Identity mId;
|
Identity mId;
|
||||||
uint8_t mAttempts;
|
time_t mFirstTryTS;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GxsGrpPendingSign
|
class GxsGrpPendingSign
|
||||||
@ -656,6 +649,9 @@ public:
|
|||||||
virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) ;
|
virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) ;
|
||||||
|
|
||||||
uint16_t serviceType() const { return mServType ; }
|
uint16_t serviceType() const { return mServType ; }
|
||||||
|
uint32_t serviceFullType() const { return ((uint32_t)mServType << 8) + (((uint32_t) RS_PKT_VERSION_SERVICE) << 24); }
|
||||||
|
|
||||||
|
virtual RsReputations::ReputationLevel minReputationForForwardingMessages(uint32_t group_sign_flags,uint32_t identity_flags);
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** Notifications **/
|
/** Notifications **/
|
||||||
@ -880,9 +876,9 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const uint8_t CREATE_FAIL, CREATE_SUCCESS, CREATE_FAIL_TRY_LATER, SIGN_MAX_ATTEMPTS;
|
const uint8_t CREATE_FAIL, CREATE_SUCCESS, CREATE_FAIL_TRY_LATER, SIGN_MAX_WAITING_TIME;
|
||||||
const uint8_t SIGN_FAIL, SIGN_SUCCESS, SIGN_FAIL_TRY_LATER;
|
const uint8_t SIGN_FAIL, SIGN_SUCCESS, SIGN_FAIL_TRY_LATER;
|
||||||
const uint8_t VALIDATE_FAIL, VALIDATE_SUCCESS, VALIDATE_FAIL_TRY_LATER, VALIDATE_MAX_ATTEMPTS;
|
const uint8_t VALIDATE_FAIL, VALIDATE_SUCCESS, VALIDATE_FAIL_TRY_LATER, VALIDATE_MAX_WAITING_TIME;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
virtual bool signData(const uint8_t *data,uint32_t data_size,const RsGxsId& signer_id,RsTlvKeySignature& signature,uint32_t& signing_error) = 0 ;
|
virtual bool signData(const uint8_t *data,uint32_t data_size,const RsGxsId& signer_id,RsTlvKeySignature& signature,uint32_t& signing_error) = 0 ;
|
||||||
virtual bool validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,uint32_t& signing_error) = 0 ;
|
virtual bool validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,const std::string& info_string,uint32_t& signing_error) = 0 ;
|
||||||
|
|
||||||
virtual bool encryptData(const uint8_t *clear_data,uint32_t clear_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& encryption_error) = 0 ;
|
virtual bool encryptData(const uint8_t *clear_data,uint32_t clear_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& encryption_error) = 0 ;
|
||||||
virtual bool decryptData(const uint8_t *encrypted_data,uint32_t encrypted_data_size,uint8_t *& clear_data,uint32_t& clear_data_size,const RsGxsId& encryption_key_id,uint32_t& encryption_error) = 0 ;
|
virtual bool decryptData(const uint8_t *encrypted_data,uint32_t encrypted_data_size,uint8_t *& clear_data,uint32_t& clear_data_size,const RsGxsId& encryption_key_id,uint32_t& encryption_error) = 0 ;
|
||||||
@ -125,7 +125,7 @@ public:
|
|||||||
virtual bool getOwnIds(std::list<RsGxsId>& ids) = 0;
|
virtual bool getOwnIds(std::list<RsGxsId>& ids) = 0;
|
||||||
virtual bool isOwnId(const RsGxsId& key_id) = 0 ;
|
virtual bool isOwnId(const RsGxsId& key_id) = 0 ;
|
||||||
|
|
||||||
virtual void timeStampKey(const RsGxsId& key_id) = 0 ;
|
virtual void timeStampKey(const RsGxsId& key_id,const std::string& reason) = 0 ;
|
||||||
|
|
||||||
// Key related interface - used for validating msgs and groups.
|
// Key related interface - used for validating msgs and groups.
|
||||||
/*!
|
/*!
|
||||||
@ -149,7 +149,7 @@ public:
|
|||||||
* @param keyref the KeyRef of the key being requested
|
* @param keyref the KeyRef of the key being requested
|
||||||
* @return will
|
* @return will
|
||||||
*/
|
*/
|
||||||
virtual bool requestKey(const RsGxsId &id, const std::list<RsPeerId> &peers) = 0;
|
virtual bool requestKey(const RsGxsId &id, const std::list<RsPeerId> &peers,const std::string& info) = 0;
|
||||||
virtual bool requestPrivateKey(const RsGxsId &id) = 0;
|
virtual bool requestPrivateKey(const RsGxsId &id) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1954,8 +1954,6 @@ void RsGxsNetService::updateServerSyncTS()
|
|||||||
|
|
||||||
for(std::map<RsGxsGroupId, RsGxsGrpMetaData*>::const_iterator mit = gxsMap.begin();mit != gxsMap.end(); ++mit)
|
for(std::map<RsGxsGroupId, RsGxsGrpMetaData*>::const_iterator mit = gxsMap.begin();mit != gxsMap.end(); ++mit)
|
||||||
{
|
{
|
||||||
//const RsGxsGroupId& grpId = mit->first;
|
|
||||||
|
|
||||||
// Check if the group is subscribed and restricted to a circle. If the circle has changed, update the
|
// Check if the group is subscribed and restricted to a circle. If the circle has changed, update the
|
||||||
// global TS to reflect that change to clients who may be able to see/subscribe to that particular group.
|
// global TS to reflect that change to clients who may be able to see/subscribe to that particular group.
|
||||||
|
|
||||||
@ -2810,16 +2808,13 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
|
|||||||
if(reqListSize < (int)MAX_REQLIST_SIZE && msgIdSet.find(msgId) == msgIdSet.end())
|
if(reqListSize < (int)MAX_REQLIST_SIZE && msgIdSet.find(msgId) == msgIdSet.end())
|
||||||
{
|
{
|
||||||
|
|
||||||
// if reputation is in reputations cache then proceed
|
|
||||||
// or if there isn't an author (note as author requirement is
|
|
||||||
// enforced at service level, if no author is needed then reputation
|
|
||||||
// filtering is optional)
|
|
||||||
bool noAuthor = syncItem->authorId.isNull();
|
bool noAuthor = syncItem->authorId.isNull();
|
||||||
|
|
||||||
#ifdef NXS_NET_DEBUG_1
|
#ifdef NXS_NET_DEBUG_1
|
||||||
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", reqlist size=" << reqListSize << ", message not present." ;
|
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", reqlist size=" << reqListSize << ", message not present." ;
|
||||||
#endif
|
#endif
|
||||||
// grp meta must be present if author present
|
// grp meta must be present if author present
|
||||||
|
|
||||||
if(!noAuthor && grpMeta == NULL)
|
if(!noAuthor && grpMeta == NULL)
|
||||||
{
|
{
|
||||||
#ifdef NXS_NET_DEBUG_1
|
#ifdef NXS_NET_DEBUG_1
|
||||||
@ -2828,7 +2823,13 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rsIdentity && rsIdentity->isBanned(syncItem->authorId))
|
// The algorithm on request of message is:
|
||||||
|
//
|
||||||
|
// - always re-check for author ban level
|
||||||
|
// - if author is locally banned, do not download.
|
||||||
|
// - if author is not locally banned, download, whatever friends' opinion might be.
|
||||||
|
|
||||||
|
if(rsIdentity && rsIdentity->overallReputationLevel(syncItem->authorId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
{
|
{
|
||||||
#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;
|
||||||
@ -2844,7 +2845,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
|
|||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TO_BE_REMOVED
|
||||||
if(mReputations->haveReputation(syncItem->authorId) || noAuthor)
|
if(mReputations->haveReputation(syncItem->authorId) || noAuthor)
|
||||||
{
|
{
|
||||||
GixsReputation rep;
|
GixsReputation rep;
|
||||||
@ -2859,17 +2860,20 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
|
|||||||
// at genexchange side of things
|
// at genexchange side of things
|
||||||
if(rep.score >= (int)grpMeta->mReputationCutOff || noAuthor)
|
if(rep.score >= (int)grpMeta->mReputationCutOff || noAuthor)
|
||||||
{
|
{
|
||||||
#ifdef NXS_NET_DEBUG_1
|
|
||||||
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", passed! Adding message to req list." << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
RsNxsSyncMsgItem* msgItem = new RsNxsSyncMsgItem(mServType);
|
#ifdef NXS_NET_DEBUG_1
|
||||||
msgItem->grpId = grpId;
|
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", passed! Adding message to req list." << std::endl;
|
||||||
msgItem->msgId = msgId;
|
#endif
|
||||||
msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST;
|
RsNxsSyncMsgItem* msgItem = new RsNxsSyncMsgItem(mServType);
|
||||||
msgItem->transactionNumber = transN;
|
msgItem->grpId = grpId;
|
||||||
msgItem->PeerId(peerFrom);
|
msgItem->msgId = msgId;
|
||||||
reqList.push_back(msgItem);
|
msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST;
|
||||||
++reqListSize ;
|
msgItem->transactionNumber = transN;
|
||||||
|
msgItem->PeerId(peerFrom);
|
||||||
|
reqList.push_back(msgItem);
|
||||||
|
++reqListSize ;
|
||||||
|
|
||||||
|
#ifdef TO_BE_REMOVED
|
||||||
}
|
}
|
||||||
#ifdef NXS_NET_DEBUG_1
|
#ifdef NXS_NET_DEBUG_1
|
||||||
else
|
else
|
||||||
@ -2889,6 +2893,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
|
|||||||
entry.mMsgId = syncItem->msgId;
|
entry.mMsgId = syncItem->msgId;
|
||||||
toVet.push_back(entry);
|
toVet.push_back(entry);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef NXS_NET_DEBUG_1
|
#ifdef NXS_NET_DEBUG_1
|
||||||
else
|
else
|
||||||
@ -3061,13 +3066,14 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
|
|||||||
}
|
}
|
||||||
// FIXTESTS global variable rsReputations not available in unittests!
|
// FIXTESTS global variable rsReputations not available in unittests!
|
||||||
|
|
||||||
if(!grpSyncItem->authorId.isNull() && rsIdentity && rsIdentity->isBanned(grpSyncItem->authorId))
|
#warning Update the code below to correctly send/recv dependign on reputation
|
||||||
{
|
if(!grpSyncItem->authorId.isNull() && rsIdentity && rsIdentity->overallReputationLevel(grpSyncItem->authorId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
|
{
|
||||||
#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;
|
||||||
#endif
|
#endif
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (mGrpAutoSync && !haveItem) || latestVersion)
|
if( (mGrpAutoSync && !haveItem) || latestVersion)
|
||||||
{
|
{
|
||||||
@ -4202,59 +4208,83 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
|
|||||||
uint32_t transN = locked_getTransactionId();
|
uint32_t transN = locked_getTransactionId();
|
||||||
RsGxsCircleId should_encrypt_to_this_circle_id ;
|
RsGxsCircleId should_encrypt_to_this_circle_id ;
|
||||||
|
|
||||||
|
time_t now = time(NULL) ;
|
||||||
|
|
||||||
|
uint32_t max_send_delay = mServerGrpConfigMap[item->grpId].msg_req_delay; // we should use "sync" but there's only one variable used in the GUI: the req one.
|
||||||
|
|
||||||
if(canSendMsgIds(msgMetas, *grpMeta, peer, should_encrypt_to_this_circle_id))
|
if(canSendMsgIds(msgMetas, *grpMeta, peer, should_encrypt_to_this_circle_id))
|
||||||
{
|
{
|
||||||
for(std::vector<RsGxsMsgMetaData*>::iterator vit = msgMetas.begin();vit != msgMetas.end(); ++vit)
|
for(std::vector<RsGxsMsgMetaData*>::iterator vit = msgMetas.begin();vit != msgMetas.end(); ++vit)
|
||||||
if(item->createdSinceTS < (*vit)->mPublishTs)
|
{
|
||||||
|
RsGxsMsgMetaData* m = *vit;
|
||||||
|
|
||||||
|
RsIdentityDetails details ;
|
||||||
|
|
||||||
|
if(!rsIdentity->getIdDetails(m->mAuthorId,details))
|
||||||
{
|
{
|
||||||
RsGxsMsgMetaData* m = *vit;
|
std::cerr << /* GXSNETDEBUG_PG(item->PeerId(),item->grpId) << */ " not sending grp message ID " << (*vit)->mMsgId << ", because the identity of the author is not accessible (unknown/not cached)" << std::endl;
|
||||||
|
continue ;
|
||||||
RsNxsSyncMsgItem* mItem = new RsNxsSyncMsgItem(mServType);
|
|
||||||
mItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE;
|
|
||||||
mItem->grpId = m->mGroupId;
|
|
||||||
mItem->msgId = m->mMsgId;
|
|
||||||
mItem->authorId = m->mAuthorId;
|
|
||||||
mItem->PeerId(peer);
|
|
||||||
mItem->transactionNumber = transN;
|
|
||||||
|
|
||||||
if(!should_encrypt_to_this_circle_id.isNull())
|
|
||||||
{
|
|
||||||
#ifdef NXS_NET_DEBUG_7
|
|
||||||
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending info item for msg id " << mItem->msgId << ". Transaction will be encrypted for group " << should_encrypt_to_this_circle_id << std::endl;
|
|
||||||
#endif
|
|
||||||
RsNxsItem *encrypted_item = NULL ;
|
|
||||||
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
|
|
||||||
|
|
||||||
if(encryptSingleNxsItem(mItem, grpMeta->mCircleId,m->mGroupId, encrypted_item,status))
|
|
||||||
{
|
|
||||||
itemL.push_back(encrypted_item) ;
|
|
||||||
delete mItem ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Something's not ready (probably the circle content. We could put on a vetting list, but actually the client will re-ask the list asap.
|
|
||||||
|
|
||||||
std::cerr << " (EE) Cannot encrypt msg meta data. MsgId=" << mItem->msgId << ", grpId=" << mItem->grpId << ", circleId=" << should_encrypt_to_this_circle_id << ". Dropping the whole list." << std::endl;
|
|
||||||
|
|
||||||
for(std::list<RsNxsItem*>::const_iterator it(itemL.begin());it!=itemL.end();++it)
|
|
||||||
delete *it ;
|
|
||||||
|
|
||||||
itemL.clear() ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef NXS_NET_DEBUG_7
|
|
||||||
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending info item for msg id " << mItem->msgId << " in clear." << std::endl;
|
|
||||||
#endif
|
|
||||||
itemL.push_back(mItem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(details.mReputation.mOverallReputationLevel < minReputationForForwardingMessages(grpMeta->mSignFlags, details.mFlags))
|
||||||
|
{
|
||||||
|
//#ifdef NXS_NET_DEBUG_0
|
||||||
|
std::cerr << /* GXSNETDEBUG_PG(item->PeerId(),item->grpId) << */ " not sending item ID " << (*vit)->mMsgId << ", because the author is flags " << std::hex << details.mFlags << std::dec << " and reputation level " << details.mReputation.mOverallReputationLevel << std::endl;
|
||||||
|
//#endif
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// Check publish TS
|
||||||
|
|
||||||
|
if(item->createdSinceTS > (*vit)->mPublishTs || (*vit)->mPublishTs + max_send_delay < now)
|
||||||
|
{
|
||||||
#ifdef NXS_NET_DEBUG_0
|
#ifdef NXS_NET_DEBUG_0
|
||||||
else
|
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " not sending item ID " << (*vit)->mMsgId << ", because it is too old (publishTS = " << (time(NULL)-(*vit)->mPublishTs)/86400 << " days ago" << std::endl;
|
||||||
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " not sending item ID " << (*vit)->mMsgId << ", because it is too old (publishTS = " << (time(NULL)-(*vit)->mPublishTs)/86400 << " days ago" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsNxsSyncMsgItem* mItem = new RsNxsSyncMsgItem(mServType);
|
||||||
|
mItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE;
|
||||||
|
mItem->grpId = m->mGroupId;
|
||||||
|
mItem->msgId = m->mMsgId;
|
||||||
|
mItem->authorId = m->mAuthorId;
|
||||||
|
mItem->PeerId(peer);
|
||||||
|
mItem->transactionNumber = transN;
|
||||||
|
|
||||||
|
if(!should_encrypt_to_this_circle_id.isNull())
|
||||||
|
{
|
||||||
|
#ifdef NXS_NET_DEBUG_7
|
||||||
|
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending info item for msg id " << mItem->msgId << ". Transaction will be encrypted for group " << should_encrypt_to_this_circle_id << std::endl;
|
||||||
|
#endif
|
||||||
|
RsNxsItem *encrypted_item = NULL ;
|
||||||
|
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
|
||||||
|
|
||||||
|
if(encryptSingleNxsItem(mItem, grpMeta->mCircleId,m->mGroupId, encrypted_item,status))
|
||||||
|
{
|
||||||
|
itemL.push_back(encrypted_item) ;
|
||||||
|
delete mItem ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Something's not ready (probably the circle content. We could put on a vetting list, but actually the client will re-ask the list asap.
|
||||||
|
|
||||||
|
std::cerr << " (EE) Cannot encrypt msg meta data. MsgId=" << mItem->msgId << ", grpId=" << mItem->grpId << ", circleId=" << should_encrypt_to_this_circle_id << ". Dropping the whole list." << std::endl;
|
||||||
|
|
||||||
|
for(std::list<RsNxsItem*>::const_iterator it(itemL.begin());it!=itemL.end();++it)
|
||||||
|
delete *it ;
|
||||||
|
|
||||||
|
itemL.clear() ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef NXS_NET_DEBUG_7
|
||||||
|
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending info item for msg id " << mItem->msgId << " in clear." << std::endl;
|
||||||
|
#endif
|
||||||
|
itemL.push_back(mItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef NXS_NET_DEBUG_0
|
#ifdef NXS_NET_DEBUG_0
|
||||||
else
|
else
|
||||||
|
@ -139,7 +139,7 @@ bool RsGxsIntegrityCheck::check()
|
|||||||
GxsMsgReq msgIds;
|
GxsMsgReq msgIds;
|
||||||
GxsMsgReq grps;
|
GxsMsgReq grps;
|
||||||
|
|
||||||
std::set<RsGxsId> used_gxs_ids ;
|
std::map<RsGxsId,RsGxsGroupId> used_gxs_ids ;
|
||||||
std::set<RsGxsGroupId> subscribed_groups ;
|
std::set<RsGxsGroupId> subscribed_groups ;
|
||||||
|
|
||||||
// compute hash and compare to stored value, if it fails then simply add it
|
// compute hash and compare to stored value, if it fails then simply add it
|
||||||
@ -171,8 +171,8 @@ bool RsGxsIntegrityCheck::check()
|
|||||||
GXSUTIL_DEBUG() << "TimeStamping group authors' key ID " << grp->metaData->mAuthorId << " in group ID " << grp->grpId << std::endl;
|
GXSUTIL_DEBUG() << "TimeStamping group authors' key ID " << grp->metaData->mAuthorId << " in group ID " << grp->grpId << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(rsIdentity!=NULL && !rsIdentity->isBanned(grp->metaData->mAuthorId))
|
if(rsIdentity!=NULL && rsIdentity->overallReputationLevel(grp->metaData->mAuthorId) > RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
used_gxs_ids.insert(grp->metaData->mAuthorId) ;
|
used_gxs_ids.insert(std::make_pair(grp->metaData->mAuthorId,grp->grpId)) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,8 +269,8 @@ bool RsGxsIntegrityCheck::check()
|
|||||||
#ifdef DEBUG_GXSUTIL
|
#ifdef DEBUG_GXSUTIL
|
||||||
GXSUTIL_DEBUG() << "TimeStamping message authors' key ID " << msg->metaData->mAuthorId << " in message " << msg->msgId << ", group ID " << msg->grpId<< std::endl;
|
GXSUTIL_DEBUG() << "TimeStamping message authors' key ID " << msg->metaData->mAuthorId << " in message " << msg->msgId << ", group ID " << msg->grpId<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
if(rsIdentity!=NULL && !rsIdentity->isBanned(msg->metaData->mAuthorId))
|
if(rsIdentity!=NULL && rsIdentity->overallReputationLevel(msg->metaData->mAuthorId) > RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
used_gxs_ids.insert(msg->metaData->mAuthorId) ;
|
used_gxs_ids.insert(std::make_pair(msg->metaData->mAuthorId,msg->metaData->mGroupId)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete msg;
|
delete msg;
|
||||||
@ -297,9 +297,9 @@ bool RsGxsIntegrityCheck::check()
|
|||||||
std::list<RsPeerId> connected_friends ;
|
std::list<RsPeerId> connected_friends ;
|
||||||
rsPeers->getOnlineList(connected_friends) ;
|
rsPeers->getOnlineList(connected_friends) ;
|
||||||
|
|
||||||
std::vector<RsGxsId> gxs_ids ;
|
std::vector<std::pair<RsGxsId,RsGxsGroupId> > gxs_ids ;
|
||||||
|
|
||||||
for(std::set<RsGxsId>::const_iterator it(used_gxs_ids.begin());it!=used_gxs_ids.end();++it)
|
for(std::map<RsGxsId,RsGxsGroupId>::const_iterator it(used_gxs_ids.begin());it!=used_gxs_ids.end();++it)
|
||||||
{
|
{
|
||||||
gxs_ids.push_back(*it) ;
|
gxs_ids.push_back(*it) ;
|
||||||
#ifdef DEBUG_GXSUTIL
|
#ifdef DEBUG_GXSUTIL
|
||||||
@ -321,9 +321,9 @@ bool RsGxsIntegrityCheck::check()
|
|||||||
GXSUTIL_DEBUG() << " requesting ID " << gxs_ids[n] ;
|
GXSUTIL_DEBUG() << " requesting ID " << gxs_ids[n] ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!mGixs->haveKey(gxs_ids[n])) // checks if we have it already in the cache (conservative way to ensure that we atually have it)
|
if(!mGixs->haveKey(gxs_ids[n].first)) // checks if we have it already in the cache (conservative way to ensure that we atually have it)
|
||||||
{
|
{
|
||||||
mGixs->requestKey(gxs_ids[n],connected_friends);
|
mGixs->requestKey(gxs_ids[n].first,connected_friends,"Author in service \"" + rsServiceControl->getServiceName(mGenExchangeClient->serviceFullType())+"\" (group ID " + gxs_ids[n].second.toStdString() + ")" ) ;
|
||||||
|
|
||||||
++nb_requested_not_in_cache ;
|
++nb_requested_not_in_cache ;
|
||||||
#ifdef DEBUG_GXSUTIL
|
#ifdef DEBUG_GXSUTIL
|
||||||
@ -335,12 +335,8 @@ bool RsGxsIntegrityCheck::check()
|
|||||||
#ifdef DEBUG_GXSUTIL
|
#ifdef DEBUG_GXSUTIL
|
||||||
GXSUTIL_DEBUG() << " ... already in cache" << std::endl;
|
GXSUTIL_DEBUG() << " ... already in cache" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Note: we could time_stamp even in the case where the id is not cached. Anyway, it's not really a problem here, since IDs have a high chance of
|
|
||||||
// behing eventually stamped.
|
|
||||||
|
|
||||||
mGixs->timeStampKey(gxs_ids[n]) ;
|
|
||||||
}
|
}
|
||||||
|
mGixs->timeStampKey(gxs_ids[n].first,"Author in service \"" + rsServiceControl->getServiceName(mGenExchangeClient->serviceFullType())+"\" (group ID " + gxs_ids[n].second.toStdString() + ")");
|
||||||
|
|
||||||
gxs_ids[n] = gxs_ids[gxs_ids.size()-1] ;
|
gxs_ids[n] = gxs_ids[gxs_ids.size()-1] ;
|
||||||
gxs_ids.pop_back() ;
|
gxs_ids.pop_back() ;
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "services/p3service.h"
|
#include "services/p3service.h"
|
||||||
|
#include "retroshare/rsreputations.h"
|
||||||
|
#include "retroshare/rsidentity.h"
|
||||||
#include "rsgds.h"
|
#include "rsgds.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -159,6 +161,55 @@ public:
|
|||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
virtual bool stampMsgServerUpdateTS(const RsGxsGroupId& gid) =0;
|
virtual bool stampMsgServerUpdateTS(const RsGxsGroupId& gid) =0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief minReputationForForwardingMessages
|
||||||
|
* Encodes the policy for sending/requesting messages depending on anti-spam settings.
|
||||||
|
*
|
||||||
|
* \param group_sign_flags Sign flags from the group meta data
|
||||||
|
* \param identity_flags Flags of the identity
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
static RsReputations::ReputationLevel minReputationForRequestingMessages(uint32_t /* group_sign_flags */, uint32_t /* identity_flags */)
|
||||||
|
{
|
||||||
|
// We always request messages, except if the author identity is locally banned.
|
||||||
|
|
||||||
|
return RsReputations::REPUTATION_REMOTELY_NEGATIVE;
|
||||||
|
}
|
||||||
|
static RsReputations::ReputationLevel minReputationForForwardingMessages(uint32_t group_sign_flags, uint32_t identity_flags)
|
||||||
|
{
|
||||||
|
// If anti-spam is enabled, do not send messages from authors with bad reputation. The policy is to only forward messages if the reputation of the author is at least
|
||||||
|
// equal to the minimal reputation in the table below (R=remotely, L=locally, P=positive, N=negative, O=neutral) :
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// +----------------------------------------------------+
|
||||||
|
// | Identity flags |
|
||||||
|
// +----------------------------------------------------+
|
||||||
|
// | Anonymous Signed Signed+Known |
|
||||||
|
// +-------------+-----------+----------------------------------------------------+
|
||||||
|
// | |NONE | O O O |
|
||||||
|
// | Forum flags |GPG_AUTHED | RP O O |
|
||||||
|
// | |GPG_KNOWN | RP RP O |
|
||||||
|
// +-------------+-----------+----------------------------------------------------+
|
||||||
|
//
|
||||||
|
|
||||||
|
if(identity_flags & RS_IDENTITY_FLAGS_PGP_KNOWN)
|
||||||
|
return RsReputations::REPUTATION_NEUTRAL;
|
||||||
|
else if(identity_flags & RS_IDENTITY_FLAGS_PGP_LINKED)
|
||||||
|
{
|
||||||
|
if(group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN)
|
||||||
|
return RsReputations::REPUTATION_REMOTELY_POSITIVE;
|
||||||
|
else
|
||||||
|
return RsReputations::REPUTATION_NEUTRAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( (group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) || (group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG))
|
||||||
|
return RsReputations::REPUTATION_REMOTELY_POSITIVE;
|
||||||
|
else
|
||||||
|
return RsReputations::REPUTATION_NEUTRAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RSGNP_H
|
#endif // RSGNP_H
|
||||||
|
@ -937,7 +937,7 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item)
|
|||||||
std::cerr << "(SS) Signature was verified and it doesn't check! This is a security issue!" << std::endl;
|
std::cerr << "(SS) Signature was verified and it doesn't check! This is a security issue!" << std::endl;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
mGixs->timeStampKey(item->signature.keyId) ;
|
mGixs->timeStampKey(item->signature.keyId,"Used to validate GXS tunnel DH half-key.") ;
|
||||||
|
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << " Signature checks! Sender's ID = " << senders_id << std::endl;
|
std::cerr << " Signature checks! Sender's ID = " << senders_id << std::endl;
|
||||||
|
@ -362,6 +362,20 @@ void p3ServiceControl::getServiceChanges(std::set<RsPeerId> &updateSet)
|
|||||||
mUpdatedSet.clear();
|
mUpdatedSet.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string p3ServiceControl::getServiceName(uint32_t service_id)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/
|
||||||
|
|
||||||
|
std::map<uint32_t, RsServiceInfo>::const_iterator it = mOwnServices.find(service_id) ;
|
||||||
|
|
||||||
|
if(it == mOwnServices.end())
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) Cannot find own service for ID = " << std::hex << service_id << std::dec << std::endl;
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
return it->second.mServiceName;
|
||||||
|
}
|
||||||
|
|
||||||
bool p3ServiceControl::getOwnServices(RsPeerServiceInfo &info)
|
bool p3ServiceControl::getOwnServices(RsPeerServiceInfo &info)
|
||||||
{
|
{
|
||||||
|
@ -85,6 +85,7 @@ virtual const RsPeerId& getOwnId();
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
virtual bool getOwnServices(RsPeerServiceInfo &info);
|
virtual bool getOwnServices(RsPeerServiceInfo &info);
|
||||||
|
virtual std::string getServiceName(uint32_t service_id) ;
|
||||||
|
|
||||||
// This is what is passed to peers, can be displayed by GUI too.
|
// This is what is passed to peers, can be displayed by GUI too.
|
||||||
virtual bool getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info);
|
virtual bool getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info);
|
||||||
|
@ -61,37 +61,36 @@ std::ostream &operator<<(std::ostream &out, const RsGxsForumMsg &msg);
|
|||||||
|
|
||||||
class RsGxsForums: public RsGxsIfaceHelper
|
class RsGxsForums: public RsGxsIfaceHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RsGxsForums(RsGxsIface *gxs)
|
RsGxsForums(RsGxsIface *gxs)
|
||||||
:RsGxsIfaceHelper(gxs) { return; }
|
:RsGxsIfaceHelper(gxs) { return; }
|
||||||
virtual ~RsGxsForums() { return; }
|
virtual ~RsGxsForums() { return; }
|
||||||
|
|
||||||
/* Specific Service Data */
|
/* Specific Service Data */
|
||||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups) = 0;
|
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups) = 0;
|
||||||
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) = 0;
|
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) = 0;
|
||||||
//Not currently used
|
//Not currently used
|
||||||
//virtual bool getRelatedMessages(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) = 0;
|
//virtual bool getRelatedMessages(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) = 0;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0;
|
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0;
|
||||||
|
|
||||||
//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
|
//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
|
||||||
//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
|
//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
|
||||||
|
|
||||||
//virtual bool groupRestoreKeys(const std::string &groupId);
|
//virtual bool groupRestoreKeys(const std::string &groupId);
|
||||||
//virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
|
//virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
|
||||||
|
|
||||||
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0;
|
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0;
|
||||||
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0;
|
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0;
|
||||||
|
/*!
|
||||||
/*!
|
|
||||||
* To update forum group with new information
|
* To update forum group with new information
|
||||||
* @param token the token used to check completion status of update
|
* @param token the token used to check completion status of update
|
||||||
* @param group group to be updated, groupId element must be set or will be rejected
|
* @param group group to be updated, groupId element must be set or will be rejected
|
||||||
* @return false groupId not set, true if set and accepted (still check token for completion)
|
* @return false groupId not set, true if set and accepted (still check token for completion)
|
||||||
*/
|
*/
|
||||||
virtual bool updateGroup(uint32_t &token, RsGxsForumGroup &group) = 0;
|
virtual bool updateGroup(uint32_t &token, RsGxsForumGroup &group) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#ifndef RSGXSIFACE_H_
|
#ifndef RSGXSIFACE_H_
|
||||||
#define RSGXSIFACE_H_
|
#define RSGXSIFACE_H_
|
||||||
|
|
||||||
|
#include "retroshare/rsreputations.h"
|
||||||
#include "retroshare/rsgxsservice.h"
|
#include "retroshare/rsgxsservice.h"
|
||||||
#include "gxs/rsgxsdata.h"
|
#include "gxs/rsgxsdata.h"
|
||||||
#include "retroshare/rsgxsifacetypes.h"
|
#include "retroshare/rsgxsifacetypes.h"
|
||||||
@ -181,6 +182,8 @@ public:
|
|||||||
virtual uint32_t getDefaultSyncPeriod() = 0;
|
virtual uint32_t getDefaultSyncPeriod() = 0;
|
||||||
virtual uint32_t getSyncPeriod(const RsGxsGroupId& grpId) = 0;
|
virtual uint32_t getSyncPeriod(const RsGxsGroupId& grpId) = 0;
|
||||||
virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) = 0;
|
virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) = 0;
|
||||||
|
|
||||||
|
virtual RsReputations::ReputationLevel minReputationForForwardingMessages(uint32_t group_sign_flags,uint32_t identity_flags)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "retroshare/rsgxsiface.h"
|
#include "retroshare/rsgxsiface.h"
|
||||||
|
#include "retroshare/rsreputations.h"
|
||||||
#include "rsgxsflags.h"
|
#include "rsgxsflags.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -236,6 +237,10 @@ public:
|
|||||||
mGxs->setSyncPeriod(grpId,age_in_secs);
|
mGxs->setSyncPeriod(grpId,age_in_secs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RsReputations::ReputationLevel minReputationForForwardingMessages(uint32_t group_sign_flags,uint32_t identity_flags)
|
||||||
|
{
|
||||||
|
return mGxs->minReputationForForwardingMessages(group_sign_flags,identity_flags);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
|
|
||||||
RsGxsIface* mGxs;
|
RsGxsIface* mGxs;
|
||||||
|
@ -184,8 +184,6 @@ public:
|
|||||||
// Cyril: Reputation details. At some point we might want to merge information
|
// Cyril: Reputation details. At some point we might want to merge information
|
||||||
// between the two into a single global score. Since the old reputation system
|
// between the two into a single global score. Since the old reputation system
|
||||||
// is not finished yet, I leave this in place. We should decide what to do with it.
|
// is not finished yet, I leave this in place. We should decide what to do with it.
|
||||||
|
|
||||||
GxsReputation mReputation_oldSystem; // this is the old "mReputation" field, which apparently is not used.
|
|
||||||
RsReputations::ReputationInfo mReputation;
|
RsReputations::ReputationInfo mReputation;
|
||||||
|
|
||||||
// avatar
|
// avatar
|
||||||
@ -193,6 +191,7 @@ public:
|
|||||||
|
|
||||||
// last usage
|
// last usage
|
||||||
time_t mLastUsageTS ;
|
time_t mLastUsageTS ;
|
||||||
|
std::map<std::string,time_t> mUseCases ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -254,7 +253,14 @@ public:
|
|||||||
|
|
||||||
virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) = 0 ;
|
virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) = 0 ;
|
||||||
virtual bool isARegularContact(const RsGxsId& id) = 0 ;
|
virtual bool isARegularContact(const RsGxsId& id) = 0 ;
|
||||||
virtual bool isBanned(const RsGxsId& id) =0;
|
|
||||||
|
/*!
|
||||||
|
* \brief overallReputationLevel
|
||||||
|
* Returns the overall reputation level of the supplied identity. See rsreputations.h
|
||||||
|
* \param id
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
virtual RsReputations::ReputationLevel overallReputationLevel(const RsGxsId& id)=0;
|
||||||
virtual time_t getLastUsageTS(const RsGxsId &id) =0;
|
virtual time_t getLastUsageTS(const RsGxsId &id) =0;
|
||||||
|
|
||||||
// Specific RsIdentity Functions....
|
// Specific RsIdentity Functions....
|
||||||
|
@ -36,17 +36,28 @@ public:
|
|||||||
|
|
||||||
// This is the interface file for the reputation system
|
// This is the interface file for the reputation system
|
||||||
//
|
//
|
||||||
enum Opinion { OPINION_NEGATIVE = 0, OPINION_NEUTRAL = 1, OPINION_POSITIVE = 2 } ;
|
enum Opinion { OPINION_NEGATIVE = 0, OPINION_NEUTRAL = 1, OPINION_POSITIVE = 2 } ;
|
||||||
enum Assessment { ASSESSMENT_BAD = 0, ASSESSMENT_OK = 1 } ;
|
|
||||||
|
enum ReputationLevel { REPUTATION_LOCALLY_NEGATIVE = 0x00, // local opinion is positive
|
||||||
|
REPUTATION_REMOTELY_NEGATIVE = 0x01, // local opinion is neutral and friends are positive in average
|
||||||
|
REPUTATION_NEUTRAL = 0x02, // no reputation information ;
|
||||||
|
REPUTATION_REMOTELY_POSITIVE = 0x03, // local opinion is neutral and friends are negative in average
|
||||||
|
REPUTATION_LOCALLY_POSITIVE = 0x04, // local opinion is negative
|
||||||
|
REPUTATION_UNKNOWN = 0x05 // missing info
|
||||||
|
};
|
||||||
|
|
||||||
struct ReputationInfo
|
struct ReputationInfo
|
||||||
{
|
{
|
||||||
ReputationInfo() : mOwnOpinion(OPINION_NEUTRAL), mOverallReputationScore(REPUTATION_THRESHOLD_DEFAULT), mFriendAverage(REPUTATION_THRESHOLD_DEFAULT),mAssessment(ASSESSMENT_OK){}
|
ReputationInfo() : mOwnOpinion(OPINION_NEUTRAL), mFriendAverageScore(REPUTATION_THRESHOLD_DEFAULT),mOverallReputationLevel(REPUTATION_NEUTRAL){}
|
||||||
|
|
||||||
RsReputations::Opinion mOwnOpinion ;
|
RsReputations::Opinion mOwnOpinion ;
|
||||||
float mOverallReputationScore ;
|
|
||||||
float mFriendAverage ;
|
uint32_t mFriendsPositiveVotes ;
|
||||||
RsReputations::Assessment mAssessment; // this should help clients in taking decisions
|
uint32_t mFriendsNegativeVotes ;
|
||||||
|
|
||||||
|
float mFriendAverageScore ;
|
||||||
|
|
||||||
|
RsReputations::ReputationLevel mOverallReputationLevel; // this should help clients in taking decisions
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0;
|
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0;
|
||||||
@ -54,16 +65,16 @@ public:
|
|||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
|
|
||||||
// virtual void setNodeAutoBanThreshold(uint32_t n) =0;
|
|
||||||
// virtual uint32_t nodeAutoBanThreshold() =0;
|
|
||||||
|
|
||||||
virtual void setNodeAutoPositiveOpinionForContacts(bool b) =0;
|
virtual void setNodeAutoPositiveOpinionForContacts(bool b) =0;
|
||||||
virtual bool nodeAutoPositiveOpinionForContacts() =0;
|
virtual bool nodeAutoPositiveOpinionForContacts() =0;
|
||||||
virtual float nodeAutoBanIdentitiesLimit() =0;
|
|
||||||
virtual void setNodeAutoBanIdentitiesLimit(float f) =0;
|
|
||||||
|
|
||||||
// This one is a proxy designed to allow fast checking of a GXS id.
|
virtual uint32_t thresholdForRemotelyNegativeReputation()=0;
|
||||||
// it basically returns true if assessment is not ASSESSMENT_OK
|
virtual uint32_t thresholdForRemotelyPositiveReputation()=0;
|
||||||
|
virtual void setThresholdForRemotelyNegativeReputation(uint32_t thresh)=0;
|
||||||
|
virtual void setThresholdForRemotelyPositiveReputation(uint32_t thresh)=0;
|
||||||
|
|
||||||
|
// This one is a proxy designed to allow fast checking of a GXS id.
|
||||||
|
// it basically returns true if assessment is not ASSESSMENT_OK
|
||||||
|
|
||||||
virtual bool isIdentityBanned(const RsGxsId& id) =0;
|
virtual bool isIdentityBanned(const RsGxsId& id) =0;
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ class RsServiceControl
|
|||||||
virtual ~RsServiceControl() { return; }
|
virtual ~RsServiceControl() { return; }
|
||||||
|
|
||||||
virtual bool getOwnServices(RsPeerServiceInfo &info) = 0;
|
virtual bool getOwnServices(RsPeerServiceInfo &info) = 0;
|
||||||
|
virtual std::string getServiceName(uint32_t service_id) = 0;
|
||||||
|
|
||||||
virtual bool getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0;
|
virtual bool getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0;
|
||||||
virtual bool getServicesProvided(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0;
|
virtual bool getServicesProvided(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0;
|
||||||
|
@ -1094,7 +1094,7 @@ bool p3GxsCircles::locked_processLoadingCacheEntry(RsGxsCircleCache& cache)
|
|||||||
rsPeers->getOnlineList(peers) ;
|
rsPeers->getOnlineList(peers) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
mIdentities->requestKey(pit->first, peers);
|
mIdentities->requestKey(pit->first, peers,"Membership status check in Circle "+cache.mCircleName+" ("+cache.mCircleId.toStdString()+")");
|
||||||
//isUnprocessedPeers = true;
|
//isUnprocessedPeers = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,9 @@ static const uint32_t BANNED_NODES_UPDATE_DELAY = 313 ; // update
|
|||||||
static const uint32_t REPUTATION_INFO_KEEP_DELAY = 86400*35; // remove old reputation info 5 days after last usage limit, in case the ID would come back..
|
static const uint32_t REPUTATION_INFO_KEEP_DELAY = 86400*35; // remove old reputation info 5 days after last usage limit, in case the ID would come back..
|
||||||
static const uint32_t BANNED_NODES_INACTIVITY_KEEP = 86400*60; // remove all info about banned nodes after 2 months of inactivity
|
static const uint32_t BANNED_NODES_INACTIVITY_KEEP = 86400*60; // remove all info about banned nodes after 2 months of inactivity
|
||||||
|
|
||||||
|
static const uint32_t REPUTATION_DEFAULT_MIN_VOTES_FOR_REMOTELY_POSITIVE = 1; // min difference in votes that makes friends opinion globally positive
|
||||||
|
static const uint32_t REPUTATION_DEFAULT_MIN_VOTES_FOR_REMOTELY_NEGATIVE = 1; // min difference in votes that makes friends opinion globally negative
|
||||||
|
|
||||||
p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
|
p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
|
||||||
:p3Service(), p3Config(),
|
:p3Service(), p3Config(),
|
||||||
mReputationMtx("p3GxsReputation"), mLinkMgr(lm)
|
mReputationMtx("p3GxsReputation"), mLinkMgr(lm)
|
||||||
@ -157,8 +160,9 @@ p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
|
|||||||
mLastBannedNodesUpdate = 0 ;
|
mLastBannedNodesUpdate = 0 ;
|
||||||
mBannedNodesProxyNeedsUpdate = false;
|
mBannedNodesProxyNeedsUpdate = false;
|
||||||
|
|
||||||
mAutoBanIdentitiesLimit = REPUTATION_ASSESSMENT_THRESHOLD_X1;
|
|
||||||
mAutoSetPositiveOptionToContacts = true; // default
|
mAutoSetPositiveOptionToContacts = true; // default
|
||||||
|
mMinVotesForRemotelyPositive = REPUTATION_DEFAULT_MIN_VOTES_FOR_REMOTELY_POSITIVE;
|
||||||
|
mMinVotesForRemotelyNegative = REPUTATION_DEFAULT_MIN_VOTES_FOR_REMOTELY_NEGATIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string GXS_REPUTATION_APP_NAME = "gxsreputation";
|
const std::string GXS_REPUTATION_APP_NAME = "gxsreputation";
|
||||||
@ -256,27 +260,6 @@ bool p3GxsReputation::nodeAutoPositiveOpinionForContacts()
|
|||||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
return mAutoSetPositiveOptionToContacts ;
|
return mAutoSetPositiveOptionToContacts ;
|
||||||
}
|
}
|
||||||
float p3GxsReputation::nodeAutoBanIdentitiesLimit()
|
|
||||||
{
|
|
||||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
|
||||||
return mAutoBanIdentitiesLimit - 1.0f;
|
|
||||||
}
|
|
||||||
void p3GxsReputation::setNodeAutoBanIdentitiesLimit(float f)
|
|
||||||
{
|
|
||||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
|
||||||
|
|
||||||
if(f < -1.0 || f >= 0.0)
|
|
||||||
{
|
|
||||||
std::cerr << "(EE) Unexpected value for auto ban identities limit: " << f << std::endl;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if(f != mAutoBanIdentitiesLimit)
|
|
||||||
{
|
|
||||||
mLastBannedNodesUpdate = 0 ;
|
|
||||||
mAutoBanIdentitiesLimit = f+1.0 ;
|
|
||||||
IndicateConfigChanged() ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int p3GxsReputation::status()
|
int p3GxsReputation::status()
|
||||||
{
|
{
|
||||||
@ -795,8 +778,9 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
|
|||||||
if(it == mReputations.end())
|
if(it == mReputations.end())
|
||||||
{
|
{
|
||||||
info.mOwnOpinion = RsReputations::OPINION_NEUTRAL ;
|
info.mOwnOpinion = RsReputations::OPINION_NEUTRAL ;
|
||||||
info.mOverallReputationScore = RsReputations::REPUTATION_THRESHOLD_DEFAULT ;
|
info.mFriendAverageScore = REPUTATION_THRESHOLD_DEFAULT ;
|
||||||
info.mFriendAverage = REPUTATION_THRESHOLD_DEFAULT ;
|
info.mFriendsNegativeVotes = 0 ;
|
||||||
|
info.mFriendsPositiveVotes = 0 ;
|
||||||
|
|
||||||
owner_id = ownerNode ;
|
owner_id = ownerNode ;
|
||||||
}
|
}
|
||||||
@ -805,8 +789,9 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
|
|||||||
Reputation& rep(it->second) ;
|
Reputation& rep(it->second) ;
|
||||||
|
|
||||||
info.mOwnOpinion = RsReputations::Opinion(rep.mOwnOpinion) ;
|
info.mOwnOpinion = RsReputations::Opinion(rep.mOwnOpinion) ;
|
||||||
info.mOverallReputationScore = rep.mReputation ;
|
info.mFriendAverageScore = rep.mFriendAverage ;
|
||||||
info.mFriendAverage = rep.mFriendAverage ;
|
info.mFriendsNegativeVotes = rep.mFriendsNegative ;
|
||||||
|
info.mFriendsPositiveVotes = rep.mFriendsPositive ;
|
||||||
|
|
||||||
if(rep.mOwnerNode.isNull())
|
if(rep.mOwnerNode.isNull())
|
||||||
rep.mOwnerNode = ownerNode ;
|
rep.mOwnerNode = ownerNode ;
|
||||||
@ -814,33 +799,67 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
|
|||||||
owner_id = rep.mOwnerNode ;
|
owner_id = rep.mOwnerNode ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// now compute overall score and reputation
|
||||||
|
|
||||||
|
// 0 - check for own opinion. If positive or negative, it decides on the result
|
||||||
|
|
||||||
|
if(info.mOwnOpinion == RsReputations::OPINION_NEGATIVE)
|
||||||
|
{
|
||||||
|
// own opinion is always read in priority
|
||||||
|
|
||||||
|
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
if(info.mOwnOpinion == RsReputations::OPINION_POSITIVE)
|
||||||
|
{
|
||||||
|
// own opinion is always read in priority
|
||||||
|
|
||||||
|
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_POSITIVE ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1 - check for banned PGP ids.
|
||||||
|
|
||||||
std::map<RsPgpId,BannedNodeInfo>::iterator it2 ;
|
std::map<RsPgpId,BannedNodeInfo>::iterator it2 ;
|
||||||
|
|
||||||
if(!owner_id.isNull() && (it2 = mBannedPgpIds.find(owner_id))!=mBannedPgpIds.end())
|
if(!owner_id.isNull() && (it2 = mBannedPgpIds.find(owner_id))!=mBannedPgpIds.end())
|
||||||
{
|
{
|
||||||
|
// Check if current identity is present in the list of known identities for this banned node.
|
||||||
|
|
||||||
if(it2->second.known_identities.find(gxsid) == it2->second.known_identities.end())
|
if(it2->second.known_identities.find(gxsid) == it2->second.known_identities.end())
|
||||||
{
|
{
|
||||||
it2->second.known_identities.insert(gxsid) ;
|
it2->second.known_identities.insert(gxsid) ;
|
||||||
it2->second.last_activity_TS = now ;
|
it2->second.last_activity_TS = now ;
|
||||||
|
|
||||||
|
// if so, update
|
||||||
|
|
||||||
mBannedNodesProxyNeedsUpdate = true ;
|
mBannedNodesProxyNeedsUpdate = true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
info.mAssessment = RsReputations::ASSESSMENT_BAD ;
|
|
||||||
#ifdef DEBUG_REPUTATION2
|
#ifdef DEBUG_REPUTATION2
|
||||||
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in banned nodes list)." << std::endl;
|
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in banned nodes list)." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
|
||||||
|
return true ;
|
||||||
}
|
}
|
||||||
else if(mPerNodeBannedIdsProxy.find(gxsid) != mPerNodeBannedIdsProxy.end())
|
// also check the proxy
|
||||||
|
|
||||||
|
if(mPerNodeBannedIdsProxy.find(gxsid) != mPerNodeBannedIdsProxy.end())
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_REPUTATION2
|
#ifdef DEBUG_REPUTATION2
|
||||||
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in proxy)." << std::endl;
|
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in proxy)." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
info.mAssessment = RsReputations::ASSESSMENT_BAD ;
|
info.mOverallReputationLevel = RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if(info.mOverallReputationScore <= mAutoBanIdentitiesLimit)
|
// 2 - now, our own opinion is neutral, which means we rely on what our friends tell
|
||||||
info.mAssessment = RsReputations::ASSESSMENT_BAD ;
|
|
||||||
|
if(info.mFriendsPositiveVotes >= info.mFriendsNegativeVotes + mMinVotesForRemotelyPositive)
|
||||||
|
info.mOverallReputationLevel = RsReputations::REPUTATION_REMOTELY_POSITIVE ;
|
||||||
|
else if(info.mFriendsPositiveVotes + mMinVotesForRemotelyNegative <= info.mFriendsNegativeVotes)
|
||||||
|
info.mOverallReputationLevel = RsReputations::REPUTATION_REMOTELY_NEGATIVE ;
|
||||||
else
|
else
|
||||||
info.mAssessment = RsReputations::ASSESSMENT_OK ;
|
info.mOverallReputationLevel = RsReputations::REPUTATION_NEUTRAL ;
|
||||||
|
|
||||||
#ifdef DEBUG_REPUTATION2
|
#ifdef DEBUG_REPUTATION2
|
||||||
std::cerr << " information present. OwnOp = " << info.mOwnOpinion << ", owner node=" << owner_id << ", overall score=" << info.mAssessment << std::endl;
|
std::cerr << " information present. OwnOp = " << info.mOwnOpinion << ", owner node=" << owner_id << ", overall score=" << info.mAssessment << std::endl;
|
||||||
@ -849,6 +868,36 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& own
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t p3GxsReputation::thresholdForRemotelyNegativeReputation()
|
||||||
|
{
|
||||||
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
return mMinVotesForRemotelyNegative ;
|
||||||
|
}
|
||||||
|
uint32_t p3GxsReputation::thresholdForRemotelyPositiveReputation()
|
||||||
|
{
|
||||||
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
return mMinVotesForRemotelyPositive ;
|
||||||
|
}
|
||||||
|
void p3GxsReputation::setThresholdForRemotelyPositiveReputation(uint32_t thresh)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
if(mMinVotesForRemotelyPositive == thresh || thresh==0)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
mMinVotesForRemotelyPositive = thresh ;
|
||||||
|
IndicateConfigChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void p3GxsReputation::setThresholdForRemotelyNegativeReputation(uint32_t thresh)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
if(mMinVotesForRemotelyNegative == thresh || thresh==0)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
mMinVotesForRemotelyNegative = thresh ;
|
||||||
|
IndicateConfigChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void p3GxsReputation::banNode(const RsPgpId& id,bool b)
|
void p3GxsReputation::banNode(const RsPgpId& id,bool b)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
@ -887,7 +936,7 @@ bool p3GxsReputation::isIdentityBanned(const RsGxsId &id)
|
|||||||
#ifdef DEBUG_REPUTATION
|
#ifdef DEBUG_REPUTATION
|
||||||
std::cerr << "isIdentityBanned(): returning " << (info.mAssessment == RsReputations::ASSESSMENT_BAD) << " for GXS id " << id << std::endl;
|
std::cerr << "isIdentityBanned(): returning " << (info.mAssessment == RsReputations::ASSESSMENT_BAD) << " for GXS id " << id << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return info.mAssessment == RsReputations::ASSESSMENT_BAD ;
|
return info.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::Opinion& opinion)
|
bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::Opinion& opinion)
|
||||||
@ -1026,13 +1075,14 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list<RsItem*> &savelist)
|
|||||||
|
|
||||||
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
|
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
|
||||||
RsTlvKeyValue kv;
|
RsTlvKeyValue kv;
|
||||||
// kv.key = "AUTO_BAN_NODES_THRESHOLD" ;
|
|
||||||
// rs_sprintf(kv.value, "%d", mPgpAutoBanThreshold);
|
|
||||||
// vitem->tlvkvs.pairs.push_back(kv) ;
|
|
||||||
|
|
||||||
kv.key = "AUTO_BAN_IDENTITIES_THRESHOLD" ;
|
kv.key = "AUTO_REMOTELY_POSITIVE_THRESHOLD" ;
|
||||||
rs_sprintf(kv.value, "%f", mAutoBanIdentitiesLimit);
|
rs_sprintf(kv.value, "%d", mMinVotesForRemotelyPositive);
|
||||||
vitem->tlvkvs.pairs.push_back(kv) ;
|
vitem->tlvkvs.pairs.push_back(kv) ;
|
||||||
|
|
||||||
|
kv.key = "AUTO_REMOTELY_NEGATIVE_THRESHOLD" ;
|
||||||
|
rs_sprintf(kv.value, "%d", mMinVotesForRemotelyNegative);
|
||||||
|
vitem->tlvkvs.pairs.push_back(kv) ;
|
||||||
|
|
||||||
kv.key = "AUTO_POSITIVE_CONTACTS" ;
|
kv.key = "AUTO_POSITIVE_CONTACTS" ;
|
||||||
kv.value = mAutoSetPositiveOptionToContacts?"YES":"NO";
|
kv.value = mAutoSetPositiveOptionToContacts?"YES":"NO";
|
||||||
@ -1093,27 +1143,24 @@ bool p3GxsReputation::loadList(std::list<RsItem *>& loadList)
|
|||||||
if(vitem)
|
if(vitem)
|
||||||
for(std::list<RsTlvKeyValue>::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
|
for(std::list<RsTlvKeyValue>::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
|
||||||
{
|
{
|
||||||
// if(kit->key == "AUTO_BAN_NODES_THRESHOLD")
|
if(kit->key == "AUTO_REMOTELY_POSITIVE_THRESHOLD")
|
||||||
// {
|
{
|
||||||
// int val ;
|
int val ;
|
||||||
// if (sscanf(kit->value.c_str(), "%d", &val) == 1)
|
if (sscanf(kit->value.c_str(), "%d", &val) == 1)
|
||||||
// {
|
{
|
||||||
// mPgpAutoBanThreshold = val ;
|
mMinVotesForRemotelyPositive = val ;
|
||||||
// std::cerr << "Setting AutoBanNode threshold to " << val << std::endl ;
|
std::cerr << "Setting mMinVotesForRemotelyPositive threshold to " << val << std::endl ;
|
||||||
// mLastBannedNodesUpdate = 0 ; // force update
|
}
|
||||||
// }
|
};
|
||||||
// };
|
if(kit->key == "AUTO_REMOTELY_NEGATIVE_THRESHOLD")
|
||||||
if(kit->key == "AUTO_BAN_IDENTITIES_THRESHOLD")
|
{
|
||||||
{
|
int val ;
|
||||||
float val ;
|
if (sscanf(kit->value.c_str(), "%d", &val) == 1)
|
||||||
|
{
|
||||||
if (sscanf(kit->value.c_str(), "%f", &val) == 1)
|
mMinVotesForRemotelyNegative = val ;
|
||||||
{
|
std::cerr << "Setting mMinVotesForRemotelyNegative threshold to " << val << std::endl ;
|
||||||
mAutoBanIdentitiesLimit = val ;
|
}
|
||||||
std::cerr << "Setting AutoBanIdentity threshold to " << val << std::endl ;
|
};
|
||||||
mLastBannedNodesUpdate = 0 ; // force update
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if(kit->key == "AUTO_POSITIVE_CONTACTS")
|
if(kit->key == "AUTO_POSITIVE_CONTACTS")
|
||||||
{
|
{
|
||||||
mAutoSetPositiveOptionToContacts = (kit->value == "YES");
|
mAutoSetPositiveOptionToContacts = (kit->value == "YES");
|
||||||
@ -1292,11 +1339,22 @@ void Reputation::updateReputation()
|
|||||||
|
|
||||||
int friend_total = 0;
|
int friend_total = 0;
|
||||||
|
|
||||||
|
mFriendsNegative = 0 ;
|
||||||
|
mFriendsPositive = 0 ;
|
||||||
|
|
||||||
// accounts for all friends. Neutral opinions count for 1-1=0
|
// accounts for all friends. Neutral opinions count for 1-1=0
|
||||||
// because the average is performed over only accessible peers (not the total number) we need to shift to 1
|
// because the average is performed over only accessible peers (not the total number) we need to shift to 1
|
||||||
|
|
||||||
for(std::map<RsPeerId,RsReputations::Opinion>::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it)
|
for(std::map<RsPeerId,RsReputations::Opinion>::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it)
|
||||||
|
{
|
||||||
|
if(it->second == RsReputations::OPINION_NEGATIVE)
|
||||||
|
++mFriendsNegative ;
|
||||||
|
|
||||||
|
if(it->second == RsReputations::OPINION_POSITIVE)
|
||||||
|
++mFriendsPositive ;
|
||||||
|
|
||||||
friend_total += it->second - 1;
|
friend_total += it->second - 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(mOpinions.empty()) // includes the case of no friends!
|
if(mOpinions.empty()) // includes the case of no friends!
|
||||||
mFriendAverage = 1.0f ;
|
mFriendAverage = 1.0f ;
|
||||||
@ -1351,9 +1409,9 @@ void Reputation::updateReputation()
|
|||||||
// now compute a bias for PGP-signed ids.
|
// now compute a bias for PGP-signed ids.
|
||||||
|
|
||||||
if(mOwnOpinion == RsReputations::OPINION_NEUTRAL)
|
if(mOwnOpinion == RsReputations::OPINION_NEUTRAL)
|
||||||
mReputation = mFriendAverage ;
|
mReputationScore = mFriendAverage ;
|
||||||
else
|
else
|
||||||
mReputation = (float)mOwnOpinion ;
|
mReputationScore = (float)mOwnOpinion ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3GxsReputation::debug_print()
|
void p3GxsReputation::debug_print()
|
||||||
@ -1366,7 +1424,7 @@ void p3GxsReputation::debug_print()
|
|||||||
|
|
||||||
for(std::map<RsGxsId,Reputation>::const_iterator it(mReputations.begin());it!=mReputations.end();++it)
|
for(std::map<RsGxsId,Reputation>::const_iterator it(mReputations.begin());it!=mReputations.end();++it)
|
||||||
{
|
{
|
||||||
std::cerr << " " << it->first << ": own: " << it->second.mOwnOpinion << ", Friend average: " << it->second.mFriendAverage << ", global_score: " << it->second.mReputation
|
std::cerr << " " << it->first << ": own: " << it->second.mOwnOpinion << ", Friend average: " << it->second.mFriendAverage << ", global_score: " << it->second.mReputationScore
|
||||||
<< ", last own update: " << now - it->second.mOwnOpinionTs << " secs ago." << std::endl;
|
<< ", last own update: " << now - it->second.mOwnOpinionTs << " secs ago." << std::endl;
|
||||||
#ifdef DEBUG_REPUTATION2
|
#ifdef DEBUG_REPUTATION2
|
||||||
for(std::map<RsPeerId,RsReputations::Opinion>::const_iterator it2(it->second.mOpinions.begin());it2!=it->second.mOpinions.end();++it2)
|
for(std::map<RsPeerId,RsReputations::Opinion>::const_iterator it2(it->second.mOpinions.begin());it2!=it->second.mOpinions.end();++it2)
|
||||||
|
@ -69,10 +69,10 @@ class Reputation
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Reputation()
|
Reputation()
|
||||||
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ }
|
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputationScore(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ }
|
||||||
|
|
||||||
Reputation(const RsGxsId& /*about*/)
|
Reputation(const RsGxsId& /*about*/)
|
||||||
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputation(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ }
|
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0),mFriendAverage(1.0f), mReputationScore(RsReputations::OPINION_NEUTRAL),mIdentityFlags(REPUTATION_IDENTITY_FLAG_NEEDS_UPDATE){ }
|
||||||
|
|
||||||
void updateReputation();
|
void updateReputation();
|
||||||
|
|
||||||
@ -80,12 +80,15 @@ public:
|
|||||||
int32_t mOwnOpinion;
|
int32_t mOwnOpinion;
|
||||||
time_t mOwnOpinionTs;
|
time_t mOwnOpinionTs;
|
||||||
|
|
||||||
float mFriendAverage ;
|
float mFriendAverage ;
|
||||||
float mReputation;
|
uint32_t mFriendsPositive ; // number of positive vites from friends
|
||||||
|
uint32_t mFriendsNegative ; // number of negative vites from friends
|
||||||
|
|
||||||
RsPgpId mOwnerNode;
|
float mReputationScore;
|
||||||
|
|
||||||
uint32_t mIdentityFlags;
|
RsPgpId mOwnerNode;
|
||||||
|
|
||||||
|
uint32_t mIdentityFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -109,13 +112,13 @@ public:
|
|||||||
virtual bool isNodeBanned(const RsPgpId& id);
|
virtual bool isNodeBanned(const RsPgpId& id);
|
||||||
virtual void banNode(const RsPgpId& id,bool b) ;
|
virtual void banNode(const RsPgpId& id,bool b) ;
|
||||||
|
|
||||||
//virtual void setNodeAutoBanThreshold(uint32_t n) ;
|
|
||||||
//virtual uint32_t nodeAutoBanThreshold() ;
|
|
||||||
|
|
||||||
virtual void setNodeAutoPositiveOpinionForContacts(bool b) ;
|
virtual void setNodeAutoPositiveOpinionForContacts(bool b) ;
|
||||||
virtual bool nodeAutoPositiveOpinionForContacts() ;
|
virtual bool nodeAutoPositiveOpinionForContacts() ;
|
||||||
virtual float nodeAutoBanIdentitiesLimit() ;
|
|
||||||
virtual void setNodeAutoBanIdentitiesLimit(float f) ;
|
uint32_t thresholdForRemotelyNegativeReputation();
|
||||||
|
uint32_t thresholdForRemotelyPositiveReputation();
|
||||||
|
void setThresholdForRemotelyNegativeReputation(uint32_t thresh);
|
||||||
|
void setThresholdForRemotelyPositiveReputation(uint32_t thresh);
|
||||||
|
|
||||||
/***** overloaded from p3Service *****/
|
/***** overloaded from p3Service *****/
|
||||||
virtual int tick();
|
virtual int tick();
|
||||||
@ -180,8 +183,10 @@ private:
|
|||||||
// PGP Ids auto-banned. This is updated regularly.
|
// PGP Ids auto-banned. This is updated regularly.
|
||||||
std::map<RsPgpId,BannedNodeInfo> mBannedPgpIds ;
|
std::map<RsPgpId,BannedNodeInfo> mBannedPgpIds ;
|
||||||
std::set<RsGxsId> mPerNodeBannedIdsProxy ;
|
std::set<RsGxsId> mPerNodeBannedIdsProxy ;
|
||||||
//uint32_t mPgpAutoBanThreshold ;
|
|
||||||
bool mBannedNodesProxyNeedsUpdate ;
|
bool mBannedNodesProxyNeedsUpdate ;
|
||||||
|
|
||||||
|
uint32_t mMinVotesForRemotelyPositive ;
|
||||||
|
uint32_t mMinVotesForRemotelyNegative ;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //SERVICE_RSGXSREPUTATION_HEADER
|
#endif //SERVICE_RSGXSREPUTATION_HEADER
|
||||||
|
@ -128,8 +128,9 @@ RsIdentity *rsIdentity = NULL;
|
|||||||
|
|
||||||
/* delays */
|
/* delays */
|
||||||
|
|
||||||
#define CACHETEST_PERIOD 60
|
#define CACHETEST_PERIOD 60
|
||||||
#define DELAY_BETWEEN_CONFIG_UPDATES 300
|
#define DELAY_BETWEEN_CONFIG_UPDATES 300
|
||||||
|
#define GXS_MAX_KEY_TS_USAGE_MAP_SIZE 5
|
||||||
|
|
||||||
#define OWNID_RELOAD_DELAY 10
|
#define OWNID_RELOAD_DELAY 10
|
||||||
|
|
||||||
@ -255,23 +256,47 @@ void p3IdService::slowIndicateConfigChanged()
|
|||||||
}
|
}
|
||||||
time_t p3IdService::locked_getLastUsageTS(const RsGxsId& gxs_id)
|
time_t p3IdService::locked_getLastUsageTS(const RsGxsId& gxs_id)
|
||||||
{
|
{
|
||||||
std::map<RsGxsId,time_t>::const_iterator it = mKeysTS.find(gxs_id) ;
|
std::map<RsGxsId,keyTSInfo>::const_iterator it = mKeysTS.find(gxs_id) ;
|
||||||
|
|
||||||
if(it == mKeysTS.end())
|
if(it == mKeysTS.end())
|
||||||
return 0 ;
|
return 0 ;
|
||||||
else
|
else
|
||||||
return it->second ;
|
return it->second.TS ;
|
||||||
}
|
}
|
||||||
void p3IdService::timeStampKey(const RsGxsId& gxs_id)
|
void p3IdService::timeStampKey(const RsGxsId& gxs_id, const std::string& reason)
|
||||||
{
|
{
|
||||||
if(rsReputations->isIdentityBanned(gxs_id) )
|
if(rsReputations->isIdentityBanned(gxs_id) )
|
||||||
{
|
{
|
||||||
std::cerr << "(II) p3IdService:timeStampKey(): refusing to time stamp key " << gxs_id << " because it is banned." << std::endl;
|
std::cerr << "(II) p3IdService:timeStampKey(): refusing to time stamp key " << gxs_id << " because it is banned." << std::endl;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
std::cerr << "(II) time stamping key " << gxs_id << " for the following reason: " << reason << std::endl;
|
||||||
|
|
||||||
RS_STACK_MUTEX(mIdMtx) ;
|
RS_STACK_MUTEX(mIdMtx) ;
|
||||||
mKeysTS[gxs_id] = time(NULL) ;
|
|
||||||
|
time_t now = time(NULL) ;
|
||||||
|
|
||||||
|
keyTSInfo& info(mKeysTS[gxs_id]) ;
|
||||||
|
|
||||||
|
info.TS = now ;
|
||||||
|
info.usage_map[reason] = now;
|
||||||
|
|
||||||
|
while(info.usage_map.size() > GXS_MAX_KEY_TS_USAGE_MAP_SIZE)
|
||||||
|
{
|
||||||
|
// This is very costly, but normally the outerloop should never be rolled more than once.
|
||||||
|
|
||||||
|
std::map<std::string,time_t>::iterator best_it ;
|
||||||
|
time_t best_time = now+1;
|
||||||
|
|
||||||
|
for(std::map<std::string,time_t>::iterator it(info.usage_map.begin());it!=info.usage_map.end();++it)
|
||||||
|
if(it->second < best_time)
|
||||||
|
{
|
||||||
|
best_time = it->second ;
|
||||||
|
best_it = it;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.usage_map.erase(best_it) ;
|
||||||
|
}
|
||||||
|
|
||||||
slowIndicateConfigChanged() ;
|
slowIndicateConfigChanged() ;
|
||||||
}
|
}
|
||||||
@ -286,7 +311,7 @@ bool p3IdService::loadList(std::list<RsItem*>& items)
|
|||||||
if( (lii = dynamic_cast<RsGxsIdLocalInfoItem*>(*it)) != NULL)
|
if( (lii = dynamic_cast<RsGxsIdLocalInfoItem*>(*it)) != NULL)
|
||||||
{
|
{
|
||||||
for(std::map<RsGxsId,time_t>::const_iterator it2 = lii->mTimeStamps.begin();it2!=lii->mTimeStamps.end();++it2)
|
for(std::map<RsGxsId,time_t>::const_iterator it2 = lii->mTimeStamps.begin();it2!=lii->mTimeStamps.end();++it2)
|
||||||
mKeysTS.insert(*it2) ;
|
mKeysTS[it2->first].TS = it2->second;
|
||||||
|
|
||||||
mContacts = lii->mContacts ;
|
mContacts = lii->mContacts ;
|
||||||
}
|
}
|
||||||
@ -307,7 +332,10 @@ bool p3IdService::saveList(bool& cleanup,std::list<RsItem*>& items)
|
|||||||
RS_STACK_MUTEX(mIdMtx) ;
|
RS_STACK_MUTEX(mIdMtx) ;
|
||||||
cleanup = true ;
|
cleanup = true ;
|
||||||
RsGxsIdLocalInfoItem *item = new RsGxsIdLocalInfoItem ;
|
RsGxsIdLocalInfoItem *item = new RsGxsIdLocalInfoItem ;
|
||||||
item->mTimeStamps = mKeysTS ;
|
|
||||||
|
for(std::map<RsGxsId,keyTSInfo>::const_iterator it(mKeysTS.begin());it!=mKeysTS.end();++it)
|
||||||
|
item->mTimeStamps[it->first] = it->second.TS;
|
||||||
|
|
||||||
item->mContacts = mContacts ;
|
item->mContacts = mContacts ;
|
||||||
|
|
||||||
items.push_back(item) ;
|
items.push_back(item) ;
|
||||||
@ -317,7 +345,7 @@ bool p3IdService::saveList(bool& cleanup,std::list<RsItem*>& items)
|
|||||||
class IdCacheEntryCleaner
|
class IdCacheEntryCleaner
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IdCacheEntryCleaner(const std::map<RsGxsId,time_t>& last_usage_TSs) : mLastUsageTS(last_usage_TSs) {}
|
IdCacheEntryCleaner(const std::map<RsGxsId,p3IdService::keyTSInfo>& last_usage_TSs) : mLastUsageTS(last_usage_TSs) {}
|
||||||
|
|
||||||
bool processEntry(RsGxsIdCache& entry)
|
bool processEntry(RsGxsIdCache& entry)
|
||||||
{
|
{
|
||||||
@ -338,11 +366,11 @@ public:
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<RsGxsId,time_t>::const_iterator it = mLastUsageTS.find(gxs_id) ;
|
std::map<RsGxsId,p3IdService::keyTSInfo>::const_iterator it = mLastUsageTS.find(gxs_id) ;
|
||||||
|
|
||||||
bool no_ts = (it == mLastUsageTS.end()) ;
|
bool no_ts = (it == mLastUsageTS.end()) ;
|
||||||
|
|
||||||
time_t last_usage_ts = no_ts?0:(it->second);
|
time_t last_usage_ts = no_ts?0:(it->second.TS);
|
||||||
time_t max_keep_time ;
|
time_t max_keep_time ;
|
||||||
|
|
||||||
if(no_ts)
|
if(no_ts)
|
||||||
@ -370,7 +398,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::list<RsGxsId> ids_to_delete ;
|
std::list<RsGxsId> ids_to_delete ;
|
||||||
const std::map<RsGxsId,time_t>& mLastUsageTS;
|
const std::map<RsGxsId,p3IdService::keyTSInfo>& mLastUsageTS;
|
||||||
};
|
};
|
||||||
|
|
||||||
void p3IdService::cleanUnusedKeys()
|
void p3IdService::cleanUnusedKeys()
|
||||||
@ -495,7 +523,7 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
|
|
||||||
// also time_stamp the key that this group represents
|
// also time_stamp the key that this group represents
|
||||||
|
|
||||||
timeStampKey(RsGxsId(*git)) ;
|
timeStampKey(RsGxsId(*git),"Group meta data changed") ;
|
||||||
|
|
||||||
++git;
|
++git;
|
||||||
}
|
}
|
||||||
@ -552,7 +580,16 @@ bool p3IdService::getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
|
|||||||
rsReputations->setOwnOpinion(id,RsReputations::OPINION_POSITIVE) ;
|
rsReputations->setOwnOpinion(id,RsReputations::OPINION_POSITIVE) ;
|
||||||
|
|
||||||
details = data.details;
|
details = data.details;
|
||||||
details.mLastUsageTS = locked_getLastUsageTS(id) ;
|
|
||||||
|
std::map<RsGxsId,keyTSInfo>::const_iterator it = mKeysTS.find(id) ;
|
||||||
|
|
||||||
|
if(it == mKeysTS.end())
|
||||||
|
details.mLastUsageTS = 0 ;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
details.mLastUsageTS = it->second.TS ;
|
||||||
|
details.mUseCases = it->second.usage_map ;
|
||||||
|
}
|
||||||
|
|
||||||
// one utf8 symbol can be at most 4 bytes long - would be better to measure real unicode length !!!
|
// one utf8 symbol can be at most 4 bytes long - would be better to measure real unicode length !!!
|
||||||
if(details.mNickname.length() > RSID_MAXIMUM_NICKNAME_SIZE*4)
|
if(details.mNickname.length() > RSID_MAXIMUM_NICKNAME_SIZE*4)
|
||||||
@ -570,15 +607,12 @@ bool p3IdService::getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3IdService::isBanned(const RsGxsId &id)
|
RsReputations::ReputationLevel p3IdService::overallReputationLevel(const RsGxsId &id)
|
||||||
{
|
{
|
||||||
RsIdentityDetails det ;
|
RsIdentityDetails det ;
|
||||||
getIdDetails(id,det) ;
|
getIdDetails(id,det) ;
|
||||||
|
|
||||||
#ifdef DEBUG_REPUTATION
|
return det.mReputation.mOverallReputationLevel ;
|
||||||
std::cerr << "isIdentityBanned(): returning " << (det.mReputation.mAssessment == RsReputations::ASSESSMENT_BAD) << " for GXS id " << id << std::endl;
|
|
||||||
#endif
|
|
||||||
return det.mReputation.mAssessment == RsReputations::ASSESSMENT_BAD ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3IdService::isOwnId(const RsGxsId& id)
|
bool p3IdService::isOwnId(const RsGxsId& id)
|
||||||
@ -752,7 +786,7 @@ static void mergeIds(std::map<RsGxsId,std::list<RsPeerId> >& idmap,const RsGxsId
|
|||||||
old_peers.push_back(*it) ;
|
old_peers.push_back(*it) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3IdService::requestKey(const RsGxsId &id, const std::list<RsPeerId>& peers)
|
bool p3IdService::requestKey(const RsGxsId &id, const std::list<RsPeerId>& peers,const std::string& info)
|
||||||
{
|
{
|
||||||
if(id.isNull())
|
if(id.isNull())
|
||||||
{
|
{
|
||||||
@ -773,12 +807,12 @@ bool p3IdService::requestKey(const RsGxsId &id, const std::list<RsPeerId>& peers
|
|||||||
RsReputations::ReputationInfo info ;
|
RsReputations::ReputationInfo info ;
|
||||||
rsReputations->getReputationInfo(id,RsPgpId(),info) ;
|
rsReputations->getReputationInfo(id,RsPgpId(),info) ;
|
||||||
|
|
||||||
if(info.mAssessment == RsReputations::ASSESSMENT_BAD)
|
if(info.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
{
|
{
|
||||||
std::cerr << "(II) not requesting Key " << id << " because it has been banned." << std::endl;
|
std::cerr << "(II) not requesting Key " << id << " because it has been banned." << std::endl;
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
RS_STACK_MUTEX(mIdMtx); /********** STACK LOCKED MTX ******/
|
||||||
mIdsNotPresent.erase(id) ;
|
mIdsNotPresent.erase(id) ;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -796,6 +830,10 @@ bool p3IdService::requestKey(const RsGxsId &id, const std::list<RsPeerId>& peers
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mIdMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
mKeysTS[id].usage_map["Requested to friends: "+info] = time(NULL) ;
|
||||||
|
}
|
||||||
|
|
||||||
return cache_request_load(id, peers);
|
return cache_request_load(id, peers);
|
||||||
}
|
}
|
||||||
@ -892,10 +930,10 @@ bool p3IdService::signData(const uint8_t *data,uint32_t data_size,const RsGxsId&
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
error_status = RS_GIXS_ERROR_NO_ERROR ;
|
error_status = RS_GIXS_ERROR_NO_ERROR ;
|
||||||
timeStampKey(own_gxs_id) ;
|
timeStampKey(own_gxs_id,"Own GXS id") ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
bool p3IdService::validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,uint32_t& signing_error)
|
bool p3IdService::validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,const std::string& info_string,uint32_t& signing_error)
|
||||||
{
|
{
|
||||||
// RsIdentityDetails details ;
|
// RsIdentityDetails details ;
|
||||||
// getIdDetails(signature.keyId,details);
|
// getIdDetails(signature.keyId,details);
|
||||||
@ -929,7 +967,7 @@ bool p3IdService::validateData(const uint8_t *data,uint32_t data_size,const RsTl
|
|||||||
}
|
}
|
||||||
signing_error = RS_GIXS_ERROR_NO_ERROR ;
|
signing_error = RS_GIXS_ERROR_NO_ERROR ;
|
||||||
|
|
||||||
timeStampKey(signature.keyId) ;
|
timeStampKey(signature.keyId,"Used in signature checking: "+info_string ) ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
bool p3IdService::encryptData(const uint8_t *decrypted_data,uint32_t decrypted_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& error_status)
|
bool p3IdService::encryptData(const uint8_t *decrypted_data,uint32_t decrypted_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& error_status)
|
||||||
@ -957,7 +995,7 @@ bool p3IdService::encryptData(const uint8_t *decrypted_data,uint32_t decrypted_d
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
error_status = RS_GIXS_ERROR_NO_ERROR ;
|
error_status = RS_GIXS_ERROR_NO_ERROR ;
|
||||||
timeStampKey(encryption_key_id) ;
|
timeStampKey(encryption_key_id,"Used to encrypt data") ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@ -989,7 +1027,7 @@ bool p3IdService::decryptData(const uint8_t *encrypted_data,uint32_t encrypted_d
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
error_status = RS_GIXS_ERROR_NO_ERROR ;
|
error_status = RS_GIXS_ERROR_NO_ERROR ;
|
||||||
timeStampKey(key_id) ;
|
timeStampKey(key_id,"Used to decrypt data") ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@ -2399,7 +2437,8 @@ bool p3IdService::cache_load_ownids(uint32_t token)
|
|||||||
|
|
||||||
// This prevents automatic deletion to get rid of them.
|
// This prevents automatic deletion to get rid of them.
|
||||||
// In other words, own ids are always used.
|
// In other words, own ids are always used.
|
||||||
mKeysTS[RsGxsId(item->meta.mGroupId)] = time(NULL) ;
|
|
||||||
|
mKeysTS[RsGxsId(item->meta.mGroupId)].TS = time(NULL) ;
|
||||||
}
|
}
|
||||||
delete item ;
|
delete item ;
|
||||||
}
|
}
|
||||||
@ -2493,7 +2532,7 @@ bool p3IdService::cachetest_handlerequest(uint32_t token)
|
|||||||
if (!haveKey(*vit))
|
if (!haveKey(*vit))
|
||||||
{
|
{
|
||||||
std::list<RsPeerId> nullpeers;
|
std::list<RsPeerId> nullpeers;
|
||||||
requestKey(*vit, nullpeers);
|
requestKey(*vit, nullpeers,"Cache test in p3IdService");
|
||||||
|
|
||||||
#ifdef DEBUG_IDS
|
#ifdef DEBUG_IDS
|
||||||
std::cerr << "p3IdService::cachetest_request() Requested Key Id: " << *vit;
|
std::cerr << "p3IdService::cachetest_request() Requested Key Id: " << *vit;
|
||||||
@ -2691,7 +2730,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
|
|||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
return SERVICE_CREATE_FAIL;
|
return SERVICE_CREATE_FAIL;
|
||||||
}
|
}
|
||||||
mKeysTS[RsGxsId(item->meta.mGroupId)] = time(NULL) ;
|
mKeysTS[RsGxsId(item->meta.mGroupId)].TS = time(NULL) ;
|
||||||
|
|
||||||
/********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/
|
/********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/
|
||||||
|
|
||||||
@ -2851,7 +2890,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
|
|||||||
if (std::find(mOwnIds.begin(), mOwnIds.end(), gxsId) == mOwnIds.end())
|
if (std::find(mOwnIds.begin(), mOwnIds.end(), gxsId) == mOwnIds.end())
|
||||||
{
|
{
|
||||||
mOwnIds.push_back(gxsId);
|
mOwnIds.push_back(gxsId);
|
||||||
mKeysTS[gxsId] = time(NULL) ;
|
mKeysTS[gxsId].TS = time(NULL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ public:
|
|||||||
|
|
||||||
virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) ;
|
virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) ;
|
||||||
virtual bool isARegularContact(const RsGxsId& id) ;
|
virtual bool isARegularContact(const RsGxsId& id) ;
|
||||||
virtual bool isBanned(const RsGxsId& id) ;
|
virtual RsReputations::ReputationLevel overallReputationLevel(const RsGxsId& id);
|
||||||
virtual time_t getLastUsageTS(const RsGxsId &id) ;
|
virtual time_t getLastUsageTS(const RsGxsId &id) ;
|
||||||
|
|
||||||
/**************** RsGixs Implementation ***************/
|
/**************** RsGixs Implementation ***************/
|
||||||
@ -287,7 +287,7 @@ public:
|
|||||||
virtual bool isOwnId(const RsGxsId& key_id) ;
|
virtual bool isOwnId(const RsGxsId& key_id) ;
|
||||||
|
|
||||||
virtual bool signData(const uint8_t *data,uint32_t data_size,const RsGxsId& signer_id,RsTlvKeySignature& signature,uint32_t& signing_error) ;
|
virtual bool signData(const uint8_t *data,uint32_t data_size,const RsGxsId& signer_id,RsTlvKeySignature& signature,uint32_t& signing_error) ;
|
||||||
virtual bool validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,uint32_t& signing_error) ;
|
virtual bool validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,const std::string& info_string,uint32_t& signing_error) ;
|
||||||
|
|
||||||
virtual bool encryptData(const uint8_t *decrypted_data,uint32_t decrypted_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& encryption_error) ;
|
virtual bool encryptData(const uint8_t *decrypted_data,uint32_t decrypted_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& encryption_error) ;
|
||||||
virtual bool decryptData(const uint8_t *encrypted_data,uint32_t encrypted_data_size,uint8_t *& decrypted_data,uint32_t& decrypted_data_size,const RsGxsId& encryption_key_id,uint32_t& encryption_error) ;
|
virtual bool decryptData(const uint8_t *encrypted_data,uint32_t encrypted_data_size,uint8_t *& decrypted_data,uint32_t& decrypted_data_size,const RsGxsId& encryption_key_id,uint32_t& encryption_error) ;
|
||||||
@ -298,7 +298,7 @@ public:
|
|||||||
virtual bool getKey(const RsGxsId &id, RsTlvPublicRSAKey &key);
|
virtual bool getKey(const RsGxsId &id, RsTlvPublicRSAKey &key);
|
||||||
virtual bool getPrivateKey(const RsGxsId &id, RsTlvPrivateRSAKey &key);
|
virtual bool getPrivateKey(const RsGxsId &id, RsTlvPrivateRSAKey &key);
|
||||||
|
|
||||||
virtual bool requestKey(const RsGxsId &id, const std::list<RsPeerId> &peers);
|
virtual bool requestKey(const RsGxsId &id, const std::list<RsPeerId> &peers, const std::string &info);
|
||||||
virtual bool requestPrivateKey(const RsGxsId &id);
|
virtual bool requestPrivateKey(const RsGxsId &id);
|
||||||
|
|
||||||
|
|
||||||
@ -467,7 +467,7 @@ private:
|
|||||||
void cleanUnusedKeys() ;
|
void cleanUnusedKeys() ;
|
||||||
void slowIndicateConfigChanged() ;
|
void slowIndicateConfigChanged() ;
|
||||||
|
|
||||||
virtual void timeStampKey(const RsGxsId& id) ;
|
virtual void timeStampKey(const RsGxsId& id,const std::string& reason) ;
|
||||||
time_t locked_getLastUsageTS(const RsGxsId& gxs_id);
|
time_t locked_getLastUsageTS(const RsGxsId& gxs_id);
|
||||||
|
|
||||||
std::string genRandomId(int len = 20);
|
std::string genRandomId(int len = 20);
|
||||||
@ -507,10 +507,19 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
struct keyTSInfo
|
||||||
|
{
|
||||||
|
keyTSInfo() : TS(0) {}
|
||||||
|
|
||||||
|
time_t TS ;
|
||||||
|
std::map<std::string,time_t> usage_map ;
|
||||||
|
};
|
||||||
|
friend class IdCacheEntryCleaner;
|
||||||
|
|
||||||
std::map<uint32_t, std::set<RsGxsGroupId> > mIdsPendingCache;
|
std::map<uint32_t, std::set<RsGxsGroupId> > mIdsPendingCache;
|
||||||
std::map<uint32_t, std::list<RsGxsGroupId> > mGroupNotPresent;
|
std::map<uint32_t, std::list<RsGxsGroupId> > mGroupNotPresent;
|
||||||
std::map<RsGxsId, std::list<RsPeerId> > mIdsNotPresent;
|
std::map<RsGxsId, std::list<RsPeerId> > mIdsNotPresent;
|
||||||
std::map<RsGxsId,time_t> mKeysTS ;
|
std::map<RsGxsId,keyTSInfo> mKeysTS ;
|
||||||
|
|
||||||
// keep a list of regular contacts. This is useful to sort IDs, and allow some services to priviledged ids only.
|
// keep a list of regular contacts. This is useful to sort IDs, and allow some services to priviledged ids only.
|
||||||
std::set<RsGxsId> mContacts;
|
std::set<RsGxsId> mContacts;
|
||||||
|
@ -36,9 +36,13 @@
|
|||||||
#include <sys/timeb.h>
|
#include <sys/timeb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string RsUtil::NumberToString(uint64_t n)
|
std::string RsUtil::NumberToString(uint64_t n,bool hex)
|
||||||
{
|
{
|
||||||
std::ostringstream os ;
|
std::ostringstream os ;
|
||||||
|
|
||||||
|
if(hex)
|
||||||
|
os << std::hex ;
|
||||||
|
|
||||||
os << n ;
|
os << n ;
|
||||||
os.flush() ;
|
os.flush() ;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ namespace RsUtil {
|
|||||||
std::string BinToHex(const std::string &bin);
|
std::string BinToHex(const std::string &bin);
|
||||||
std::string BinToHex(const char *arr, const uint32_t len);
|
std::string BinToHex(const char *arr, const uint32_t len);
|
||||||
std::string BinToHex(const unsigned char *arr, const uint32_t len);
|
std::string BinToHex(const unsigned char *arr, const uint32_t len);
|
||||||
std::string NumberToString(uint64_t n);
|
std::string NumberToString(uint64_t n, bool hex=false);
|
||||||
std::string HashId(const std::string &id, bool reverse = false);
|
std::string HashId(const std::string &id, bool reverse = false);
|
||||||
|
|
||||||
//std::string AccurateTimeString();
|
//std::string AccurateTimeString();
|
||||||
|
@ -264,10 +264,9 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
|
|||||||
RsReputations::ReputationInfo info ;
|
RsReputations::ReputationInfo info ;
|
||||||
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),data.mPgpId,info) ;
|
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),data.mPgpId,info) ;
|
||||||
|
|
||||||
ui->neighborNodesOpinion_TF->setText(QString::number(info.mOverallReputationScore-1.0f));
|
#warning (csoler) Do we need to do this? This code is apparently not used.
|
||||||
|
ui->neighborNodesOpinion_TF->setText(QString::number(info.mFriendAverageScore));
|
||||||
ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationScore-1.0f) +" ("+
|
ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationLevel));
|
||||||
((info.mAssessment == RsReputations::ASSESSMENT_OK)? tr("OK") : tr("Banned")) +")" ) ;
|
|
||||||
|
|
||||||
switch(info.mOwnOpinion)
|
switch(info.mOwnOpinion)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QWidgetAction>
|
#include <QWidgetAction>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
#include "IdDialog.h"
|
#include "IdDialog.h"
|
||||||
#include "ui_IdDialog.h"
|
#include "ui_IdDialog.h"
|
||||||
@ -127,6 +129,7 @@ class TreeWidgetItem : public QTreeWidgetItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
IdDialog::IdDialog(QWidget *parent) :
|
IdDialog::IdDialog(QWidget *parent) :
|
||||||
RsGxsUpdateBroadcastPage(rsIdentity, parent),
|
RsGxsUpdateBroadcastPage(rsIdentity, parent),
|
||||||
@ -142,12 +145,15 @@ IdDialog::IdDialog(QWidget *parent) :
|
|||||||
|
|
||||||
ownItem = new QTreeWidgetItem();
|
ownItem = new QTreeWidgetItem();
|
||||||
ownItem->setText(0, tr("My own identities"));
|
ownItem->setText(0, tr("My own identities"));
|
||||||
|
ownItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff); // this is in order to prevent displaying a reputaiton icon next to these items.
|
||||||
|
|
||||||
allItem = new QTreeWidgetItem();
|
allItem = new QTreeWidgetItem();
|
||||||
allItem->setText(0, tr("All"));
|
allItem->setText(0, tr("All"));
|
||||||
|
allItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff);
|
||||||
|
|
||||||
contactsItem = new QTreeWidgetItem();
|
contactsItem = new QTreeWidgetItem();
|
||||||
contactsItem->setText(0, tr("My contacts"));
|
contactsItem->setText(0, tr("My contacts"));
|
||||||
|
contactsItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff);
|
||||||
|
|
||||||
ui->treeWidget_membership->clear();
|
ui->treeWidget_membership->clear();
|
||||||
|
|
||||||
@ -318,6 +324,8 @@ IdDialog::IdDialog(QWidget *parent) :
|
|||||||
ui->idTreeWidget->setColumnWidth(RSID_COL_IDTYPE, 18 * fontWidth);
|
ui->idTreeWidget->setColumnWidth(RSID_COL_IDTYPE, 18 * fontWidth);
|
||||||
ui->idTreeWidget->setColumnWidth(RSID_COL_VOTES, 7 * fontWidth);
|
ui->idTreeWidget->setColumnWidth(RSID_COL_VOTES, 7 * fontWidth);
|
||||||
|
|
||||||
|
ui->idTreeWidget->setItemDelegateForColumn(RSID_COL_VOTES,new ReputationItemDelegate(RsReputations::ReputationLevel(0xff))) ;
|
||||||
|
|
||||||
//QHeaderView_setSectionResizeMode(ui->idTreeWidget->header(), QHeaderView::ResizeToContents);
|
//QHeaderView_setSectionResizeMode(ui->idTreeWidget->header(), QHeaderView::ResizeToContents);
|
||||||
|
|
||||||
mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this);
|
mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this);
|
||||||
@ -1392,7 +1400,8 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
|
|||||||
bool isOwnId = (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
|
bool isOwnId = (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
|
||||||
RsIdentityDetails idd ;
|
RsIdentityDetails idd ;
|
||||||
rsIdentity->getIdDetails(RsGxsId(data.mMeta.mGroupId),idd) ;
|
rsIdentity->getIdDetails(RsGxsId(data.mMeta.mGroupId),idd) ;
|
||||||
bool isBanned = idd.mReputation.mAssessment == RsReputations::ASSESSMENT_BAD;
|
|
||||||
|
bool isBanned = idd.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE;
|
||||||
uint32_t item_flags = 0 ;
|
uint32_t item_flags = 0 ;
|
||||||
|
|
||||||
/* do filtering */
|
/* do filtering */
|
||||||
@ -1462,7 +1471,7 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
|
|||||||
|
|
||||||
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
|
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
|
||||||
item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight | Qt::AlignVCenter);
|
item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight | Qt::AlignVCenter);
|
||||||
item->setData(RSID_COL_VOTES,Qt::DisplayRole, QString::number(idd.mReputation.mOverallReputationScore - 1.0f,'f',3));
|
item->setData(RSID_COL_VOTES,Qt::DecorationRole, idd.mReputation.mOverallReputationLevel);
|
||||||
|
|
||||||
if(isOwnId)
|
if(isOwnId)
|
||||||
{
|
{
|
||||||
@ -1836,10 +1845,24 @@ void IdDialog::insertIdDetails(uint32_t token)
|
|||||||
RsReputations::ReputationInfo info ;
|
RsReputations::ReputationInfo info ;
|
||||||
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),data.mPgpId,info) ;
|
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),data.mPgpId,info) ;
|
||||||
|
|
||||||
ui->neighborNodesOpinion_TF->setText(QString::number(info.mFriendAverage - 1.0f));
|
QString frep_string ;
|
||||||
|
if(info.mFriendsPositiveVotes > 0) frep_string += QString::number(info.mFriendsPositiveVotes) + tr(" positive ") ;
|
||||||
|
if(info.mFriendsNegativeVotes > 0) frep_string += QString::number(info.mFriendsNegativeVotes) + tr(" negative ") ;
|
||||||
|
|
||||||
ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationScore - 1.0f) +" ("+
|
if(info.mFriendsPositiveVotes==0 && info.mFriendsNegativeVotes==0)
|
||||||
((info.mAssessment == RsReputations::ASSESSMENT_OK)? tr("OK") : tr("Banned")) +")" ) ;
|
frep_string = tr("No votes from friends") ;
|
||||||
|
|
||||||
|
ui->neighborNodesOpinion_TF->setText(frep_string) ;
|
||||||
|
|
||||||
|
switch(info.mOverallReputationLevel)
|
||||||
|
{
|
||||||
|
case RsReputations::REPUTATION_LOCALLY_POSITIVE: ui->overallOpinion_TF->setText(tr("Positive")) ; break ;
|
||||||
|
case RsReputations::REPUTATION_LOCALLY_NEGATIVE: ui->overallOpinion_TF->setText(tr("Negative (Banned by you)")) ; break ;
|
||||||
|
case RsReputations::REPUTATION_REMOTELY_POSITIVE: ui->overallOpinion_TF->setText(tr("Positive (according to your friends)")) ; break ;
|
||||||
|
case RsReputations::REPUTATION_REMOTELY_NEGATIVE: ui->overallOpinion_TF->setText(tr("Negative (according to your friends)")) ; break ;
|
||||||
|
default:
|
||||||
|
case RsReputations::REPUTATION_NEUTRAL: ui->overallOpinion_TF->setText(tr("Neutral")) ; break ;
|
||||||
|
}
|
||||||
|
|
||||||
switch(info.mOwnOpinion)
|
switch(info.mOwnOpinion)
|
||||||
{
|
{
|
||||||
@ -1849,6 +1872,24 @@ void IdDialog::insertIdDetails(uint32_t token)
|
|||||||
default:
|
default:
|
||||||
std::cerr << "Unexpected value in own opinion: " << info.mOwnOpinion << std::endl;
|
std::cerr << "Unexpected value in own opinion: " << info.mOwnOpinion << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// now fill in usage cases
|
||||||
|
|
||||||
|
RsIdentityDetails det ;
|
||||||
|
rsIdentity->getIdDetails(RsGxsId(data.mMeta.mGroupId),det) ;
|
||||||
|
|
||||||
|
QString usage_txt ;
|
||||||
|
std::map<time_t,std::string> rmap ;
|
||||||
|
for(std::map<std::string,time_t>::const_iterator it(det.mUseCases.begin());it!=det.mUseCases.end();++it)
|
||||||
|
rmap.insert(std::make_pair(it->second,it->first)) ;
|
||||||
|
|
||||||
|
for(std::map<time_t,std::string>::const_iterator it(rmap.begin());it!=rmap.end();++it)
|
||||||
|
usage_txt += QString("<b>")+ getHumanReadableDuration(now - data.mLastUsageTS) + "</b> \t: " + QString::fromStdString(it->second) + "<br/>" ;
|
||||||
|
|
||||||
|
if(usage_txt.isNull())
|
||||||
|
usage_txt = tr("<b>[No record in current session]</b>") ;
|
||||||
|
|
||||||
|
ui->usageStatistics_TB->setText(usage_txt) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdDialog::modifyReputation()
|
void IdDialog::modifyReputation()
|
||||||
@ -1900,6 +1941,22 @@ void IdDialog::modifyReputation()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IdDialog::navigate(const RsGxsId& gxs_id)
|
||||||
|
{
|
||||||
|
std::cerr << "IdDialog::navigate to " << gxs_id.toStdString() << std::endl;
|
||||||
|
|
||||||
|
// in order to do this, we just select the correct ID in the ID list
|
||||||
|
|
||||||
|
QList<QTreeWidgetItem*> select = ui->idTreeWidget->findItems(QString::fromStdString(gxs_id.toStdString()),Qt::MatchExactly | Qt::MatchRecursive | Qt::MatchWrap,RSID_COL_KEYID) ;
|
||||||
|
|
||||||
|
if(select.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot find item with ID " << gxs_id << " in ID list." << std::endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
ui->idTreeWidget->setCurrentItem(*select.begin(),true);
|
||||||
|
|
||||||
|
}
|
||||||
void IdDialog::updateDisplay(bool complete)
|
void IdDialog::updateDisplay(bool complete)
|
||||||
{
|
{
|
||||||
/* Update identity list */
|
/* Update identity list */
|
||||||
|
@ -62,6 +62,7 @@ public:
|
|||||||
|
|
||||||
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
|
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
|
||||||
|
|
||||||
|
void navigate(const RsGxsId& gxs_id) ; // shows the info about this particular ID
|
||||||
protected:
|
protected:
|
||||||
virtual void updateDisplay(bool complete);
|
virtual void updateDisplay(bool complete);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1269</width>
|
<width>1269</width>
|
||||||
<height>911</height>
|
<height>1040</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -485,14 +485,14 @@
|
|||||||
<item row="8" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="QCheckBox" name="autoBanIdentities_CB">
|
<widget class="QCheckBox" name="autoBanIdentities_CB">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Auto-Ban all identities from this node</string>
|
<string>Auto-Ban all identities signed by the same node</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0">
|
<item row="9" column="0">
|
||||||
<widget class="QLabel" name="neighborNodesOpinion_LB">
|
<widget class="QLabel" name="neighborNodesOpinion_LB">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Neighbor nodes:</string>
|
<string>Friend votes:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -595,6 +595,18 @@ p, li { white-space: pre-wrap; }
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Usage statistics</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTextBrowser" name="usageStatistics_TB"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="reputationVSpacer">
|
<spacer name="reputationVSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -352,7 +352,6 @@ void MainWindow::initStackedPage()
|
|||||||
addPage(peopleDialog = new PeopleDialog(ui->stackPages), grp, ¬ify);
|
addPage(peopleDialog = new PeopleDialog(ui->stackPages), grp, ¬ify);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IdDialog *idDialog = NULL;
|
|
||||||
addPage(idDialog = new IdDialog(ui->stackPages), grp, ¬ify);
|
addPage(idDialog = new IdDialog(ui->stackPages), grp, ¬ify);
|
||||||
|
|
||||||
//#ifdef RS_USE_CIRCLES
|
//#ifdef RS_USE_CIRCLES
|
||||||
@ -878,6 +877,9 @@ void SetForegroundWindowInternal(HWND hWnd)
|
|||||||
case Friends:
|
case Friends:
|
||||||
_instance->ui->stackPages->setCurrentPage( _instance->friendsDialog );
|
_instance->ui->stackPages->setCurrentPage( _instance->friendsDialog );
|
||||||
break;
|
break;
|
||||||
|
case People:
|
||||||
|
_instance->ui->stackPages->setCurrentPage( _instance->idDialog );
|
||||||
|
break;
|
||||||
case ChatLobby:
|
case ChatLobby:
|
||||||
_instance->ui->stackPages->setCurrentPage( _instance->chatLobbyDialog );
|
_instance->ui->stackPages->setCurrentPage( _instance->chatLobbyDialog );
|
||||||
break;
|
break;
|
||||||
@ -974,6 +976,8 @@ void SetForegroundWindowInternal(HWND hWnd)
|
|||||||
return _instance->friendsDialog->networkDialog;
|
return _instance->friendsDialog->networkDialog;
|
||||||
case Friends:
|
case Friends:
|
||||||
return _instance->friendsDialog;
|
return _instance->friendsDialog;
|
||||||
|
case People:
|
||||||
|
return _instance->idDialog;
|
||||||
case ChatLobby:
|
case ChatLobby:
|
||||||
return _instance->chatLobbyDialog;
|
return _instance->chatLobbyDialog;
|
||||||
case Transfers:
|
case Transfers:
|
||||||
|
@ -51,6 +51,7 @@ class GxsChannelDialog ;
|
|||||||
class GxsForumsDialog ;
|
class GxsForumsDialog ;
|
||||||
class PostedDialog;
|
class PostedDialog;
|
||||||
class FriendsDialog;
|
class FriendsDialog;
|
||||||
|
class IdDialog;
|
||||||
class ChatLobbyWidget;
|
class ChatLobbyWidget;
|
||||||
class ChatDialog;
|
class ChatDialog;
|
||||||
class NetworkDialog;
|
class NetworkDialog;
|
||||||
@ -103,6 +104,7 @@ public:
|
|||||||
Links = 10, /** Links page. */
|
Links = 10, /** Links page. */
|
||||||
#endif
|
#endif
|
||||||
Posted = 11, /** Posted links */
|
Posted = 11, /** Posted links */
|
||||||
|
People = 12 /** People page. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Create main window */
|
/** Create main window */
|
||||||
@ -137,6 +139,7 @@ public:
|
|||||||
NewsFeed *newsFeed;
|
NewsFeed *newsFeed;
|
||||||
FriendsDialog *friendsDialog;
|
FriendsDialog *friendsDialog;
|
||||||
TransfersDialog *transfersDialog;
|
TransfersDialog *transfersDialog;
|
||||||
|
IdDialog *idDialog ;
|
||||||
ChatLobbyWidget *chatLobbyDialog;
|
ChatLobbyWidget *chatLobbyDialog;
|
||||||
MessagesDialog *messagesDialog;
|
MessagesDialog *messagesDialog;
|
||||||
SharedFilesDialog *sharedfilesDialog;
|
SharedFilesDialog *sharedfilesDialog;
|
||||||
|
@ -418,7 +418,7 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token)
|
|||||||
std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment.mMeta.mMsgId;
|
std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment.mMeta.mMsgId;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
|
||||||
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(NULL) ;
|
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(NULL,GxsIdDetails::ICON_TYPE_ALL) ;
|
||||||
QString text;
|
QString text;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -48,6 +48,13 @@
|
|||||||
#define IMAGE_DEV_PATCHER ":/images/tags/dev-patcher.png"
|
#define IMAGE_DEV_PATCHER ":/images/tags/dev-patcher.png"
|
||||||
#define IMAGE_DEV_DEVELOPER ":/images/tags/developer.png"
|
#define IMAGE_DEV_DEVELOPER ":/images/tags/developer.png"
|
||||||
|
|
||||||
|
#define REPUTATION_LOCALLY_POSITIVE_ICON ":/icons/bullet_green_yellow_star_128.png"
|
||||||
|
#define REPUTATION_REMOTELY_POSITIVE_ICON ":/icons/bullet_green_128.png"
|
||||||
|
#define REPUTATION_NEUTRAL_ICON ":/icons/bullet_grey_128.png"
|
||||||
|
#define REPUTATION_REMOTELY_NEGATIVE_ICON ":/icons/yellow_biohazard64.png"
|
||||||
|
#define REPUTATION_LOCALLY_NEGATIVE_ICON ":/icons/red_biohazard64.png"
|
||||||
|
#define REPUTATION_VOID ":/icons/void_128.png"
|
||||||
|
|
||||||
#define TIMER_INTERVAL 500
|
#define TIMER_INTERVAL 500
|
||||||
#define MAX_ATTEMPTS 10
|
#define MAX_ATTEMPTS 10
|
||||||
#define MAX_PROCESS_COUNT_PER_TIMER 50
|
#define MAX_PROCESS_COUNT_PER_TIMER 50
|
||||||
@ -60,6 +67,35 @@ const int kRecognTagType_Dev_Translator = 3;
|
|||||||
const int kRecognTagType_Dev_Patcher = 4;
|
const int kRecognTagType_Dev_Patcher = 4;
|
||||||
const int kRecognTagType_Dev_Developer = 5;
|
const int kRecognTagType_Dev_Developer = 5;
|
||||||
|
|
||||||
|
|
||||||
|
void ReputationItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
Q_ASSERT(index.isValid());
|
||||||
|
|
||||||
|
QStyleOptionViewItemV4 opt = option;
|
||||||
|
initStyleOption(&opt, index);
|
||||||
|
// disable default icon
|
||||||
|
opt.icon = QIcon();
|
||||||
|
// draw default item
|
||||||
|
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0);
|
||||||
|
|
||||||
|
const QRect r = option.rect;
|
||||||
|
|
||||||
|
// get pixmap
|
||||||
|
unsigned int icon_index = qvariant_cast<unsigned int>(index.data(Qt::DecorationRole));
|
||||||
|
|
||||||
|
if(icon_index > mMaxLevelToDisplay)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
QIcon icon = GxsIdDetails::getReputationIcon(RsReputations::ReputationLevel(icon_index),0xff);
|
||||||
|
|
||||||
|
QPixmap pix = icon.pixmap(r.size());
|
||||||
|
|
||||||
|
// draw pixmap at center of item
|
||||||
|
const QPoint p = QPoint((r.width() - pix.width())/2, (r.height() - pix.height())/2);
|
||||||
|
painter->drawPixmap(r.topLeft() + p, pix);
|
||||||
|
}
|
||||||
|
|
||||||
/* The global object */
|
/* The global object */
|
||||||
GxsIdDetails *GxsIdDetails::mInstance = NULL ;
|
GxsIdDetails *GxsIdDetails::mInstance = NULL ;
|
||||||
|
|
||||||
@ -904,7 +940,7 @@ bool GxsIdDetails::MakeIdDesc(const RsGxsId &id, bool doIcons, QString &str, QLi
|
|||||||
|
|
||||||
QString GxsIdDetails::getName(const RsIdentityDetails &details)
|
QString GxsIdDetails::getName(const RsIdentityDetails &details)
|
||||||
{
|
{
|
||||||
if(rsIdentity->isBanned(details.mId))
|
if(details.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
return tr("[Banned]") ;
|
return tr("[Banned]") ;
|
||||||
|
|
||||||
QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE);
|
QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE);
|
||||||
@ -923,7 +959,7 @@ QString GxsIdDetails::getComment(const RsIdentityDetails &details)
|
|||||||
QString comment;
|
QString comment;
|
||||||
QString nickname ;
|
QString nickname ;
|
||||||
|
|
||||||
bool banned = rsIdentity->isBanned(details.mId) ;
|
bool banned = (details.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE);
|
||||||
|
|
||||||
if(details.mNickname.empty())
|
if(details.mNickname.empty())
|
||||||
nickname = tr("[Unknown]") ;
|
nickname = tr("[Unknown]") ;
|
||||||
@ -958,17 +994,38 @@ QString nickname ;
|
|||||||
return comment;
|
return comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsIdDetails::getIcons(const RsIdentityDetails &details, QList<QIcon> &icons,uint32_t icon_types)
|
QIcon GxsIdDetails::getReputationIcon(RsReputations::ReputationLevel icon_index,uint32_t min_reputation)
|
||||||
|
{
|
||||||
|
if(icon_index >= min_reputation)
|
||||||
|
return QIcon(REPUTATION_VOID);
|
||||||
|
|
||||||
|
switch(icon_index)
|
||||||
|
{
|
||||||
|
case RsReputations::REPUTATION_LOCALLY_NEGATIVE: return QIcon(REPUTATION_LOCALLY_NEGATIVE_ICON) ; break ;
|
||||||
|
case RsReputations::REPUTATION_LOCALLY_POSITIVE: return QIcon(REPUTATION_LOCALLY_POSITIVE_ICON) ; break ;
|
||||||
|
case RsReputations::REPUTATION_REMOTELY_POSITIVE: return QIcon(REPUTATION_REMOTELY_POSITIVE_ICON) ; break ;
|
||||||
|
case RsReputations::REPUTATION_REMOTELY_NEGATIVE: return QIcon(REPUTATION_REMOTELY_NEGATIVE_ICON) ; break ;
|
||||||
|
case RsReputations::REPUTATION_NEUTRAL: return QIcon(REPUTATION_NEUTRAL_ICON) ; break ;
|
||||||
|
default:
|
||||||
|
std::cerr << "Asked for unidentified icon index " << icon_index << std::endl;
|
||||||
|
return QIcon(); // dont draw anything
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GxsIdDetails::getIcons(const RsIdentityDetails &details, QList<QIcon> &icons,uint32_t icon_types,uint32_t minimal_required_reputation)
|
||||||
{
|
{
|
||||||
QPixmap pix ;
|
QPixmap pix ;
|
||||||
|
|
||||||
if(rsIdentity->isBanned(details.mId))
|
if(details.mReputation.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
{
|
{
|
||||||
icons.clear() ;
|
icons.clear() ;
|
||||||
icons.push_back(QIcon(IMAGE_BANNED)) ;
|
icons.push_back(QIcon(IMAGE_BANNED)) ;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(icon_types & ICON_TYPE_REPUTATION)
|
||||||
|
icons.push_back(getReputationIcon(details.mReputation.mOverallReputationLevel,minimal_required_reputation)) ;
|
||||||
|
|
||||||
if(icon_types & ICON_TYPE_AVATAR)
|
if(icon_types & ICON_TYPE_AVATAR)
|
||||||
{
|
{
|
||||||
if(details.mAvatar.mSize == 0 || !pix.loadFromData(details.mAvatar.mData, details.mAvatar.mSize, "PNG"))
|
if(details.mAvatar.mSize == 0 || !pix.loadFromData(details.mAvatar.mData, details.mAvatar.mSize, "PNG"))
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
#include <retroshare/rsidentity.h>
|
#include <retroshare/rsidentity.h>
|
||||||
|
|
||||||
@ -45,16 +46,31 @@ enum GxsIdDetailsType
|
|||||||
|
|
||||||
typedef void (*GxsIdDetailsCallbackFunction)(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &data);
|
typedef void (*GxsIdDetailsCallbackFunction)(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &data);
|
||||||
|
|
||||||
|
// This class allows to draw the item in a reputation column using an appropriate size. The max_level_to_display parameter allows to replace
|
||||||
|
// the icon by an empty icon when needed. This allows to keep the focus on the critical icons only.
|
||||||
|
|
||||||
|
class ReputationItemDelegate: public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReputationItemDelegate(RsReputations::ReputationLevel max_level_to_display) : mMaxLevelToDisplay(max_level_to_display) {}
|
||||||
|
|
||||||
|
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t mMaxLevelToDisplay ;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class GxsIdDetails : public QObject
|
class GxsIdDetails : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const int ICON_TYPE_AVATAR = 0x0001 ;
|
static const int ICON_TYPE_AVATAR = 0x0001 ;
|
||||||
static const int ICON_TYPE_PGP = 0x0002 ;
|
static const int ICON_TYPE_PGP = 0x0002 ;
|
||||||
static const int ICON_TYPE_RECOGN = 0x0004 ;
|
static const int ICON_TYPE_RECOGN = 0x0004 ;
|
||||||
static const int ICON_TYPE_ALL = 0x0007 ;
|
static const int ICON_TYPE_REPUTATION = 0x0008 ;
|
||||||
static const int ICON_TYPE_REDACTED= 0x0008 ;
|
static const int ICON_TYPE_ALL = 0x000f ;
|
||||||
|
|
||||||
GxsIdDetails();
|
GxsIdDetails();
|
||||||
virtual ~GxsIdDetails();
|
virtual ~GxsIdDetails();
|
||||||
@ -67,7 +83,13 @@ public:
|
|||||||
|
|
||||||
static QString getName(const RsIdentityDetails &details);
|
static QString getName(const RsIdentityDetails &details);
|
||||||
static QString getComment(const RsIdentityDetails &details);
|
static QString getComment(const RsIdentityDetails &details);
|
||||||
static void getIcons(const RsIdentityDetails &details, QList<QIcon> &icons,uint32_t icon_types=ICON_TYPE_ALL);
|
|
||||||
|
/*!
|
||||||
|
* \brief getIcons
|
||||||
|
* Returns the list of icons to display along with the ID name. The types of icons to show is a compound of the ICON_TYPE_* flags.
|
||||||
|
* If reputation is needed and exceeds the minimal reputation, an empty/void icon is showsn . This allow to only show reputation for IDs for which a problem exists.
|
||||||
|
*/
|
||||||
|
static void getIcons(const RsIdentityDetails &details, QList<QIcon> &icons, uint32_t icon_types=ICON_TYPE_ALL, uint32_t minimal_required_reputation=0xff);
|
||||||
|
|
||||||
static QString getEmptyIdText();
|
static QString getEmptyIdText();
|
||||||
static QString getLoadingText(const RsGxsId &id);
|
static QString getLoadingText(const RsGxsId &id);
|
||||||
@ -76,6 +98,7 @@ public:
|
|||||||
static QString getNameForType(GxsIdDetailsType type, const RsIdentityDetails &details);
|
static QString getNameForType(GxsIdDetailsType type, const RsIdentityDetails &details);
|
||||||
|
|
||||||
static QIcon getLoadingIcon(const RsGxsId &id);
|
static QIcon getLoadingIcon(const RsGxsId &id);
|
||||||
|
static QIcon getReputationIcon(RsReputations::ReputationLevel icon_index, uint32_t min_reputation);
|
||||||
|
|
||||||
static void GenerateCombinedPixmap(QPixmap &pixmap, const QList<QIcon> &icons, int iconSize);
|
static void GenerateCombinedPixmap(QPixmap &pixmap, const QList<QIcon> &icons, int iconSize);
|
||||||
|
|
||||||
|
@ -35,12 +35,6 @@ GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,QTreeWidgetItem *parent)
|
|
||||||
: QObject(NULL), RSTreeWidgetItem(compareRole, parent), mColumn(0), mIconTypeMask(icon_mask)
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GxsIdRSTreeWidgetItem::init()
|
void GxsIdRSTreeWidgetItem::init()
|
||||||
{
|
{
|
||||||
mIdFound = false;
|
mIdFound = false;
|
||||||
@ -116,14 +110,14 @@ void GxsIdRSTreeWidgetItem::setId(const RsGxsId &id, int column, bool retryWhenF
|
|||||||
|
|
||||||
void GxsIdRSTreeWidgetItem::updateBannedState()
|
void GxsIdRSTreeWidgetItem::updateBannedState()
|
||||||
{
|
{
|
||||||
if(mBannedState != rsIdentity->isBanned(mId))
|
if(mBannedState != (rsIdentity->overallReputationLevel(mId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE))
|
||||||
forceUpdate() ;
|
forceUpdate() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsIdRSTreeWidgetItem::forceUpdate()
|
void GxsIdRSTreeWidgetItem::forceUpdate()
|
||||||
{
|
{
|
||||||
mIdFound = false;
|
mIdFound = false;
|
||||||
mBannedState = rsIdentity->isBanned(mId) ;
|
mBannedState = (rsIdentity->overallReputationLevel(mId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE);
|
||||||
|
|
||||||
startProcess();
|
startProcess();
|
||||||
}
|
}
|
||||||
@ -169,7 +163,7 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const
|
|||||||
|
|
||||||
if(mId.isNull())
|
if(mId.isNull())
|
||||||
return RSTreeWidgetItem::data(column, role);
|
return RSTreeWidgetItem::data(column, role);
|
||||||
else if(rsIdentity->isBanned(mId))
|
else if(rsIdentity->overallReputationLevel(mId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
pix = QImage(BANNED_IMAGE) ;
|
pix = QImage(BANNED_IMAGE) ;
|
||||||
else if (mAvatar.mSize == 0 || !pix.loadFromData(mAvatar.mData, mAvatar.mSize, "PNG"))
|
else if (mAvatar.mSize == 0 || !pix.loadFromData(mAvatar.mData, mAvatar.mSize, "PNG"))
|
||||||
pix = GxsIdDetails::makeDefaultIcon(mId);
|
pix = GxsIdDetails::makeDefaultIcon(mId);
|
||||||
|
@ -40,8 +40,7 @@ class GxsIdRSTreeWidgetItem : public QObject, public RSTreeWidgetItem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask=GxsIdDetails::ICON_TYPE_ALL,QTreeWidget *parent = NULL);
|
GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,QTreeWidget *parent = NULL);
|
||||||
GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,QTreeWidgetItem *parent);
|
|
||||||
|
|
||||||
void setId(const RsGxsId &id, int column, bool retryWhenFailed);
|
void setId(const RsGxsId &id, int column, bool retryWhenFailed);
|
||||||
bool getId(RsGxsId &id);
|
bool getId(RsGxsId &id);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
#include "GxsForumThreadWidget.h"
|
#include "GxsForumThreadWidget.h"
|
||||||
#include "ui_GxsForumThreadWidget.h"
|
#include "ui_GxsForumThreadWidget.h"
|
||||||
@ -33,9 +34,11 @@
|
|||||||
#include "gui/common/RSElidedItemDelegate.h"
|
#include "gui/common/RSElidedItemDelegate.h"
|
||||||
#include "gui/settings/rsharesettings.h"
|
#include "gui/settings/rsharesettings.h"
|
||||||
#include "gui/gxs/GxsIdTreeWidgetItem.h"
|
#include "gui/gxs/GxsIdTreeWidgetItem.h"
|
||||||
|
#include "gui/Identity/IdDialog.h"
|
||||||
#include "gui/gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
#include "util/HandleRichText.h"
|
#include "util/HandleRichText.h"
|
||||||
#include "CreateGxsForumMsg.h"
|
#include "CreateGxsForumMsg.h"
|
||||||
|
#include "gui/MainWindow.h"
|
||||||
#include "gui/msgs/MessageComposer.h"
|
#include "gui/msgs/MessageComposer.h"
|
||||||
#include "util/DateTime.h"
|
#include "util/DateTime.h"
|
||||||
#include "gui/common/UIStateHelper.h"
|
#include "gui/common/UIStateHelper.h"
|
||||||
@ -54,26 +57,34 @@
|
|||||||
//#define DEBUG_FORUMS
|
//#define DEBUG_FORUMS
|
||||||
|
|
||||||
/* Images for context menu icons */
|
/* Images for context menu icons */
|
||||||
#define IMAGE_MESSAGE ":/images/mail_new.png"
|
#define IMAGE_MESSAGE ":/images/mail_new.png"
|
||||||
#define IMAGE_MESSAGEREPLY ":/images/mail_reply.png"
|
#define IMAGE_MESSAGEREPLY ":/images/mail_reply.png"
|
||||||
#define IMAGE_MESSAGEREMOVE ":/images/mail_delete.png"
|
#define IMAGE_MESSAGEREMOVE ":/images/mail_delete.png"
|
||||||
#define IMAGE_DOWNLOAD ":/images/start.png"
|
#define IMAGE_DOWNLOAD ":/images/start.png"
|
||||||
#define IMAGE_DOWNLOADALL ":/images/startall.png"
|
#define IMAGE_DOWNLOADALL ":/images/startall.png"
|
||||||
#define IMAGE_COPYLINK ":/images/copyrslink.png"
|
#define IMAGE_COPYLINK ":/images/copyrslink.png"
|
||||||
#define IMAGE_BIOHAZARD ":/icons/yellow_biohazard64.png"
|
#define IMAGE_BIOHAZARD ":/icons/yellow_biohazard64.png"
|
||||||
|
#define IMAGE_WARNING_YELLOW ":/icons/warning_yellow_128.png"
|
||||||
|
#define IMAGE_WARNING_RED ":/icons/warning_red_128.png"
|
||||||
|
#define IMAGE_WARNING_UNKNOWN ":/icons/bullet_grey_128.png"
|
||||||
|
#define IMAGE_VOID ":/icons/void_128.png"
|
||||||
|
#define IMAGE_POSITIVE_OPINION ":/icons/png/thumbs-up.png"
|
||||||
|
#define IMAGE_NEUTRAL_OPINION ":/icons/png/thumbs-neutral.png"
|
||||||
|
#define IMAGE_NEGATIVE_OPINION ":/icons/png/thumbs-down.png"
|
||||||
|
|
||||||
#define VIEW_LAST_POST 0
|
#define VIEW_LAST_POST 0
|
||||||
#define VIEW_THREADED 1
|
#define VIEW_THREADED 1
|
||||||
#define VIEW_FLAT 2
|
#define VIEW_FLAT 2
|
||||||
|
|
||||||
/* Thread constants */
|
/* Thread constants */
|
||||||
#define COLUMN_THREAD_COUNT 6
|
#define COLUMN_THREAD_TITLE 0
|
||||||
#define COLUMN_THREAD_TITLE 0
|
#define COLUMN_THREAD_READ 1
|
||||||
#define COLUMN_THREAD_READ 1
|
#define COLUMN_THREAD_DATE 2
|
||||||
#define COLUMN_THREAD_DATE 2
|
#define COLUMN_THREAD_DISTRIBUTION 3
|
||||||
#define COLUMN_THREAD_AUTHOR 3
|
#define COLUMN_THREAD_AUTHOR 4
|
||||||
#define COLUMN_THREAD_SIGNED 4
|
#define COLUMN_THREAD_SIGNED 5
|
||||||
#define COLUMN_THREAD_CONTENT 5
|
#define COLUMN_THREAD_CONTENT 6
|
||||||
|
#define COLUMN_THREAD_COUNT 7
|
||||||
|
|
||||||
#define COLUMN_THREAD_DATA 0 // column for storing the userdata like msgid and parentid
|
#define COLUMN_THREAD_DATA 0 // column for storing the userdata like msgid and parentid
|
||||||
|
|
||||||
@ -88,18 +99,61 @@
|
|||||||
|
|
||||||
#define ROLE_THREAD_COUNT 4
|
#define ROLE_THREAD_COUNT 4
|
||||||
|
|
||||||
|
class DistributionItemDelegate: public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DistributionItemDelegate() {}
|
||||||
|
|
||||||
|
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
Q_ASSERT(index.isValid());
|
||||||
|
|
||||||
|
QStyleOptionViewItemV4 opt = option;
|
||||||
|
initStyleOption(&opt, index);
|
||||||
|
// disable default icon
|
||||||
|
opt.icon = QIcon();
|
||||||
|
// draw default item
|
||||||
|
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0);
|
||||||
|
|
||||||
|
const QRect r = option.rect;
|
||||||
|
|
||||||
|
QIcon icon ;
|
||||||
|
|
||||||
|
// get pixmap
|
||||||
|
unsigned int warning_level = qvariant_cast<unsigned int>(index.data(Qt::DecorationRole));
|
||||||
|
|
||||||
|
switch(warning_level)
|
||||||
|
{
|
||||||
|
case 0: icon = QIcon(IMAGE_VOID); break;
|
||||||
|
case 1: icon = QIcon(IMAGE_WARNING_YELLOW); break;
|
||||||
|
case 2: icon = QIcon(IMAGE_WARNING_RED); break;
|
||||||
|
default:
|
||||||
|
case 3: icon = QIcon(IMAGE_WARNING_UNKNOWN); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap pix = icon.pixmap(r.size());
|
||||||
|
|
||||||
|
// draw pixmap at center of item
|
||||||
|
const QPoint p = QPoint((r.width() - pix.width())/2, (r.height() - pix.height())/2);
|
||||||
|
painter->drawPixmap(r.topLeft() + p, pix);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget *parent) :
|
GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget *parent) :
|
||||||
GxsMessageFrameWidget(rsGxsForums, parent),
|
GxsMessageFrameWidget(rsGxsForums, parent),
|
||||||
ui(new Ui::GxsForumThreadWidget)
|
ui(new Ui::GxsForumThreadWidget)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
mTokenTypeGroupData = nextTokenType();
|
mTokenTypeGroupData = nextTokenType();
|
||||||
mTokenTypeInsertThreads = nextTokenType();
|
mTokenTypeInsertThreads = nextTokenType();
|
||||||
mTokenTypeMessageData = nextTokenType();
|
mTokenTypeMessageData = nextTokenType();
|
||||||
mTokenTypeReplyMessage = nextTokenType();
|
mTokenTypeReplyMessage = nextTokenType();
|
||||||
mTokenTypeReplyForumMessage = nextTokenType();
|
mTokenTypeReplyForumMessage = nextTokenType();
|
||||||
mTokenTypeBanAuthor = nextTokenType();
|
mTokenTypeShowAuthorInPeople = nextTokenType();
|
||||||
|
mTokenTypeNegativeAuthor = nextTokenType();
|
||||||
|
mTokenTypeNeutralAuthor = nextTokenType();
|
||||||
|
mTokenTypePositiveAuthor = nextTokenType();
|
||||||
|
|
||||||
setUpdateWhenInvisible(true);
|
setUpdateWhenInvisible(true);
|
||||||
|
|
||||||
@ -137,6 +191,8 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
|||||||
mThreadCompareRole = new RSTreeWidgetItemCompareRole;
|
mThreadCompareRole = new RSTreeWidgetItemCompareRole;
|
||||||
mThreadCompareRole->setRole(COLUMN_THREAD_DATE, ROLE_THREAD_SORT);
|
mThreadCompareRole->setRole(COLUMN_THREAD_DATE, ROLE_THREAD_SORT);
|
||||||
|
|
||||||
|
ui->threadTreeWidget->setItemDelegateForColumn(COLUMN_THREAD_DISTRIBUTION,new DistributionItemDelegate()) ;
|
||||||
|
|
||||||
connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint)));
|
connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint)));
|
||||||
connect(ui->postText, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuTextBrowser(QPoint)));
|
connect(ui->postText, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuTextBrowser(QPoint)));
|
||||||
|
|
||||||
@ -219,6 +275,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
|||||||
available posts from your subscribed friends, and make the \
|
available posts from your subscribed friends, and make the \
|
||||||
forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p>"));
|
forum visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the forum list at left.</p>"));
|
||||||
ui->threadTreeWidget->enableColumnCustomize(true);
|
ui->threadTreeWidget->enableColumnCustomize(true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsForumThreadWidget::~GxsForumThreadWidget()
|
GxsForumThreadWidget::~GxsForumThreadWidget()
|
||||||
@ -415,12 +472,23 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
|||||||
QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply"), &contextMnu);
|
QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply"), &contextMnu);
|
||||||
connect(replyAct, SIGNAL(triggered()), this, SLOT(replytoforummessage()));
|
connect(replyAct, SIGNAL(triggered()), this, SLOT(replytoforummessage()));
|
||||||
|
|
||||||
QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply with private message"), &contextMnu);
|
QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply to author with private message"), &contextMnu);
|
||||||
connect(replyauthorAct, SIGNAL(triggered()), this, SLOT(replytomessage()));
|
connect(replyauthorAct, SIGNAL(triggered()), this, SLOT(replytomessage()));
|
||||||
|
|
||||||
QAction *flagasbadAct = new QAction(QIcon(IMAGE_BIOHAZARD), tr("Ban this author"), &contextMnu);
|
QAction *flagaspositiveAct = new QAction(QIcon(IMAGE_POSITIVE_OPINION), tr("Give positive opinion"), &contextMnu);
|
||||||
flagasbadAct->setToolTip(tr("This will block/hide messages from this person, and notify neighbor nodes.")) ;
|
flagaspositiveAct->setToolTip(tr("This will block/hide messages from this person, and notify friend nodes.")) ;
|
||||||
connect(flagasbadAct, SIGNAL(triggered()), this, SLOT(flagpersonasbad()));
|
flagaspositiveAct->setData(mTokenTypePositiveAuthor) ;
|
||||||
|
connect(flagaspositiveAct, SIGNAL(triggered()), this, SLOT(flagperson()));
|
||||||
|
|
||||||
|
QAction *flagasneutralAct = new QAction(QIcon(IMAGE_NEUTRAL_OPINION), tr("Give neutral opinion"), &contextMnu);
|
||||||
|
flagasneutralAct->setToolTip(tr("Doing this, you trust your friends to decide to forward this message or not.")) ;
|
||||||
|
flagasneutralAct->setData(mTokenTypeNeutralAuthor) ;
|
||||||
|
connect(flagasneutralAct, SIGNAL(triggered()), this, SLOT(flagperson()));
|
||||||
|
|
||||||
|
QAction *flagasnegativeAct = new QAction(QIcon(IMAGE_NEGATIVE_OPINION), tr("Give negative opinion"), &contextMnu);
|
||||||
|
flagasnegativeAct->setToolTip(tr("This will block/hide messages from this person, and notify friend nodes.")) ;
|
||||||
|
flagasnegativeAct->setData(mTokenTypeNegativeAuthor) ;
|
||||||
|
connect(flagasnegativeAct, SIGNAL(triggered()), this, SLOT(flagperson()));
|
||||||
|
|
||||||
QAction *newthreadAct = new QAction(QIcon(IMAGE_MESSAGE), tr("Start New Thread"), &contextMnu);
|
QAction *newthreadAct = new QAction(QIcon(IMAGE_MESSAGE), tr("Start New Thread"), &contextMnu);
|
||||||
newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(mSubscribeFlags));
|
newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(mSubscribeFlags));
|
||||||
@ -444,6 +512,9 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
|||||||
QAction *markMsgAsUnreadChildren = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread") + " (" + tr ("with children") + ")", &contextMnu);
|
QAction *markMsgAsUnreadChildren = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread") + " (" + tr ("with children") + ")", &contextMnu);
|
||||||
connect(markMsgAsUnreadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsUnreadChildren()));
|
connect(markMsgAsUnreadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsUnreadChildren()));
|
||||||
|
|
||||||
|
QAction *showinpeopleAct = new QAction(QIcon(":/images/message-mail.png"), tr("Show author in people tab"), &contextMnu);
|
||||||
|
connect(showinpeopleAct, SIGNAL(triggered()), this, SLOT(showInPeopleTab()));
|
||||||
|
|
||||||
if (IS_GROUP_SUBSCRIBED(mSubscribeFlags)) {
|
if (IS_GROUP_SUBSCRIBED(mSubscribeFlags)) {
|
||||||
QList<QTreeWidgetItem*> rows;
|
QList<QTreeWidgetItem*> rows;
|
||||||
QList<QTreeWidgetItem*> rowsRead;
|
QList<QTreeWidgetItem*> rowsRead;
|
||||||
@ -501,8 +572,13 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
|||||||
contextMnu.addAction(collapseAll);
|
contextMnu.addAction(collapseAll);
|
||||||
|
|
||||||
contextMnu.addSeparator();
|
contextMnu.addSeparator();
|
||||||
contextMnu.addAction(flagasbadAct);
|
|
||||||
contextMnu.addSeparator();
|
QMenu *submenu1 = contextMnu.addMenu(tr("Author's reputation")) ;
|
||||||
|
submenu1->addAction(flagaspositiveAct);
|
||||||
|
submenu1->addAction(flagasneutralAct);
|
||||||
|
submenu1->addAction(flagasnegativeAct);
|
||||||
|
contextMnu.addAction(showinpeopleAct);
|
||||||
|
|
||||||
contextMnu.addAction(replyauthorAct);
|
contextMnu.addAction(replyauthorAct);
|
||||||
|
|
||||||
contextMnu.exec(QCursor::pos());
|
contextMnu.exec(QCursor::pos());
|
||||||
@ -794,8 +870,8 @@ static QString getDurationString(uint32_t days)
|
|||||||
tw->ui->forumName->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str()));
|
tw->ui->forumName->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str()));
|
||||||
|
|
||||||
QString anti_spam_features1 ;
|
QString anti_spam_features1 ;
|
||||||
if(IS_GROUP_PGP_KNOWN_AUTHED(tw->mSignFlags)) anti_spam_features1 = tr("Anonymous/unknown node IDs reputation threshold set to 0.4");
|
if(IS_GROUP_PGP_KNOWN_AUTHED(tw->mSignFlags)) anti_spam_features1 = tr("Anonymous/unknown posts forwarded if reputation is positive");
|
||||||
else if(IS_GROUP_PGP_AUTHED(tw->mSignFlags)) anti_spam_features1 = tr("Anonymous IDs reputation threshold set to 0.4");
|
else if(IS_GROUP_PGP_AUTHED(tw->mSignFlags)) anti_spam_features1 = tr("Anonymous posts forwarded if reputation is positive");
|
||||||
|
|
||||||
tw->mForumDescription = QString("<b>%1: \t</b>%2<br/>").arg(tr("Forum name"), QString::fromUtf8( group.mMeta.mGroupName.c_str()));
|
tw->mForumDescription = QString("<b>%1: \t</b>%2<br/>").arg(tr("Forum name"), QString::fromUtf8( group.mMeta.mGroupName.c_str()));
|
||||||
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Subscribers")).arg(group.mMeta.mPop);
|
tw->mForumDescription += QString("<b>%1: \t</b>%2<br/>").arg(tr("Subscribers")).arg(group.mMeta.mPop);
|
||||||
@ -996,18 +1072,54 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
|
|||||||
// Early check for a message that should be hidden because its author
|
// Early check for a message that should be hidden because its author
|
||||||
// is flagged with a bad reputation
|
// is flagged with a bad reputation
|
||||||
|
|
||||||
|
RsIdentityDetails iddetails ;
|
||||||
|
|
||||||
bool redacted = rsIdentity->isBanned(msg.mMeta.mAuthorId) ;
|
RsReputations::ReputationLevel reputation_level = RsReputations::REPUTATION_NEUTRAL ;
|
||||||
|
bool redacted = false ;
|
||||||
|
|
||||||
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL || (redacted?(GxsIdDetails::ICON_TYPE_REDACTED):0));
|
if(rsIdentity->getIdDetails(msg.mMeta.mAuthorId,iddetails))
|
||||||
|
{
|
||||||
|
reputation_level = iddetails.mReputation.mOverallReputationLevel ;
|
||||||
|
redacted = (reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
reputation_level = RsReputations::REPUTATION_UNKNOWN ;
|
||||||
|
|
||||||
|
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_AVATAR );
|
||||||
item->moveToThread(ui->threadTreeWidget->thread());
|
item->moveToThread(ui->threadTreeWidget->thread());
|
||||||
|
|
||||||
|
|
||||||
if(redacted)
|
if(redacted)
|
||||||
item->setText(COLUMN_THREAD_TITLE, tr("[ ... Redacted message ... ]"));
|
item->setText(COLUMN_THREAD_TITLE, tr("[ ... Redacted message ... ]"));
|
||||||
else
|
else
|
||||||
item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msg.mMeta.mMsgName.c_str()));
|
item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msg.mMeta.mMsgName.c_str()));
|
||||||
|
|
||||||
|
QString rep_tooltip_str ;
|
||||||
|
uint32_t rep_warning_level ;
|
||||||
|
|
||||||
|
if(reputation_level == RsReputations::REPUTATION_UNKNOWN)
|
||||||
|
{
|
||||||
|
rep_warning_level = 3 ;
|
||||||
|
rep_tooltip_str = tr("Information for this identity is currently missing.") ;
|
||||||
|
}
|
||||||
|
else if(reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE)
|
||||||
|
{
|
||||||
|
rep_warning_level = 2 ;
|
||||||
|
rep_tooltip_str = tr("You have banned this ID. The message will not be\ndisplayed nor forwarded to your friends.") ;
|
||||||
|
}
|
||||||
|
else if(reputation_level < rsGxsForums->minReputationForForwardingMessages(mForumGroup.mMeta.mSignFlags,iddetails.mFlags))
|
||||||
|
{
|
||||||
|
rep_warning_level = 1 ;
|
||||||
|
rep_tooltip_str = tr("You have not set an opinion for this person,\n and your friends do not vote positively: Spam regulation \nprevents the message to be forwarded to your friends.") ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rep_warning_level = 0 ;
|
||||||
|
rep_tooltip_str = tr("Message will be forwarded to your friends.") ;
|
||||||
|
}
|
||||||
|
std::cerr << "Inserting post from ID " << msg.mMeta.mAuthorId << ", group flags=" << std::hex << mForumGroup.mMeta.mSignFlags << " Identity flags = " << iddetails.mFlags << ": warning level = " << rep_warning_level << std::dec << std::endl;
|
||||||
|
|
||||||
|
item->setData(COLUMN_THREAD_DISTRIBUTION,Qt::ToolTipRole,rep_tooltip_str) ;
|
||||||
|
item->setData(COLUMN_THREAD_DISTRIBUTION,Qt::DecorationRole,rep_warning_level) ;
|
||||||
|
|
||||||
//msg.mMeta.mChildTs Was not updated when received new child
|
//msg.mMeta.mChildTs Was not updated when received new child
|
||||||
// so do it here.
|
// so do it here.
|
||||||
@ -1096,7 +1208,7 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
|
|||||||
|
|
||||||
QTreeWidgetItem *GxsForumThreadWidget::generateMissingItem(const RsGxsMessageId &msgId)
|
QTreeWidgetItem *GxsForumThreadWidget::generateMissingItem(const RsGxsMessageId &msgId)
|
||||||
{
|
{
|
||||||
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL);
|
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_AVATAR);
|
||||||
|
|
||||||
item->setText(COLUMN_THREAD_TITLE, tr("[ ... Missing Message ... ]"));
|
item->setText(COLUMN_THREAD_TITLE, tr("[ ... Missing Message ... ]"));
|
||||||
item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgId.toStdString()));
|
item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgId.toStdString()));
|
||||||
@ -1431,7 +1543,8 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool redacted = rsIdentity->isBanned(msg.mMeta.mAuthorId) ;
|
uint32_t overall_reputation = rsIdentity->overallReputationLevel(msg.mMeta.mAuthorId) ;
|
||||||
|
bool redacted = (overall_reputation == RsReputations::REPUTATION_LOCALLY_NEGATIVE) ;
|
||||||
|
|
||||||
mStateHelper->setActive(mTokenTypeMessageData, true);
|
mStateHelper->setActive(mTokenTypeMessageData, true);
|
||||||
|
|
||||||
@ -1644,6 +1757,17 @@ void GxsForumThreadWidget::setMsgReadStatus(QList<QTreeWidgetItem*> &rows, bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxsForumThreadWidget::showInPeopleTab()
|
||||||
|
{
|
||||||
|
if (groupId().isNull() || mThreadId.isNull()) {
|
||||||
|
QMessageBox::information(this, tr("RetroShare"),tr("You cant act on the author to a non-existant Message"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId);
|
||||||
|
requestMsgData_ShowAuthorInPeople(postId) ;
|
||||||
|
}
|
||||||
|
|
||||||
void GxsForumThreadWidget::markMsgAsReadUnread (bool read, bool children, bool forum)
|
void GxsForumThreadWidget::markMsgAsReadUnread (bool read, bool children, bool forum)
|
||||||
{
|
{
|
||||||
if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(mSubscribeFlags)) {
|
if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(mSubscribeFlags)) {
|
||||||
@ -1827,24 +1951,26 @@ static QString buildReplyHeader(const RsMsgMetaData &meta)
|
|||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsForumThreadWidget::flagpersonasbad()
|
void GxsForumThreadWidget::flagperson()
|
||||||
{
|
{
|
||||||
// no need to use the token system for that, since we just need to find out the author's name, which is in the item.
|
// no need to use the token system for that, since we just need to find out the author's name, which is in the item.
|
||||||
|
|
||||||
if (groupId().isNull() || mThreadId.isNull()) {
|
if (groupId().isNull() || mThreadId.isNull()) {
|
||||||
QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message"));
|
QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t token_type = qobject_cast<QAction*>(sender())->data().toUInt();
|
||||||
|
|
||||||
// Get Message ... then complete replyMessageData().
|
// Get Message ... then complete replyMessageData().
|
||||||
RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId);
|
RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId);
|
||||||
|
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||||
|
|
||||||
#ifdef DEBUG_FORUMS
|
#ifdef DEBUG_FORUMS
|
||||||
std::cerr << "GxsForumThreadWidget::requestMsgData_BanAuthor(" << postId.first << "," << postId.second << ")";
|
std::cerr << "GxsForumThreadWidget::requestMsgData_BanAuthor(" << postId.first << "," << postId.second << ")";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GxsMsgReq msgIds;
|
GxsMsgReq msgIds;
|
||||||
@ -1852,7 +1978,7 @@ void GxsForumThreadWidget::flagpersonasbad()
|
|||||||
vect.push_back(postId.second);
|
vect.push_back(postId.second);
|
||||||
|
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeBanAuthor);
|
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, token_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsForumThreadWidget::replytomessage()
|
void GxsForumThreadWidget::replytomessage()
|
||||||
@ -1907,6 +2033,18 @@ void GxsForumThreadWidget::replyMessageData(const RsGxsForumMsg &msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxsForumThreadWidget::showAuthorInPeople(const RsGxsForumMsg& msg)
|
||||||
|
{
|
||||||
|
if ((msg.mMeta.mGroupId != groupId()) || (msg.mMeta.mMsgId != mThreadId))
|
||||||
|
{
|
||||||
|
std::cerr << "GxsForumThreadWidget::replyMessageData() ERROR Message Ids have changed!";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId);
|
||||||
|
requestMsgData_ShowAuthorInPeople(postId);
|
||||||
|
}
|
||||||
|
|
||||||
void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg)
|
void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg)
|
||||||
{
|
{
|
||||||
if ((msg.mMeta.mGroupId != groupId()) || (msg.mMeta.mMsgId != mThreadId))
|
if ((msg.mMeta.mGroupId != groupId()) || (msg.mMeta.mMsgId != mThreadId))
|
||||||
@ -2069,6 +2207,8 @@ void GxsForumThreadWidget::loadGroupData(const uint32_t &token)
|
|||||||
|
|
||||||
mStateHelper->setActive(mTokenTypeGroupData, true);
|
mStateHelper->setActive(mTokenTypeGroupData, true);
|
||||||
|
|
||||||
|
// Don't show the distribution column if the forum has no anti-spam
|
||||||
|
ui->threadTreeWidget->setColumnHidden(COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags)));
|
||||||
ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mSubscribeFlags)) ;
|
ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mSubscribeFlags)) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2158,6 +2298,24 @@ void GxsForumThreadWidget::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &
|
|||||||
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeReplyMessage);
|
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeReplyMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxsForumThreadWidget::requestMsgData_ShowAuthorInPeople(const RsGxsGrpMsgIdPair& msgId)
|
||||||
|
{
|
||||||
|
RsTokReqOptions opts;
|
||||||
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FORUMS
|
||||||
|
std::cerr << "GxsForumThreadWidget::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GxsMsgReq msgIds;
|
||||||
|
std::vector<RsGxsMessageId> &vect = msgIds[msgId.first];
|
||||||
|
vect.push_back(msgId.second);
|
||||||
|
|
||||||
|
uint32_t token;
|
||||||
|
mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeShowAuthorInPeople);
|
||||||
|
}
|
||||||
|
|
||||||
void GxsForumThreadWidget::requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId)
|
void GxsForumThreadWidget::requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId)
|
||||||
{
|
{
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
@ -2227,7 +2385,43 @@ void GxsForumThreadWidget::loadMsgData_ReplyForumMessage(const uint32_t &token)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsForumThreadWidget::loadMsgData_BanAuthor(const uint32_t &token)
|
void GxsForumThreadWidget::loadMsgData_ShowAuthorInPeople(const uint32_t &token)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_FORUMS
|
||||||
|
std::cerr << "GxsForumThreadWidget::loadMsgData_ReplyMessage()";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<RsGxsForumMsg> msgs;
|
||||||
|
if (rsGxsForums->getMsgData(token, msgs))
|
||||||
|
{
|
||||||
|
if (msgs.size() != 1)
|
||||||
|
{
|
||||||
|
std::cerr << "GxsForumThreadWidget::loadMsgData_showAuthorInPeople() ERROR Wrong number of answers";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(msgs[0].mMeta.mAuthorId.isNull())
|
||||||
|
{
|
||||||
|
std::cerr << "GxsForumThreadWidget::loadMsgData_showAuthorInPeople() ERROR Missing Message Data...";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* window will destroy itself! */
|
||||||
|
IdDialog *idDialog = dynamic_cast<IdDialog*>(MainWindow::getPage(MainWindow::People));
|
||||||
|
|
||||||
|
if (!idDialog)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
MainWindow::showWindow(MainWindow::People);
|
||||||
|
idDialog->navigate(RsGxsId(msgs[0].mMeta.mAuthorId));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
std::cerr << "GxsForumThreadWidget::loadMsgData_showAuthorInPeople() ERROR Missing Message Data...";
|
||||||
|
}
|
||||||
|
|
||||||
|
void GxsForumThreadWidget::loadMsgData_SetAuthorOpinion(const uint32_t &token,RsReputations::Opinion opinion)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_FORUMS
|
#ifdef DEBUG_FORUMS
|
||||||
std::cerr << "GxsForumThreadWidget::loadMsgData_BanAuthor()";
|
std::cerr << "GxsForumThreadWidget::loadMsgData_BanAuthor()";
|
||||||
@ -2245,7 +2439,8 @@ void GxsForumThreadWidget::loadMsgData_BanAuthor(const uint32_t &token)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << " banning author id " << msgs[0].mMeta.mAuthorId << std::endl;
|
std::cerr << " banning author id " << msgs[0].mMeta.mAuthorId << std::endl;
|
||||||
rsReputations->setOwnOpinion(msgs[0].mMeta.mAuthorId,RsReputations::OPINION_NEGATIVE) ;
|
|
||||||
|
rsReputations->setOwnOpinion(msgs[0].mMeta.mAuthorId,opinion) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2291,8 +2486,23 @@ void GxsForumThreadWidget::loadRequest(const TokenQueue *queue, const TokenReque
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.mUserType == mTokenTypeBanAuthor) {
|
if (req.mUserType == mTokenTypeShowAuthorInPeople) {
|
||||||
loadMsgData_BanAuthor(req.mToken);
|
loadMsgData_ShowAuthorInPeople(req.mToken);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.mUserType == mTokenTypePositiveAuthor) {
|
||||||
|
loadMsgData_SetAuthorOpinion(req.mToken,RsReputations::OPINION_POSITIVE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.mUserType == mTokenTypeNegativeAuthor) {
|
||||||
|
loadMsgData_SetAuthorOpinion(req.mToken,RsReputations::OPINION_NEGATIVE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.mUserType == mTokenTypeNeutralAuthor) {
|
||||||
|
loadMsgData_SetAuthorOpinion(req.mToken,RsReputations::OPINION_NEUTRAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,7 @@ private slots:
|
|||||||
|
|
||||||
void replyMessageData(const RsGxsForumMsg &msg);
|
void replyMessageData(const RsGxsForumMsg &msg);
|
||||||
void replyForumMessageData(const RsGxsForumMsg &msg);
|
void replyForumMessageData(const RsGxsForumMsg &msg);
|
||||||
|
void showAuthorInPeople(const RsGxsForumMsg& msg);
|
||||||
|
|
||||||
void saveImage();
|
void saveImage();
|
||||||
|
|
||||||
@ -94,6 +95,7 @@ private slots:
|
|||||||
void markMsgAsUnreadChildren();
|
void markMsgAsUnreadChildren();
|
||||||
|
|
||||||
void copyMessageLink();
|
void copyMessageLink();
|
||||||
|
void showInPeopleTab();
|
||||||
|
|
||||||
/* handle splitter */
|
/* handle splitter */
|
||||||
void togglethreadview();
|
void togglethreadview();
|
||||||
@ -108,7 +110,7 @@ private slots:
|
|||||||
void downloadAllFiles();
|
void downloadAllFiles();
|
||||||
|
|
||||||
void changedViewBox();
|
void changedViewBox();
|
||||||
void flagpersonasbad();
|
void flagperson();
|
||||||
|
|
||||||
void filterColumnChanged(int column);
|
void filterColumnChanged(int column);
|
||||||
void filterItems(const QString &text);
|
void filterItems(const QString &text);
|
||||||
@ -145,13 +147,15 @@ private:
|
|||||||
static void loadAuthorIdCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/);
|
static void loadAuthorIdCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/);
|
||||||
|
|
||||||
void requestMessageData(const RsGxsGrpMsgIdPair &msgId);
|
void requestMessageData(const RsGxsGrpMsgIdPair &msgId);
|
||||||
void loadMessageData(const uint32_t &token);
|
|
||||||
void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId);
|
void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId);
|
||||||
void loadMsgData_ReplyMessage(const uint32_t &token);
|
void requestMsgData_ShowAuthorInPeople(const RsGxsGrpMsgIdPair &msgId);
|
||||||
|
|
||||||
void requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId);
|
void requestMsgData_ReplyForumMessage(const RsGxsGrpMsgIdPair &msgId);
|
||||||
|
|
||||||
|
void loadMessageData(const uint32_t &token);
|
||||||
|
void loadMsgData_ReplyMessage(const uint32_t &token);
|
||||||
void loadMsgData_ReplyForumMessage(const uint32_t &token);
|
void loadMsgData_ReplyForumMessage(const uint32_t &token);
|
||||||
void loadMsgData_BanAuthor(const uint32_t &token);
|
void loadMsgData_ShowAuthorInPeople(const uint32_t &token);
|
||||||
|
void loadMsgData_SetAuthorOpinion(const uint32_t &token, RsReputations::Opinion opinion);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RsGxsGroupId mLastForumID;
|
RsGxsGroupId mLastForumID;
|
||||||
@ -173,7 +177,10 @@ private:
|
|||||||
uint32_t mTokenTypeMessageData;
|
uint32_t mTokenTypeMessageData;
|
||||||
uint32_t mTokenTypeReplyMessage;
|
uint32_t mTokenTypeReplyMessage;
|
||||||
uint32_t mTokenTypeReplyForumMessage;
|
uint32_t mTokenTypeReplyForumMessage;
|
||||||
uint32_t mTokenTypeBanAuthor;
|
uint32_t mTokenTypeShowAuthorInPeople;
|
||||||
|
uint32_t mTokenTypeNegativeAuthor;
|
||||||
|
uint32_t mTokenTypePositiveAuthor;
|
||||||
|
uint32_t mTokenTypeNeutralAuthor;
|
||||||
|
|
||||||
/* Color definitions (for standard see qss.default) */
|
/* Color definitions (for standard see qss.default) */
|
||||||
QColor mTextColorRead;
|
QColor mTextColorRead;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>851</width>
|
<width>1217</width>
|
||||||
<height>721</height>
|
<height>721</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -238,6 +238,11 @@
|
|||||||
<string>Date</string>
|
<string>Date</string>
|
||||||
</property>
|
</property>
|
||||||
</column>
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Distribution</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
<column>
|
<column>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Author</string>
|
<string>Author</string>
|
||||||
|
@ -1,149 +1,227 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>icons/svg/profile.svg</file>
|
<file>icons/add_user_256.png</file>
|
||||||
<file>icons/svg/download.svg</file>
|
<file>icons/anonymous_blue_128.png</file>
|
||||||
<file>icons/svg/folders.svg</file>
|
<file>icons/anonymous_green_128.png</file>
|
||||||
<file>icons/svg/folders1.svg</file>
|
<file>icons/aol.png</file>
|
||||||
<file>icons/svg/magnifying-glass.svg</file>
|
<file>icons/avatar_128.png</file>
|
||||||
<file>icons/svg/upload.svg</file>
|
<file>icons/avatar_grey_128.png</file>
|
||||||
<file>icons/svg/paste.svg</file>
|
<file>icons/blank_blue_128.png</file>
|
||||||
<file>icons/svg/share.svg</file>
|
<file>icons/blank_green_128.png</file>
|
||||||
<file>icons/settings/appearance.svg</file>
|
<file>icons/blank_red_128.png</file>
|
||||||
<file>icons/settings/channels.svg</file>
|
<file>icons/browsable_blue_128.png</file>
|
||||||
<file>icons/settings/chat.svg</file>
|
<file>icons/browsable_green_128.png</file>
|
||||||
<file>icons/settings/directories.svg</file>
|
<file>icons/bullet_blue_128.png</file>
|
||||||
<file>icons/settings/filesharing.svg</file>
|
<file>icons/bullet_green_128.png</file>
|
||||||
<file>icons/settings/forums.svg</file>
|
<file>icons/bullet_green_yellow_star_128.png</file>
|
||||||
<file>icons/settings/general.svg</file>
|
<file>icons/bullet_grey_128.png</file>
|
||||||
<file>icons/settings/messages.svg</file>
|
<file>icons/bullet_red_128.png</file>
|
||||||
<file>icons/settings/network.svg</file>
|
<file>icons/bullet_yellow_128.png</file>
|
||||||
<file>icons/settings/notify.svg</file>
|
<file>icons/channels_128.png</file>
|
||||||
<file>icons/settings/people.svg</file>
|
<file>icons/channels_red_128.png</file>
|
||||||
<file>icons/settings/permissions.svg</file>
|
<file>icons/chat_128.png</file>
|
||||||
<file>icons/settings/plugins.svg</file>
|
<file>icons/chat_red_128.png</file>
|
||||||
<file>icons/settings/posted.svg</file>
|
<file>icons/circles_128.png</file>
|
||||||
<file>icons/settings/profile.svg</file>
|
<file>icons/circles_new_128.png</file>
|
||||||
<file>icons/settings/server.svg</file>
|
<file>icons/friends_128.png</file>
|
||||||
<file>icons/settings/sound.svg</file>
|
<file>icons/global_switch_off_128.png</file>
|
||||||
<file>icons/settings/webinterface.svg</file>
|
<file>icons/global_switch_on_128.png</file>
|
||||||
<file>icons/add_user_256.png</file>
|
<file>icons/gmail.png</file>
|
||||||
<file>icons/aol.png</file>
|
<file>icons/help_128.png</file>
|
||||||
<file>icons/avatar_128.png</file>
|
<file>icons/help_64.png</file>
|
||||||
<file>icons/avatar_grey_128.png</file>
|
<file>icons/information_128.png</file>
|
||||||
<file>icons/blank_red_128.png</file>
|
<file>icons/internet_128.png</file>
|
||||||
<file>icons/void_128.png</file>
|
<file>icons/invite64.png</file>
|
||||||
<file>icons/blank_green_128.png</file>
|
<file>icons/knews_128.png</file>
|
||||||
<file>icons/blank_blue_128.png</file>
|
<file>icons/knews_red_128.png</file>
|
||||||
<file>icons/browsable_green_128.png</file>
|
<file>icons/konversation_128.png</file>
|
||||||
<file>icons/search_red_128.png</file>
|
<file>icons/konversation128.png</file>
|
||||||
<file>icons/anonymous_blue_128.png</file>
|
<file>icons/konversation_red_128.png</file>
|
||||||
<file>icons/bullet_blue_128.png</file>
|
<file>icons/ktorrent_128.png</file>
|
||||||
<file>icons/bullet_green_128.png</file>
|
<file>icons/ktorrent_red_128.png</file>
|
||||||
<file>icons/bullet_grey_128.png</file>
|
<file>icons/logo_0_connected_128.png</file>
|
||||||
<file>icons/bullet_red_128.png</file>
|
<file>icons/logo_128.png</file>
|
||||||
<file>icons/bullet_yellow_128.png</file>
|
<file>icons/logo_1_connected_128.png</file>
|
||||||
<file>icons/channels_128.png</file>
|
<file>icons/logo_2_connected_128.png</file>
|
||||||
<file>icons/channels_red_128.png</file>
|
<file>icons/mail_128.png</file>
|
||||||
<file>icons/chat_128.png</file>
|
<file>icons/mail_old_128.png</file>
|
||||||
<file>icons/chat_red_128.png</file>
|
<file>icons/mail_red_128.png</file>
|
||||||
<file>icons/circles_128.png</file>
|
<file>icons/newsfeed128.png</file>
|
||||||
<file>icons/circles_new_128.png</file>
|
<file>icons/outlook.png</file>
|
||||||
<file>icons/friends_128.png</file>
|
<file>icons/plugins_128.png</file>
|
||||||
<file>icons/global_switch_off_128.png</file>
|
<file>icons/png/add.png</file>
|
||||||
<file>icons/global_switch_on_128.png</file>
|
<file>icons/png/attach-image.png</file>
|
||||||
<file>icons/gmail.png</file>
|
<file>icons/png/attach.png</file>
|
||||||
<file>icons/help_128.png</file>
|
<file>icons/png/channels-notify.png</file>
|
||||||
<file>icons/help_64.png</file>
|
<file>icons/png/channels.png</file>
|
||||||
<file>icons/information_128.png</file>
|
<file>icons/png/chat-bubble-notify.png</file>
|
||||||
<file>icons/internet_128.png</file>
|
<file>icons/png/chat-bubble.png</file>
|
||||||
<file>icons/invite64.png</file>
|
<file>icons/png/chat-lobbies-notify.png</file>
|
||||||
<file>icons/knews_128.png</file>
|
<file>icons/png/chat-lobbies.png</file>
|
||||||
<file>icons/knews_red_128.png</file>
|
<file>icons/png/circles.png</file>
|
||||||
<file>icons/konversation_128.png</file>
|
<file>icons/png/empty-circle.png</file>
|
||||||
<file>icons/konversation128.png</file>
|
<file>icons/png/exit.png</file>
|
||||||
<file>icons/konversation_red_128.png</file>
|
<file>icons/png/feedreader-notify.png</file>
|
||||||
<file>icons/ktorrent_128.png</file>
|
<file>icons/png/feedreader.png</file>
|
||||||
<file>icons/ktorrent_red_128.png</file>
|
<file>icons/png/filesharing-notify.png</file>
|
||||||
<file>icons/logo_0_connected_128.png</file>
|
<file>icons/png/filesharing.png</file>
|
||||||
<file>icons/logo_128.png</file>
|
<file>icons/png/font.png</file>
|
||||||
<file>icons/logo_1_connected_128.png</file>
|
<file>icons/png/forums-notify.png</file>
|
||||||
<file>icons/logo_2_connected_128.png</file>
|
<file>icons/png/forums.png</file>
|
||||||
<file>icons/mail_128.png</file>
|
<file>icons/png/fullscreen_arrows.png</file>
|
||||||
<file>icons/mail_old_128.png</file>
|
<file>icons/png/highlight.png</file>
|
||||||
<file>icons/mail_red_128.png</file>
|
<file>icons/png/info.png</file>
|
||||||
<file>icons/newsfeed128.png</file>
|
<file>icons/png/invite.png</file>
|
||||||
<file>icons/outlook.png</file>
|
<file>icons/png/keyring.png</file>
|
||||||
<file>icons/plugins_128.png</file>
|
<file>icons/png/leave.png</file>
|
||||||
<file>icons/posted_128.png</file>
|
<file>icons/png/messages-notify.png</file>
|
||||||
<file>icons/posted_red_128.png</file>
|
<file>icons/png/messages.png</file>
|
||||||
<file>icons/quit_128.png</file>
|
<file>icons/png/microphone_mute.png</file>
|
||||||
<file>icons/security_high_128.png</file>
|
<file>icons/png/microphone.png</file>
|
||||||
<file>icons/security_low_128.png</file>
|
<file>icons/png/netgraph.png</file>
|
||||||
<file>icons/security_medium_128.png</file>
|
<file>icons/png/network-notify.png</file>
|
||||||
<file>icons/star_overlay_128.png</file>
|
<file>icons/png/network.png</file>
|
||||||
<file>icons/switch00_128.png</file>
|
<file>icons/png/network-puplic.png</file>
|
||||||
<file>icons/switch01_128.png</file>
|
<file>icons/png/newsfeed-notify.png</file>
|
||||||
<file>icons/switch10_128.png</file>
|
<file>icons/png/newsfeed.png</file>
|
||||||
<file>icons/switch11_128.png</file>
|
<file>icons/png/options.png</file>
|
||||||
<file>icons/system_128.png</file>
|
<file>icons/png/people-notify.png</file>
|
||||||
<file>icons/tile_checking_48.png</file>
|
<file>icons/png/people.png</file>
|
||||||
<file>icons/tile_downloaded_48.png</file>
|
<file>icons/png/person.png</file>
|
||||||
<file>icons/tile_downloading_48.png</file>
|
<file>icons/png/phone_hangup.png</file>
|
||||||
<file>icons/tile_inactive_48.png</file>
|
<file>icons/png/phone.png</file>
|
||||||
<file>icons/tor-logo.png</file>
|
<file>icons/png/posted-notify.png</file>
|
||||||
<file>icons/tor-off.png</file>
|
<file>icons/png/posted.png</file>
|
||||||
<file>icons/tor-on.png</file>
|
<file>icons/png/search.png</file>
|
||||||
<file>icons/tor-starting.png</file>
|
<file>icons/png/send-message-blocked.png</file>
|
||||||
<file>icons/tor-stopping.png</file>
|
<file>icons/png/send-message.png</file>
|
||||||
<file>icons/user-away_64.png</file>
|
<file>icons/png/settings.png</file>
|
||||||
<file>icons/user-away-extended_64.png</file>
|
<file>icons/png/smiley.png</file>
|
||||||
<file>icons/user-busy_64.png</file>
|
<file>icons/png/speaker_mute.png</file>
|
||||||
<file>icons/user-offline_64.png</file>
|
<file>icons/png/speaker.png</file>
|
||||||
<file>icons/user-online_64.png</file>
|
<file>icons/png/thumbs-down.png</file>
|
||||||
<file>icons/yahoo.png</file>
|
<file>icons/png/thumbs-neutral.png</file>
|
||||||
<file>icons/yandex.png</file>
|
<file>icons/png/thumbs-up.png</file>
|
||||||
<file>icons/yellow_biohazard64.png</file>
|
<file>icons/png/video.png</file>
|
||||||
<file>icons/png/attach.png</file>
|
<file>icons/posted_128.png</file>
|
||||||
<file>icons/png/attach-image.png</file>
|
<file>icons/posted_red_128.png</file>
|
||||||
<file>icons/png/highlight.png</file>
|
<file>icons/quit_128.png</file>
|
||||||
<file>icons/png/invite.png</file>
|
<file>icons/red_biohazard64.png</file>
|
||||||
<file>icons/png/leave.png</file>
|
<file>icons/search_red_128.png</file>
|
||||||
<file>icons/png/search.png</file>
|
<file>icons/security_high_128.png</file>
|
||||||
<file>icons/png/send-message.png</file>
|
<file>icons/security_low_128.png</file>
|
||||||
<file>icons/png/settings.png</file>
|
<file>icons/security_medium_128.png</file>
|
||||||
<file>icons/png/smiley.png</file>
|
<file>icons/settings/appearance.svg</file>
|
||||||
<file>icons/png/font.png</file>
|
<file>icons/settings/channels.svg</file>
|
||||||
<file>icons/png/send-message-blocked.png</file>
|
<file>icons/settings/chat.svg</file>
|
||||||
<file>icons/png/chat-bubble-notify.png</file>
|
<file>icons/settings/directories.svg</file>
|
||||||
<file>icons/png/channels.png</file>
|
<file>icons/settings/filesharing.svg</file>
|
||||||
<file>icons/png/chat-lobbies.png</file>
|
<file>icons/settings/forums.svg</file>
|
||||||
<file>icons/png/forums.png</file>
|
<file>icons/settings/general.svg</file>
|
||||||
<file>icons/png/info.png</file>
|
<file>icons/settings/messages.svg</file>
|
||||||
<file>icons/png/messages.png</file>
|
<file>icons/settings/network.svg</file>
|
||||||
<file>icons/png/network.png</file>
|
<file>icons/settings/notify.svg</file>
|
||||||
<file>icons/png/newsfeed.png</file>
|
<file>icons/settings/people.svg</file>
|
||||||
<file>icons/png/people.png</file>
|
<file>icons/settings/permissions.svg</file>
|
||||||
<file>icons/png/posted.png</file>
|
<file>icons/settings/plugins.svg</file>
|
||||||
<file>icons/png/exit.png</file>
|
<file>icons/settings/posted.svg</file>
|
||||||
<file>icons/png/options.png</file>
|
<file>icons/settings/profile.svg</file>
|
||||||
<file>icons/png/filesharing.png</file>
|
<file>icons/settings/server.svg</file>
|
||||||
<file>icons/png/channels-notify.png</file>
|
<file>icons/settings/sound.svg</file>
|
||||||
<file>icons/png/chat-lobbies-notify.png</file>
|
<file>icons/settings/webinterface.svg</file>
|
||||||
<file>icons/png/forums-notify.png</file>
|
<file>icons/star_overlay_128.png</file>
|
||||||
<file>icons/png/messages-notify.png</file>
|
<file>icons/svg/add.svg</file>
|
||||||
<file>icons/png/network-notify.png</file>
|
<file>icons/svg/attach-image.svg</file>
|
||||||
<file>icons/png/newsfeed-notify.png</file>
|
<file>icons/svg/attach.svg</file>
|
||||||
<file>icons/png/people-notify.png</file>
|
<file>icons/svg/channels-notify.svg</file>
|
||||||
<file>icons/png/posted-notify.png</file>
|
<file>icons/svg/channels.svg</file>
|
||||||
<file>icons/png/filesharing-notify.png</file>
|
<file>icons/svg/chat-bubble-notify.svg</file>
|
||||||
<file>icons/png/thumbs-up.png</file>
|
<file>icons/svg/chat-bubble.svg</file>
|
||||||
<file>icons/png/thumbs-down.png</file>
|
<file>icons/svg/chat-lobbies-notify.svg</file>
|
||||||
<file>icons/png/thumbs-neutral.png</file>
|
<file>icons/svg/chat-lobbies.svg</file>
|
||||||
<file>icons/png/add.png</file>
|
<file>icons/svg/circles.svg</file>
|
||||||
<file>icons/png/netgraph.png</file>
|
<file>icons/svg/download.svg</file>
|
||||||
<file>icons/png/network-puplic.png</file>
|
<file>icons/svg/empty-circle.svg</file>
|
||||||
<file>icons/png/circles.png</file>
|
<file>icons/svg/exit-red.svg</file>
|
||||||
<file>icons/png/person.png</file>
|
<file>icons/svg/exit.svg</file>
|
||||||
<file>icons/png/keyring.png</file>
|
<file>icons/svg/feedreader-notify.svg</file>
|
||||||
</qresource>
|
<file>icons/svg/feedreader.svg</file>
|
||||||
|
<file>icons/svg/filesharing-notify.svg</file>
|
||||||
|
<file>icons/svg/filesharing.svg</file>
|
||||||
|
<file>icons/svg/folders1.svg</file>
|
||||||
|
<file>icons/svg/folders.svg</file>
|
||||||
|
<file>icons/svg/font.svg</file>
|
||||||
|
<file>icons/svg/forums-notify.svg</file>
|
||||||
|
<file>icons/svg/forums.svg</file>
|
||||||
|
<file>icons/svg/fullscreen_arrows.svg</file>
|
||||||
|
<file>icons/svg/highlight.svg</file>
|
||||||
|
<file>icons/svg/info.svg</file>
|
||||||
|
<file>icons/svg/invite.svg</file>
|
||||||
|
<file>icons/svg/keyring.svg</file>
|
||||||
|
<file>icons/svg/leave.svg</file>
|
||||||
|
<file>icons/svg/magnifying-glass.svg</file>
|
||||||
|
<file>icons/svg/messages-notify.svg</file>
|
||||||
|
<file>icons/svg/messages.svg</file>
|
||||||
|
<file>icons/svg/microphone_mute.svg</file>
|
||||||
|
<file>icons/svg/microphone.svg</file>
|
||||||
|
<file>icons/svg/netgraph.svg</file>
|
||||||
|
<file>icons/svg/network-notify.svg</file>
|
||||||
|
<file>icons/svg/network-puplic.svg</file>
|
||||||
|
<file>icons/svg/network.svg</file>
|
||||||
|
<file>icons/svg/newsfeed-notify.svg</file>
|
||||||
|
<file>icons/svg/newsfeed.svg</file>
|
||||||
|
<file>icons/svg/options.svg</file>
|
||||||
|
<file>icons/svg/paste.svg</file>
|
||||||
|
<file>icons/svg/people-notify.svg</file>
|
||||||
|
<file>icons/svg/people.svg</file>
|
||||||
|
<file>icons/svg/person.svg</file>
|
||||||
|
<file>icons/svg/phone_hangup.svg</file>
|
||||||
|
<file>icons/svg/phone.svg</file>
|
||||||
|
<file>icons/svg/posted-notify.svg</file>
|
||||||
|
<file>icons/svg/posted.svg</file>
|
||||||
|
<file>icons/svg/profile.svg</file>
|
||||||
|
<file>icons/svg/retroshare-info.svg</file>
|
||||||
|
<file>icons/svg/retroshare-splash.svg</file>
|
||||||
|
<file>icons/svg/retroshare-symbol_black_bg.svg</file>
|
||||||
|
<file>icons/svg/retroshare-symbol_gradients.svg</file>
|
||||||
|
<file>icons/svg/retroshare-symbol-minimal.svg</file>
|
||||||
|
<file>icons/svg/search.svg</file>
|
||||||
|
<file>icons/svg/send-message-blocked.svg</file>
|
||||||
|
<file>icons/svg/send-message.svg</file>
|
||||||
|
<file>icons/svg/settings.svg</file>
|
||||||
|
<file>icons/svg/share.svg</file>
|
||||||
|
<file>icons/svg/smiley.svg</file>
|
||||||
|
<file>icons/svg/speaker_mute.svg</file>
|
||||||
|
<file>icons/svg/speaker.svg</file>
|
||||||
|
<file>icons/svg/thumbs-down.svg</file>
|
||||||
|
<file>icons/svg/thumbs-neutral.svg</file>
|
||||||
|
<file>icons/svg/thumbs-up.svg</file>
|
||||||
|
<file>icons/svg/upload.svg</file>
|
||||||
|
<file>icons/svg/video.svg</file>
|
||||||
|
<file>icons/switch00_128.png</file>
|
||||||
|
<file>icons/switch01_128.png</file>
|
||||||
|
<file>icons/switch10_128.png</file>
|
||||||
|
<file>icons/switch11_128.png</file>
|
||||||
|
<file>icons/system_128.png</file>
|
||||||
|
<file>icons/tile_checking_48.png</file>
|
||||||
|
<file>icons/tile_downloaded_48.png</file>
|
||||||
|
<file>icons/tile_downloading_48.png</file>
|
||||||
|
<file>icons/tile_inactive_48.png</file>
|
||||||
|
<file>icons/tor-logo.png</file>
|
||||||
|
<file>icons/tor-off.png</file>
|
||||||
|
<file>icons/tor-on.png</file>
|
||||||
|
<file>icons/tor-starting.png</file>
|
||||||
|
<file>icons/tor-stopping.png</file>
|
||||||
|
<file>icons/user-away_64.png</file>
|
||||||
|
<file>icons/user-away-extended_64.png</file>
|
||||||
|
<file>icons/user-busy_64.png</file>
|
||||||
|
<file>icons/user-offline_64.png</file>
|
||||||
|
<file>icons/user-online_64.png</file>
|
||||||
|
<file>icons/void_128.png</file>
|
||||||
|
<file>icons/warning_red_128.png</file>
|
||||||
|
<file>icons/warning_yellow_128.png</file>
|
||||||
|
<file>icons/yahoo.png</file>
|
||||||
|
<file>icons/yandex.png</file>
|
||||||
|
<file>icons/yellow_biohazard64.png</file>
|
||||||
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
BIN
retroshare-gui/src/gui/icons/bullet_green_yellow_star_128.png
Normal file
BIN
retroshare-gui/src/gui/icons/bullet_green_yellow_star_128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
retroshare-gui/src/gui/icons/red_biohazard64.png
Normal file
BIN
retroshare-gui/src/gui/icons/red_biohazard64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.8 KiB |
BIN
retroshare-gui/src/gui/icons/warning_red_128.png
Normal file
BIN
retroshare-gui/src/gui/icons/warning_red_128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
retroshare-gui/src/gui/icons/warning_yellow_128.png
Normal file
BIN
retroshare-gui/src/gui/icons/warning_yellow_128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
@ -42,7 +42,8 @@ bool PeoplePage::save(QString &/*errmsg*/)
|
|||||||
else
|
else
|
||||||
rsReputations->setNodeAutoPositiveOpinionForContacts(false) ;
|
rsReputations->setNodeAutoPositiveOpinionForContacts(false) ;
|
||||||
|
|
||||||
rsReputations->setNodeAutoBanIdentitiesLimit(ui.autoBanIdentitiesLimit_SB->value());
|
rsReputations->setThresholdForRemotelyPositiveReputation(ui.thresholdForPositive_SB->value());
|
||||||
|
rsReputations->setThresholdForRemotelyNegativeReputation(ui.thresholdForNegative_SB->value());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -51,8 +52,10 @@ bool PeoplePage::save(QString &/*errmsg*/)
|
|||||||
void PeoplePage::load()
|
void PeoplePage::load()
|
||||||
{
|
{
|
||||||
bool auto_positive_contacts = rsReputations->nodeAutoPositiveOpinionForContacts() ;
|
bool auto_positive_contacts = rsReputations->nodeAutoPositiveOpinionForContacts() ;
|
||||||
float node_auto_ban_identities_limit = rsReputations->nodeAutoBanIdentitiesLimit();
|
uint32_t threshold_for_positive = rsReputations->thresholdForRemotelyPositiveReputation();
|
||||||
|
uint32_t threshold_for_negative = rsReputations->thresholdForRemotelyNegativeReputation();
|
||||||
|
|
||||||
ui.autoPositiveOpinion_CB->setChecked(auto_positive_contacts);
|
ui.autoPositiveOpinion_CB->setChecked(auto_positive_contacts);
|
||||||
ui.autoBanIdentitiesLimit_SB->setValue(node_auto_ban_identities_limit);
|
ui.thresholdForPositive_SB->setValue(threshold_for_positive);
|
||||||
|
ui.thresholdForNegative_SB->setValue(threshold_for_negative);
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,13 @@
|
|||||||
<height>441</height>
|
<height>441</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="generalGroupBox">
|
<widget class="QGroupBox" name="generalGroupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Identities handling</string>
|
<string>Identities handling</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="autoPositiveOpinion_CB">
|
<widget class="QCheckBox" name="autoPositiveOpinion_CB">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
@ -31,30 +31,44 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item>
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Friend average opinion below which identities are banned:</string>
|
<string>Difference in votes to make friends globally negative:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="1" column="2">
|
||||||
<widget class="QDoubleSpinBox" name="autoBanIdentitiesLimit_SB">
|
<widget class="QSpinBox" name="thresholdForNegative_SB">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>The default value of -0.6 needs 3 to 4 friends to set a negative opinion in order for that identity to be banned at your own node. This is a pretty conservative value. If you want to more easily get rid of banned identities, set the value to e.g. -0.2</p></body></html></string>
|
<string><html><head/><body><p>The default value of -0.6 needs 3 to 4 friends to set a negative opinion in order for that identity to be banned at your own node. This is a pretty conservative value. If you want to more easily get rid of banned identities, set the value to e.g. -0.2</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<double>-1.000000000000000</double>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>-0.010000000000000</double>
|
<number>100</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="singleStep">
|
</widget>
|
||||||
<double>0.010000000000000</double>
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QSpinBox" name="thresholdForPositive_SB">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>The default value of -0.6 needs 3 to 4 friends to set a negative opinion in order for that identity to be banned at your own node. This is a pretty conservative value. If you want to more easily get rid of banned identities, set the value to e.g. -0.2</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="value">
|
<property name="minimum">
|
||||||
<double>-0.600000000000000</double>
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Difference in votes to make friends globally positive:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user