Merge pull request #396 from csoler/v0.6-Circles

V0.6 circles
This commit is contained in:
Cyril Soler 2016-05-27 17:35:23 -04:00
commit dafb2e6bc2
34 changed files with 1565 additions and 925 deletions

View File

@ -187,6 +187,7 @@ void RsGenExchange::tick()
processGroupUpdatePublish();
processGroupDelete();
processMessageDelete();
processRecvdData();
@ -1620,6 +1621,11 @@ void RsGenExchange::deleteGroup(uint32_t& token, RsGxsGrpItem* grpItem)
std::cerr << std::endl;
#endif
}
void RsGenExchange::deleteMsgs(uint32_t& token, const GxsMsgReq& msgs)
{
token = mDataAccess->generatePublicToken();
mMsgDeletePublish.push_back(MsgDeletePublish(msgs, token));
}
void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem)
{
@ -2188,6 +2194,7 @@ void RsGenExchange::processRoutingClues()
mTrackingClues.clear() ;
}
void RsGenExchange::processGroupDelete()
{
RS_STACK_MUTEX(mGenMtx) ;
@ -2234,6 +2241,52 @@ void RsGenExchange::processGroupDelete()
mGroupDeletePublish.clear();
}
void RsGenExchange::processMessageDelete()
{
RS_STACK_MUTEX(mGenMtx) ;
#ifdef TODO
typedef std::pair<bool, RsGxsGroupId> GrpNote;
std::map<uint32_t, GrpNote> toNotify;
#endif
for( std::vector<MsgDeletePublish>::iterator vit = mMsgDeletePublish.begin(); vit != mMsgDeletePublish.end(); ++vit)
{
#ifdef TODO
uint32_t token = (*vit).mToken;
const RsGxsGroupId& groupId = gdp.grpItem->meta.mGroupId;
toNotify.insert(std::make_pair( token, GrpNote(true, groupId)));
#endif
mDataStore->removeMsgs( (*vit).mMsgs );
}
#warning TODO: notify for deleted messages
#ifdef SUSPENDED
std::list<RsGxsGroupId> grpDeleted;
std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
for(; mit != toNotify.end(); ++mit)
{
GrpNote& note = mit->second;
uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
: RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
mGrpNotify.insert(std::make_pair(mit->first, note.second));
mDataAccess->updatePublicRequestStatus(mit->first, status);
if(note.first)
grpDeleted.push_back(note.second);
}
if(!grpDeleted.empty())
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false);
gc->mGrpIdList = grpDeleted;
mNotifications.push_back(gc);
}
#endif
mMsgDeletePublish.clear();
}
bool RsGenExchange::checkKeys(const RsTlvSecurityKeySet& keySet)
{
@ -2957,7 +3010,7 @@ void RsGenExchange::performUpdateValidation()
if(gu.validUpdate)
{
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information

View File

@ -535,6 +535,14 @@ public:
*/
void publishMsg(uint32_t& token, RsGxsMsgItem* msgItem);
/*!
* Deletes the messages \n
* This will induce a related change message \n
* @param token
* @param msgs
*/
void deleteMsgs(uint32_t& token, const GxsMsgReq& msgs);
protected:
/*!
* This represents the group before its signature is calculated
@ -657,6 +665,7 @@ private:
void processGroupUpdatePublish();
void processGroupDelete();
void processMessageDelete();
void processRoutingClues();
void publishMsgs();
@ -869,6 +878,7 @@ private:
std::vector<GroupUpdatePublish> mGroupUpdatePublish;
std::vector<GroupDeletePublish> mGroupDeletePublish;
std::vector<MsgDeletePublish> mMsgDeletePublish;
std::map<RsGxsId,std::set<RsPeerId> > mRoutingClues ;
std::list<std::pair<RsGxsMessageId,RsPeerId> > mTrackingClues ;

View File

@ -213,9 +213,11 @@ class RsGcxs
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id,bool& should_encrypt) = 0;
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>& friendlist) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId>& idlist) = 0;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, std::list<RsGxsId>& idlist) = 0;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, const RsGxsId& id) = 0;
virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) =0;
};

View File

@ -761,7 +761,7 @@ void RsGxsNetService::syncWithPeers()
RsNxsItem *encrypted_item = NULL ;
uint32_t status ;
if(encryptSingleNxsItem(msg, encrypt_to_this_circle_id, encrypted_item, status))
if(encryptSingleNxsItem(msg, encrypt_to_this_circle_id, grpId, encrypted_item, status))
sendItem(encrypted_item) ;
else
std::cerr << "(WW) could not encrypt for circle ID " << encrypt_to_this_circle_id << ". Not yet in cache?" << std::endl;
@ -1270,7 +1270,7 @@ bool RsGxsNetService::locked_createTransactionFromPending(GrpCircleIdRequestVett
RsNxsItem *encrypted_item = NULL ;
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
if(encryptSingleNxsItem(gItem, entry.mCircleId, encrypted_item,status))
if(encryptSingleNxsItem(gItem, entry.mCircleId, entry.mGroupId,encrypted_item,status))
{
itemL.push_back(encrypted_item) ;
delete gItem ;
@ -1321,7 +1321,7 @@ bool RsGxsNetService::locked_createTransactionFromPending(MsgCircleIdsRequestVet
RsNxsItem *encrypted_item = NULL ;
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
if(encryptSingleNxsItem(mItem,msgPend->mCircleId,encrypted_item,status))
if(encryptSingleNxsItem(mItem,msgPend->mCircleId,msgPend->mGrpId,encrypted_item,status))
{
itemL.push_back(encrypted_item) ;
delete mItem ;
@ -3665,7 +3665,7 @@ bool RsGxsNetService::locked_addTransaction(NxsTransaction* tr)
// Returns false when the keys are not loaded. Question to solve: what do we do if we miss some keys??
// We should probably send anyway.
bool RsGxsNetService::encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, RsNxsItem *&encrypted_item, uint32_t& status)
bool RsGxsNetService::encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, const RsGxsGroupId& destination_group, RsNxsItem *&encrypted_item, uint32_t& status)
{
encrypted_item = NULL ;
status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
@ -3678,7 +3678,7 @@ bool RsGxsNetService::encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId&
std::list<RsGxsId> recipients ;
if(!mCircles->recipients(destination_circle,recipients))
if(!mCircles->recipients(destination_circle,destination_group,recipients))
{
std::cerr << " (EE) Cannot encrypt transaction: recipients list not available. Should re-try later." << std::endl;
status = RS_NXS_ITEM_ENCRYPTION_STATUS_CIRCLE_ERROR ;
@ -4048,7 +4048,7 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrpReqItem *item)
RsNxsItem *encrypted_item = NULL ;
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
if(encryptSingleNxsItem(gItem, grpMeta->mCircleId, encrypted_item,status))
if(encryptSingleNxsItem(gItem, grpMeta->mCircleId,mit->first, encrypted_item,status))
{
itemL.push_back(encrypted_item) ;
delete gItem ;
@ -4158,7 +4158,7 @@ bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpM
#endif
}
if(circleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
if(circleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId)<< " YOUREYESONLY, checking further"<< std::endl;
@ -4222,125 +4222,125 @@ bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpM
return true;
}
bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& grpMeta, RsGxsCircleId &should_encrypt_id)
bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& grpMeta, RsGxsCircleId& should_encrypt_id)
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::checkCanRecvMsgFromPeer()";
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " peer Id = " << sslId << ", grpId=" << grpMeta.mGroupId <<std::endl;
#endif
// first do the simple checks
uint8_t circleType = grpMeta.mCircleType;
should_encrypt_id.clear() ;
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::checkCanRecvMsgFromPeer()";
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " peer Id = " << sslId << ", grpId=" << grpMeta.mGroupId <<std::endl;
#endif
// first do the simple checks
uint8_t circleType = grpMeta.mCircleType;
should_encrypt_id.clear() ;
if(circleType == GXS_CIRCLE_TYPE_LOCAL)
if(circleType == GXS_CIRCLE_TYPE_LOCAL)
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " LOCAL_CIRCLE, cannot request sync from peer" << std::endl;
#endif
return false;
}
if(circleType == GXS_CIRCLE_TYPE_PUBLIC)
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " PUBLIC_CIRCLE, can request msg sync" << std::endl;
#endif
return true;
}
if(circleType == GXS_CIRCLE_TYPE_EXTERNAL)
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: EXTERNAL => returning true. Msgs will be encrypted." << std::endl;
#endif
should_encrypt_id = grpMeta.mCircleId ;
return true ;
#ifdef TO_BE_REMOVED_OLD_VETTING_FOR_EXTERNAL_CIRCLES
const RsGxsCircleId& circleId = grpMeta.mCircleId;
if(circleId.isNull())
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " LOCAL_CIRCLE, cannot request sync from peer" << std::endl;
#endif
return false;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " ERROR; EXTERNAL_CIRCLE missing NULL CircleId";
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << grpMeta.mGroupId;
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << std::endl;
#endif
// should just be shared. ? no - this happens for
// Circle Groups which lose their CircleIds.
// return true;
}
if(circleType == GXS_CIRCLE_TYPE_PUBLIC)
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " PUBLIC_CIRCLE, can request msg sync" << std::endl;
#endif
return true;
}
if(circleType == GXS_CIRCLE_TYPE_EXTERNAL)
if(mCircles->isLoaded(circleId))
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: EXTERNAL => returning true. Msgs will be encrypted." << std::endl;
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " EXTERNAL_CIRCLE, checking mCircles->canSend" << std::endl;
#endif
should_encrypt_id = grpMeta.mCircleId ;
return true ;
#ifdef TO_BE_REMOVED_OLD_VETTING_FOR_EXTERNAL_CIRCLES
const RsGxsCircleId& circleId = grpMeta.mCircleId;
if(circleId.isNull())
{
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " ERROR; EXTERNAL_CIRCLE missing NULL CircleId";
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << grpMeta.mGroupId;
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << std::endl;
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
return mCircles->canSend(circleId, pgpId);
}
else
mCircles->loadCircle(circleId); // simply request for next pass
return false;
#endif
}
if(circleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY) // do not attempt to sync msg unless to originator or those permitted
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " YOUREYESONLY, checking further" << std::endl;
#endif
// a non empty internal circle id means this
// is the personal circle owner
if(!grpMeta.mInternalCircle.isNull())
{
const RsGxsCircleId& internalCircleId = grpMeta.mInternalCircle;
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " have mInternalCircle - we are Group creator" << std::endl;
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " mCircleId: " << grpMeta.mCircleId << std::endl;
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " mInternalCircle: " << grpMeta.mInternalCircle << std::endl;
#endif
// should just be shared. ? no - this happens for
// Circle Groups which lose their CircleIds.
// return true;
}
if(mCircles->isLoaded(circleId))
if(mCircles->isLoaded(internalCircleId))
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " EXTERNAL_CIRCLE, checking mCircles->canSend" << std::endl;
#endif
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " circle Loaded - checking mCircles->canSend" << std::endl;
#endif
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
return mCircles->canSend(circleId, pgpId);
bool should_encrypt ;
return mCircles->canSend(internalCircleId, pgpId,should_encrypt);
}
else
mCircles->loadCircle(circleId); // simply request for next pass
mCircles->loadCircle(internalCircleId); // request for next pass
return false;
#endif
}
if(circleType == GXS_CIRCLE_TYPE_YOUREYESONLY) // do not attempt to sync msg unless to originator or those permitted
else
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " YOUREYESONLY, checking further" << std::endl;
#endif
// a non empty internal circle id means this
// is the personal circle owner
if(!grpMeta.mInternalCircle.isNull())
// an empty internal circle id means this peer can only
// send circle related info from peer he received it
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " mInternalCircle not set, someone else's personal circle" << std::endl;
#endif
if(grpMeta.mOriginator == sslId)
{
const RsGxsCircleId& internalCircleId = grpMeta.mInternalCircle;
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " have mInternalCircle - we are Group creator" << std::endl;
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " mCircleId: " << grpMeta.mCircleId << std::endl;
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " mInternalCircle: " << grpMeta.mInternalCircle << std::endl;
#endif
if(mCircles->isLoaded(internalCircleId))
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " circle Loaded - checking mCircles->canSend" << std::endl;
#endif
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
bool should_encrypt ;
return mCircles->canSend(internalCircleId, pgpId,should_encrypt);
}
else
mCircles->loadCircle(internalCircleId); // request for next pass
return false;
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Originator matches -> can send" << std::endl;
#endif
return true;
}
else
{
// an empty internal circle id means this peer can only
// send circle related info from peer he received it
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " mInternalCircle not set, someone else's personal circle" << std::endl;
#endif
if(grpMeta.mOriginator == sslId)
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Originator matches -> can send" << std::endl;
#endif
return true;
}
else
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Originator doesn't match -> cannot send"<< std::endl;
#endif
return false;
}
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Originator doesn't match -> cannot send"<< std::endl;
#endif
return false;
}
}
}
return true;
return true;
}
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem *item)
@ -4471,7 +4471,7 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
RsNxsItem *encrypted_item = NULL ;
uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ;
if(encryptSingleNxsItem(mItem, grpMeta->mCircleId, encrypted_item,status))
if(encryptSingleNxsItem(mItem, grpMeta->mCircleId,m->mGroupId, encrypted_item,status))
{
itemL.push_back(encrypted_item) ;
delete mItem ;
@ -4619,7 +4619,7 @@ bool RsGxsNetService::canSendMsgIds(std::vector<RsGxsMsgMetaData*>& msgMetas, co
++i ;
else
{
if(mCircles->isLoaded(circleId) && mCircles->isRecipient(circleId, msgMetas[i]->mAuthorId))
if(mCircles->isLoaded(circleId) && mCircles->isRecipient(circleId, grpMeta.mGroupId, msgMetas[i]->mAuthorId))
{
++i ;
continue ;
@ -4645,7 +4645,7 @@ bool RsGxsNetService::canSendMsgIds(std::vector<RsGxsMsgMetaData*>& msgMetas, co
return true ;
}
if(circleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
if(circleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: YOUR EYES ONLY" << std::endl;

View File

@ -454,7 +454,7 @@ private:
/*!
* encrypts/decrypts the transaction for the destination circle id.
*/
bool encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, RsNxsItem *& encrypted_item, uint32_t &status) ;
bool encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, const RsGxsGroupId &destination_group, RsNxsItem *& encrypted_item, uint32_t &status) ;
bool decryptSingleNxsItem(const RsNxsEncryptedDataItem *encrypted_item, RsNxsItem *&nxsitem, std::vector<RsTlvSecurityKey> *private_keys=NULL);
bool processTransactionForDecryption(NxsTransaction *tr); // return false when the keys are not loaded => need retry later

