diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 468792b18..cb50aceb6 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -61,7 +61,7 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key #define GXS_MASK "GXS_MASK_HACK" -//#define GEN_EXCH_DEBUG 1 +#define GEN_EXCH_DEBUG 1 #define MSG_CLEANUP_PERIOD 60*5 // 5 minutes #define INTEGRITY_CHECK_PERIOD 60*30 // 30 minutes diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 5f6dcd7c3..f7e282e10 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -100,11 +100,14 @@ class RsGxsCircleMsg class RsGxsCircleDetails { public: + RsGxsCircleDetails() : mCircleType(GXS_CIRCLE_TYPE_EXTERNAL), mIsExternal(true), mAmIAllowed(false) {} + RsGxsCircleId mCircleId; std::string mCircleName; uint32_t mCircleType; bool mIsExternal; + bool mAmIAllowed ; bool operator ==(const RsGxsCircleDetails& rGxsDetails) { return ( mCircleId == rGxsDetails.mCircleId diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index d70e4cd3e..408bf40ae 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -37,6 +37,7 @@ /**** * #define DEBUG_CIRCLES 1 ****/ +#define DEBUG_CIRCLES 1 RsGxsCircles *rsGxsCircles = NULL; @@ -270,6 +271,8 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails details.mAllowedAnonPeers = data.mAllowedAnonPeers; details.mAllowedSignedPeers = data.mAllowedSignedPeers; + + details.mAmIAllowed = data.mAmIAllowed ; return true; } } @@ -527,6 +530,7 @@ RsGxsCircleCache::RsGxsCircleCache() { mCircleType = GXS_CIRCLE_TYPE_EXTERNAL; mIsExternal = true; + mAmIAllowed = false ; mUpdateTime = 0; mGroupStatus = 0; mGroupSubscribeFlags = 0; @@ -547,6 +551,7 @@ bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup &circle) mIsExternal = (mCircleType != GXS_CIRCLE_TYPE_LOCAL); mGroupStatus = circle.mMeta.mGroupStatus; mGroupSubscribeFlags = circle.mMeta.mSubscribeFlags; + mAmIAllowed = false ; // by default. Will be computed later. #ifdef DEBUG_CIRCLES std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << ")"; @@ -929,8 +934,7 @@ bool p3GxsCircles::cache_start_load() bool p3GxsCircles::cache_load_for_token(uint32_t token) { #ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_load_for_token() : " << token; - std::cerr << std::endl; + std::cerr << "p3GxsCircles::cache_load_for_token() : " << token << std::endl; #endif // DEBUG_CIRCLES std::vector grpData; @@ -945,7 +949,7 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token) RsGxsCircleGroupItem *item = dynamic_cast(*vit); if (!item) { - std::cerr << "Not a RsGxsCircleGroupItem Item, deleting!" << std::endl; + std::cerr << " Not a RsGxsCircleGroupItem Item, deleting!" << std::endl; delete(*vit); continue; } @@ -953,9 +957,7 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token) item->convertTo(group); #ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_load_for_token() Loaded Id with Meta: "; - std::cerr << item->meta; - std::cerr << std::endl; + std::cerr << " Loaded Id with Meta: " << item->meta << std::endl; #endif // DEBUG_CIRCLES @@ -978,6 +980,7 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token) RsGxsCircleCache &cache = it->second; cache.loadBaseCircle(group); cache.mOriginator = item->meta.mOriginator ; + cache.mAmIAllowed = false; delete item; @@ -988,19 +991,31 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token) if (cache.mIsExternal) { #ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_load_for_token() Loading External Circle"; - std::cerr << std::endl; + std::cerr << " Loading External Circle" << std::endl; #endif std::set &peers = group.mInvitedMembers; std::set::const_iterator pit; + + std::list myOwnIds; + + rsIdentity->getOwnIds(myOwnIds) ; + bool ownIdInCircle = false ; + for(std::list::const_iterator it(myOwnIds.begin());it!=myOwnIds.end() && !ownIdInCircle;++it) + ownIdInCircle = ownIdInCircle || (peers.find(*it) != peers.end()) ; + +#ifdef DEBUG_CIRCLES + std::cerr << " own ID in circle: " << ownIdInCircle << std::endl; +#endif + + cache.mAmIAllowed = ownIdInCircle; + // need to trigger the searches. for(pit = peers.begin(); pit != peers.end(); ++pit) { #ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_load_for_token() Invited Member: " << *pit; - std::cerr << std::endl; + std::cerr << " Invited Member: " << *pit ; #endif /* check cache */ @@ -1013,16 +1028,14 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token) if ((details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) &&(details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN)) { #ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_load_for_token() Is Known -> AllowedPeer: " << *pit; - std::cerr << std::endl; + std::cerr << " Is Known -> AllowedPeer: " << *pit << std::endl; #endif cache.addAllowedPeer(details.mPgpId, *pit); } else { #ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_load_for_token() Is Unknown -> UnknownPeer: " << *pit; - std::cerr << std::endl; + std::cerr << " Is Unknown -> UnknownPeer: " << *pit << std::endl; #endif cache.mAllowedAnonPeers.insert(*pit); } @@ -1038,8 +1051,7 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token) { #ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_load_for_token() Requesting UnprocessedPeer: " << *pit; - std::cerr << std::endl; + std::cerr << " Requesting UnprocessedPeer: " << *pit << std::endl; #endif std::list peers; @@ -1094,8 +1106,7 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token) else { #ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_load_for_token() Loading Personal Circle"; - std::cerr << std::endl; + std::cerr << " Loading Personal Circle" << std::endl; #endif // LOCAL Load. @@ -1106,8 +1117,7 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token) for(pit = peers.begin(); pit != peers.end(); ++pit) { #ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_load_for_token() Local Friend: " << *pit; - std::cerr << std::endl; + std::cerr << " Local Friend: " << *pit << std::endl; #endif cache.addLocalFriend(*pit); @@ -1128,10 +1138,14 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token) /* remove from loading queue */ mLoadingCache.erase(it); + + std::cerr << " Loading complete." << std::endl; } if (isUnprocessedPeers) { + std::cerr << " Unprocessed peers. Requesting reload..." << std::endl; + /* schedule event to try reload gxsIds */ RsTickEvent::schedule_in(CIRCLE_EVENT_RELOADIDS, GXSID_LOAD_CYCLE, id.toStdString()); } @@ -1271,8 +1285,6 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId) bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache) { -#warning we should also check for items in mLoadingCache in this method. - #ifdef DEBUG_CIRCLES std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : "<< cache.mCircleId << std::endl; #endif @@ -1299,31 +1311,9 @@ bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache) /* if we appear in the group - then autosubscribe, and mark as processed */ - const RsPgpId& ownId = mPgpUtils->getPGPOwnId(); + const RsPgpId& ownPgpId = mPgpUtils->getPGPOwnId(); - std::map >::iterator it = cache.mAllowedSignedPeers.find(ownId); - bool am_I_allowed = it != cache.mAllowedSignedPeers.end() ; - - if(!am_I_allowed) - { - // also check if there's an unknown anonymous identity in the list that would belong to us - std::list own_gxs_ids ; - rsIdentity->getOwnIds(own_gxs_ids) ; - - for(std::list::const_iterator it(own_gxs_ids.begin());it!=own_gxs_ids.end();++it) - if(cache.mAllowedAnonPeers.end() != cache.mAllowedAnonPeers.find(*it)) - { - am_I_allowed = true ; -#ifdef DEBUG_CIRCLES - std::cerr << " found own GxsId " << *it << " as being in the circle" << std::endl; -#endif - break ; - } - } -#ifdef DEBUG_CIRCLES - else - std::cerr << " found own PGP id as signed to one of the circle's GxsIds" << std::endl; -#endif + bool am_I_allowed = cache.mAmIAllowed || (cache.mAllowedSignedPeers.find(ownPgpId) != cache.mAllowedSignedPeers.end()) ; if(am_I_allowed) { @@ -1344,7 +1334,7 @@ bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache) RsGenExchange::setGroupStatusFlags(token2, RsGxsGroupId(cache.mCircleId), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED); - cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED; + cache.mGroupStatus &= ~GXS_SERV::GXS_GRP_STATUS_UNPROCESSED; return true; } @@ -1366,7 +1356,7 @@ bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache) std::cerr << " Not part of the group, and not subscribed either." << std::endl; #endif - cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED; + cache.mGroupStatus &= ~GXS_SERV::GXS_GRP_STATUS_UNPROCESSED; return true ; } diff --git a/libretroshare/src/services/p3gxscircles.h b/libretroshare/src/services/p3gxscircles.h index f17f7dc12..1d645c40c 100644 --- a/libretroshare/src/services/p3gxscircles.h +++ b/libretroshare/src/services/p3gxscircles.h @@ -143,6 +143,7 @@ class RsGxsCircleCache uint32_t mCircleType; bool mIsExternal; + bool mAmIAllowed ; uint32_t mGroupStatus; uint32_t mGroupSubscribeFlags; diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index bcf87ef8b..e55539b10 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -339,150 +339,158 @@ 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 groupInfo; - std::list::iterator vit; + std::list groupInfo; + std::list::iterator vit; - 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); - - /* 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")); - - ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem); - } - - if(!mExternalSubCircleItem ) - { - mExternalSubCircleItem = new QTreeWidgetItem(); - mExternalSubCircleItem->setText(0, tr("Circles I belong to")); - ui->treeWidget_membership->addTopLevelItem(mExternalSubCircleItem); - } - - if(!mExternalLocalCircleItem) - { - mExternalLocalCircleItem = new QTreeWidgetItem(); - mExternalLocalCircleItem->setText(0, tr("Local circles")); - ui->treeWidget_membership->addTopLevelItem(mExternalLocalCircleItem); - } - - for(vit = groupInfo.begin(); vit != groupInfo.end();) - { -#ifdef ID_DEBUG - std::cerr << "CirclesDialog::loadCircleGroupMeta() GroupId: " << vit->mGroupId << " Group: " << vit->mGroupName << std::endl; -#endif - - QList clist = ui->treeWidget_membership->findItems( QString::fromStdString(vit->mGroupId.toStdString()), Qt::MatchExactly|Qt::MatchRecursive, CIRCLEGROUP_CIRCLE_COL_GROUPID); - - if(clist.empty()) - { - ++vit ; -#ifdef ID_DEBUG - std::cerr << " group not already in list." << std::endl; -#endif - continue ; - } - - if(clist.size() > 1) - { - std::cerr << " (EE) found " << clist.size() << " items in tree for group id " << vit->mGroupId << ": this is unexpected." << std::endl; - vit = groupInfo.erase(vit) ; - continue ; - } - QTreeWidgetItem *item = clist.front() ; - - bool subscribed = vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ; - - if(subscribed && item->parent() != mExternalSubCircleItem) - { -#ifdef ID_DEBUG - std::cerr << " Existing group is not in subscribed items although it is subscribed. Removing." << std::endl; -#endif - delete item ; - ++vit ; - continue ; - } - if(!subscribed && item->parent() != mExternalOtherCircleItem) - { -#ifdef ID_DEBUG - std::cerr << " Existing group is not in subscribed items although it is subscribed. Removing." << std::endl; -#endif - delete item ; - ++vit ; - continue ; - } - 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; -#endif - item->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(vit->mGroupName.c_str())); - } - - // the item is at the right place. Just remove it from the list of items to add. -#ifdef ID_DEBUG - std::cerr << " item already in place. Removing from list." << std::endl; -#endif - vit = groupInfo.erase(vit) ; - } - - for(vit = groupInfo.begin(); vit != groupInfo.end(); ++vit) + if (!rsGxsCircles->getGroupSummary(token,groupInfo)) { - 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 */ + std::cerr << "CirclesDialog::loadCircleGroupMeta() Error getting GroupMeta"; + std::cerr << std::endl; + mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, false); + return; + } - QTreeWidgetItem *groupItem = new QTreeWidgetItem(); - groupItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(vit->mGroupName.c_str())); - groupItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, QString::fromStdString(vit->mGroupId.toStdString())); - groupItem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(vit->mSubscribeFlags)); + mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true); - if (vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) + /* 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")); + + ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem); + } + + if(!mExternalSubCircleItem ) + { + mExternalSubCircleItem = new QTreeWidgetItem(); + mExternalSubCircleItem->setText(0, tr("Circles I belong to")); + ui->treeWidget_membership->addTopLevelItem(mExternalSubCircleItem); + } + + if(!mExternalLocalCircleItem) + { + mExternalLocalCircleItem = new QTreeWidgetItem(); + mExternalLocalCircleItem->setText(0, tr("Local circles")); + ui->treeWidget_membership->addTopLevelItem(mExternalLocalCircleItem); + } + + for(vit = groupInfo.begin(); vit != groupInfo.end();++vit) + { +#ifdef ID_DEBUG + std::cerr << "CirclesDialog::loadCircleGroupMeta() GroupId: " << vit->mGroupId << " Group: " << vit->mGroupName << std::endl; +#endif + RsGxsCircleDetails details; + rsGxsCircles->getCircleDetails(RsGxsCircleId(vit->mGroupId), details) ; + + bool should_re_add = true ; + bool subscribed = vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ; + bool am_I_in_circle = details.mAmIAllowed ; + QTreeWidgetItem *item = NULL ; + + std::cerr << "Loaded info for circle " << vit->mGroupId << ". ubscribed=" << subscribed << ", am_I_in_circle=" << am_I_in_circle << std::endl; + + // find already existing items for this circle + + QList clist = ui->treeWidget_membership->findItems( QString::fromStdString(vit->mGroupId.toStdString()), Qt::MatchExactly|Qt::MatchRecursive, CIRCLEGROUP_CIRCLE_COL_GROUPID); + + if(!clist.empty()) + { + // delete all duplicate items. This should not happen, but just in case it does. + + while(clist.size() > 1) { #ifdef ID_DEBUG - std::cerr << " adding item for group " << vit->mGroupId << " to subscribed"<< std::endl; + std::cerr << " more than 1 item correspond to this ID. Removing!" << std::endl; #endif - mExternalSubCircleItem->addChild(groupItem); - } - else - { + delete clist.front() ; + } + + item = clist.front() ; + + if(am_I_in_circle && item->parent() != mExternalSubCircleItem) + { #ifdef ID_DEBUG - std::cerr << " adding item for group " << vit->mGroupId << " to others"<< std::endl; + std::cerr << " Existing group is not in subscribed items although it is subscribed. Removing." << std::endl; #endif - mExternalOtherCircleItem->addChild(groupItem); - } - - if (vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) - { - QFont font = groupItem->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ; - font.setBold(true) ; - groupItem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ; - groupItem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ; - groupItem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ; - } + 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; +#endif + delete item ; + item = NULL ; + } + else + 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 */ + + 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)); + + if(am_I_in_circle) + { +#ifdef ID_DEBUG + std::cerr << " adding item for group " << vit->mGroupId << " to own circles"<< std::endl; +#endif + mExternalSubCircleItem->addChild(item); + } + else + { +#ifdef ID_DEBUG + std::cerr << " adding item for group " << vit->mGroupId << " to others"<< std::endl; +#endif + mExternalOtherCircleItem->addChild(item); + } + } + 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; +#endif + item->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(vit->mGroupName.c_str())); + } + + 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 (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")) ; } }