mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-30 09:56:14 -05:00
first version of circle messages
This commit is contained in:
parent
c9846c0dcf
commit
9a86989060
@ -136,8 +136,8 @@ virtual bool getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
|
|||||||
|
|
||||||
/* membership management for external circles */
|
/* membership management for external circles */
|
||||||
|
|
||||||
virtual bool requestCircleMembership(const RsGxsCircleId& id)=0 ;
|
virtual bool requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
|
||||||
virtual bool cancelCircleMembership(const RsGxsCircleId& id)=0 ;
|
virtual bool cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
|
||||||
|
|
||||||
/* standard load */
|
/* standard load */
|
||||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;
|
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;
|
||||||
|
@ -1819,15 +1819,132 @@ void p3GxsCircles::handle_event(uint32_t event_type, const std::string &elabel)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Circle membership is requested/denied by posting a message into the cicle group, according to the following rules:
|
||||||
|
//
|
||||||
|
// - a subscription request is a RsItem (which serialises into a radix64 message, that is further signed by the group message publishing system)
|
||||||
|
// The item contains:
|
||||||
|
// * subscribe order (yes/no), boolean
|
||||||
|
// * circle ID (this is important, otherwise people can copy subscribe messages from one circle to another)
|
||||||
|
// * subscribe date
|
||||||
|
// * subscribe timeout (how long is the message kept. When timed out, the message is removed and subscription cancelled)
|
||||||
|
//
|
||||||
|
// - subscribe messages follow the following rules, which are enforced by a timer-based method:
|
||||||
|
// * subscription requests from a given user are always replaced by the last subscription request
|
||||||
|
// * a complete list of who's subscribed to a given group is kept, saved, and regularly updated when new subscribe messages are received, or when admin list is changed.
|
||||||
|
// * getGroupDetails reads this list in order to respond who's subscribed to a group. The list of
|
||||||
|
//
|
||||||
|
// - compatibility with self-restricted circles:
|
||||||
|
// * subscription should be based on admin list, so that non subscribed peers still receive the invitation
|
||||||
|
//
|
||||||
|
// - Use cases
|
||||||
|
// * user sees group (not self restricted) and requests to subscribe => RS subscribes the group and the user can propagate the response
|
||||||
|
//
|
||||||
|
// - Threat model
|
||||||
|
// * a malicious user forges a new subscription request: NP-hard as it needs to break the RSA key of the GXS id.
|
||||||
|
// * a malicious corrupts a subscription request: NP-hard. Messages are signed.
|
||||||
|
// * a malicious user copies an old subscription of someone else and inserts it in the system.
|
||||||
|
// => not possible. Either this existing old susbscription already exists, or it has been replaced by a more recent one, which
|
||||||
|
// will always replace the old one because of the date.
|
||||||
|
// * a malicious user removes someone's subscription messages. This is possible, but the mesh nature of the network will allow the message to propagate anyway.
|
||||||
|
|
||||||
bool p3GxsCircles::requestCircleMembership(const RsGxsCircleId& id)
|
bool p3GxsCircles::pushCircleMembershipRequest(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id,uint32_t request_type)
|
||||||
{
|
{
|
||||||
#warning code missing here !!!
|
// check for some consistency
|
||||||
|
|
||||||
|
if(request_type != RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_SUBSCRIBE && request_type != RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_UNSUBSCRIBE)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
std::list<RsGxsId> own_ids ;
|
||||||
|
if(!rsIdentity->getOwnIds(own_ids))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
bool found = false ;
|
||||||
|
for(std::list<RsGxsId>::const_iterator it(own_ids.begin());it!=own_ids.end() && !found;++it)
|
||||||
|
found = ( (*it) == own_gxsid) ;
|
||||||
|
|
||||||
|
if(!found)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// Create a subscribe item
|
||||||
|
|
||||||
|
RsGxsCircleSubscriptionRequestItem s ;
|
||||||
|
|
||||||
|
s.time_stamp = time(NULL) ;
|
||||||
|
s.subscription_request = RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_SUBSCRIBE ;
|
||||||
|
s.circle_id = id ;
|
||||||
|
s.time_out = 0 ; // means never
|
||||||
|
|
||||||
|
// Serialise it into a base64 string
|
||||||
|
|
||||||
|
uint32_t pktsize = s.serial_size() ;
|
||||||
|
|
||||||
|
RsTemporaryMemory mem(s.serial_size()) ;
|
||||||
|
|
||||||
|
if(!mem)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
s.serialise(mem,pktsize) ;
|
||||||
|
|
||||||
|
std::string msg ;
|
||||||
|
Radix64::encode(mem,pktsize,msg) ;
|
||||||
|
|
||||||
|
// Create the group message to store and publish it
|
||||||
|
|
||||||
|
RsTemporaryMemory tmpmem(RsGxsCircleId::SIZE_IN_BYTES + RsGxsId::SIZE_IN_BYTES) ;
|
||||||
|
|
||||||
|
if(!tmpmem)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
circle_id.serialise(tmpmem,tmpmem.size()) ;
|
||||||
|
own_gxsid.serialise(tmpmem+RsGxsCircleId::SIZE_IN_BYTES,(int)tmpmem.size()-(int)RsGxsCircleId::SIZE_IN_BYTES) ;
|
||||||
|
|
||||||
|
RsGxsCircleMsgItem* msgItem = new RsGxsCircleMsgItem();
|
||||||
|
msgItem->mMsg = msg;
|
||||||
|
|
||||||
|
msgItem->meta.mGroupId = id ;
|
||||||
|
msgItem->meta.mMsgId.clear();
|
||||||
|
msgItem->meta.mThreadId = sha1sum(tmpmem,tmpmem.size()); // make the ID from the hash of the cirle ID and the author ID
|
||||||
|
msgItem->meta.mAuthorId = own_id;
|
||||||
|
|
||||||
|
// msgItem->meta.mParentId = ; // leave these blank
|
||||||
|
// msgItem->meta.mOrigMsgId= ;
|
||||||
|
|
||||||
|
std::cerr << "p3GxsCircles::publishSubscribeRequest()" << std::endl;
|
||||||
|
std::cerr << " GroupId : " << circle_id << std::endl;
|
||||||
|
std::cerr << " AuthorId : " << msgItem->meta.mAuthorId << std::endl;
|
||||||
|
std::cerr << " ThreadId : " << msgItem->meta.mThreadId << std::endl;
|
||||||
|
|
||||||
|
#warning Would be nice to wait for a few seconds before publishing, so that the user can potentially cancel a wrong request before it gets piped into the system
|
||||||
|
//RsGenExchange::publishMsg(token, msgItem);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3GxsCircles::cancelCircleMembership(const RsGxsCircleId& id)
|
bool p3GxsCircles::requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)
|
||||||
{
|
{
|
||||||
#warning code missing here !!!
|
return pushCircleMembershipRequest(own_id,circle_id,RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_SUBSCRIBE) ;
|
||||||
|
}
|
||||||
|
bool p3GxsCircles::cancelCircleMembership(const RsGxsId& own_id,const RsGxsCircleId& id)
|
||||||
|
{
|
||||||
|
return pushCircleMembershipRequest(own_id,circle_id,RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_UNSUBSCRIBE) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,8 +194,8 @@ virtual RsServiceInfo getServiceInfo();
|
|||||||
|
|
||||||
/* membership management for external circles */
|
/* membership management for external circles */
|
||||||
|
|
||||||
virtual bool requestCircleMembership(const RsGxsCircleId& id) ;
|
virtual bool requestCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) ;
|
||||||
virtual bool cancelCircleMembership(const RsGxsCircleId& id) ;
|
virtual bool cancelCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) ;
|
||||||
|
|
||||||
/**********************************************/
|
/**********************************************/
|
||||||
|
|
||||||
@ -204,6 +204,7 @@ virtual RsServiceInfo getServiceInfo();
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
bool pushCircleMembershipRequest(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id,uint32_t request_type) ;
|
||||||
static uint32_t circleAuthenPolicy();
|
static uint32_t circleAuthenPolicy();
|
||||||
|
|
||||||
/** Notifications **/
|
/** Notifications **/
|
||||||
|
@ -436,7 +436,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
|
|||||||
if(am_I_in_circle && item->parent() != mExternalBelongingCircleItem)
|
if(am_I_in_circle && item->parent() != mExternalBelongingCircleItem)
|
||||||
{
|
{
|
||||||
#ifdef ID_DEBUG
|
#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
|
#endif
|
||||||
delete item ;
|
delete item ;
|
||||||
item = NULL ;
|
item = NULL ;
|
||||||
@ -444,7 +444,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
|
|||||||
else if(!am_I_in_circle && item->parent() != mExternalOtherCircleItem)
|
else if(!am_I_in_circle && item->parent() != mExternalOtherCircleItem)
|
||||||
{
|
{
|
||||||
#ifdef ID_DEBUG
|
#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
|
#endif
|
||||||
delete item ;
|
delete item ;
|
||||||
item = NULL ;
|
item = NULL ;
|
||||||
@ -467,14 +467,14 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
|
|||||||
if(am_I_in_circle)
|
if(am_I_in_circle)
|
||||||
{
|
{
|
||||||
#ifdef ID_DEBUG
|
#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
|
#endif
|
||||||
mExternalBelongingCircleItem->addChild(item);
|
mExternalBelongingCircleItem->addChild(item);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef ID_DEBUG
|
#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
|
#endif
|
||||||
mExternalOtherCircleItem->addChild(item);
|
mExternalOtherCircleItem->addChild(item);
|
||||||
}
|
}
|
||||||
@ -482,7 +482,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
|
|||||||
else if(item->text(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) != QString::fromUtf8(vit->mGroupName.c_str()))
|
else if(item->text(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) != QString::fromUtf8(vit->mGroupName.c_str()))
|
||||||
{
|
{
|
||||||
#ifdef ID_DEBUG
|
#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
|
#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()));
|
||||||
}
|
}
|
||||||
@ -504,17 +504,17 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
|
|||||||
{
|
{
|
||||||
case GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED:
|
case GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED:
|
||||||
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_yellow_128.png")) ;
|
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_yellow_128.png")) ;
|
||||||
item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("Your request to be in this group is still pending. You need to wait the administrator to validate it.")) ;
|
item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("Your request to be in this circle is pending. You need to wait for the administrator to validate it.")) ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST:
|
case GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST:
|
||||||
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_blue_128.png")) ;
|
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_blue_128.png")) ;
|
||||||
item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("You are invited to this group by the administrator. Right click to join the group.")) ;
|
item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("You are invited to this circle by the administrator. Right click to join the circle.")) ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST | GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED:
|
case GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST | GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED:
|
||||||
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_green_128.png")) ;
|
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_green_128.png")) ;
|
||||||
item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("You are a member of this group.")) ;
|
item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("You are a validated member of this circle.")) ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user