View File

@ -291,7 +291,7 @@ bool MsgCircleIdsRequestVetting::cleared()
}
for(uint32_t i=0;i<mMsgs.size();)
if(!mCircles->isRecipient(mCircleId,mMsgs[i].mAuthorId))
if(!mCircles->isRecipient(mCircleId,mGrpId,mMsgs[i].mAuthorId))
{
std::cerr << "(WW) MsgCircleIdsRequestVetting::cleared() filtering out message " << mMsgs[i].mMsgId << " because it's signed by author " << mMsgs[i].mAuthorId << " which is not in circle " << mCircleId << std::endl;

View File

@ -162,4 +162,15 @@ public:
uint32_t mToken;
};
class MsgDeletePublish
{
public:
MsgDeletePublish(const GxsMsgReq& msgs, uint32_t token)
: mMsgs(msgs), mToken(token) {}
GxsMsgReq mMsgs ;
uint32_t mToken;
};
#endif /* GXSUTIL_H_ */

View File

@ -121,13 +121,13 @@ std::string PGPKeyParser::extractRadixPartFromArmouredKey(const std::string& pgp
std::string PGPKeyManagement::makeArmouredKey(const unsigned char *keydata,size_t key_size,const std::string& version_string)
{
std::string outstring ;
Radix64::encode((const char *)keydata,key_size,outstring) ;
Radix64::encode(keydata,key_size,outstring) ;
uint32_t crc = compute24bitsCRC((unsigned char *)keydata,key_size) ;
unsigned char tmp[3] = { uint8_t((crc >> 16) & 0xff), uint8_t((crc >> 8) & 0xff), uint8_t(crc & 0xff) } ;
std::string crc_string ;
Radix64::encode((const char *)tmp,3,crc_string) ;
Radix64::encode(tmp,3,crc_string) ;
#ifdef DEBUG_PGPUTIL
std::cerr << "After signature pruning: " << std::endl;

View File

@ -109,7 +109,7 @@ std::string RsCertificate::toStdString() const
std::string out_string ;
Radix64::encode((char *)buf, p, out_string) ;
Radix64::encode(buf, p, out_string) ;
// Now slice up to 64 chars.
//

View File

@ -48,18 +48,25 @@ class RsGxsCircles;
extern RsGxsCircles *rsGxsCircles;
typedef RsPgpId RsPgpId;
//typedef RsGxsCircleId RsCircleInternalId;
#define GXS_CIRCLE_TYPE_PUBLIC 0x0001
#define GXS_CIRCLE_TYPE_EXTERNAL 0x0002
#define GXS_CIRCLE_TYPE_YOUREYESONLY 0x0003
#define GXS_CIRCLE_TYPE_LOCAL 0x0004
// The meaning of the different circle types is:
//
//
static const uint32_t GXS_CIRCLE_TYPE_PUBLIC = 0x0001 ; // not restricted to a circle
static const uint32_t GXS_CIRCLE_TYPE_EXTERNAL = 0x0002 ; // restricted to an external circle, made of RsGxsId
static const uint32_t GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY = 0x0003 ; // restricted to a subset of friend nodes of a given RS node given by a RsPgpId list
static const uint32_t GXS_CIRCLE_TYPE_LOCAL = 0x0004 ; // not distributed at all
static const uint32_t GXS_CIRCLE_TYPE_EXT_SELF = 0x0005 ; // self-restricted. Not used, except at creation time when the circle ID isn't known yet. Set to EXTERNAL afterwards.
static const uint32_t GXS_CIRCLE_TYPE_YOUR_EYES_ONLY = 0x0006 ; // distributed to nodes signed by your own PGP key only.
// A special one - used only by Circles themselves - meaning Circle ID == Group ID.
#define GXS_CIRCLE_TYPE_EXT_SELF 0x0005
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST = 0x0001 ;// user is validated by circle admin
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED = 0x0002 ;// user has subscribed the group
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_KEY_AVAILABLE = 0x0004 ;// key is available, so we can encrypt for this circle
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_ALLOWED = 0x0007 ;// user is allowed. Combines all flags above.
/* Permissions is part of GroupMetaData
*/
static const uint32_t GXS_CIRCLE_FLAGS_IS_EXTERNAL = 0x0008 ;// user is allowed
/* Permissions is part of GroupMetaData */
class GxsPermissions
{
@ -72,7 +79,6 @@ public:
RsGxsCircleId mInternalCircle; // if Originator == ownId, otherwise blank.
};
class RsGxsCircleGroup
{
public:
@ -100,37 +106,19 @@ class RsGxsCircleMsg
class RsGxsCircleDetails
{
public:
RsGxsCircleDetails() : mCircleType(GXS_CIRCLE_TYPE_EXTERNAL), mIsExternal(true), mAmIAllowed(false) {}
RsGxsCircleDetails() : mCircleType(GXS_CIRCLE_TYPE_EXTERNAL), mAmIAllowed(false) {}
RsGxsCircleId mCircleId;
std::string mCircleName;
uint32_t mCircleType;
bool mIsExternal;
bool mAmIAllowed ;
bool mAmIAllowed ; // true when one of load GXS ids belong to the circle allowed list (admin list & subscribed list).
bool operator ==(const RsGxsCircleDetails& rGxsDetails) {
return ( mCircleId == rGxsDetails.mCircleId
&& mCircleName == rGxsDetails.mCircleName
&& mCircleType == rGxsDetails.mCircleType
&& mIsExternal == rGxsDetails.mIsExternal
&& mAllowedAnonPeers == rGxsDetails.mAllowedAnonPeers
&& mAllowedSignedPeers == rGxsDetails.mAllowedSignedPeers
);
}
bool operator !=(const RsGxsCircleDetails& rGxsDetails) {
return ( mCircleId != rGxsDetails.mCircleId
|| mCircleName != rGxsDetails.mCircleName
|| mCircleType != rGxsDetails.mCircleType
|| mIsExternal != rGxsDetails.mIsExternal
|| mAllowedAnonPeers != rGxsDetails.mAllowedAnonPeers
|| mAllowedSignedPeers != rGxsDetails.mAllowedSignedPeers
);
}
std::set<RsGxsId> mAllowedAnonPeers;
std::map<RsPgpId, std::set<RsGxsId> > mAllowedSignedPeers;
std::set<RsGxsId> mAllowedGxsIds; // This crosses admin list and subscribed list
std::set<RsPgpId> mAllowedNodes;
std::map<RsGxsId,uint32_t> mSubscriptionFlags ; // subscription flags for all ids
};
class RsGxsCircles: public RsGxsIfaceHelper
@ -147,6 +135,11 @@ virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &detai
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
/* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
virtual bool cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
/* standard load */
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;

View File

@ -235,6 +235,7 @@ virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details) = 0;
// Fills up list of all own ids. Returns false if ids are not yet loaded.
virtual bool getOwnIds(std::list<RsGxsId> &ownIds) = 0;
virtual bool isOwnId(const RsGxsId& id) = 0;
//
virtual bool submitOpinion(uint32_t& token, const RsGxsId &id,

View File

@ -1083,12 +1083,12 @@ bool p3Peers::GetPGPBase64StringAndCheckSum( const RsPgpId& gpg_id,
if(!AuthGPG::getAuthGPG()->exportPublicKey(gpg_id,mem_block,mem_block_size,false,false))
return false ;
Radix64::encode((const char *)mem_block,mem_block_size,gpg_base64_string) ;
Radix64::encode(mem_block,mem_block_size,gpg_base64_string) ;
uint32_t crc = PGPKeyManagement::compute24bitsCRC((unsigned char *)mem_block,mem_block_size) ;
unsigned char tmp[3] = { uint8_t((crc >> 16) & 0xff), uint8_t((crc >> 8) & 0xff), uint8_t(crc & 0xff) } ;
Radix64::encode((const char *)tmp,3,gpg_base64_checksum) ;
Radix64::encode(tmp,3,gpg_base64_checksum) ;
delete[] mem_block ;

View File

@ -1345,15 +1345,13 @@ int RsServer::StartupRetroShare()
mGxsCircles, mGxsCircles->getServiceInfo(),
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils,
true,false); // synchronise group automatic
// don't sync messages at all.
true, // synchronise group automatic
true); // sync messages automatic, since they contain subscription requests.
mGxsCircles->setNetworkExchangeService(gxscircles_ns) ;
/**** Posted GXS service ****/
RsGeneralDataService* posted_ds = new RsDataService(currGxsDir + "/", "posted_db",
RS_SERVICE_GXS_TYPE_POSTED,
NULL, rsInitConfig->gxs_passwd);

View File

@ -35,6 +35,7 @@ uint32_t RsGxsCircleSerialiser::size(RsItem *item)
{
RsGxsCircleGroupItem* grp_item = NULL;
RsGxsCircleMsgItem* snap_item = NULL;
RsGxsCircleSubscriptionRequestItem* subr_item = NULL;
if((grp_item = dynamic_cast<RsGxsCircleGroupItem*>(item)) != NULL)
{
@ -43,6 +44,10 @@ uint32_t RsGxsCircleSerialiser::size(RsItem *item)
else if((snap_item = dynamic_cast<RsGxsCircleMsgItem*>(item)) != NULL)
{
return sizeGxsCircleMsgItem(snap_item);
}
else if((subr_item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(item)) != NULL)
{
return sizeGxsCircleSubscriptionRequestItem(subr_item);
}
else
return 0 ;
@ -52,6 +57,7 @@ bool RsGxsCircleSerialiser::serialise(RsItem *item, void *data, uint32_t *size)
{
RsGxsCircleGroupItem* grp_item = NULL;
RsGxsCircleMsgItem* snap_item = NULL;
RsGxsCircleSubscriptionRequestItem* subr_item = NULL;
if((grp_item = dynamic_cast<RsGxsCircleGroupItem*>(item)) != NULL)
{
@ -61,6 +67,10 @@ bool RsGxsCircleSerialiser::serialise(RsItem *item, void *data, uint32_t *size)
{
return serialiseGxsCircleMsgItem(snap_item, data, size);
}
else if((subr_item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(item)) != NULL)
{
return serialiseGxsCircleSubscriptionRequestItem(subr_item, data, size);
}
return false;
}
@ -73,8 +83,7 @@ RsItem* RsGxsCircleSerialiser::deserialise(void* data, uint32_t* size)
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_GXS_TYPE_GXSCIRCLE != getRsItemService(rstype)))
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_GXS_TYPE_GXSCIRCLE != getRsItemService(rstype)))
{
return NULL; /* wrong type */
}
@ -88,6 +97,9 @@ RsItem* RsGxsCircleSerialiser::deserialise(void* data, uint32_t* size)
case RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM:
return deserialiseGxsCircleMsgItem(data, size);
break;
case RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM:
return deserialiseGxsCircleSubscriptionRequestItem(data, size);
break;
default:
#ifdef CIRCLE_DEBUG
std::cerr << "RsGxsCircleSerialiser::deserialise(): unknown subtype";
@ -104,6 +116,25 @@ RsItem* RsGxsCircleSerialiser::deserialise(void* data, uint32_t* size)
/*****************************************************************************************/
/*****************************************************************************************/
void RsGxsCircleSubscriptionRequestItem::clear()
{
time_stamp = 0 ;
time_out = 0 ;
subscription_type = SUBSCRIPTION_REQUEST_UNKNOWN;
}
std::ostream& RsGxsCircleSubscriptionRequestItem::print(std::ostream& out, uint16_t indent)
{
printRsItemBase(out, "RsGxsCircleSubscriptionRequestItem", indent);
uint16_t int_Indent = indent + 2;
printRsItemBase(out, "time stmp: ", indent); out << time_stamp ;
printRsItemBase(out, "time out : ", indent); out << time_out ;
printRsItemBase(out, "Subs type: ", indent); out << subscription_type ;
printRsItemEnd(out ,"RsGxsCircleSubscriptionRequestItem", indent);
return out;
}
void RsGxsCircleGroupItem::clear()
{
@ -176,6 +207,16 @@ std::ostream& RsGxsCircleGroupItem::print(std::ostream& out, uint16_t indent)
return out;
}
uint32_t RsGxsCircleSerialiser::sizeGxsCircleSubscriptionRequestItem(RsGxsCircleSubscriptionRequestItem * /* item */)
{
uint32_t s=8 ; // header
s += 4 ; // time_stamp serialised as uint32_t;
s += 4 ; // time_out serialised as uint32_t;
s += 1 ; // subscription_type ;
return s ;
}
uint32_t RsGxsCircleSerialiser::sizeGxsCircleGroupItem(RsGxsCircleGroupItem *item)
{
@ -188,6 +229,54 @@ uint32_t RsGxsCircleSerialiser::sizeGxsCircleGroupItem(RsGxsCircleGroupItem *ite
return s;
}
bool RsGxsCircleSerialiser::serialiseGxsCircleSubscriptionRequestItem(RsGxsCircleSubscriptionRequestItem *item, void *data, uint32_t *size)
{
#ifdef CIRCLE_DEBUG
std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleSubscriptionRequestItem()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsCircleSubscriptionRequestItem(item);
uint32_t offset = 0;
if(*size < tlvsize)
{
#ifdef CIRCLE_DEBUG
std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleSubscriptionRequestItem()" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* GxsCircleGroupItem */
ok &= setRawUInt32(data,tlvsize,&offset,item->time_stamp) ;
ok &= setRawUInt32(data,tlvsize,&offset,item->time_out) ;
ok &= setRawUInt8(data,tlvsize,&offset,item->subscription_type) ;
if(offset != tlvsize)
{
//#ifdef CIRCLE_DEBUG
std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleSubscriptionRequestItem() FAIL Size Error! " << std::endl;
//#endif
ok = false;
}
//#ifdef CIRCLE_DEBUG
if (!ok)
std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleSubscriptionRequestItem() NOK" << std::endl;
//#endif
return ok;
}
bool RsGxsCircleSerialiser::serialiseGxsCircleGroupItem(RsGxsCircleGroupItem *item, void *data, uint32_t *size)
{
@ -238,6 +327,72 @@ bool RsGxsCircleSerialiser::serialiseGxsCircleGroupItem(RsGxsCircleGroupItem *it
return ok;
}
RsGxsCircleSubscriptionRequestItem *RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem(void *data, uint32_t *size)
{
#ifdef CIRCLE_DEBUG
std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_GXS_TYPE_GXSCIRCLE != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM != getRsItemSubType(rstype)))
{
#ifdef CIRCLE_DEBUG
std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef CIRCLE_DEBUG
std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsCircleSubscriptionRequestItem* item = new RsGxsCircleSubscriptionRequestItem();
/* skip the header */
offset += 8;
uint32_t tmp ;
ok &= getRawUInt32(data,rssize,&offset,&tmp) ; item->time_stamp = tmp ;
ok &= getRawUInt32(data,rssize,&offset,&tmp) ; item->time_out = tmp ;
ok &= getRawUInt8(data,rssize,&offset,&item->subscription_type) ;
if (offset != rssize)
{
#ifdef CIRCLE_DEBUG
std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef CIRCLE_DEBUG
std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}
RsGxsCircleGroupItem* RsGxsCircleSerialiser::deserialiseGxsCircleGroupItem(void *data, uint32_t *size)
{

View File

@ -37,13 +37,16 @@
#include "rsgxsitems.h"
#include "retroshare/rsgxscircles.h"
const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM = 0x02;
const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM = 0x03;
const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM = 0x02;
const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM = 0x03;
const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM = 0x04;
const uint16_t GXSCIRCLE_PGPIDSET = 0x0001;
const uint16_t GXSCIRCLE_GXSIDSET = 0x0002;
const uint16_t GXSCIRCLE_SUBCIRCLESET = 0x0003;
// These classes are a mess. Needs proper item serialisation etc.
class RsGxsCircleGroupItem : public RsGxsGrpItem
{
@ -83,6 +86,27 @@ public:
RsGxsCircleMsg msg;
};
class RsGxsCircleSubscriptionRequestItem: public RsGxsMsgItem
{
public:
RsGxsCircleSubscriptionRequestItem() : RsGxsMsgItem(RS_SERVICE_GXS_TYPE_GXSCIRCLE, RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM) { }
virtual ~RsGxsCircleSubscriptionRequestItem() {}
void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
enum {
SUBSCRIPTION_REQUEST_UNKNOWN = 0x00,
SUBSCRIPTION_REQUEST_SUBSCRIBE = 0x01,
SUBSCRIPTION_REQUEST_UNSUBSCRIBE = 0x02
};
time_t time_stamp ;
time_t time_out ;
uint8_t subscription_type ;
};
class RsGxsCircleSerialiser : public RsSerialType
{
public:
@ -98,6 +122,10 @@ public:
private:
uint32_t sizeGxsCircleSubscriptionRequestItem(RsGxsCircleSubscriptionRequestItem *item);
bool serialiseGxsCircleSubscriptionRequestItem (RsGxsCircleSubscriptionRequestItem *item, void *data, uint32_t *size);
RsGxsCircleSubscriptionRequestItem * deserialiseGxsCircleSubscriptionRequestItem(void *data, uint32_t *size);
uint32_t sizeGxsCircleGroupItem(RsGxsCircleGroupItem *item);
bool serialiseGxsCircleGroupItem (RsGxsCircleGroupItem *item, void *data, uint32_t *size);
RsGxsCircleGroupItem * deserialiseGxsCircleGroupItem(void *data, uint32_t *size);

View File

@ -993,7 +993,7 @@ std::string SSGxsChannelGroup::save() const
if(!mDownloadDirectory.empty())
{
std::string encoded_str ;
Radix64::encode(mDownloadDirectory.c_str(),mDownloadDirectory.length(),encoded_str);
Radix64::encode((unsigned char*)mDownloadDirectory.c_str(),mDownloadDirectory.length(),encoded_str);
output += " {P:" + encoded_str + "}";
}

File diff suppressed because it is too large Load Diff

View File

@ -124,6 +124,15 @@
/* Permissions is part of GroupMetaData
*/
class RsGxsCircleMembershipStatus
{
public:
RsGxsCircleMembershipStatus() : last_subscription_TS(0), subscription_flags(0) {}
time_t last_subscription_TS ;
uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED
};
class RsGxsCircleCache
{
public:
@ -134,8 +143,8 @@ class RsGxsCircleCache
bool getAllowedPeersList(std::list<RsPgpId> &friendlist) const;
bool isAllowedPeer(const RsPgpId &id) const;
bool isAllowedPeer(const RsGxsId &id) const;
bool addAllowedPeer(const RsPgpId &pgpid, const RsGxsId &gxsId);
bool isAllowedPeer(const RsGxsId &id, const RsGxsGroupId &destination_group) const;
bool addAllowedPeer(const RsPgpId &pgpid);
bool addLocalFriend(const RsPgpId &pgpid);
RsGxsCircleId mCircleId;
@ -143,7 +152,6 @@ class RsGxsCircleCache
uint32_t mCircleType;
bool mIsExternal;
bool mAmIAllowed ;
uint32_t mGroupStatus;
uint32_t mGroupSubscribeFlags;
@ -153,10 +161,11 @@ class RsGxsCircleCache
std::set<RsGxsCircleId> mUnprocessedCircles;
std::set<RsGxsCircleId> mProcessedCircles;
#endif
std::set<RsGxsId> mUnprocessedPeers;
std::map<RsGxsId,RsGxsCircleMembershipStatus> mMembershipStatus;
time_t mLastUpdatedMembershipTS ; // last time the subscribe messages have been requested. Should be reset when new messages arrive.
std::set<RsGxsId> mAllowedAnonPeers;
std::map<RsPgpId, std::set<RsGxsId> > mAllowedSignedPeers;
std::set<RsGxsId> mAllowedGxsIds; // IDs that are allowed in the circle and have requested membership. This is the official members list.
std::set<RsPgpId> mAllowedNodes;
RsPeerId mOriginator ; // peer who sent the data, in case we need to ask for ids
};
@ -164,12 +173,10 @@ class RsGxsCircleCache
class PgpAuxUtils;
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
public GxsTokenQueue, public RsTickEvent
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles, public GxsTokenQueue, public RsTickEvent
{
public:
p3GxsCircles(RsGeneralDataService* gds, RsNetworkExchangeService* nes,
p3IdService *identities, PgpAuxUtils *pgpUtils);
p3GxsCircles(RsGeneralDataService* gds, RsNetworkExchangeService* nes, p3IdService *identities, PgpAuxUtils *pgpUtils);
virtual RsServiceInfo getServiceInfo();
@ -184,9 +191,10 @@ virtual RsServiceInfo getServiceInfo();
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool &should_encrypt);
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id);
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) ;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId> &gxs_ids) ;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id) ;
virtual bool recipients(const RsGxsCircleId &circleId, const RsGxsGroupId& dest_group, std::list<RsGxsId> &gxs_ids) ;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, const RsGxsId& id) ;
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups);
@ -194,6 +202,11 @@ virtual RsServiceInfo getServiceInfo();
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group);
/* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) ;
virtual bool cancelCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) ;
/**********************************************/
// needed for background processing.
@ -201,6 +214,7 @@ virtual RsServiceInfo getServiceInfo();
protected:
bool pushCircleMembershipRequest(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id,uint32_t request_type) ;
static uint32_t circleAuthenPolicy();
/** Notifications **/
@ -220,6 +234,7 @@ virtual RsServiceInfo getServiceInfo();
// Load data.
bool request_CircleIdList();
bool load_CircleIdList(uint32_t token);
bool processMembershipRequests(uint32_t token);
// Need some crazy arsed cache to store the circle info.
// so we don't have to keep loading groups.
@ -232,8 +247,11 @@ virtual RsServiceInfo getServiceInfo();
bool cache_load_for_token(uint32_t token);
bool cache_reloadids(const RsGxsCircleId &circleId);
bool checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache);
bool checkCircleCacheForMembershipUpdate();
bool locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache);
bool locked_processLoadingCacheEntry(RsGxsCircleCache &cache);
bool locked_checkCircleCacheForMembershipUpdate(RsGxsCircleCache &cache);
p3IdService *mIdentities; // Needed for constructing Circle Info,
PgpAuxUtils *mPgpUtils;
@ -270,12 +288,11 @@ virtual RsServiceInfo getServiceInfo();
void checkDummyIdData();
void generateDummyCircle();
time_t mLastCacheMembershipUpdateTS ;
uint32_t mDummyIdToken;
std::list<RsGxsId> mDummyPgpLinkedIds;
std::list<RsGxsId> mDummyOwnIds;
};
#endif // P3_CIRCLES_SERVICE_HEADER

View File

@ -101,7 +101,7 @@ again:
/****************
* create a radix64 encoded string.
*/
static void encode(const char *data,int len,std::string& out_string)
static void encode(const unsigned char *data,int len,std::string& out_string)
{
char *buffer, *p;

View File

@ -486,7 +486,9 @@ bool RsRecogn::itemToRadix64(RsItem *item, std::string &radstr)
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
RsTemporaryMemory buf(len) ;
if (!serialiser.serialise(item, buf, &len))
{
return false;
@ -609,7 +611,7 @@ bool RsRecogn::createTagRequest(const RsTlvSecurityKey &key, const RsGxsId &id,
/* write out the item for signing */
RsGxsRecognSerialiser serialiser;
uint32_t len = serialiser.size(item);
char *buf = new char[len];
RsTemporaryMemory buf(len) ;
bool serOk = serialiser.serialise(item, buf, &len);
if (serOk)
@ -617,8 +619,6 @@ bool RsRecogn::createTagRequest(const RsTlvSecurityKey &key, const RsGxsId &id,
Radix64::encode(buf, len, tag);
}
delete []buf;
if (!serOk)
{
#ifdef DEBUG_RECOGN

View File

@ -315,7 +315,7 @@ void mark_circle_item(QTreeWidgetItem *item, const std::set<RsPgpId> &names)
std::set<RsPgpId>::iterator it;
for(it = names.begin(); it != names.end(); ++it)
{
if (details.mAllowedSignedPeers.end() != details.mAllowedSignedPeers.find(*it))
if (details.mAllowedNodes.end() != details.mAllowedNodes.find(*it))
{
set_item_background(item, GREEN_BACKGROUND);
std::cerr << "CirclesDialog mark_circle_item: found match: " << id;
@ -387,15 +387,7 @@ void CirclesDialog::circle_selected()
if (rsGxsCircles->getCircleDetails(id, details))
{
/* now mark all the members */
std::set<RsPgpId> members;
for( std::map<RsPgpId, std::set<RsGxsId> >::iterator it = details.mAllowedSignedPeers.begin(); it != details.mAllowedSignedPeers.end(); ++it)
{
members.insert(it->first);
std::cerr << "Circle member: " << it->first;
std::cerr << std::endl;
}
mark_matching_tree(ui.treeWidget_friends, members, CIRCLEGROUP_FRIEND_COL_ID, GREEN_BACKGROUND);
mark_matching_tree(ui.treeWidget_friends, details.mAllowedNodes, CIRCLEGROUP_FRIEND_COL_ID, GREEN_BACKGROUND);
}
else
{

View File

@ -300,8 +300,8 @@ void CreateCircleDialog::addMember(const QString& keyId, const QString& idtype,
void CreateCircleDialog::addCircle(const RsGxsCircleDetails &cirDetails)
{
typedef std::set<RsGxsId>::iterator itUnknownPeers;
for (itUnknownPeers it = cirDetails.mAllowedAnonPeers.begin()
; it != cirDetails.mAllowedAnonPeers.end()
for (itUnknownPeers it = cirDetails.mAllowedGxsIds.begin()
; it != cirDetails.mAllowedGxsIds.end()
; ++it) {
RsGxsId gxs_id = *it;
RsIdentityDetails gxs_details ;
@ -316,10 +316,10 @@ void CreateCircleDialog::addCircle(const RsGxsCircleDetails &cirDetails)
}//if(!gxs_id.isNull() && rsIdentity->getIdDetails(gxs_id,gxs_details))
}//for (itUnknownPeers it = cirDetails.mUnknownPeers.begin()
typedef std::map<RsPgpId, std::set<RsGxsId> >::const_iterator itAllowedPeers;
for (itAllowedPeers it = cirDetails.mAllowedSignedPeers.begin() ; it != cirDetails.mAllowedSignedPeers.end() ; ++it )
typedef std::set<RsPgpId>::const_iterator itAllowedPeers;
for (itAllowedPeers it = cirDetails.mAllowedNodes.begin() ; it != cirDetails.mAllowedNodes.end() ; ++it )
{
RsPgpId gpg_id = it->first;
RsPgpId gpg_id = *it;
RsPeerDetails details ;
if(!gpg_id.isNull() && rsPeers->getGPGDetails(gpg_id,details)) {

View File

@ -14,16 +14,7 @@
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
@ -53,7 +44,7 @@
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Circle Members</string>
<string>Invited Members</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
@ -155,16 +146,7 @@
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item>
@ -341,16 +323,7 @@
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>2</number>
</property>
<item row="0" column="0">

View File

@ -57,9 +57,10 @@
#define IDDIALOG_REPLIST 3
#define IDDIALOG_REFRESH 4
#define CIRCLEGROUP_CIRCLE_COL_GROUPNAME 0
#define CIRCLEGROUP_CIRCLE_COL_GROUPID 1
#define CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS 2
#define CIRCLEGROUP_CIRCLE_COL_GROUPNAME 0
#define CIRCLEGROUP_CIRCLE_COL_GROUPID 1
#define CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS 2
#define CIRCLEGROUP_CIRCLE_COL_SUBSCRIBEFLAGS 3
#define CIRCLEGROUP_FRIEND_COL_NAME 0
#define CIRCLEGROUP_FRIEND_COL_ID 1
@ -95,6 +96,11 @@
#define IMAGE_EDIT ":/images/edit_16.png"
#define IMAGE_CREATE ":/icons/circle_new_128.png"
#define IMAGE_INVITED ":/icons/bullet_yellow_128.png"
#define IMAGE_MEMBER ":/icons/bullet_green_128.png"
// comment this out in order to remove the sorting of circles into "belong to" and "other visible circles"
#define CIRCLE_MEMBERSHIP_CATEGORIES 1
// quick solution for RSID_COL_VOTES sorting
class TreeWidgetItem : public QTreeWidgetItem {
@ -141,7 +147,7 @@ IdDialog::IdDialog(QWidget *parent) :
ui->treeWidget_membership->clear();
mExternalOtherCircleItem = NULL ;
mExternalSubCircleItem = NULL ;
mExternalBelongingCircleItem = NULL ;
/* Setup UI helper */
mStateHelper = new UIStateHelper(this);
@ -231,7 +237,7 @@ IdDialog::IdDialog(QWidget *parent) :
/* Set initial section sizes */
QHeaderView * circlesheader = ui->treeWidget_membership->header () ;
circlesheader->resizeSection (CIRCLEGROUP_CIRCLE_COL_GROUPNAME, 280);
circlesheader->resizeSection (CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QFontMetricsF(ui->idTreeWidget->font()).width("Circle name")*1.5) ;
ui->filterLineEdit->addFilter(QIcon(), tr("ID"), RSID_COL_KEYID, tr("Search ID"));
@ -260,14 +266,20 @@ IdDialog::IdDialog(QWidget *parent) :
QString hlp_str = tr(
" <h1><img width=\"32\" src=\":/icons/help_64.png\">&nbsp;&nbsp;Identities</h1> \
<p>In this tab you can create/edit pseudo-anonymous identities.</p> \
<p>Identities are used to securely identify your data: sign forum and channel posts,\
and receive feedback using Retroshare built-in email system, post comments \
after channel posts, etc.</p> \
<p>Identities can optionally be signed by your Retroshare node's certificate. \
<p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> \
<p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts,\
receive feedback using the Retroshare built-in email system, post comments \
after channel posts, chat using secured tunnels, etc.</p> \
<p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. \
Signed identities are easier to trust but are easily linked to your node's IP address.</p> \
<p> Anonymous identities allow you to anonymously interact with other users. They cannot be \
spoofed, but noone can prove who really owns a given identity.</p>") ;
<p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be \
spoofed, but noone can prove who really owns a given identity.</p> \
<p><b>External circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be \
used to restrict the visibility to forums, channels, etc. </p> \
<p>An <b>external circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle \
or even self-restricted, meaning that it is only visible to its members.</p> \
<p>A <b>local circle</b> is a group of friend nodes (represented by their PGP Ids), and can also be used to restrict the \
visibility of forums and channels. They are not shared over the network, and their list of members is only visible to you.</p>") ;
registerHelpButton(ui->helpButton, hlp_str) ;
@ -276,7 +288,7 @@ IdDialog::IdDialog(QWidget *parent) :
// circles stuff
connect(ui->treeWidget_membership, SIGNAL(itemSelectionChanged()), this, SLOT(circle_selected()));
//connect(ui->treeWidget_membership, SIGNAL(itemSelectionChanged()), this, SLOT(circle_selected()));
connect(ui->treeWidget_membership, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CircleListCustomPopupMenu(QPoint)));
@ -291,7 +303,7 @@ IdDialog::IdDialog(QWidget *parent) :
QTimer *tmer = new QTimer(this) ;
connect(tmer,SIGNAL(timeout()),this,SLOT(updateCirclesDisplay())) ;
tmer->start(10000) ; // update every minute.
tmer->start(10000) ; // update every 10 secs.
}
void IdDialog::updateCirclesDisplay()
@ -315,10 +327,10 @@ void IdDialog::requestCircleGroupMeta()
{
mStateHelper->setLoading(CIRCLESDIALOG_GROUPMETA, true);
//#ifdef ID_DEBUG
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::requestGroupMeta()";
std::cerr << std::endl;
//#endif
#endif
mCircleQueue->cancelActiveRequestTokens(CIRCLESDIALOG_GROUPMETA);
@ -352,163 +364,284 @@ void IdDialog::requestCircleGroupData(const RsGxsCircleId& circle_id)
void IdDialog::loadCircleGroupMeta(const uint32_t &token)
{
mStateHelper->setLoading(CIRCLESDIALOG_GROUPMETA, false);
mStateHelper->setLoading(CIRCLESDIALOG_GROUPMETA, false);
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::loadCircleGroupMeta()";
std::cerr << std::endl;
std::cerr << "CirclesDialog::loadCircleGroupMeta()";
std::cerr << std::endl;
#endif
std::list<RsGroupMetaData> groupInfo;
std::list<RsGroupMetaData>::iterator vit;
std::list<RsGroupMetaData> groupInfo;
std::list<RsGroupMetaData>::iterator vit;
if (!rsGxsCircles->getGroupSummary(token,groupInfo))
{
std::cerr << "CirclesDialog::loadCircleGroupMeta() Error getting GroupMeta";
std::cerr << std::endl;
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, false);
return;
}
if (!rsGxsCircles->getGroupSummary(token,groupInfo))
{
std::cerr << "CirclesDialog::loadCircleGroupMeta() Error getting GroupMeta";
std::cerr << std::endl;
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, false);
return;
}
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true);
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true);
/* add the top level item */
//QTreeWidgetItem *personalCirclesItem = new QTreeWidgetItem();
//personalCirclesItem->setText(0, tr("Personal Circles"));
//ui->treeWidget_membership->addTopLevelItem(personalCirclesItem);
/* add the top level item */
//QTreeWidgetItem *personalCirclesItem = new QTreeWidgetItem();
//personalCirclesItem->setText(0, tr("Personal Circles"));
//ui->treeWidget_membership->addTopLevelItem(personalCirclesItem);
if(!mExternalOtherCircleItem)
{
mExternalOtherCircleItem = new QTreeWidgetItem();
mExternalOtherCircleItem->setText(0, tr("Other visible circles"));
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
if(!mExternalOtherCircleItem)
{
mExternalOtherCircleItem = new QTreeWidgetItem();
mExternalOtherCircleItem->setText(0, tr("Other visible external circles"));
ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem);
}
ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem);
}
if(!mExternalSubCircleItem )
{
mExternalSubCircleItem = new QTreeWidgetItem();
mExternalSubCircleItem->setText(0, tr("Circles I belong to"));
ui->treeWidget_membership->addTopLevelItem(mExternalSubCircleItem);
}
if(!mExternalBelongingCircleItem )
{
mExternalBelongingCircleItem = new QTreeWidgetItem();
mExternalBelongingCircleItem->setText(0, tr("External circles my identities belong to"));
ui->treeWidget_membership->addTopLevelItem(mExternalBelongingCircleItem);
}
#endif
if(!mExternalLocalCircleItem)
{
mExternalLocalCircleItem = new QTreeWidgetItem();
mExternalLocalCircleItem->setText(0, tr("Local circles"));
ui->treeWidget_membership->addTopLevelItem(mExternalLocalCircleItem);
}
std::list<RsGxsId> own_identities ;
rsIdentity->getOwnIds(own_identities) ;
for(vit = groupInfo.begin(); vit != groupInfo.end();++vit)
{
for(vit = groupInfo.begin(); vit != groupInfo.end();++vit)
{
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::loadCircleGroupMeta() GroupId: " << vit->mGroupId << " Group: " << vit->mGroupName << std::endl;
std::cerr << "CirclesDialog::loadCircleGroupMeta() GroupId: " << vit->mGroupId << " Group: " << vit->mGroupName << std::endl;
#endif
RsGxsCircleDetails details;
rsGxsCircles->getCircleDetails(RsGxsCircleId(vit->mGroupId), details) ;
RsGxsCircleDetails details;
rsGxsCircles->getCircleDetails(RsGxsCircleId(vit->mGroupId), details) ;
bool should_re_add = true ;
bool am_I_in_circle = details.mAmIAllowed ;
QTreeWidgetItem *item = NULL ;
bool should_re_add = true ;
bool subscribed = vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ;
bool am_I_in_circle = details.mAmIAllowed ;
QTreeWidgetItem *item = NULL ;
#ifdef ID_DEBUG
std::cerr << "Loaded info for circle " << vit->mGroupId << ". ubscribed=" << subscribed << ", am_I_in_circle=" << am_I_in_circle << std::endl;
std::cerr << "Loaded info for circle " << vit->mGroupId << ". am_I_in_circle=" << am_I_in_circle << std::endl;
#endif
// find already existing items for this circle
// find already existing items for this circle
QList<QTreeWidgetItem*> clist = ui->treeWidget_membership->findItems( QString::fromStdString(vit->mGroupId.toStdString()), Qt::MatchExactly|Qt::MatchRecursive, CIRCLEGROUP_CIRCLE_COL_GROUPID);
// implement the search manually, because there's no find based on user role.
//QList<QTreeWidgetItem*> clist = ui->treeWidget_membership->findItems( QString::fromStdString(vit->mGroupId.toStdString()), Qt::MatchExactly|Qt::MatchRecursive, CIRCLEGROUP_CIRCLE_COL_GROUPID);
QList<QTreeWidgetItem*> clist ;
QString test_str = QString::fromStdString(vit->mGroupId.toStdString()) ;
for(QTreeWidgetItemIterator itt(ui->treeWidget_membership);*itt;++itt)
if( (*itt)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString() == test_str)
clist.push_back(*itt) ;
if(!clist.empty())
{
// delete all duplicate items. This should not happen, but just in case it does.
if(!clist.empty())
{
// delete all duplicate items. This should not happen, but just in case it does.
while(clist.size() > 1)
{
while(clist.size() > 1)
{
#ifdef ID_DEBUG
std::cerr << " more than 1 item correspond to this ID. Removing!" << std::endl;
std::cerr << " more than 1 item correspond to this ID. Removing!" << std::endl;
#endif
delete clist.front() ;
}
delete clist.front() ;
}
item = clist.front() ;
item = clist.front() ;
if(am_I_in_circle && item->parent() != mExternalSubCircleItem)
{
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
if(am_I_in_circle && item->parent() != mExternalBelongingCircleItem)
{
#ifdef ID_DEBUG
std::cerr << " Existing group is not in subscribed items although it is subscribed. Removing." << std::endl;
std::cerr << " Existing circle is not in subscribed items although it is subscribed. Removing." << std::endl;
#endif
delete item ;
item = NULL ;
}
else if(!am_I_in_circle && item->parent() != mExternalOtherCircleItem)
{
delete item ;
item = NULL ;
}
else if(!am_I_in_circle && item->parent() != mExternalOtherCircleItem)
{
#ifdef ID_DEBUG
std::cerr << " Existing group is not in subscribed items although it is subscribed. Removing." << std::endl;
std::cerr << " Existing circle is not in subscribed items although it is subscribed. Removing." << std::endl;
#endif
delete item ;
item = NULL ;
}
else
should_re_add = false ; // item already exists
}
delete item ;
item = NULL ;
}
else
#endif
should_re_add = false ; // item already exists
}
// if (vit->mCircleType == GXS_CIRCLE_TYPE_LOCAL)
// {
// std::cerr << "(WW) Local circle not added to tree widget. Needs to be implmeented." << std::endl;
// continue ;
// }
/* Add Widget, and request Pages */
/* Add Widget, and request Pages */
if(should_re_add)
{
item = new QTreeWidgetItem();
if(should_re_add)
{
item = new QTreeWidgetItem();
item->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(vit->mGroupName.c_str()));
item->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, QString::fromStdString(vit->mGroupId.toStdString()));
item->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(vit->mSubscribeFlags));
item->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(vit->mGroupName.c_str()));
item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("Circle ID: ")+QString::fromStdString(vit->mGroupId.toStdString()));
item->setData(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole, QString::fromStdString(vit->mGroupId.toStdString()));
item->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(vit->mSubscribeFlags));
#warning TODO
//item->setData(CIRCLEGROUP_CIRCLE_COL_SUBSCRIBEFLAGS, Qt::UserRole, QVariant(details.mSubscribeFlags));
if(am_I_in_circle)
{
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
if(am_I_in_circle)
{
#ifdef ID_DEBUG
std::cerr << " adding item for group " << vit->mGroupId << " to own circles"<< std::endl;
std::cerr << " adding item for circle " << vit->mGroupId << " to own circles"<< std::endl;
#endif
mExternalSubCircleItem->addChild(item);
}
else
{
mExternalBelongingCircleItem->addChild(item);
}
else
{
#ifdef ID_DEBUG
std::cerr << " adding item for group " << vit->mGroupId << " to others"<< std::endl;
std::cerr << " adding item for circle " << vit->mGroupId << " to others"<< std::endl;
#endif
mExternalOtherCircleItem->addChild(item);
}
}
else if(item->text(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) != QString::fromUtf8(vit->mGroupName.c_str()))
{
mExternalOtherCircleItem->addChild(item);
}
#else
ui->treeWidget_membership->addTopLevelItem(item) ;
#endif
}
else if(item->text(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) != QString::fromUtf8(vit->mGroupName.c_str()))
{
#ifdef ID_DEBUG
std::cerr << " Existing group has a new name. Updating it in the tree." << std::endl;
std::cerr << " Existing circle has a new name. Updating it in the tree." << std::endl;
#endif
item->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(vit->mGroupName.c_str()));
}
item->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(vit->mGroupName.c_str()));
}
// just in case.
item->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(vit->mSubscribeFlags));
#warning TODO
//item->setData(CIRCLEGROUP_CIRCLE_COL_SUBSCRIBEFLAGS, Qt::UserRole, QVariant(details.mSubscribeFlags));
if (vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
{
QFont font = item->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ;
font.setBold(true) ;
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ;
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ;
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ;
}
// now determine for this circle wether we have pending invites
// we add a sub-item to the circle (to show the invite system info) in the following two cases:
// - own GXS id is in admin list but not subscribed
// - own GXS id is is admin and subscribed
// - own GXS id is is subscribed
bool am_I_invited = false ;
bool am_I_pending = false ;
#ifdef ID_DEBUG
std::cerr << " updating status of all identities for this circle:" << std::endl;
#endif
//for(std::list<RsGxsId>::const_iterator it(own_identities.begin());it!=own_identities.end();++it)
for(std::map<RsGxsId,uint32_t>::const_iterator it(details.mSubscriptionFlags.begin());it!=details.mSubscriptionFlags.end();++it)
{
#ifdef ID_DEBUG
std::cerr << " ID " << *it << ": " ;
#endif
bool is_own_id = rsIdentity->isOwnId(it->first) ;
bool invited ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST );
bool subscrb ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED );
#ifdef ID_DEBUG
std::cerr << "invited: " << invited << ", subscription: " << subscrb ;
#endif
QTreeWidgetItem *subitem = NULL ;
// see if the item already exists
for(uint32_t k=0;k<item->childCount();++k)
if(item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString() == it->first.toStdString())
{
subitem = item->child(k);
#ifdef ID_DEBUG
std::cerr << " found existing sub item." << std::endl;
#endif
break ;
}
if(!(invited || subscrb))
{
if(subitem != NULL)
delete subitem ;
#ifdef ID_DEBUG
std::cerr << ". not relevant. Skipping." << std::endl;
#endif
continue ;
}
// remove item if flags are not ok.
if (vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
{
QFont font = item->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ;
font.setBold(true) ;
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ;
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ;
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ;
}
if(subitem && subitem->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt() != it->second)
{
delete subitem ;
subitem = NULL ;
}
if(!subitem)
{
#ifdef ID_DEBUG
if (subscribed)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_green_128.png")) ;
else
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_yellow_128.png")) ;
std::cerr << " no existing sub item. Creating new one." << std::endl;
#endif
}
subitem = new QTreeWidgetItem(item);
RsIdentityDetails idd ;
bool has_id = rsIdentity->getIdDetails(it->first,idd) ;
QPixmap pixmap ;
if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG"))
pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(it->first)) ;
if(has_id)
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(idd.mNickname.c_str())) ;
else
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Unknown ID :")+QString::fromStdString(it->first.toStdString())) ;
subitem->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Indentity ID: ")+QString::fromStdString(it->first.toStdString())) ;
subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(it->second)) ;
subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPID, Qt::UserRole, QString::fromStdString(it->first.toStdString())) ;
subitem->setIcon(RSID_COL_NICKNAME, QIcon(pixmap));
item->addChild(subitem) ;
}
if(invited && !subscrb)
{
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Invited")) ;
if(is_own_id)
am_I_invited = true ;
}
if(!invited && subscrb)
{
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Subscription pending")) ;
if(is_own_id)
am_I_pending = true ;
}
if(invited && subscrb)
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Member")) ;
if (is_own_id)
{
QFont font = subitem->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ;
font.setBold(true) ;
subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ;
subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ;
subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ;
}
}
if(am_I_in_circle)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_MEMBER)) ;
else if(am_I_invited || am_I_pending)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_INVITED)) ;
else
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon()) ;
}
}
static void mark_matching_tree(QTreeWidget *w, const std::set<RsGxsId>& members, int col)
@ -550,11 +683,9 @@ void IdDialog::loadCircleGroupData(const uint32_t& token)
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
if ((!item) || (!item->parent()))
return;
QString coltext = item->text(CIRCLEGROUP_CIRCLE_COL_GROUPID);
RsGxsCircleId id ( coltext.toStdString()) ;
RsGxsCircleId id ;
if(!getItemCircleId(item,id))
return ;
if(requested_cid != id)
{
@ -571,6 +702,24 @@ void IdDialog::loadCircleGroupData(const uint32_t& token)
mStateHelper->setLoading(CIRCLESDIALOG_GROUPDATA, false);
}
bool IdDialog::getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id)
{
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
if ((!item) || (!item->parent()))
return false;
QString coltext = (item->parent()->parent())? (item->parent()->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString()) : (item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString());
id = RsGxsCircleId( coltext.toStdString()) ;
#else
if(!item)
return false;
QString coltext = (item->parent())? (item->parent()->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString()) : (item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString());
id = RsGxsCircleId( coltext.toStdString()) ;
#endif
return true ;
}
void IdDialog::createExternalCircle()
{
CreateCircleDialog dlg;
@ -581,45 +730,189 @@ void IdDialog::createExternalCircle()
}
void IdDialog::showEditExistingCircle()
{
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
if ((!item) || (!item->parent()))
{
return;
}
RsGxsCircleId id ;
uint32_t subscribe_flags = item->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),id))
return ;
uint32_t subscribe_flags = ui->treeWidget_membership->currentItem()->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
QString coltext = item->text(CIRCLEGROUP_CIRCLE_COL_GROUPID);
RsGxsGroupId id ( coltext.toStdString());
CreateCircleDialog dlg;
CreateCircleDialog dlg;
dlg.editExistingId(id,true,!(subscribe_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) ;
dlg.exec();
dlg.editExistingId(RsGxsGroupId(id),true,!(subscribe_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) ;
dlg.exec();
requestCircleGroupMeta(); // update GUI
}
void IdDialog::acceptCircleSubscription()
{
RsGxsCircleId circle_id ;
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
return;
RsGxsId own_id(qobject_cast<QAction*>(sender())->data().toString().toStdString());
rsGxsCircles->requestCircleMembership(own_id,circle_id) ;
}
void IdDialog::cancelCircleSubscription()
{
RsGxsCircleId circle_id ;
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
return;
RsGxsId own_id(qobject_cast<QAction*>(sender())->data().toString().toStdString());
rsGxsCircles->cancelCircleMembership(own_id,circle_id) ;
}
void IdDialog::CircleListCustomPopupMenu( QPoint )
{
QMenu contextMnu( this );
QMenu contextMnu( this );
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
RsGxsCircleId circle_id ;
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
if(!getItemCircleId(item,circle_id))
return ;
RsGxsId current_gxs_id ;
RsGxsId item_id(item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString());
bool is_circle ;
contextMnu.addAction(QIcon(IMAGE_CREATE), tr("Create Circle"), this, SLOT(createExternalCircle()));
if(item_id == RsGxsId(circle_id)) // is it a circle?
{
uint32_t group_flags = item->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
if(item->parent() != NULL)
{
#endif
if(group_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
contextMnu.addAction(QIcon(IMAGE_EDIT), tr("Edit Circle"), this, SLOT(showEditExistingCircle()));
else
contextMnu.addAction(QIcon(IMAGE_EDIT), tr("See details"), this, SLOT(showEditExistingCircle()));
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
}
#endif
if (item)
{
uint32_t subscribe_flags = item->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
std::cerr << " Item is a circle item. Adding Edit/Details menu entry." << std::endl;
is_circle = true ;
if(item->parent() != NULL)
if(subscribe_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
contextMnu.addAction(QIcon(IMAGE_EDIT), tr("Edit Circle"), this, SLOT(showEditExistingCircle()));
else
contextMnu.addAction(QIcon(IMAGE_EDIT), tr("See details"), this, SLOT(showEditExistingCircle()));
}
contextMnu.addSeparator() ;
}
else if(rsIdentity->isOwnId(item_id)) // is it one of our GXS ids?
{
current_gxs_id = RsGxsId(item_id);
is_circle =false ;
std::cerr << " Item is a GxsId item. Requesting flags/group id from parent: " << circle_id << std::endl;
}
RsGxsCircleDetails details ;
contextMnu.exec(QCursor::pos());
if(!rsGxsCircles->getCircleDetails(circle_id,details))// grab real circle ID from parent. Make sure circle id is used correctly afterwards!
{
std::cerr << " (EE) cannot get circle info for ID " << circle_id << ". Not in cache?" << std::endl;
return ;
}
static const int REQUES = 0 ; // Admin list: no Subscription request: no
static const int ACCEPT = 1 ; // Admin list: yes Subscription request: no
static const int REMOVE = 2 ; // Admin list: yes Subscription request: yes
static const int CANCEL = 3 ; // Admin list: no Subscription request: yes
const QString menu_titles[4] = { tr("Request subscription"), tr("Accept circle invitation"), tr("Quit this circle"),tr("Cancel subscribe request")} ;
const QString image_names[4] = { ":/images/edit_16.png",":/images/edit_16.png",":/images/edit_16.png",":/images/edit_16.png" } ;
std::vector< std::vector<RsGxsId> > ids(4) ;
std::list<RsGxsId> own_identities ;
rsIdentity->getOwnIds(own_identities) ;
// policy is:
// - if on a circle item
// => add possible subscription requests for all ids
// - if on a Id item
// => only add subscription requests for that ID
for(std::list<RsGxsId>::const_iterator it(own_identities.begin());it!=own_identities.end();++it)
if(is_circle || current_gxs_id == *it)
{
std::map<RsGxsId,uint32_t>::const_iterator vit = details.mSubscriptionFlags.find(*it) ;
uint32_t subscribe_flags = (vit == details.mSubscriptionFlags.end())?0:(vit->second) ;
if(subscribe_flags & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED)
if(subscribe_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST)
ids[REMOVE].push_back(*it) ;
else
ids[CANCEL].push_back(*it) ;
else
if(subscribe_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST)
ids[ACCEPT].push_back(*it) ;
else
ids[REQUES].push_back(*it) ;
}
contextMnu.addSeparator() ;
for(int i=0;i<4;++i)
{
if(ids[i].size() == 1)
{
RsIdentityDetails det ;
QString id_name ;
if(rsIdentity->getIdDetails(ids[i][0],det))
id_name = tr("for identity ")+QString::fromUtf8(det.mNickname.c_str()) + "(ID=" + QString::fromStdString(ids[i][0].toStdString()) + ")" ;
else
id_name = tr("for identity ")+QString::fromStdString(ids[i][0].toStdString()) ;
QAction *action ;
if(is_circle)
action = new QAction(QIcon(image_names[i]), menu_titles[i] + " " + id_name,this) ;
else
action = new QAction(QIcon(image_names[i]), menu_titles[i],this) ;
if(i <2)
QObject::connect(action,SIGNAL(triggered()), this, SLOT(acceptCircleSubscription()));
else
QObject::connect(action,SIGNAL(triggered()), this, SLOT(cancelCircleSubscription()));
action->setData(QString::fromStdString(ids[i][0].toStdString()));
contextMnu.addAction(action) ;
}
else if(ids[i].size() > 1)
{
QMenu *menu = new QMenu(menu_titles[i],this) ;
for(uint32_t j=0;j<ids[i].size();++j)
{
RsIdentityDetails det ;
QString id_name ;
if(rsIdentity->getIdDetails(ids[i][j],det))
id_name = tr("for identity ")+QString::fromUtf8(det.mNickname.c_str()) + "(ID=" + QString::fromStdString(ids[i][j].toStdString()) + ")" ;
else
id_name = tr("for identity ")+QString::fromStdString(ids[i][j].toStdString()) ;
QAction *action = new QAction(QIcon(image_names[i]), id_name,this) ;
if(i <2)
QObject::connect(action,SIGNAL(triggered()), this, SLOT(acceptCircleSubscription()));
else
QObject::connect(action,SIGNAL(triggered()), this, SLOT(cancelCircleSubscription()));
action->setData(QString::fromStdString(ids[i][j].toStdString()));
menu->addAction(action) ;
}
contextMnu.addMenu(menu) ;
}
}
contextMnu.exec(QCursor::pos());
}
static void set_item_background(QTreeWidgetItem *item, uint32_t type)
@ -690,7 +983,7 @@ static void check_mark_item(QTreeWidgetItem *item, const std::set<RsPgpId> &name
std::cerr << std::endl;
}
}
#endif
void IdDialog::circle_selected()
{
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
@ -699,32 +992,14 @@ void IdDialog::circle_selected()
std::cerr << "CirclesDialog::circle_selected() valid circle chosen";
std::cerr << std::endl;
#endif
if ((!item) || (!item->parent()))
{
//mStateHelper->setWidgetEnabled(ui->pushButton_editCircle, false);
//ui->pushButton_editCircle->setText(tr("Show details")) ;
//ui->pushButton_editCircle->setEnabled(false) ;
mark_matching_tree(ui->idTreeWidget, std::set<RsGxsId>(), RSID_COL_KEYID) ;
return;
}
#ifdef TO_REMOVE
uint32_t subscribe_flags = item->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
ui->pushButton_editCircle->setEnabled(true) ;
if(subscribe_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
ui->pushButton_editCircle->setText(tr("Edit circle")) ;
else
ui->pushButton_editCircle->setText(tr("Show details")) ;
#endif
//set_item_background(item, BLUE_BACKGROUND);
QString coltext = item->text(CIRCLEGROUP_CIRCLE_COL_GROUPID);
QString coltext = (item->parent()->parent())? (item->parent()->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString()) : (item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString());
RsGxsCircleId id ( coltext.toStdString()) ;
requestCircleGroupData(id) ;
}
#endif
IdDialog::~IdDialog()
{

View File

@ -61,11 +61,15 @@ protected:
void requestCircleGroupMeta();
void requestCircleGroupData(const RsGxsCircleId& circle_id);
bool getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id) ;
private slots:
void createExternalCircle();
void showEditExistingCircle();
void updateCirclesDisplay();
void acceptCircleSubscription() ;
void cancelCircleSubscription() ;
void filterComboBoxChanged();
void filterChanged(const QString &text);
@ -85,7 +89,9 @@ private slots:
void IdListCustomPopupMenu( QPoint point );
void CircleListCustomPopupMenu(QPoint point) ;
#ifdef SUSPENDED
void circle_selected() ;
#endif
void addtoContacts();
void removefromContacts();
@ -124,9 +130,8 @@ private:
QTreeWidgetItem *contactsItem;
QTreeWidgetItem *allItem;
QTreeWidgetItem *ownItem;
QTreeWidgetItem *mExternalSubCircleItem;
QTreeWidgetItem *mExternalBelongingCircleItem;
QTreeWidgetItem *mExternalOtherCircleItem;
QTreeWidgetItem *mExternalLocalCircleItem;
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
RsGxsGroupId mId;

View File

@ -20,16 +20,7 @@
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@ -47,16 +38,7 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>2</number>
</property>
<item>
@ -147,16 +129,7 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>1</number>
</property>
<item>
@ -284,7 +257,7 @@
<string>Reputation</string>
</property>
<property name="textAlignment">
<set>AlignLeading|AlignVCenter</set>
<set>AlignLeft|AlignVCenter</set>
</property>
</column>
</widget>
@ -361,16 +334,7 @@
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>6</number>
</property>
<property name="spacing">
@ -544,16 +508,7 @@
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>6</number>
</property>
<item row="2" column="1">
@ -730,12 +685,12 @@ p, li { white-space: pre-wrap; }
</property>
<column>
<property name="text">
<string>Name</string>
<string>Circle name</string>
</property>
</column>
<column>
<property name="text">
<string>IDs</string>
<string>Membership</string>
</property>
</column>
<item>

View File

@ -38,6 +38,17 @@ CircleWidget::~CircleWidget()
delete ui;
}
static bool same_RsGxsCircleDetails(const RsGxsCircleDetails& d1,const RsGxsCircleDetails& d2)
{
return ( d1.mCircleId == d2.mCircleId
&& d1.mCircleName == d2.mCircleName
&& d1.mCircleType == d2.mCircleType
&& d1.mSubscriptionFlags == d2.mSubscriptionFlags
&& d1.mAllowedGxsIds== d2.mAllowedGxsIds
&& d1.mAllowedNodes == d2.mAllowedNodes
);
}
void CircleWidget::updateData(const RsGroupMetaData& gxs_group_info
, const RsGxsCircleDetails& details)
{
@ -49,40 +60,40 @@ void CircleWidget::updateData(const RsGroupMetaData& gxs_group_info
ui->label->setText(m_myName);
ui->label->setToolTip(m_myName);
update();
//}//if (_group_info != gxs_group_info)
//}
if (_circle_details != details) {
if(!same_RsGxsCircleDetails(_circle_details , details))
{
_circle_details=details;
typedef std::set<RsGxsId>::iterator itUnknownPeers;
for (itUnknownPeers it = _circle_details.mAllowedAnonPeers.begin()
; it != _circle_details.mAllowedAnonPeers.end()
for (itUnknownPeers it = _circle_details.mAllowedGxsIds.begin()
; it != _circle_details.mAllowedGxsIds.end()
; ++it) {
RsGxsId gxs_id = *it;
if(!gxs_id.isNull()) {
emit askForGXSIdentityWidget(gxs_id);
}//if(!gxs_id.isNull())
}//for (itUnknownPeers it = _circle_details.mUnknownPeers.begin()
}
}
typedef std::map<RsPgpId, std::set<RsGxsId> >::const_iterator itAllowedPeers;
for (itAllowedPeers it = _circle_details.mAllowedSignedPeers.begin() ; it != _circle_details.mAllowedSignedPeers.end() ; ++it )
typedef std::set<RsPgpId>::const_iterator itAllowedPeers;
for (itAllowedPeers it = _circle_details.mAllowedNodes.begin() ; it != _circle_details.mAllowedNodes.end() ; ++it )
{
RsPgpId pgp_id = it->first;
RsPgpId pgp_id = *it;
emit askForPGPIdentityWidget(pgp_id);
std::set<RsGxsId> gxs_id_list = it->second;
typedef std::set<RsGxsId>::const_iterator itGxsId;
for (itGxsId curs=gxs_id_list.begin()
; curs != gxs_id_list.end()
; ++curs) {
RsGxsId gxs_id = *curs;
if(!gxs_id.isNull()) {
emit askForGXSIdentityWidget(gxs_id);
}//if(!gxs_id.isNull())
}//for (itGxsId curs=gxs_id_list.begin()
}//for (itAllowedPeers it = _circle_details.mAllowedPeers.begin()
// std::set<RsGxsId> gxs_id_list = it->second;
// typedef std::set<RsGxsId>::const_iterator itGxsId;
// for (itGxsId curs=gxs_id_list.begin(); curs != gxs_id_list.end(); ++curs)
// {
// RsGxsId gxs_id = *curs;
// if(!gxs_id.isNull())
// emit askForGXSIdentityWidget(gxs_id);
// }
// }
}
update();
}//if (details!=_circle_details)
}
}
QSize CircleWidget::sizeHint()

View File

@ -286,7 +286,7 @@ void PeopleDialog::insertCircles(uint32_t token)
continue ;
}//if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(git->mGroupId), details))
if (!details.mIsExternal){
if (details.mCircleType != GXS_CIRCLE_TYPE_EXTERNAL){
std::map<RsGxsGroupId, CircleWidget*>::iterator itFound;
if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end()) {
std::cerr << "PeopleDialog::insertExtCircles() add new Internal GroupId: " << gsItem.mGroupId;

View File

@ -441,7 +441,7 @@ void GxsGroupDialog::updateFromExistingMeta(const QString &description)
switch(mGrpMeta.mCircleType)
{
case GXS_CIRCLE_TYPE_YOUREYESONLY:
case GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY:
ui.typeLocal->setChecked(true);
distribution_string = tr("Your friends only") ;
ui.localComboBox->loadCircles(GXS_CIRCLE_CHOOSER_PERSONAL, mGrpMeta.mInternalCircle);
@ -740,7 +740,7 @@ bool GxsGroupDialog::setCircleParameters(RsGroupMetaData &meta)
}
else if (ui.typeLocal->isChecked())
{
meta.mCircleType = GXS_CIRCLE_TYPE_YOUREYESONLY;
meta.mCircleType = GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY;
meta.mCircleId.clear();
meta.mOriginator.clear();
meta.mInternalCircle.clear() ;

View File

@ -288,7 +288,7 @@ void GxsChannelPostsWidget::insertChannelDetails(const RsGxsChannelGroup &group)
distrib_string = tr("Restricted to members of circle ")+QString::fromStdString(group.mMeta.mCircleId.toStdString()) ;
}
break ;
case GXS_CIRCLE_TYPE_YOUREYESONLY: distrib_string = tr("Your eyes only");
case GXS_CIRCLE_TYPE_YOUR_EYES_ONLY: distrib_string = tr("Your eyes only");
break ;
case GXS_CIRCLE_TYPE_LOCAL: distrib_string = tr("You and your friend nodes");
break ;

View File

@ -817,7 +817,7 @@ void GxsForumThreadWidget::insertGroupData()
distrib_string = tr("Restricted to members of circle ")+QString::fromStdString(group.mMeta.mCircleId.toStdString()) ;
}
break ;
case GXS_CIRCLE_TYPE_YOUREYESONLY: distrib_string = tr("Your eyes only");
case GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY: distrib_string = tr("Your eyes only");
break ;
case GXS_CIRCLE_TYPE_LOCAL: distrib_string = tr("You and your friend nodes");
break ;

View File

@ -10,6 +10,7 @@
<file>icons/blank_green_128.png</file>
<file>icons/browsable_blue_128.png</file>
<file>icons/browsable_green_128.png</file>
<file>icons/bullet_blue_128.png</file>
<file>icons/bullet_green_128.png</file>
<file>icons/bullet_grey_128.png</file>
<file>icons/bullet_red_128.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -214,7 +214,7 @@ bool GxsPeerNode::createIdentity(const std::string &name,
switch(circleType)
{
case GXS_CIRCLE_TYPE_YOUREYESONLY:
case GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY:
id.mMeta.mInternalCircle = circleId;
break;
case GXS_CIRCLE_TYPE_LOCAL:
@ -283,7 +283,7 @@ bool GxsPeerNode::createCircle(const std::string &name,
// THIS is for LOCAL Storage....
grp1.mLocalFriends = localMembers;
break;
case GXS_CIRCLE_TYPE_YOUREYESONLY:
case GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY:
// Circle shouldn't use this.
// but could potentially.
grp1.mMeta.mInternalCircle = circleId;
@ -343,7 +343,7 @@ bool GxsPeerNode::createGroup(const std::string &name,
switch(circleType)
{
case GXS_CIRCLE_TYPE_YOUREYESONLY:
case GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY:
grp1.mMeta.mInternalCircle = circleId;
break;
case GXS_CIRCLE_TYPE_LOCAL: